[JEDI.NET-commits] main/run Jedi.System.SourceVersioning.pas,NONE,1.1
Status: Pre-Alpha
Brought to you by:
jedi_mbe
From: Marcel B. <jed...@us...> - 2005-01-21 20:07:29
|
Update of /cvsroot/jedidotnet/main/run In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9583/main/run Added Files: Jedi.System.SourceVersioning.pas Log Message: Attribute that can be used to keep track of source version for classes, delegates, enumerations, interfaces and records --- NEW FILE: Jedi.System.SourceVersioning.pas --- unit Jedi.System.SourceVersioning; interface type {$REGION 'Forward declarations'} SourceVersionAttribute = class; SourceVersionRevision = record; {$ENDREGION} {$REGION 'SourceVersion attribute'} [AttributeUsage(AttributeTargets.Class or AttributeTargets.Delegate or AttributeTargets.Enum or AttributeTargets.Interface or AttributeTargets.Struct, &Inherited = False)] SourceVersionAttribute = class (Attribute) {$REGION 'Constructors'} public constructor Create(id: string); overload; constructor Create(sourceFile, revision, date: string); overload; {$ENDREGION} {$REGION 'Constants'} strict protected const dateFormat = 'yyyy\/MM\/dd HH\:mm\:ss'; {$ENDREGION} {$REGION 'Data'} strict private FDate: DateTime; FRevision: SourceVersionRevision; FSourceFile: string; {$ENDREGION} {$REGION 'Properties'} public property Date: DateTime read FDate; property Revision: SourceVersionRevision read FRevision; property SourceFile: string read FSourceFile; {$ENDREGION} {$REGION 'Static parsing methods'} public class function ParseDate(date: string): DateTime; static; class procedure ParseId(id: string; out source: string; out revision: SourceVersionRevision; out date: DateTime); static; class function ParseRevision(revision: string): SourceVersionRevision; static; class function ParseSource(source: string): string; static; {$ENDREGION} end; {$ENDREGION} {$REGION 'SourceVersion revision type'} [SourceVersion('$header$')] SourceVersionRevision = record (IComparable) {$REGION 'Constructors'} public constructor Create(revision: string); overload; constructor Create(revision: Double); overload; constructor Create(major, minor: Integer); overload; constructor Create(values: array of Integer); overload; {$ENDREGION} {$REGION 'Data'} strict private FValues: array of Integer; {$ENDREGION} {$REGION 'IComparable methods'} strict private function CompareTo(obj: &Object): Integer; {$ENDREGION} {$REGION 'Operators: comparisons'} public class operator Equal(left, right: SourceVersionRevision): Boolean; class operator GreaterThan(left, right: SourceVersionRevision): Boolean; class operator GreaterThanOrEqual(left, right: SourceVersionRevision): Boolean; class operator LessThan(left, right: SourceVersionRevision): Boolean; class operator LessThanOrEqual(left, right: SourceVersionRevision): Boolean; class operator NotEqual(left, right: SourceVersionRevision): Boolean; {$ENDREGION} {$REGION 'Operators: conversions'} public class operator Implicit(const Value: Double): SourceVersionRevision; class operator Implicit(const Value: SourceVersionRevision): Double; class operator Implicit(const Value: string): SourceVersionRevision; class operator Implicit(const Value: SourceVersionRevision): string; {$ENDREGION} {$REGION 'Overrides'} public function ToString: string; override; {$ENDREGION} {$REGION 'Properties (accessors)'} public function get_Count: Integer; function get_Items(index: Integer): Integer; {$ENDREGION} {$REGION 'Properties'} public property Count: Integer read get_Count; property Items[&index: Integer]: Integer read get_Items; default; {$ENDREGION} end; {$ENDREGION} implementation {$AUTOBOX ON} {$REGION 'implementation uses'} uses System.Globalization, System.Text, Jedi.System.Strings; {$ENDREGION} {$REGION 'Array types'} type IntegerArray = array of Integer; {$ENDREGION} {$REGION 'SourceVersionAttribute'} constructor SourceVersionAttribute.Create(id: string); begin inherited Create; ParseId(id, FSourceFile, FRevision, FDate); end; constructor SourceVersionAttribute.Create(sourceFile, revision, date: string); begin inherited Create; FDate := ParseDate(date); FSourceFile := ParseSource(sourceFile); FRevision := ParseRevision(revision); end; class function SourceVersionAttribute.ParseDate(date: string): DateTime; begin if date.ToLower.StartsWith('$date: ') then Result := DateTime.ParseExact(date.Substring(7, date.Length - 8).Trim, dateFormat, DateTimeFormatInfo.InvariantInfo) else Result := DateTime.ParseExact(date.Trim, dateFormat, DateTimeFormatInfo.InvariantInfo); end; class procedure SourceVersionAttribute.ParseId(id: string; out source: string; out revision: SourceVersionRevision; out date: DateTime); var idx: Integer; begin if id.ToLower.StartsWith('$id: ') then id := id.Substring(5, id.Length - 6).Trim else if id.ToLower.StartsWith('$header: ') then id := id.Substring(9, id.Length - 10).Trim else raise FormatException.Create('Not an $Id' + '$ or $Header' + '$ CVS keyword expansion.'); idx := id.ToLower.IndexOf(',v '); if idx <= 0 then raise FormatException.Create('file name not found in the specified id string.'); source := id.Substring(0, idx); id := id.Remove(0, idx + 3).Trim; idx := id.IndexOf(' '); if idx < 0 then raise FormatException.Create('revision number not found in the specified id string.'); revision := id.Substring(0, idx); id := id.Remove(0, idx + 1).Trim; idx := id.IndexOf(' '); if idx < 0 then raise FormatException.Create('date not found in the specified id string.'); date := DateTime.ParseExact(id.Substring(0, idx), dateFormat, DateTimeFormatInfo.InvariantInfo); end; class function SourceVersionAttribute.ParseRevision(revision: string): SourceVersionRevision; begin if revision.ToLower.StartsWith('$revision: ') then Result := revision.Substring(11, revision.Length - 12).Trim else Result := revision.Trim; end; class function SourceVersionAttribute.ParseSource(source: string): string; begin if source.ToLower.StartsWith('$rcsfile: ') then Result := source.Substring(10, source.Length - 13) else if source.ToLower.StartsWith('$source: ') then Result := source.Substring(9, source.Length - 12) else begin Result := source.Trim; if Result.ToLower.EndsWith(',v') then Result := Result.Substring(0, Result.Length - 2); end; end; {$ENDREGION} {$REGION 'SourceVersionRevision'} constructor SourceVersionRevision.Create(revision: string); var elements: array of string; idx: Integer; begin inherited Create; elements := revision.Split(['.']); FValues := new (IntegerArray, &Array(elements).Length); for idx := 0 to &Array(elements).Length - 1 do FValues[idx] := Int32.Parse(elements[idx]); end; constructor SourceVersionRevision.Create(revision: Double); begin Create(revision.ToString('r', NumberFormatInfo.InvariantInfo)); end; constructor SourceVersionRevision.Create(major, minor: Integer); begin inherited Create; FValues := IntegerArray.Create(major, minor); end; constructor SourceVersionRevision.Create(values: array of Integer); begin inherited Create; FValues := values; end; function SourceVersionRevision.CompareTo(obj: &Object): Integer; var secRev: SourceVersionRevision; maxIdx: Integer; idx: Integer; begin secRev := SourceVersionRevision(obj); maxIdx := Math.Min(&Array(FValues).Length, &Array(secRev.FValues).Length) - 1; Result := 0; idx := 0; while (Result = 0) and (idx <= maxIdx) do begin Result := IComparable(FValues[idx]).CompareTo(secRev.FValues[idx]); Inc(idx); end; if Result = 0 then Result := IComparable(&Array(FValues).Length).CompareTo(&Array(secRev.FValues).Length); end; class operator SourceVersionRevision.Equal(left, right: SourceVersionRevision): Boolean; begin Result := left.CompareTo(right) = 0; end; function SourceVersionRevision.get_Count: Integer; begin Result := &Array(FValues).Length; end; function SourceVersionRevision.get_Items(index: Integer): Integer; begin Result := FValues[index]; end; class operator SourceVersionRevision.GreaterThan(left, right: SourceVersionRevision): Boolean; begin Result := left.CompareTo(right) > 0; end; class operator SourceVersionRevision.GreaterThanOrEqual(left, right: SourceVersionRevision): Boolean; begin Result := left.CompareTo(right) >= 0; end; class operator SourceVersionRevision.Implicit(const value: Double): SourceVersionRevision; begin Result := SourceVersionRevision.Create(value); end; class operator SourceVersionRevision.Implicit(const value: SourceVersionRevision): Double; begin if value.Count > 2 then Result := System.Double.Nan else Result := System.Double.Parse(value.ToString, NumberFormatInfo.InvariantInfo); end; class operator SourceVersionRevision.Implicit(const value: string): SourceVersionRevision; begin Result := SourceVersionRevision.Create(value); end; class operator SourceVersionRevision.Implicit(const value: SourceVersionRevision): string; begin Result := value.ToString; end; class operator SourceVersionRevision.LessThan(left, right: SourceVersionRevision): Boolean; begin Result := left.CompareTo(right) < 0; end; class operator SourceVersionRevision.LessThanOrEqual(left, right: SourceVersionRevision): Boolean; begin Result := left.CompareTo(right) <= 0; end; class operator SourceVersionRevision.NotEqual(left, right: SourceVersionRevision): Boolean; begin Result := left.CompareTo(right) <> 0; end; function SourceVersionRevision.ToString: string; var sb: StringBuilder; element: Integer; begin sb := StringBuilder.Create; for element in FValues do begin sb.Append(element); sb.Append('.'); end; if sb.Length > 0 then Result := sb.ToString(0, sb.Length - 1) else Result := System.String.Empty; end; {$ENDREGION} end. |