mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 07:29:21 +02:00
implemented global and user package links
git-svn-id: trunk@3995 -
This commit is contained in:
parent
785fa3ffb3
commit
ea9a0852aa
@ -1039,8 +1039,15 @@ begin
|
|||||||
if (not FileExists(ConfFileName)) then begin
|
if (not FileExists(ConfFileName)) then begin
|
||||||
writeln('NOTE: editor options config file not found - using defaults');
|
writeln('NOTE: editor options config file not found - using defaults');
|
||||||
end;
|
end;
|
||||||
XMLConfig:=TXMLConfig.Create(ConfFileName);
|
try
|
||||||
|
XMLConfig:=TXMLConfig.Create(ConfFileName);
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
writeln('WARNING: unable to read ',ConfFileName);
|
||||||
|
XMLConfig:=nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
|
|
||||||
// General options
|
// General options
|
||||||
|
@ -52,7 +52,7 @@ uses
|
|||||||
|
|
||||||
{ The primary config path is the local or user specific path.
|
{ The primary config path is the local or user specific path.
|
||||||
If the primary config path does not exists, it will automatically be
|
If the primary config path does not exists, it will automatically be
|
||||||
created.
|
created by the IDE.
|
||||||
The secondary config path is for templates. The IDE will never write to it.
|
The secondary config path is for templates. The IDE will never write to it.
|
||||||
If a config file is not found in the primary config file, Lazarus will
|
If a config file is not found in the primary config file, Lazarus will
|
||||||
copy the template file from the secondary config file. If there is no
|
copy the template file from the secondary config file. If there is no
|
||||||
@ -124,6 +124,9 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.15 2003/04/01 22:49:47 mattias
|
||||||
|
implemented global and user package links
|
||||||
|
|
||||||
Revision 1.14 2003/03/13 10:11:41 mattias
|
Revision 1.14 2003/03/13 10:11:41 mattias
|
||||||
fixed TControl.Show in design mode
|
fixed TControl.Show in design mode
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ This directory is used for global "package links".
|
|||||||
"Package links" are used by the IDE whenever it searches the .lpk file of a
|
"Package links" are used by the IDE whenever it searches the .lpk file of a
|
||||||
required package. The files should have filenames with the format
|
required package. The files should have filenames with the format
|
||||||
<pkgname>-<version>.lpl.
|
<pkgname>-<version>.lpl.
|
||||||
Where <pkgname> is a valid pascal identifier in lowercase and <version> is for
|
Where <pkgname> is a valid pascal identifier and <version> is for example
|
||||||
example 1.2.3.4 (four integers divided by point).
|
1.2.3.4 (four integers divided by point).
|
||||||
Each file should contain a single absolute filename.
|
Each file should contain a single absolute filename.
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,8 @@ type
|
|||||||
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string;
|
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string;
|
||||||
FileVersion: integer);
|
FileVersion: integer);
|
||||||
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
||||||
|
function Compare(Version2: TPkgVersion): integer;
|
||||||
|
procedure Assign(Source: TPkgVersion);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -129,7 +131,8 @@ type
|
|||||||
|
|
||||||
TPkgDependencyFlag = (
|
TPkgDependencyFlag = (
|
||||||
pdfMinVersion, // >= MinVersion
|
pdfMinVersion, // >= MinVersion
|
||||||
pdfMaxVersion // <= MaxVersion
|
pdfMaxVersion, // <= MaxVersion
|
||||||
|
pdfActive
|
||||||
);
|
);
|
||||||
TPkgDependencyFlags = set of TPkgDependencyFlag;
|
TPkgDependencyFlags = set of TPkgDependencyFlag;
|
||||||
|
|
||||||
@ -150,6 +153,11 @@ type
|
|||||||
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string;
|
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string;
|
||||||
FileVersion: integer);
|
FileVersion: integer);
|
||||||
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
||||||
|
function MakeSense: boolean;
|
||||||
|
function IsCompatible(const Version: TPkgVersion): boolean;
|
||||||
|
function IsCompatible(const PkgName: string;
|
||||||
|
const Version: TPkgVersion): boolean;
|
||||||
|
function Compare(Dependency2: TPkgDependency): integer;
|
||||||
public
|
public
|
||||||
property PackageName: string read FPackageName write SetPackageName;
|
property PackageName: string read FPackageName write SetPackageName;
|
||||||
property Flags: TPkgDependencyFlags read FFlags write SetFlags;
|
property Flags: TPkgDependencyFlags read FFlags write SetFlags;
|
||||||
@ -244,6 +252,7 @@ type
|
|||||||
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
||||||
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
||||||
function IsVirtual: boolean;
|
function IsVirtual: boolean;
|
||||||
|
procedure CheckInnerDependencies;
|
||||||
public
|
public
|
||||||
property Author: string read FAuthor write SetAuthor;
|
property Author: string read FAuthor write SetAuthor;
|
||||||
property AutoIncrementVersionOnBuild: boolean
|
property AutoIncrementVersionOnBuild: boolean
|
||||||
@ -299,7 +308,7 @@ const
|
|||||||
PkgFileFlag: array[TPkgFileFlag] of string = (
|
PkgFileFlag: array[TPkgFileFlag] of string = (
|
||||||
'pffHasRegisterProc');
|
'pffHasRegisterProc');
|
||||||
PkgDependencyFlagNames: array[TPkgDependencyFlag] of string = (
|
PkgDependencyFlagNames: array[TPkgDependencyFlag] of string = (
|
||||||
'pdfMinVersion', 'pdfMaxVersion');
|
'pdfMinVersion', 'pdfMaxVersion', 'pdfActive');
|
||||||
LazPackageTypeNames: array[TLazPackageType] of string = (
|
LazPackageTypeNames: array[TLazPackageType] of string = (
|
||||||
'lptRunTime', 'lptDesignTime', 'lptRunAndDesignTime');
|
'lptRunTime', 'lptDesignTime', 'lptRunAndDesignTime');
|
||||||
LazPackageTypeIdents: array[TLazPackageType] of string = (
|
LazPackageTypeIdents: array[TLazPackageType] of string = (
|
||||||
@ -311,7 +320,7 @@ const
|
|||||||
|
|
||||||
function PkgFileTypeIdentToType(const s: string): TPkgFileType;
|
function PkgFileTypeIdentToType(const s: string): TPkgFileType;
|
||||||
function LazPackageTypeIdentToType(const s: string): TLazPackageType;
|
function LazPackageTypeIdentToType(const s: string): TLazPackageType;
|
||||||
|
procedure SortDependencyList(Dependencies: TList);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -330,6 +339,40 @@ begin
|
|||||||
Result:=lptRunTime;
|
Result:=lptRunTime;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure SortDependencyList(Dependencies: TList);
|
||||||
|
var
|
||||||
|
Count: Integer;
|
||||||
|
i, j: Integer;
|
||||||
|
Dependency1: TPkgDependency;
|
||||||
|
Dependency2: TPkgDependency;
|
||||||
|
Sorted: Boolean;
|
||||||
|
begin
|
||||||
|
if (Dependencies=nil) or (Dependencies.Count<2) then exit;
|
||||||
|
// check if already sorted
|
||||||
|
Count:=Dependencies.Count;
|
||||||
|
Sorted:=true;
|
||||||
|
for i:=0 to Count-2 do begin
|
||||||
|
Dependency1:=TPkgDependency(Dependencies[i]);
|
||||||
|
Dependency2:=TPkgDependency(Dependencies[i+1]);
|
||||||
|
if Dependency1.Compare(Dependency2)>0 then begin
|
||||||
|
Sorted:=false;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Sorted then exit;
|
||||||
|
// bubble sort (slow, but dependency lists are normally sorted)
|
||||||
|
for i:=0 to Count-2 do begin
|
||||||
|
Dependency1:=TPkgDependency(Dependencies[i]);
|
||||||
|
for j:=i+1 to Count-1 do begin
|
||||||
|
Dependency2:=TPkgDependency(Dependencies[j]);
|
||||||
|
if Dependency1.Compare(Dependency2)>0 then begin
|
||||||
|
Dependencies.Exchange(i,j);
|
||||||
|
Dependency1:=TPkgDependency(Dependencies[i]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPkgFile }
|
{ TPkgFile }
|
||||||
|
|
||||||
procedure TPkgFile.SetFilename(const AValue: string);
|
procedure TPkgFile.SetFilename(const AValue: string);
|
||||||
@ -473,6 +516,39 @@ begin
|
|||||||
XMLConfig.SetDeleteValue(Path+'MinVersion/Value',pdfMinVersion in FFlags,false);
|
XMLConfig.SetDeleteValue(Path+'MinVersion/Value',pdfMinVersion in FFlags,false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPkgDependency.MakeSense: boolean;
|
||||||
|
begin
|
||||||
|
Result:=(pdfActive in FFlags) and IsValidIdent(PackageName);
|
||||||
|
if Result
|
||||||
|
and (pdfMinVersion in FFlags) and (pdfMaxVersion in FFlags)
|
||||||
|
and (MinVersion.Compare(MaxVersion)>0) then
|
||||||
|
Result:=false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPkgDependency.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 TPkgDependency.IsCompatible(const PkgName: string;
|
||||||
|
const Version: TPkgVersion): boolean;
|
||||||
|
begin
|
||||||
|
Result:=(AnsiCompareText(PkgName,PackageName)=0) and IsCompatible(Version);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPkgDependency.Compare(Dependency2: TPkgDependency): integer;
|
||||||
|
begin
|
||||||
|
Result:=AnsiCompareText(PackageName,Dependency2.PackageName);
|
||||||
|
if Result<>0 then exit;
|
||||||
|
Result:=MinVersion.Compare(Dependency2.MinVersion);
|
||||||
|
if Result<>0 then exit;
|
||||||
|
Result:=MaxVersion.Compare(Dependency2.MaxVersion);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPkgVersion }
|
{ TPkgVersion }
|
||||||
|
|
||||||
procedure TPkgVersion.Clear;
|
procedure TPkgVersion.Clear;
|
||||||
@ -503,6 +579,22 @@ begin
|
|||||||
XMLConfig.SetDeleteValue(Path+'Release',Release,0);
|
XMLConfig.SetDeleteValue(Path+'Release',Release,0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPkgVersion.Compare(Version2: TPkgVersion): integer;
|
||||||
|
begin
|
||||||
|
Result:=Major-Version2.Major;
|
||||||
|
if Result=0 then Result:=Minor-Version2.Minor;
|
||||||
|
if Result=0 then Result:=Build-Version2.Build;
|
||||||
|
if Result=0 then Result:=Release-Version2.Release;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPkgVersion.Assign(Source: TPkgVersion);
|
||||||
|
begin
|
||||||
|
Major:=Source.Major;
|
||||||
|
Minor:=Source.Minor;
|
||||||
|
Build:=Source.Build;
|
||||||
|
Release:=Source.Release;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TLazPackage }
|
{ TLazPackage }
|
||||||
|
|
||||||
function TLazPackage.GetAutoIncrementVersionOnBuild: boolean;
|
function TLazPackage.GetAutoIncrementVersionOnBuild: boolean;
|
||||||
@ -760,6 +852,7 @@ var
|
|||||||
FileVersion);
|
FileVersion);
|
||||||
List.Add(PkgDependency);
|
List.Add(PkgDependency);
|
||||||
end;
|
end;
|
||||||
|
SortDependencyList(List);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure LoadFiles(const ThePath: string; List: TList);
|
procedure LoadFiles(const ThePath: string; List: TList);
|
||||||
@ -792,7 +885,7 @@ var
|
|||||||
else
|
else
|
||||||
Exclude(FFlags,lpfOpenInIDE);
|
Exclude(FFlags,lpfOpenInIDE);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
FileVersion:=XMLConfig.GetValue(Path+'Version',0);
|
FileVersion:=XMLConfig.GetValue(Path+'Version',0);
|
||||||
if FileVersion=1 then ;
|
if FileVersion=1 then ;
|
||||||
@ -871,6 +964,11 @@ begin
|
|||||||
Result:=not FilenameIsAbsolute(Filename);
|
Result:=not FilenameIsAbsolute(Filename);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TLazPackage.CheckInnerDependencies;
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPkgComponent }
|
{ TPkgComponent }
|
||||||
|
|
||||||
constructor TPkgComponent.Create(ThePkgFile: TPkgFile;
|
constructor TPkgComponent.Create(ThePkgFile: TPkgFile;
|
||||||
|
@ -38,9 +38,12 @@ unit PackageLinks;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils;
|
Classes, SysUtils, AVL_Tree, Laz_XMLCfg, FileCtrl, IDEProcs, EnvironmentOpts,
|
||||||
|
PackageDefs, LazConf;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
{ TPackageLink }
|
||||||
|
|
||||||
TPkgLinkOrigin = (
|
TPkgLinkOrigin = (
|
||||||
ploGlobal,
|
ploGlobal,
|
||||||
ploUser
|
ploUser
|
||||||
@ -49,17 +52,80 @@ type
|
|||||||
|
|
||||||
TPackageLink = class
|
TPackageLink = class
|
||||||
private
|
private
|
||||||
|
FFilename: string;
|
||||||
FOrigin: TPkgLinkOrigin;
|
FOrigin: TPkgLinkOrigin;
|
||||||
|
FPkgName: string;
|
||||||
|
FVersion: TPkgVersion;
|
||||||
|
procedure SetFilename(const AValue: string);
|
||||||
procedure SetOrigin(const AValue: TPkgLinkOrigin);
|
procedure SetOrigin(const AValue: TPkgLinkOrigin);
|
||||||
|
procedure SetPkgName(const AValue: string);
|
||||||
|
procedure SetVersion(const AValue: TPkgVersion);
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
function Compare(Link2: TPackageLink): integer;
|
||||||
public
|
public
|
||||||
property Origin: TPkgLinkOrigin read FOrigin write SetOrigin;
|
property Origin: TPkgLinkOrigin read FOrigin write SetOrigin;
|
||||||
|
property PkgName: string read FPkgName write SetPkgName;
|
||||||
|
property Version: TPkgVersion read FVersion write SetVersion;
|
||||||
|
property Filename: string read FFilename write SetFilename;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TPackageLinks }
|
||||||
|
|
||||||
|
TPackageLinks = class
|
||||||
|
private
|
||||||
|
FGlobalLinks: TAVLTree; // tree of TPackageLink
|
||||||
|
FUserLinks: TAVLTree; // tree of TPackageLink
|
||||||
|
function FindLeftMostNode(LinkTree: TAVLTree;
|
||||||
|
const PkgName: string): TAVLTreeNode;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Clear;
|
||||||
|
procedure UpdateGlobalLinks;
|
||||||
|
procedure UpdateUserLinks;
|
||||||
|
procedure UpdateAll;
|
||||||
|
function FindPkgFileName(LinkTree: TAVLTree;
|
||||||
|
const PkgName: string): TPackageLink;
|
||||||
|
function FindPkgFilename(LinkTree: TAVLTree;
|
||||||
|
Dependency: TPkgDependency): TPackageLink;
|
||||||
|
function FindPkgFileName(const PkgName: string): TPackageLink;
|
||||||
|
function FindPkgFilename(Dependency: TPkgDependency): TPackageLink;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
|
||||||
|
const
|
||||||
|
UserPkgLinkFile = 'packagefiles.xml';
|
||||||
|
|
||||||
|
function ComparePackageLinks(Data1, Data2: Pointer): integer;
|
||||||
|
var
|
||||||
|
Link1: TPackageLink;
|
||||||
|
Link2: TPackageLink;
|
||||||
|
begin
|
||||||
|
Link1:=TPackageLink(Data1);
|
||||||
|
Link2:=TPackageLink(Data2);
|
||||||
|
Result:=Link1.Compare(Link2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ComparePkgNameAndLink(Key, Data: Pointer): integer;
|
||||||
|
var
|
||||||
|
PkgName: String;
|
||||||
|
Link: TPackageLink;
|
||||||
|
begin
|
||||||
|
if Key=nil then
|
||||||
|
Result:=-1
|
||||||
|
else begin
|
||||||
|
PkgName:=AnsiString(Key);
|
||||||
|
Link:=TPackageLink(Data);
|
||||||
|
Result:=AnsiCompareText(PkgName,Link.PkgName);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPackageLink }
|
{ TPackageLink }
|
||||||
|
|
||||||
procedure TPackageLink.SetOrigin(const AValue: TPkgLinkOrigin);
|
procedure TPackageLink.SetOrigin(const AValue: TPkgLinkOrigin);
|
||||||
@ -68,15 +134,285 @@ begin
|
|||||||
FOrigin:=AValue;
|
FOrigin:=AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPackageLink.SetFilename(const AValue: string);
|
||||||
|
begin
|
||||||
|
if FFilename=AValue then exit;
|
||||||
|
FFilename:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPackageLink.SetPkgName(const AValue: string);
|
||||||
|
begin
|
||||||
|
if FPkgName=AValue then exit;
|
||||||
|
FPkgName:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPackageLink.SetVersion(const AValue: TPkgVersion);
|
||||||
|
begin
|
||||||
|
if FVersion=AValue then exit;
|
||||||
|
FVersion:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TPackageLink.Create;
|
constructor TPackageLink.Create;
|
||||||
begin
|
begin
|
||||||
|
FVersion:=TPkgVersion.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TPackageLink.Destroy;
|
destructor TPackageLink.Destroy;
|
||||||
begin
|
begin
|
||||||
|
FVersion.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPackageLink.Compare(Link2: TPackageLink): integer;
|
||||||
|
begin
|
||||||
|
Result:=AnsiCompareText(PkgName,Link2.PkgName);
|
||||||
|
if Result=0 then
|
||||||
|
Result:=Version.Compare(Link2.Version);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TPackageLinks }
|
||||||
|
|
||||||
|
function TPackageLinks.FindLeftMostNode(LinkTree: TAVLTree;
|
||||||
|
const PkgName: string): TAVLTreeNode;
|
||||||
|
// find left most link with PkgName
|
||||||
|
var
|
||||||
|
PriorNode: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
if PkgName='' then exit;
|
||||||
|
Result:=LinkTree.FindKey(PChar(PkgName),@ComparePkgNameAndLink);
|
||||||
|
if Result=nil then exit;
|
||||||
|
// find left most
|
||||||
|
while Result<>nil do begin
|
||||||
|
PriorNode:=LinkTree.FindPrecessor(Result);
|
||||||
|
if (PriorNode=nil)
|
||||||
|
or (AnsiCompareText(TPackageLink(PriorNode.Data).PkgName,PkgName)<>0)
|
||||||
|
then
|
||||||
|
break;
|
||||||
|
Result:=PriorNode;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TPackageLinks.Create;
|
||||||
|
begin
|
||||||
|
FGlobalLinks:=TAVLTree.Create(@ComparePackageLinks);
|
||||||
|
FUserLinks:=TAVLTree.Create(@ComparePackageLinks);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TPackageLinks.Destroy;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
FGlobalLinks.Free;
|
||||||
|
FUserLinks.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPackageLinks.Clear;
|
||||||
|
begin
|
||||||
|
FGlobalLinks.FreeAndClear;
|
||||||
|
FUserLinks.FreeAndClear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPackageLinks.UpdateGlobalLinks;
|
||||||
|
|
||||||
|
function ParseFilename(const Filename: string;
|
||||||
|
var PkgName: string; var PkgVersion: TPkgVersion): boolean;
|
||||||
|
// checks if filename has the form
|
||||||
|
// identifier-int.int.int.int.lpl
|
||||||
|
var
|
||||||
|
StartPos: Integer;
|
||||||
|
i: Integer;
|
||||||
|
EndPos: Integer;
|
||||||
|
ints: array[1..4] of integer;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
StartPos:=1;
|
||||||
|
// parse identifier
|
||||||
|
if (StartPos>length(Filename))
|
||||||
|
or (not (Filename[StartPos] in ['a'..'z','A'..'Z'])) then exit;
|
||||||
|
inc(StartPos);
|
||||||
|
while (StartPos<=length(Filename))
|
||||||
|
and (Filename[StartPos] in ['a'..'z','A'..'Z']) do
|
||||||
|
inc(StartPos);
|
||||||
|
PkgName:=lowercase(copy(Filename,1,StartPos-1));
|
||||||
|
// parse -
|
||||||
|
if (StartPos>length(Filename)) or (Filename[StartPos]<>'-') then exit;
|
||||||
|
inc(StartPos);
|
||||||
|
// parse 4 times 'int.'
|
||||||
|
for i:=Low(ints) to High(ints) do begin
|
||||||
|
// parse int
|
||||||
|
EndPos:=StartPos;
|
||||||
|
while (EndPos<=length(Filename))
|
||||||
|
and (Filename[EndPos] in ['0'..'9']) do inc(EndPos);
|
||||||
|
ints[i]:=StrToIntDef(copy(Filename,StartPos,EndPos-StartPos),-1);
|
||||||
|
if (ints[i]<0) or (ints[i]>99999) then exit;
|
||||||
|
StartPos:=EndPos;
|
||||||
|
// parse .
|
||||||
|
if (StartPos>length(Filename)) or (Filename[StartPos]<>'.') then exit;
|
||||||
|
inc(StartPos);
|
||||||
|
end;
|
||||||
|
// parse lpl
|
||||||
|
if (AnsiCompareText(copy(Filename,StartPos,length(Filename)-StartPos+1),
|
||||||
|
'lpl')<>0) then exit;
|
||||||
|
PkgVersion.Major:=ints[1];
|
||||||
|
PkgVersion.Minor:=ints[2];
|
||||||
|
PkgVersion.Build:=ints[3];
|
||||||
|
PkgVersion.Release:=ints[4];
|
||||||
|
Result:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
GlobalLinksDir: String;
|
||||||
|
FileInfo: TSearchRec;
|
||||||
|
NewPkgName: string;
|
||||||
|
PkgVersion: TPkgVersion;
|
||||||
|
NewPkgLink: TPackageLink;
|
||||||
|
sl: TStringList;
|
||||||
|
CurFilename: String;
|
||||||
|
NewFilename: string;
|
||||||
|
begin
|
||||||
|
FGlobalLinks.FreeAndClear;
|
||||||
|
GlobalLinksDir:=AppendPathDelim(EnvironmentOptions.LazarusDirectory)
|
||||||
|
+'packager'+PathDelim+'globallinks'+PathDelim;
|
||||||
|
if FindFirst(GlobalLinksDir+'*.lpl', faAnyFile, FileInfo)=0 then begin
|
||||||
|
PkgVersion:=TPkgVersion.Create;
|
||||||
|
repeat
|
||||||
|
CurFilename:=GlobalLinksDir+FileInfo.Name;
|
||||||
|
if ((FileInfo.Attr and faDirectory)<>0)
|
||||||
|
or (not ParseFilename(FileInfo.Name,NewPkgName,PkgVersion))
|
||||||
|
then begin
|
||||||
|
writeln('WARNING: suspicious pkg link file found (name): ',CurFilename);
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
sl:=TStringList.Create;
|
||||||
|
try
|
||||||
|
sl.LoadFromFile(CurFilename);
|
||||||
|
if sl.Count<0 then begin
|
||||||
|
writeln('WARNING: suspicious pkg link file found (content): ',CurFilename);
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
NewFilename:=sl[0];
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
writeln('ERROR: unable to read pkg link file: ',CurFilename,' : ',E.Message);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
sl.Free;
|
||||||
|
|
||||||
|
NewPkgLink:=TPackageLink.Create;
|
||||||
|
NewPkgLink.PkgName:=NewPkgName;
|
||||||
|
NewPkgLink.Version.Assign(PkgVersion);
|
||||||
|
NewPkgLink.Filename:=NewFilename;
|
||||||
|
if IsValidIdent(NewPkgLink.PkgName) and FileExists(NewPkgLink.Filename)
|
||||||
|
then
|
||||||
|
FGlobalLinks.Add(NewPkgLink)
|
||||||
|
else
|
||||||
|
NewPkgLink.Free;
|
||||||
|
|
||||||
|
until FindNext(FileInfo)<>0;
|
||||||
|
if PkgVersion<>nil then PkgVersion.Free;
|
||||||
|
end;
|
||||||
|
FindClose(FileInfo);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPackageLinks.UpdateUserLinks;
|
||||||
|
var
|
||||||
|
ConfigFilename: String;
|
||||||
|
Path: String;
|
||||||
|
XMLConfig: TXMLConfig;
|
||||||
|
LinkCount: Integer;
|
||||||
|
i: Integer;
|
||||||
|
NewPkgLink: TPackageLink;
|
||||||
|
ItemPath: String;
|
||||||
|
begin
|
||||||
|
FUserLinks.FreeAndClear;
|
||||||
|
ConfigFilename:=AppendPathDelim(GetPrimaryConfigPath)+'packagefiles.xml';
|
||||||
|
XMLConfig:=nil;
|
||||||
|
try
|
||||||
|
XMLConfig:=TXMLConfig.Create(ConfigFilename);
|
||||||
|
|
||||||
|
Path:='UserPkgLinks/';
|
||||||
|
LinkCount:=XMLConfig.GetValue(Path+'Count',0);
|
||||||
|
for i:=0 to LinkCount-1 do begin
|
||||||
|
ItemPath:=Path+'Item'+IntToStr(i)+'/';
|
||||||
|
NewPkgLink:=TPackageLink.Create;
|
||||||
|
NewPkgLink.PkgName:=XMLConfig.GetValue(ItemPath+'PkgName/Value','');
|
||||||
|
NewPkgLink.Version.LoadFromXMLConfig(XMLConfig,ItemPath+'Version/',
|
||||||
|
LazPkgXMLFileVersion);
|
||||||
|
NewPkgLink.Filename:=XMLConfig.GetValue(ItemPath+'Filename/Value','');
|
||||||
|
if IsValidIdent(NewPkgLink.PkgName) and FileExists(NewPkgLink.Filename)
|
||||||
|
then
|
||||||
|
FUserLinks.Add(NewPkgLink)
|
||||||
|
else
|
||||||
|
NewPkgLink.Free;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
writeln('WARNING: unable to read ',ConfigFilename);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if XMLConfig<>nil then XMLConfig.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPackageLinks.UpdateAll;
|
||||||
|
begin
|
||||||
|
UpdateGlobalLinks;
|
||||||
|
UpdateUserLinks;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPackageLinks.FindPkgFileName(LinkTree: TAVLTree;
|
||||||
|
const PkgName: string): TPackageLink;
|
||||||
|
// find left most link with PkgName
|
||||||
|
var
|
||||||
|
CurNode: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
if PkgName='' then exit;
|
||||||
|
CurNode:=FindLeftMostNode(LinkTree,PkgName);
|
||||||
|
if CurNode=nil then exit;
|
||||||
|
Result:=TPackageLink(CurNode.Data);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPackageLinks.FindPkgFilename(LinkTree: TAVLTree;
|
||||||
|
Dependency: TPkgDependency): TPackageLink;
|
||||||
|
var
|
||||||
|
Link: TPackageLink;
|
||||||
|
CurNode: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
if (Dependency=nil) or (not Dependency.MakeSense) then exit;
|
||||||
|
CurNode:=FindLeftMostNode(LinkTree,Dependency.PackageName);
|
||||||
|
while CurNode<>nil do begin
|
||||||
|
Link:=TPackageLink(CurNode.Data);
|
||||||
|
if Dependency.IsCompatible(Link.Version) then begin
|
||||||
|
Result:=Link;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
CurNode:=LinkTree.FindSuccessor(CurNode);
|
||||||
|
if AnsiCompareText(TPackageLink(CurNode.Data).PkgName,Dependency.PackageName)
|
||||||
|
<>0
|
||||||
|
then begin
|
||||||
|
CurNode:=nil;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPackageLinks.FindPkgFileName(const PkgName: string): TPackageLink;
|
||||||
|
begin
|
||||||
|
Result:=FindPkgFileName(FUserLinks,PkgName);
|
||||||
|
if Result=nil then
|
||||||
|
Result:=FindPkgFileName(FGlobalLinks,PkgName);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPackageLinks.FindPkgFilename(Dependency: TPkgDependency
|
||||||
|
): TPackageLink;
|
||||||
|
begin
|
||||||
|
Result:=FindPkgFileName(FUserLinks,Dependency);
|
||||||
|
if Result=nil then
|
||||||
|
Result:=FindPkgFileName(FGlobalLinks,Dependency);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user