mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 05:48:12 +02:00
332 lines
8.9 KiB
ObjectPascal
332 lines
8.9 KiB
ObjectPascal
unit PackageDependencyIntf;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,
|
|
// LazUtils
|
|
LazFileUtils;
|
|
|
|
type
|
|
|
|
{ TPkgVersion }
|
|
|
|
TPkgVersionValid = (
|
|
pvtNone,
|
|
pvtMajor,
|
|
pvtMinor,
|
|
pvtRelease,
|
|
pvtBuild
|
|
);
|
|
|
|
TPkgVersion = class
|
|
private
|
|
FMajor: integer;
|
|
FMinor: integer;
|
|
FRelease: integer;
|
|
FBuild: integer;
|
|
FValid: TPkgVersionValid;
|
|
FOnChange: TNotifyEvent;
|
|
function GetAsString: String;
|
|
procedure SetAsString(const AValue: String);
|
|
public
|
|
procedure Clear;
|
|
function Compare(Version2: TPkgVersion): integer;
|
|
function CompareMask(ExactVersion: TPkgVersion): integer;
|
|
procedure Assign(Source: TPkgVersion);
|
|
//function AsString: string;
|
|
function AsWord: string;
|
|
function GetIsNullVersion: Boolean;
|
|
function ReadString(const s: string): boolean;
|
|
procedure SetValues(NewMajor, NewMinor, NewRelease, NewBuild: integer;
|
|
NewValid: TPkgVersionValid = pvtBuild);
|
|
function VersionBound(v: integer): integer;
|
|
public
|
|
property AsString: String read GetAsString write SetAsString;
|
|
property Major: Integer read FMajor write FMajor;
|
|
property Minor: Integer read FMinor write FMinor;
|
|
property Release: Integer read FRelease write FRelease;
|
|
property Build: Integer read FBuild write FBuild;
|
|
property IsNullVersion: Boolean read GetIsNullVersion;
|
|
property Valid: TPkgVersionValid read FValid write FValid;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
end;
|
|
|
|
{ PkgDependency flags }
|
|
|
|
TPkgDependencyFlag = (
|
|
pdfMinVersion, // >= MinVersion
|
|
pdfMaxVersion // <= MaxVersion
|
|
);
|
|
TPkgDependencyFlags = set of TPkgDependencyFlag;
|
|
|
|
{ TPkgDependencyBase }
|
|
|
|
TPkgDependencyBase = class
|
|
private
|
|
protected
|
|
FFlags: TPkgDependencyFlags;
|
|
FMaxVersion: TPkgVersion;
|
|
FMinVersion: TPkgVersion;
|
|
FPackageName: string;
|
|
FRemoved: boolean;
|
|
//FRequiredPackage: TIDEPackage;
|
|
procedure SetPackageName(const AValue: string); virtual; abstract;
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure Clear; virtual;
|
|
function IsMakingSense: boolean;
|
|
function IsCompatible(const Version: TPkgVersion): boolean; overload;
|
|
function IsCompatible(const PkgName: string; const Version: TPkgVersion): boolean; overload;
|
|
// API for iterating dependencies.
|
|
function NextUsedByDependency: TPkgDependencyBase; virtual; abstract;
|
|
function PrevUsedByDependency: TPkgDependencyBase; virtual; abstract;
|
|
function NextRequiresDependency: TPkgDependencyBase; virtual; abstract;
|
|
function PrevRequiresDependency: TPkgDependencyBase; virtual; abstract;
|
|
// API for adding / removing dependencies.
|
|
procedure AddRequiresDep(var FirstDependency: TPkgDependencyBase); virtual; abstract;
|
|
procedure AddUsedByDep(var FirstDependency: TPkgDependencyBase); virtual; abstract;
|
|
procedure RemoveRequiresDep(var FirstDependency: TPkgDependencyBase); virtual; abstract;
|
|
procedure RemoveUsedByDep(var FirstDependency: TPkgDependencyBase); virtual; abstract;
|
|
public
|
|
property Flags: TPkgDependencyFlags read FFlags write FFlags;
|
|
property MinVersion: TPkgVersion read FMinVersion write FMinVersion;
|
|
property MaxVersion: TPkgVersion read FMaxVersion write FMaxVersion;
|
|
property PackageName: string read FPackageName write SetPackageName;
|
|
property Removed: boolean read FRemoved write FRemoved;
|
|
end;
|
|
|
|
function IsValidUnitName(AUnitName: String): Boolean; inline;
|
|
function IsValidPkgName(APkgName: String): Boolean; inline;
|
|
function PackageFileNameIsValid(const AFilename: string): boolean;
|
|
|
|
|
|
implementation
|
|
|
|
function IsValidUnitName(AUnitName: String): Boolean;
|
|
begin
|
|
Result := IsValidIdent(AUnitName, True, True);
|
|
end;
|
|
|
|
function IsValidPkgName(APkgName: String): Boolean;
|
|
begin
|
|
Result := IsValidIdent(APkgName, True, True);
|
|
end;
|
|
|
|
function PackageFileNameIsValid(const AFilename: string): boolean;
|
|
var
|
|
PkgName: String;
|
|
begin
|
|
Result:=false;
|
|
if not FilenameExtIs(AFilename,'lpk',true) then exit;
|
|
PkgName:=ExtractFileNameOnly(AFilename);
|
|
if (PkgName='') or (not IsValidPkgName(PkgName)) then exit;
|
|
Result:=true;
|
|
end;
|
|
|
|
{ TPkgVersion }
|
|
|
|
procedure TPkgVersion.Clear;
|
|
begin
|
|
SetValues(0,0,0,0,pvtBuild);
|
|
end;
|
|
|
|
function TPkgVersion.Compare(Version2: TPkgVersion): integer;
|
|
begin
|
|
Result:=FMajor-Version2.FMajor;
|
|
if Result<>0 then exit;
|
|
Result:=FMinor-Version2.FMinor;
|
|
if Result<>0 then exit;
|
|
Result:=FRelease-Version2.FRelease;
|
|
if Result<>0 then exit;
|
|
Result:=FBuild-Version2.FBuild;
|
|
end;
|
|
|
|
function TPkgVersion.CompareMask(ExactVersion: TPkgVersion): integer;
|
|
begin
|
|
if FValid=pvtNone then exit(0);
|
|
Result:=FMajor-ExactVersion.FMajor;
|
|
if Result<>0 then exit;
|
|
if FValid=pvtMajor then exit;
|
|
Result:=FMinor-ExactVersion.FMinor;
|
|
if Result<>0 then exit;
|
|
if FValid=pvtMinor then exit;
|
|
Result:=FRelease-ExactVersion.FRelease;
|
|
if Result<>0 then exit;
|
|
if FValid=pvtRelease then exit;
|
|
Result:=FBuild-ExactVersion.FBuild;
|
|
end;
|
|
|
|
procedure TPkgVersion.Assign(Source: TPkgVersion);
|
|
begin
|
|
SetValues(Source.FMajor,Source.FMinor,Source.FRelease,Source.FBuild,Source.FValid);
|
|
end;
|
|
|
|
function TPkgVersion.GetAsString: String;
|
|
begin
|
|
Result:=IntToStr(FMajor)+'.'+IntToStr(FMinor);
|
|
if (FBuild<>0) then
|
|
Result:=Result+'.'+IntToStr(FRelease)+'.'+IntToStr(FBuild)
|
|
else if (FRelease<>0) then
|
|
Result:=Result+'.'+IntToStr(FRelease)
|
|
end;
|
|
|
|
procedure TPkgVersion.SetAsString(const AValue: String);
|
|
var
|
|
Version: String;
|
|
P, I, V: Integer;
|
|
begin
|
|
Clear;
|
|
if AValue = '' then Exit;
|
|
I := 0;
|
|
Version := Trim(AValue) + '.';
|
|
repeat
|
|
Inc(I);
|
|
P := Pos('.', Version);
|
|
if P <> 0 then
|
|
begin
|
|
V := StrToIntDef(Copy(Version, 1, P-1), 0);
|
|
case I of
|
|
1: FMajor := V;
|
|
2: FMinor := V;
|
|
3: FRelease := V;
|
|
4: FBuild := V;
|
|
end;
|
|
Delete(Version, 1, P);
|
|
end;
|
|
until (Version = '') or (P = 0) or (I > 4);
|
|
end;
|
|
|
|
function TPkgVersion.AsWord: string;
|
|
begin
|
|
Result:=IntToStr(FMajor)+'_'+IntToStr(FMinor);
|
|
if (FBuild<>0) then
|
|
Result:=Result+'_'+IntToStr(FRelease)+'_'+IntToStr(FBuild)
|
|
else if (FRelease<>0) then
|
|
Result:=Result+'_'+IntToStr(FRelease)
|
|
end;
|
|
|
|
function TPkgVersion.GetIsNullVersion: Boolean;
|
|
begin
|
|
Result := (FMajor = 0) and (FMinor = 0) and (FRelease = 0) and (FBuild = 0);
|
|
end;
|
|
|
|
function TPkgVersion.ReadString(const s: string): boolean;
|
|
var
|
|
ints: array[1..4] of integer;
|
|
i: integer;
|
|
CurPos: Integer;
|
|
StartPos: Integer;
|
|
NewValid: TPkgVersionValid;
|
|
begin
|
|
Result:=false;
|
|
CurPos:=1;
|
|
NewValid:=pvtNone;
|
|
for i:=1 to 4 do begin
|
|
ints[i]:=0;
|
|
if CurPos<length(s) then begin
|
|
if i>Low(ints) then begin
|
|
// read point
|
|
if s[CurPos]<>'.' then exit;
|
|
inc(CurPos);
|
|
end;
|
|
// read int
|
|
StartPos:=CurPos;
|
|
while (CurPos<=length(s)) and (i<=9999)
|
|
and (s[CurPos] in ['0'..'9']) do begin
|
|
ints[i]:=ints[i]*10+ord(s[CurPos])-ord('0');
|
|
inc(CurPos);
|
|
end;
|
|
if (StartPos=CurPos) then exit;
|
|
NewValid:=succ(NewValid);
|
|
end;
|
|
end;
|
|
if CurPos<=length(s) then exit;
|
|
SetValues(ints[1],ints[2],ints[3],ints[4],NewValid);
|
|
|
|
Result:=true;
|
|
end;
|
|
|
|
procedure TPkgVersion.SetValues(NewMajor, NewMinor, NewRelease,
|
|
NewBuild: integer; NewValid: TPkgVersionValid);
|
|
begin
|
|
NewMajor:=VersionBound(NewMajor);
|
|
NewMinor:=VersionBound(NewMinor);
|
|
NewRelease:=VersionBound(NewRelease);
|
|
NewBuild:=VersionBound(NewBuild);
|
|
if (NewMajor=FMajor) and (NewMinor=FMinor) and (NewRelease=FRelease)
|
|
and (NewBuild=FBuild) and (NewValid=FValid) then exit;
|
|
FMajor:=NewMajor;
|
|
FMinor:=NewMinor;
|
|
FRelease:=NewRelease;
|
|
FBuild:=NewBuild;
|
|
FValid:=NewValid;
|
|
if Assigned(FOnChange) then FOnChange(Self);
|
|
end;
|
|
|
|
function TPkgVersion.VersionBound(v: integer): integer;
|
|
begin
|
|
if v>9999 then
|
|
Result:=9999
|
|
else if v<0 then
|
|
Result:=0
|
|
else
|
|
Result:=v;
|
|
end;
|
|
|
|
{ TLazPackageID }
|
|
|
|
constructor TPkgDependencyBase.Create;
|
|
begin
|
|
inherited Create;
|
|
MinVersion:=TPkgVersion.Create;
|
|
MaxVersion:=TPkgVersion.Create;
|
|
Clear;
|
|
end;
|
|
|
|
destructor TPkgDependencyBase.Destroy;
|
|
begin
|
|
PackageName:='';
|
|
FreeAndNil(fMinVersion);
|
|
FreeAndNil(fMaxVersion);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TPkgDependencyBase.Clear;
|
|
begin
|
|
PackageName:='';
|
|
FRemoved:=false;
|
|
FFlags:=[];
|
|
FMaxVersion.Clear;
|
|
FMinVersion.Clear;
|
|
end;
|
|
|
|
function TPkgDependencyBase.IsMakingSense: boolean;
|
|
begin
|
|
Result:=IsValidPkgName(PackageName);
|
|
if Result
|
|
and (pdfMinVersion in FFlags) and (pdfMaxVersion in FFlags)
|
|
and (MinVersion.Compare(MaxVersion)>0) then
|
|
Result:=false;
|
|
end;
|
|
|
|
function TPkgDependencyBase.IsCompatible(const Version: TPkgVersion): boolean;
|
|
begin
|
|
if ((pdfMinVersion in FFlags) and (MinVersion.Compare(Version)>0))
|
|
or ((pdfMaxVersion in FFlags) and (MaxVersion.Compare(Version)<0)) then
|
|
Result:=false
|
|
else
|
|
Result:=true;
|
|
end;
|
|
|
|
function TPkgDependencyBase.IsCompatible(const PkgName: string; const Version: TPkgVersion): boolean;
|
|
begin
|
|
Result:=(CompareText(PkgName,PackageName)=0) and IsCompatible(Version);
|
|
end;
|
|
|
|
end.
|
|
|