1 {
2 /***************************************************************************
3 packagedefs.pas
4 ---------------
5
6
7 ***************************************************************************/
8
9 ***************************************************************************
10 * *
11 * This source is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This code is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19 * General Public License for more details. *
20 * *
21 * A copy of the GNU General Public License is available on the World *
22 * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
23 * obtain it by writing to the Free Software Foundation, *
24 * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
25 * *
26 ***************************************************************************
27
28 Author: Mattias Gaertner
29
30 Abstract:
31 Classes for packages and dependencies.
32 }
33 unit PackageDefs;
34
35 {$mode objfpc}{$H+}
36
37 interface
38
39 uses
40 // FCL
41 Classes, SysUtils, contnrs, typinfo, Laz_AVL_Tree,
42 // LCL
43 LCLType, LResources, Graphics, Controls, Forms, Dialogs,
44 // Codetools
45 FileProcs, LazConfigStorage, BasicCodeTools, DefineTemplates, CodeToolManager,
46 CodeCache, CodeToolsCfgScript, CodeToolsStructs,
47 // LazUtils
48 FileUtil, LazFileUtils, LazFileCache, LazUTF8, LazTracer, LazUtilities,
49 Laz2_XMLCfg, AvgLvlTree,
50 // IDEIntf
51 PropEdits, LazIDEIntf, MacroIntf, MacroDefIntf, IDEOptionsIntf, IDEOptEditorIntf,
52 PackageDependencyIntf, PackageIntf, IDEDialogs, ComponentReg, IDEImagesIntf,
53 // IDE
54 EditDefineTree, CompilerOptions, CompOptsModes, IDEOptionDefs, ProjPackCommon,
55 LazarusIDEStrConsts, IDEProcs, TransferMacros, FileReferenceList,
56 PublishModule, ImgList;
57
58 type
59 TLazPackage = class;
60 TPkgFile = class;
61 TBasePackageEditor = class;
62 TPkgDependency = class;
63
64 TPackageUpdatePolicy = (
65 pupManually,
66 pupOnRebuildingAll,
67 pupAsNeeded
68 );
69 TPackageUpdatePolicies = set of TPackageUpdatePolicy;
70
71 TGetAllRequiredPackagesEvent =
72 procedure(APackage: TLazPackage; // if not nil then ignore FirstDependency and do not add APackage to Result
73 FirstDependency: TPkgDependency;
74 out List, FPMakeList: TFPList;
75 Flags: TPkgIntfRequiredFlags = [];
76 MinPolicy: TPackageUpdatePolicy = low(TPackageUpdatePolicy)) of object;
77 TGetDependencyOwnerDescription =
78 procedure(Dependency: TPkgDependency; out Description: string) of object;
79 TGetDependencyOwnerDirectory =
80 procedure(Dependency: TPkgDependency; out Directory: string) of object;
81 TGetWritablePkgOutputDirectory =
82 procedure(APackage: TLazPackage; var AnOutDirectory: string) of object;
83
84
85 { TPkgComponent }
86
87 TPkgComponent = class(TRegisteredComponent)
88 private
89 FPkgFile: TPkgFile;
90 procedure SetPkgFile(const AValue: TPkgFile);
91 public
92 constructor Create(ThePkgFile: TPkgFile; TheComponentClass: TComponentClass;
93 const ThePageName: string);
94 destructor Destroy; override;
GetUnitNamenull95 function GetUnitName: string; override;
GetPrioritynull96 function GetPriority: TComponentPriority; override;
97 procedure ConsistencyCheck; override;
ImageIndexnull98 function ImageIndex: TImageIndex;
Imagesnull99 class function Images: TCustomImageList;
HasIconnull100 function HasIcon: boolean;
CanBeCreatedInDesignernull101 function CanBeCreatedInDesigner: boolean; override;
102 public
103 property PkgFile: TPkgFile read FPkgFile write SetPkgFile;
104 end;
105
106 { TPkgFile }
107
108 type
109 TPFComponentBaseClass = (
110 pfcbcNone, // unknown
111 pfcbcForm, // is TForm
112 pfcbcFrame, // is TFrame
113 pfcbcDataModule,// is TDataModule
114 pfcbcCustomForm // is TCustomForm (not TForm)
115 );
116
117 const
118 PFComponentBaseClassNames: array[TPFComponentBaseClass] of string = (
119 'None',
120 'Form',
121 'Frame',
122 'DataModule',
123 'CustomForm'
124 );
125
StrToComponentBaseClassnull126 function StrToComponentBaseClass(const s: string): TPFComponentBaseClass;
GetComponentBaseClassnull127 function GetComponentBaseClass(aClass: TClass): TPFComponentBaseClass;
128
129 type
130 TPkgFileFlag = (
131 pffHasRegisterProc, // file is unit and has a 'register' procedure
132 pffAddToPkgUsesSection,// unit is added to uses section
133 pffReportedAsRemoved // file has been reported as removed
134 );
135 TPkgFileFlags = set of TPkgFileFlag;
136
137 { TPkgFile }
138
139 TPkgFile = class(TLazPackageFile)
140 private
141 FAutoReferenceSourceDir: boolean;
142 FComponentPriority: TComponentPriority;
143 FComponents: TFPList; // list of TPkgComponent
144 FDirectory: string;
145 FFlags: TPkgFileFlags;
146 fFilename: string;
147 fFullFilename: string;
148 fFullFilenameStamp: integer;
149 FPackage: TLazPackage;
150 FResourceBaseClass: TPFComponentBaseClass;
151 FSourceDirectoryReferenced: boolean;
152 FSourceDirNeedReference: boolean;
GetAddToUsesPkgSectionnull153 function GetAddToUsesPkgSection: boolean;
GetComponentsnull154 function GetComponents(Index: integer): TPkgComponent;
GetHasRegisterProcnull155 function GetHasRegisterProc: boolean;
156 procedure SetAddToUsesPkgSection(const AValue: boolean);
157 procedure SetAutoReferenceSourceDir(const AValue: boolean);
158 procedure SetFlags(const AValue: TPkgFileFlags);
159 procedure SetHasRegisterProc(const AValue: boolean);
160 procedure UpdateUnitName;
GetComponentListnull161 function GetComponentList: TFPList;
162 protected
GetInUsesnull163 function GetInUses: boolean; override;
164 procedure SetInUses(AValue: boolean); override;
GetIDEPackagenull165 function GetIDEPackage: TIDEPackage; override;
GetFilenamenull166 function GetFilename: string; override;
167 procedure SetFilename(const AValue: string); override;
168 procedure SetRemoved(const AValue: boolean); override;
169 procedure SetDisableI18NForLFM(AValue: boolean); override;
170 procedure SetFileType(const AValue: TPkgFileType); override;
171 procedure SetUnitName(const AValue: string); override;
172 public
173 constructor Create(ThePackage: TLazPackage);
174 destructor Destroy; override;
175 procedure Clear;
176 procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string;
177 FileVersion: integer; AdjustPathDelims: boolean);
178 procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string;
179 UsePathDelim: TPathDelimSwitch);
180 procedure ConsistencyCheck;
ComponentCountnull181 function ComponentCount: integer;
182 procedure AddPkgComponent(APkgComponent: TPkgComponent);
183 procedure RemovePkgComponent(APkgComponent: TPkgComponent);
HasRegisteredPluginsnull184 function HasRegisteredPlugins: boolean;
MakeSensenull185 function MakeSense: boolean;
186 procedure UpdateSourceDirectoryReference;
GetFullFilenamenull187 function GetFullFilename: string; override;
GetShortFilenamenull188 function GetShortFilename(UseUp: boolean): string; override;
GetResolvedFilenamenull189 function GetResolvedFilename: string; // GetFullFilename + resolve symlinks
GetFileOwnernull190 function GetFileOwner: TObject; override;
GetFileOwnerNamenull191 function GetFileOwnerName: string; override;
192 public
193 property AddToUsesPkgSection: boolean
194 read GetAddToUsesPkgSection write SetAddToUsesPkgSection;
195 property AutoReferenceSourceDir: boolean read FAutoReferenceSourceDir
196 write SetAutoReferenceSourceDir;
197 property ResourceBaseClass: TPFComponentBaseClass read FResourceBaseClass
198 write FResourceBaseClass;
199 property ComponentPriority: TComponentPriority read FComponentPriority
200 write FComponentPriority;
201 property Components[Index: integer]: TPkgComponent read GetComponents;// registered components
202 property Directory: string read FDirectory;
203 property Flags: TPkgFileFlags read FFlags write SetFlags;
204 property HasRegisterProc: boolean read GetHasRegisterProc write SetHasRegisterProc;
205 property LazPackage: TLazPackage read FPackage;
206 property SourceDirectoryReferenced: boolean read FSourceDirectoryReferenced;
207 end;
208
209
210 { TPkgUnitsTree - Tree of TPkgFile sorted for unitnames }
211
212 TPkgUnitsTree = class(TAVLTree)
213 private
214 FLazPackage: TLazPackage;
215 public
FindNodeWithUnitNamenull216 function FindNodeWithUnitName(const AUnitName: string): TAVLTreeNode;
FindPkgFileWithUnitNamenull217 function FindPkgFileWithUnitName(const AUnitName: string): TPkgFile;
218 constructor Create(ThePackage: TLazPackage);
219 property LazPackage: TLazPackage read FLazPackage write FLazPackage;
220 end;
221
222
223 { TPkgDependency }
224
225 TPkgMarkerFlag = (
226 pmfVisited,
227 pmfMarked
228 );
229 TPkgMarkerFlags = set of TPkgMarkerFlag;
230
231 TPkgDependencyList = (
232 pdlRequires,
233 pdlUsedBy
234 );
235
236 TPkgDependencyType = (
237 pdtLazarus,
238 pdtFPMake
239 );
240
241 const
242 PkgDependencyTypeNames: array[TPkgDependencyType] of string = (
243 'Lazarus',
244 'FPMake'
245 );
246
247 type
248
249 { TPkgDependency }
250
251 TPkgDependency = class(TPkgDependencyID)
252 private
253 FDefaultFilename: string;
254 FDependencyType: TPkgDependencyType;
255 FHoldPackage: boolean;
256 FMarkerFlags: TPKgMarkerFlags;
257 FOwner: TObject;
258 FPreferDefaultFilename: boolean;
GetRequiredPackagenull259 function GetRequiredPackage: TLazPackage;
260 procedure SetHoldPackage(const AValue: boolean);
261 procedure SetRequiredPackage(AValue: TLazPackage);
262 protected
263 procedure SetPackageName(const AValue: string); override;
264 public
265 NextDependency, PrevDependency: array[TPkgDependencyList] of TPkgDependency;
266 constructor Create;
267 destructor Destroy; override;
268 procedure Clear; override;
269 procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string;
270 FileVersion: integer);
271 procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string;
272 UsePathDelim: TPathDelimSwitch);
273
Comparenull274 function Compare(Dependency2: TPkgDependency): integer;
275 procedure Assign(Source: TPkgDependency);
276 procedure Assign(Source: TLazPackageID);
277 procedure ConsistencyCheck;
IsCompatiblenull278 function IsCompatible(Pkg: TLazPackageID): boolean; overload;
279 procedure MakeCompatible(const PkgName: string; const Version: TPkgVersion);
AsStringnull280 function AsString(WithOwner: boolean = false; WithDefaults: boolean = false): string;
281 // API for iterating dependencies.
NextUsedByDependencynull282 function NextUsedByDependency: TPkgDependency; override;
PrevUsedByDependencynull283 function PrevUsedByDependency: TPkgDependency; override;
NextRequiresDependencynull284 function NextRequiresDependency: TPkgDependency; override;
PrevRequiresDependencynull285 function PrevRequiresDependency: TPkgDependency; override;
286 // API for adding / removing dependencies, defined in base class.
287 procedure AddUsedByDep(var FirstDependency: TPkgDependencyBase); override;
288 procedure RemoveUsedByDep(var FirstDependency: TPkgDependencyBase); override;
289 procedure AddRequiresDep(var FirstDependency: TPkgDependencyBase); override;
290 procedure RemoveRequiresDep(var FirstDependency: TPkgDependencyBase); override;
291 // API using ListType.
292 procedure AddToList(var FirstDependency: TPkgDependency;
293 ListType: TPkgDependencyList);
294 procedure AddToEndOfList(var LastDependency: TPkgDependency;
295 ListType: TPkgDependencyList);
296 procedure RemoveFromList(var FirstDependency: TPkgDependency;
297 ListType: TPkgDependencyList);
MoveUpInListnull298 function MoveUpInList(var FirstDependency: TPkgDependency;
299 ListType: TPkgDependencyList): Boolean;
MoveDownInListnull300 function MoveDownInList(var FirstDependency: TPkgDependency;
301 ListType: TPkgDependencyList): Boolean;
MakeFilenameRelativeToOwnernull302 function MakeFilenameRelativeToOwner(const AFilename: string): string;
FindDefaultFilenamenull303 function FindDefaultFilename: string;
304 public
305 property Owner: TObject read FOwner write FOwner;// package or project or IDE
306 property HoldPackage: boolean read FHoldPackage write SetHoldPackage;
307 property MarkerFlags: TPKgMarkerFlags read FMarkerFlags write FMarkerFlags;
308 property DefaultFilename: string read FDefaultFilename write FDefaultFilename;
309 property PreferDefaultFilename: boolean read FPreferDefaultFilename write FPreferDefaultFilename;
310 property RequiredPackage: TLazPackage read GetRequiredPackage write SetRequiredPackage;
311 property DependencyType: TPkgDependencyType read FDependencyType write FDependencyType;
312 end;
313 PPkgDependency = ^TPkgDependency;
314
315
316 { TPkgPair }
317
318 TPkgPair = class
319 public
320 Package1: TLazPackage;
321 Package2: TLazPackage;
322 constructor Create(Pkg1, Pkg2: TLazPackage);
ComparePairnull323 function ComparePair(Pkg1, Pkg2: TLazPackage): integer;
Comparenull324 function Compare(PkgPair: TPkgPair): integer;
AsStringnull325 function AsString: string;
326 end;
327
328
329 { TPkgPairTree - Tree of TPkgPair }
330
331 TPkgPairTree = class(TAVLTree)
332 public
333 constructor Create;
334 destructor Destroy; override;
FindPairnull335 function FindPair(Pkg1, Pkg2: TLazPackage; IgnoreOrder: boolean): TPkgPair;
AddPairnull336 function AddPair(Pkg1, Pkg2: TLazPackage): TPkgPair;
AddPairIfNotExistsnull337 function AddPairIfNotExists(Pkg1, Pkg2: TLazPackage): TPkgPair;
338 end;
339
340
341 { TPkgCompilerOptions }
342
343 TPkgCompilerOptions = class(TBaseCompilerOptions)
344 private
345 FLazPackage: TLazPackage;
346 FSkipCompiler: Boolean;
347 protected
348 procedure SetLazPackage(const AValue: TLazPackage);
349 procedure SetCustomOptions(const AValue: string); override;
350 procedure SetIncludePaths(const AValue: string); override;
351 procedure SetLibraryPaths(const AValue: string); override;
352 procedure SetLinkerOptions(const AValue: string); override;
353 procedure SetObjectPath(const AValue: string); override;
354 procedure SetSrcPath(const AValue: string); override;
355 procedure SetUnitPaths(const AValue: string); override;
356 procedure SetUnitOutputDir(const AValue: string); override;
357 procedure SetConditionals(AValue: string); override;
358 public
359 constructor Create(const AOwner: TObject); override;
360 // IDE options
GetGroupCaptionnull361 class function GetGroupCaption: string; override;
GetInstancenull362 class function GetInstance: TAbstractIDEOptions; override;
IsActivenull363 function IsActive: boolean; override;
364 procedure Clear; override;
365 procedure GetInheritedCompilerOptions(var OptionsList: TFPList); override;
GetOwnerNamenull366 function GetOwnerName: string; override;
367 procedure InvalidateOptions;
GetDefaultMainSourceFileNamenull368 function GetDefaultMainSourceFileName: string; override;
CreateTargetFilenamenull369 function CreateTargetFilename: string; override;
HasCompilerCommandnull370 function HasCompilerCommand: boolean; override;
371
372 procedure LoadFromXMLConfig(AXMLConfig: TXMLConfig; const Path: string); override;
373 procedure SaveToXMLConfig(AXMLConfig: TXMLConfig; const Path: string); override;
374 procedure Assign(Source: TPersistent); override;
CreateDiffnull375 function CreateDiff(CompOpts: TBaseCompilerOptions;
376 Tool: TCompilerDiffTool = nil): boolean; override;
377 public
378 property LazPackage: TLazPackage read FLazPackage write SetLazPackage;
379 property SkipCompiler: Boolean read FSkipCompiler write FSkipCompiler;
380 end;
381
382
383 { TPkgAdditionalCompilerOptions }
384
385 TPkgAdditionalCompilerOptions = class(TAdditionalCompilerOptions)
386 private
387 FLazPackage: TLazPackage;
388 procedure SetLazPackage(const AValue: TLazPackage);
389 protected
390 procedure SetCustomOptions(const AValue: string); override;
391 procedure SetIncludePath(const AValue: string); override;
392 procedure SetLibraryPath(const AValue: string); override;
393 procedure SetLinkerOptions(const AValue: string); override;
394 procedure SetObjectPath(const AValue: string); override;
395 procedure SetUnitPath(const AValue: string); override;
396 procedure SetSrcPath(const AValue: string); override;
397 public
398 constructor Create(ThePackage: TLazPackage);
399 procedure AssignOptions(Source: TObject); override;
GetOwnerNamenull400 function GetOwnerName: string; override;
GetBaseCompilerOptionsnull401 function GetBaseCompilerOptions: TBaseCompilerOptions; override;
402 public
403 property LazPackage: TLazPackage read FLazPackage write SetLazPackage;
404 end;
405
406 { TPublishPackageOptions }
407
408 TPublishPackageOptions = class(TPublishModuleOptions)
409 protected
410 procedure DoOnModifyChange; override;
411 public
GetDefaultDestinationDirnull412 function GetDefaultDestinationDir: string; override;
413 end;
414
415
416 { TLazPackageDefineTemplates }
417
418 TLazPackageDefineTemplates = class(TProjPackDefineTemplates)
419 private
420 protected
421 procedure UpdateMain; override;
422 procedure UpdateSrcDirIfDef; override;
423 procedure UpdateSourceDirectories; override;
424 procedure UpdateOutputDirectory; override;
425 procedure UpdateDefinesForCustomDefines; override;
426 procedure ClearFlags; override;
427 public
428 constructor Create(AOwner: IProjPack);
429 destructor Destroy; override;
430 procedure AllChanged; override;
431 end;
432
433
434 { TLazPackage }
435
436 TLazPackageFlag = (
437 lpfAutoIncrementVersionOnBuild, // increment version before
438 lpfModified, // package needs saving
439 lpfNeeded, // Set by PackageGraph, if package is in use
440 // (for example because it is Installed or an Installed
441 // package requires this package)
442 lpfVisited, // Used by the PackageGraph to avoid double checking
443 lpfDestroying, // set during destruction
444 lpfLoading, // set during loading
445 lpfSkipSaving, // Used by PkgBoss to skip saving
446 lpfCycle, // Used by the PackageGraph to mark cycles
447 lpfNeedGroupCompile // set during group compile, dependent packages need compile too
448 );
449 TLazPackageFlags = set of TLazPackageFlag;
450
451 const
452 pupAllAuto = [pupAsNeeded,pupOnRebuildingAll];
453
454 type
455 TPkgOutputDirWritable = (
456 podwUnknown,
457 podwWritable,
458 podwNotWritable
459 );
460 TPkgLastCompileStats = record
461 StateFileLoaded: boolean;
462 StateFileName: string; // the .compiled file
463 StateFileDate: longint;
464 CompilerFilename: string; // path to used compiler
465 CompilerFileDate: integer;
466 Params: string; // compiler parameters
467 Complete: boolean; // compilation was successful
468 MainPPUExists: boolean; // main ppu file was there after compile
469 ViaMakefile: boolean; // compiled via make
470 DirectoryWritable: TPkgOutputDirWritable;
471 end;
472 PPkgLastCompileStats = ^TPkgLastCompileStats;
473 TPkgOutputDir = (
474 podDefault,
475 podFallback // used when podDefault is not writable
476 );
477
478 TIterateComponentClassesEvent = procedure(PkgComponent: TPkgComponent) of object;
479 TPkgChangeNameEvent = procedure(Pkg: TLazPackage; const OldName: string) of object;
480
481 { TPackageIDEOptions }
482
483 TPackageIDEOptions = class(TAbstractIDEOptions)
484 private
485 FPackage: TLazPackage;
486 public
487 constructor Create(APackage: TLazPackage);
488 destructor Destroy; override;
GetInstancenull489 class function GetInstance: TAbstractIDEOptions; override;
GetGroupCaptionnull490 class function GetGroupCaption: string; override;
491 property Package: TLazPackage read FPackage;
492 end;
493
494
495 { TLazPackage }
496
497 TLazPackage = class(TIDEPackage, IProjPack)
498 private
499 FAddToProjectUsesSection: boolean;
500 FAuthor: string;
501 FAutoUpdate: TPackageUpdatePolicy;
502 FFPDocPackageName: string;
503 FOnModifySilently: TNotifyEvent;
504 FOptionsBackup: TLazPackage;
505 FComponents: TFPList; // TFPList of TPkgComponent
506 FDefineTemplates: TLazPackageDefineTemplates;
507 FDescription: string;
508 FDirectory: string;
509 FDirectoryExpanded: string;
510 FDirectoryExpandedChangeStamp: integer;
511 FEnableI18N: boolean;
512 FEnableI18NForLFM: boolean;
513 FFileReadOnly: boolean;
514 FFiles: TFPList; // TFPList of TPkgFile
515 FFirstRemovedDependency: TPkgDependency;
516 FFirstRequiredDependency: TPkgDependency;
517 FFirstUsedByDependency: TPkgDependency;
518 FFlags: TLazPackageFlags;
519 FHasDirectory: boolean;
520 FHasStaticDirectory: boolean;
521 FHoldPackageCount: integer;
522 FIconFile: string;
523 FInstalled: TPackageInstallType;
524 FFPDocPaths: string;
525 FLicense: string;
526 FLPKSource: TCodeBuffer;
527 FLPKSourceChangeStep: integer;
528 FMacros: TTransferMacroList;
529 FMainUnit: TPkgFile;
530 FMissing: boolean;
531 FModifiedLock: integer;
532 FOutputStateFile: string;
533 FPackageEditor: TBasePackageEditor;
534 FPOOutputDirectory: string;
535 FProvides: TStrings;
536 fPublishOptions: TPublishPackageOptions;
537 FRegistered: boolean;
538 FRemovedFiles: TFPList; // TFPList of TPkgFile
539 FSourceDirectories: TFileReferenceList;
540 FStorePathDelim: TPathDelimSwitch;
541 FTopologicalLevel: integer;
542 FTranslated: string;
543 FUpdateLock: integer;
544 FUsageOptions: TPkgAdditionalCompilerOptions;
545 FUserIgnoreChangeStamp: integer;
546 FUserReadOnly: boolean;
GetAutoIncrementVersionOnBuildnull547 function GetAutoIncrementVersionOnBuild: boolean;
GetCompilerOptionsnull548 function GetCompilerOptions: TPkgCompilerOptions;
GetBaseCompilerOptionsnull549 function GetBaseCompilerOptions: TBaseCompilerOptions;
GetComponentCountnull550 function GetComponentCount: integer;
GetComponentsnull551 function GetComponents(Index: integer): TPkgComponent;
GetRemovedFilesnull552 function GetRemovedFiles(Index: integer): TPkgFile;
GetFilesnull553 function GetFiles(Index: integer): TPkgFile;
GetIDEOptionsnull554 function GetIDEOptions: TPackageIDEOptions;
GetSourceDirectoriesnull555 function GetSourceDirectories: TFileReferenceList;
556 procedure SetAddToProjectUsesSection(const AValue: boolean);
557 procedure SetAuthor(const AValue: string);
558 procedure SetAutoIncrementVersionOnBuild(const AValue: boolean);
559 procedure SetAutoUpdate(const AValue: TPackageUpdatePolicy);
560 procedure SetDescription(const AValue: string);
561 procedure SetEnableI18NForLFM(AValue: boolean);
562 procedure SetFileReadOnly(const AValue: boolean);
563 procedure SetFlags(const AValue: TLazPackageFlags);
564 procedure SetFPDocPackageName(AValue: string);
565 procedure SetIconFile(const AValue: string);
566 procedure SetInstalled(const AValue: TPackageInstallType);
567 procedure SetFPDocPaths(const AValue: string);
568 procedure SetLicense(const AValue: string);
569 procedure SetLPKSource(const AValue: TCodeBuffer);
570 procedure SetOutputStateFile(const AValue: string);
571 procedure SetProvides(const AValue: TStrings);
572 procedure SetPOOutputDirectory(const AValue: string);
573 procedure SetEnableI18N(const AValue: boolean);
574 procedure SetRegistered(const AValue: boolean);
575 procedure SetPackageEditor(const AValue: TBasePackageEditor);
576 procedure SetPackageType(const AValue: TLazPackageType);
577 procedure SetStorePathDelim(const AValue: TPathDelimSwitch);
578 procedure SetUserReadOnly(const AValue: boolean);
579 procedure OnMacroListSubstitution({%H-}TheMacro: TTransferMacro;
580 const MacroName: string; var s: string;
581 const Data: PtrInt; var Handled, {%H-}Abort: boolean; {%H-}Depth: integer);
582 procedure Clear;
583 procedure UpdateSourceDirectories;
584 procedure SourceDirectoriesChanged(Sender: TObject);
585 protected
GetDirectorynull586 function GetDirectory: string; override;
GetDefineTemplatesnull587 function GetDefineTemplates: TProjPackDefineTemplates;
GetFileCountnull588 function GetFileCount: integer; override;
GetPkgFilesnull589 function GetPkgFiles(Index: integer): TLazPackageFile; override;
GetDirectoryExpandednull590 function GetDirectoryExpanded: string; override;
GetModifiednull591 function GetModified: boolean; override;
592 procedure SetFilename(const AValue: string); override;
593 procedure SetModified(const AValue: boolean); override;
594 procedure SetName(const NewName: TComponentName); override;
595 procedure VersionChanged(Sender: TObject); override;
GetRemovedCountnull596 function GetRemovedCount: integer; override;
GetRemovedPkgFilesnull597 function GetRemovedPkgFiles(Index: integer): TLazPackageFile; override;
598 procedure SetAutoInstall(AValue: TPackageInstallType); override;
599 public
600 constructor Create; override;
601 destructor Destroy; override;
602 procedure AssignOptions(Source: TPersistent); override;
603 // IDE options
604 procedure BackupOptions;
605 procedure RestoreOptions;
606 // modified
607 procedure BeginUpdate;
608 procedure EndUpdate;
609 procedure LockModified;
610 procedure UnlockModified;
ReadOnlynull611 function ReadOnly: boolean; override;
612 procedure ModifySilently; // Set Modified but do not trigger update of editors.
613 // streaming
614 procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
615 procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
616 procedure SaveToString(out s: string);
617 // consistency
618 procedure CheckInnerDependencies;
IsMakingSensenull619 function IsMakingSense: boolean;
620 procedure ConsistencyCheck;
621 // paths, define templates
ExtendUnitSearchPathnull622 function ExtendUnitSearchPath(NewUnitPaths: string): boolean;
ExtendIncSearchPathnull623 function ExtendIncSearchPath(NewIncPaths: string): boolean;
IsVirtualnull624 function IsVirtual: boolean; override;
HasDirectorynull625 function HasDirectory: boolean; override;
HasStaticDirectorynull626 function HasStaticDirectory: boolean;
GetFullFilenamenull627 function GetFullFilename(ResolveMacros: boolean): string;
GetResolvedFilenamenull628 function GetResolvedFilename(ResolveMacros: boolean): string; // GetFullFilename + resolve symlinks
GetSourceDirsnull629 function GetSourceDirs(WithPkgDir, WithoutOutputDir: boolean): string;
630 procedure GetInheritedCompilerOptions(var OptionsList: TFPList);
GetOutputDirectorynull631 function GetOutputDirectory(UseOverride: boolean = true): string; // this can change before building, when default dir is readonly
HasSeparateOutputDirectorynull632 function HasSeparateOutputDirectory: boolean;
GetStateFilenamenull633 function GetStateFilename(UseOverride: boolean = true): string;
GetCompileSourceFilenamenull634 function GetCompileSourceFilename: string;// as GetSrcFilename without directory
GetSrcFilenamenull635 function GetSrcFilename: string;
GetSrcPPUFilenamenull636 function GetSrcPPUFilename: string;
GetCompilerFilenamenull637 function GetCompilerFilename: string;
GetPOOutDirectorynull638 function GetPOOutDirectory: string;
GetUnitPathnull639 function GetUnitPath(RelativeToBaseDir: boolean): string;
GetIncludePathnull640 function GetIncludePath(RelativeToBaseDir: boolean): string;
GetSrcPathnull641 function GetSrcPath(RelativeToBaseDir: boolean): string;
GetFPDocPackageNamenull642 function GetFPDocPackageName: string;
GetLastCompilerParamsnull643 function GetLastCompilerParams(o: TPkgOutputDir): string;
NeedsDefineTemplatesnull644 function NeedsDefineTemplates: boolean;
SubstitutePkgMacrosnull645 function SubstitutePkgMacros(const s: string; PlatformIndependent: boolean): string;
646 procedure WriteInheritedUnparsedOptions;
647 // files
IndexOfPkgFilenull648 function IndexOfPkgFile(PkgFile: TPkgFile): integer;
SearchShortFilenamenull649 function SearchShortFilename(const ShortFilename: string;
650 SearchFlags: TSearchIDEFileFlags): TPkgFile;
SearchFilenamenull651 function SearchFilename(const AFilename: string;
652 SearchFlags: TSearchIDEFileFlags): TPkgFile;
653 procedure ShortenFilename(var ExpandedFilename: string; UseUp: boolean);
654 procedure LongenFilename(var AFilename: string);
FindPkgFilenull655 function FindPkgFile(const AFilename: string;
656 IgnoreRemoved, FindVirtualFile: boolean): TPkgFile;
FindUnitWithRegisternull657 function FindUnitWithRegister(IgnorePkgFile: TPkgFile = nil): TPkgFile;
FindUnitnull658 function FindUnit(const TheUnitName: string): TPkgFile;
FindUnitnull659 function FindUnit(const TheUnitName: string; IgnoreRemoved: boolean): TPkgFile;
FindUnitnull660 function FindUnit(const TheUnitName: string; IgnoreRemoved: boolean;
661 IgnorePkgFile: TPkgFile): TPkgFile;
FindUsedUnitnull662 function FindUsedUnit(TheUnitName: string; IgnorePkgFile: TPkgFile = nil): TPkgFile;
FindRemovedPkgFilenull663 function FindRemovedPkgFile(const AFilename: string): TPkgFile;
AddFilenull664 function AddFile(const NewFilename, NewUnitName: string;
665 NewFileType: TPkgFileType; NewFlags: TPkgFileFlags;
666 CompPriorityCat: TComponentPriorityCategory): TPkgFile;
AddFileByNamenull667 function AddFileByName(aFilename: string;
668 var NewUnitPaths, NewIncPaths: String): Boolean;
AddRemovedFilenull669 function AddRemovedFile(const NewFilename, NewUnitName: string;
670 NewFileType: TPkgFileType; NewFlags: TPkgFileFlags;
671 CompPriorityCat: TComponentPriorityCategory): TPkgFile;
672 procedure DeleteFile(PkgFile: TPkgFile); // free TPkgFile
673 procedure RemoveFileSilently(PkgFile: TPkgFile);
674 procedure RemoveFile(PkgFile: TPkgFile); // move file to removed file list
675 procedure UnremovePkgFile(PkgFile: TPkgFile); // move file back to file list
676 // True if something changed. Param is ignored here, just to match with interface.
RemoveNonExistingFilesnull677 function RemoveNonExistingFiles({%H-}RemoveFromUsesSection: boolean = true): boolean;
GetFileDialogInitialDirnull678 function GetFileDialogInitialDir(const DefaultDirectory: string): string;
679 procedure MoveFile(CurIndex, NewIndex: integer);
680 procedure SortFiles;
FixFilesCaseSensitivitynull681 function FixFilesCaseSensitivity: boolean;
MainUnitHasPkgNamenull682 function MainUnitHasPkgName: boolean;
683 // required dependencies (plus removed required dependencies)
FindDependencyByNamenull684 function FindDependencyByName(const PackageName: string): TPkgDependency;
FindRemovedDependencyByNamenull685 function FindRemovedDependencyByName(const PkgName: string): TPkgDependency;
RequiredDepByIndexnull686 function RequiredDepByIndex(Index: integer): TPkgDependency;
RemovedDepByIndexnull687 function RemovedDepByIndex(Index: integer): TPkgDependency;
688 procedure AddRequiredDependency(Dependency: TPkgDependency);
689 procedure AddPackageDependency(const PackageName: string);
690 procedure RemoveRequiredDepSilently(Dependency: TPkgDependency);
691 procedure RemoveRequiredDependency(Dependency: TPkgDependency);
692 procedure DeleteRequiredDependency(Dependency: TPkgDependency);
693 procedure DeleteRemovedDependency(Dependency: TPkgDependency);
694 procedure RemoveRemovedDependency(Dependency: TPkgDependency);
MoveRequiredDependencyUpnull695 function MoveRequiredDependencyUp(Dependency: TPkgDependency): Boolean;
MoveRequiredDependencyDownnull696 function MoveRequiredDependencyDown(Dependency: TPkgDependency): Boolean;
CreateDependencyWithOwnernull697 function CreateDependencyWithOwner(NewOwner: TObject;
698 WithMinVersion: boolean = false): TPkgDependency;
Requiresnull699 function Requires(APackage: TLazPackage): boolean;
700 procedure GetAllRequiredPackages(var List, FPMakeList: TFPList; WithSelf: boolean;
701 aFlags: TPkgIntfRequiredFlags = [];
702 MinPolicy: TPackageUpdatePolicy = low(TPackageUpdatePolicy));
703 // components
IndexOfPkgComponentnull704 function IndexOfPkgComponent(PkgComponent: TPkgComponent): integer;
AddComponentnull705 function AddComponent(PkgFile: TPkgFile; const Page: string;
706 TheComponentClass: TComponentClass): TPkgComponent;
707 procedure AddPkgComponent(APkgComponent: TPkgComponent);
708 procedure RemovePkgComponent(APkgComponent: TPkgComponent);
709 procedure IterateComponentClasses(Event: TIterateComponentClassesEvent;
710 WithUsedPackages: boolean);
711 procedure SetAllComponentPriorities(const p: TComponentPriority);
712 // used by dependencies
713 procedure AddUsedByDependency(Dependency: TPkgDependencyBase); override;
714 procedure RemoveUsedByDependency(Dependency: TPkgDependencyBase); override;
UsedByDepByIndexnull715 function UsedByDepByIndex(Index: integer): TPkgDependency;
FindUsedByDepPrefernull716 function FindUsedByDepPrefer(Ignore: TPkgDependency): TPkgDependency;
717 // provides
ProvidesPackagenull718 function ProvidesPackage(const AName: string): boolean;
719 // ID
720 procedure ChangeID(const NewName: string; NewVersion: TPkgVersion);
721 public
722 LastCompile: array[TPkgOutputDir] of TPkgLastCompileStats;
GetOutputDirTypenull723 function GetOutputDirType: TPkgOutputDir;
724 public
725 property AddToProjectUsesSection: boolean read FAddToProjectUsesSection
726 write SetAddToProjectUsesSection;
727 property Author: string read FAuthor write SetAuthor;
728 property AutoIncrementVersionOnBuild: boolean read GetAutoIncrementVersionOnBuild
729 write SetAutoIncrementVersionOnBuild;
730 property AutoUpdate: TPackageUpdatePolicy read FAutoUpdate write SetAutoUpdate;
731 property CompilerOptions: TPkgCompilerOptions read GetCompilerOptions;
732 property ComponentCount: integer read GetComponentCount;
733 property Components[Index: integer]: TPkgComponent read GetComponents;
734 property DefineTemplates: TLazPackageDefineTemplates read FDefineTemplates
735 write FDefineTemplates;
736 property Description: string read FDescription write SetDescription;
737 property Editor: TBasePackageEditor read FPackageEditor write SetPackageEditor;
738 property EnableI18N: Boolean read FEnableI18N write SetEnableI18N;
739 property EnableI18NForLFM: boolean read FEnableI18NForLFM write SetEnableI18NForLFM;
740 property FileReadOnly: boolean read FFileReadOnly write SetFileReadOnly;
741 property Files[Index: integer]: TPkgFile read GetFiles;
742 property FirstRemovedDependency: TPkgDependency read FFirstRemovedDependency;
743 property FirstRequiredDependency: TPkgDependency read FFirstRequiredDependency;
744 property FirstUsedByDependency: TPkgDependency read FFirstUsedByDependency;
745 property Flags: TLazPackageFlags read FFlags write SetFlags;
746 property HoldPackageCount: integer read FHoldPackageCount;
747 property IconFile: string read FIconFile write SetIconFile;
748 property IDEOptions: TPackageIDEOptions read GetIDEOptions;
749 property Installed: TPackageInstallType read FInstalled write SetInstalled;
750 property FPDocPaths: string read FFPDocPaths write SetFPDocPaths;
751 property FPDocPackageName: string read FFPDocPackageName write SetFPDocPackageName;
752 property License: string read FLicense write SetLicense;
753 property LPKSource: TCodeBuffer read FLPKSource write SetLPKSource;// see Missing, can be nil when file on disk was removed or point to a different codebuffer during rename
754 property LPKSourceChangeStep: integer read FLPKSourceChangeStep write FLPKSourceChangeStep;
755 property Macros: TTransferMacroList read FMacros;
756 property MainUnit: TPkgFile read FMainUnit;
757 property Missing: boolean read FMissing write FMissing; // lpk is missing, Note: virtual packages can have Missing=false
758 property OptionsBackup: TLazPackage read FOptionsBackup;
759 property OutputStateFile: string read FOutputStateFile write SetOutputStateFile;
760 property PackageType: TLazPackageType read FPackageType write SetPackageType;
761 property POOutputDirectory: string read FPOOutputDirectory write SetPOOutputDirectory;
762 property Provides: TStrings read FProvides write SetProvides;
763 property PublishOptions: TPublishPackageOptions read fPublishOptions write fPublishOptions;
764 property Registered: boolean read FRegistered write SetRegistered;
765 property RemovedFiles[Index: integer]: TPkgFile read GetRemovedFiles;
766 property SourceDirectories: TFileReferenceList read GetSourceDirectories;
767 property StorePathDelim: TPathDelimSwitch read FStorePathDelim write SetStorePathDelim;
768 property TopologicalLevel: integer read FTopologicalLevel write FTopologicalLevel;
769 property Translated: string read FTranslated write FTranslated;
770 property UsageOptions: TPkgAdditionalCompilerOptions read FUsageOptions;
771 property UserReadOnly: boolean read FUserReadOnly write SetUserReadOnly;
772 property UserIgnoreChangeStamp: integer read FUserIgnoreChangeStamp
773 write FUserIgnoreChangeStamp;
774 property OnModifySilently: TNotifyEvent read FOnModifySilently write FOnModifySilently;
775 end;
776
777 PLazPackage = ^TLazPackage;
778
779
780 { TBasePackageEditor }
781
782 TBasePackageEditor = class(TForm)
783 protected
GetLazPackagenull784 function GetLazPackage: TLazPackage; virtual;
785 procedure SetLazPackage(const AValue: TLazPackage); virtual; abstract;
786 public
787 procedure UpdateAll(Immediately: boolean = false); virtual; abstract;
788 property LazPackage: TLazPackage read GetLazPackage write SetLazPackage;
789 end;
790
791
792 const
793 LazPkgXMLFileVersion = 4;
794
795 AutoUpdateNames: array[TPackageUpdatePolicy] of string = (
796 'Manually', 'OnRebuildingAll', 'AsNeeded');
797
798 var
799 // All TPkgDependency are added to this AVL tree (sorted for names, not version!)
800 PackageDependencies: TAVLTree = nil; // tree of TPkgDependency
801
802 OnGetAllRequiredPackages: TGetAllRequiredPackagesEvent = nil;
803 OnGetDependencyOwnerDescription: TGetDependencyOwnerDescription = nil;
804 OnGetDependencyOwnerDirectory: TGetDependencyOwnerDirectory = nil;
805 OnPackageFileLoaded: TNotifyEvent = nil;
806
CompareLazPackageIDnull807 function CompareLazPackageID(Data1, Data2: Pointer): integer;
CompareNameWithPackageIDnull808 function CompareNameWithPackageID(Key, Data: Pointer): integer;
ComparePkgIDMaskWithPackageIDnull809 function ComparePkgIDMaskWithPackageID(Key, Data: Pointer): integer;
CompareLazPackageIDNamesnull810 function CompareLazPackageIDNames(Data1, Data2: Pointer): integer;
CompareLazPackageTopologicallyAndNamenull811 function CompareLazPackageTopologicallyAndName(Data1, Data2: Pointer): integer;
CompareNameWithPkgDependencynull812 function CompareNameWithPkgDependency(Key, Data: Pointer): integer;
ComparePkgDependencyNamesnull813 function ComparePkgDependencyNames(Data1, Data2: Pointer): integer;
CompareUnitsTreenull814 function CompareUnitsTree(UnitTree1, UnitTree2: TPkgUnitsTree): integer;
ComparePackageWithUnitsTreenull815 function ComparePackageWithUnitsTree(Package: TLazPackage;
816 UnitTree: TPkgUnitsTree): integer;
ComparePkgFilesAlphabeticallynull817 function ComparePkgFilesAlphabetically(PkgFile1, PkgFile2: TPkgFile): integer;
818
GetUsageOptionsListnull819 function GetUsageOptionsList(PackageList: TFPList): TFPList;
820
GetPkgFileTypeLocalizedNamenull821 function GetPkgFileTypeLocalizedName(FileType: TPkgFileType): string;
NameToAutoUpdatePolicynull822 function NameToAutoUpdatePolicy(const s: string): TPackageUpdatePolicy;
FileNameToPkgFileTypenull823 function FileNameToPkgFileType(AFilename: string): TPkgFileType;
824
825 procedure SortDependencyListAlphabetically(Dependencies: TFPList);
826 procedure LoadPkgDependencyList(XMLConfig: TXMLConfig; const ThePath: string;
827 var First: TPkgDependency; ListType: TPkgDependencyList; Owner: TObject;
828 HoldPackages, SortList: boolean);
829 procedure SavePkgDependencyList(XMLConfig: TXMLConfig; const ThePath: string;
830 First: TPkgDependency; ListType: TPkgDependencyList;
831 UsePathDelim: TPathDelimSwitch);
832 procedure ListPkgIDToDependencyList(ListOfTLazPackageID: TObjectList;
833 var First: TPkgDependency; ListType: TPkgDependencyList; Owner: TObject;
834 HoldPackages: boolean);
835 procedure DeleteDependencyInList(ADependency: TPkgDependency;
836 var First: TPkgDependency; ListType: TPkgDependencyList);
837 procedure FreeDependencyList(var First: TPkgDependency;
838 ListType: TPkgDependencyList);
DependencyListAsStringnull839 function DependencyListAsString(First: TPkgDependency;
840 ListType: TPkgDependencyList): string;
841
FindDependencyByNameInListnull842 function FindDependencyByNameInList(First: TPkgDependency;
843 ListType: TPkgDependencyList; const Name: string): TPkgDependency;
FindCompatibleDependencyInListnull844 function FindCompatibleDependencyInList(First: TPkgDependency;
845 ListType: TPkgDependencyList; ComparePackage: TLazPackageID): TPkgDependency;
GetDependencyWithIndexnull846 function GetDependencyWithIndex(First: TPkgDependency;
847 ListType: TPkgDependencyList; Index: integer): TPkgDependency;
IndexOfDependencyInListnull848 function IndexOfDependencyInList(First: TPkgDependency;
849 ListType: TPkgDependencyList; FindDependency: TPkgDependency): integer;
GetFirstDependencynull850 function GetFirstDependency(ListItem: TPkgDependency;
851 ListType: TPkgDependencyList): TPkgDependency;
852
FindLowestPkgDependencyWithNamenull853 function FindLowestPkgDependencyWithName(const PkgName: string): TPkgDependency;
FindLowestPkgDependencyNodeWithNamenull854 function FindLowestPkgDependencyNodeWithName(const PkgName: string): TAVLTreeNode;
FindNextPkgDependencyNodeWithSameNamenull855 function FindNextPkgDependencyNodeWithSameName(Node: TAVLTreeNode): TAVLTreeNode;
856
GetDependencyOwnerAsStringnull857 function GetDependencyOwnerAsString(Dependency: TPkgDependency): string;
GetDependencyOwnerDirectorynull858 function GetDependencyOwnerDirectory(Dependency: TPkgDependency): string;
859
860 procedure PkgVersionLoadFromXMLConfig(Version: TPkgVersion;
861 XMLConfig: TXMLConfig; const Path: string; FileVersion: integer);
862 procedure PkgVersionSaveToXMLConfig(Version: TPkgVersion; XMLConfig: TXMLConfig;
863 const Path: string);
864 procedure PkgVersionLoadFromXMLConfig(Version: TPkgVersion;
865 XMLConfig: TXMLConfig);
866
867 var
868 Package1: TLazPackage; // don't use it - only for options dialog
869
870 function dbgs(p: TPackageUpdatePolicy): string; overload;
871 function dbgs(p: TLazPackageType): string; overload;
872 function PackagePathToStr(PathList: TFPList): string;
873
874
875 implementation
876
877 function GetPkgFileTypeLocalizedName(FileType: TPkgFileType): string;
878 begin
879 case FileType of
880 pftUnit: Result:=lisUnit;
881 pftVirtualUnit: Result:=lisPkgFileTypeVirtualUnit;
882 pftMainUnit: Result:=lisPkgFileTypeMainUnit;
883 pftLFM: Result:=lisPkgFileTypeLFM;
884 pftLRS: Result:=lisPkgFileTypeLRS;
885 pftInclude: Result:=lisPkgFileTypeInclude;
886 pftIssues: Result:=lisPkgFileTypeIssues;
887 pftText: Result:=lisPkgFileTypeText;
888 pftBinary: Result:=lisPkgFileTypeBinary;
889 else
890 Result:='Unknown';
891 end;
892 end;
893
894 function NameToAutoUpdatePolicy(const s: string): TPackageUpdatePolicy;
895 begin
896 for Result:=Low(TPackageUpdatePolicy) to High(TPackageUpdatePolicy) do
897 if SysUtils.CompareText(AutoUpdateNames[Result],s)=0 then exit;
898 Result:=pupAsNeeded;
899 end;
900
901 function FileNameToPkgFileType(AFilename: string): TPkgFileType;
902 var
903 Code: TCodeBuffer;
904 SrcType: String;
905 HasName: Boolean;
906 begin
907 HasName:=ExtractFileNameOnly(AFilename)<>'';
908 if HasName then begin
909 if CompareFileExt(AFilename,'.lfm',true)=0 then
910 exit(pftLFM)
911 else if CompareFileExt(AFilename,'.lrs',true)=0 then
912 exit(pftLRS)
913 else if CompareFileExt(AFilename,'.inc',true)=0 then
914 exit(pftInclude)
915 else if CompareFileExt(AFilename,'.xml',true)=0 then
916 exit(pftIssues)
917 else if FilenameIsPascalUnit(AFilename) then begin
918 Result:=pftUnit;
919 AFilename:=CleanAndExpandFilename(AFilename);
920 Code:=CodeToolBoss.LoadFile(aFilename,true,false);
921 if Code<>nil then begin
922 SrcType:=CodeToolBoss.GetSourceType(Code,false);
923 if CompareText(SrcType,'unit')<>0 then
924 Result:=pftInclude;
925 end;
926 exit;
927 end;
928 end;
929 if FileIsText(AFilename) then
930 Result:=pftText
931 else
932 Result:=pftBinary;
933 end;
934
935 procedure LoadPkgDependencyList(XMLConfig: TXMLConfig; const ThePath: string;
936 var First: TPkgDependency; ListType: TPkgDependencyList; Owner: TObject;
937 HoldPackages, SortList: boolean);
938 var
939 i: Integer;
940 PkgDependency: TPkgDependency;
941 NewCount: Integer;
942 List: TFPList;
943 FileVersion: Integer;
944 Last: TPkgDependency;
945 begin
946 FileVersion:=XMLConfig.GetValue(ThePath+'Version',0);
947 NewCount:=XMLConfig.GetValue(ThePath+'Count',0);
948 List:=TFPList.Create;
949 for i:=0 to NewCount-1 do begin
950 PkgDependency:=TPkgDependency.Create;
951 PkgDependency.LoadFromXMLConfig(XMLConfig,ThePath+'Item'+IntToStr(i+1)+'/',
952 FileVersion);
953 PkgDependency.HoldPackage:=HoldPackages;
954 if PkgDependency.IsMakingSense then
955 List.Add(PkgDependency)
956 else
957 PkgDependency.Free;
958 end;
959 if SortList then
960 SortDependencyListAlphabetically(List);
961 Last:=First;
962 if Last<>nil then
963 while Last.NextDependency[ListType]<>nil do
964 Last:=Last.NextDependency[ListType];
965 for i:=0 to List.Count-1 do begin
966 PkgDependency:=TPkgDependency(List[i]);
967 PkgDependency.AddToEndOfList(Last,ListType);
968 if First=nil then
969 First:=Last;
970 PkgDependency.Owner:=Owner;
971 end;
972 List.Free;
973 end;
974
975 procedure SavePkgDependencyList(XMLConfig: TXMLConfig; const ThePath: string;
976 First: TPkgDependency; ListType: TPkgDependencyList;
977 UsePathDelim: TPathDelimSwitch);
978 var
979 i: Integer;
980 Dependency: TPkgDependency;
981 begin
982 i:=0;
983 Dependency:=First;
984 while Dependency<>nil do begin
985 inc(i);
986 Dependency.SaveToXMLConfig(XMLConfig,ThePath+'Item'+IntToStr(i)+'/',UsePathDelim);
987 Dependency:=Dependency.NextDependency[ListType];
988 end;
989 XMLConfig.SetDeleteValue(ThePath+'Count',i,0);
990 end;
991
992 procedure ListPkgIDToDependencyList(ListOfTLazPackageID: TObjectList;
993 var First: TPkgDependency; ListType: TPkgDependencyList; Owner: TObject;
994 HoldPackages: boolean);
995 var
996 NewDependency: TPkgDependency;
997 i: Integer;
998 PkgID: TLazPackageID;
999 begin
1000 First:=nil;
1001 for i:=ListOfTLazPackageID.Count-1 downto 0 do begin
1002 PkgID:=TLazPackageID(ListOfTLazPackageID[i]);
1003 NewDependency:=TPkgDependency.Create;
1004 NewDependency.Assign(PkgID);
1005 NewDependency.Owner:=Owner;
1006 NewDependency.HoldPackage:=HoldPackages;
1007 NewDependency.AddToList(First,ListType);
1008 end;
1009 end;
1010
1011 procedure DeleteDependencyInList(ADependency: TPkgDependency;
1012 var First: TPkgDependency; ListType: TPkgDependencyList);
1013 var
1014 NextDependency, PrevDependency: TPkgDependency;
1015 begin
1016 NextDependency := ADependency.NextDependency[ListType];
1017 PrevDependency := ADependency.PrevDependency[ListType];
1018 if First = ADependency then First := NextDependency;
1019 if Assigned(NextDependency) then
1020 NextDependency.PrevDependency[ListType] := PrevDependency;
1021 if Assigned(PrevDependency) then
1022 PrevDependency.NextDependency[ListType] := NextDependency;
1023 ADependency.Free;
1024 end;
1025
1026 procedure FreeDependencyList(var First: TPkgDependency;
1027 ListType: TPkgDependencyList);
1028 var
1029 NextDependency: TPkgDependency;
1030 begin
1031 while First<>nil do begin
1032 NextDependency:=First.NextDependency[ListType];
1033 First.Free;
1034 First:=NextDependency;
1035 end;
1036 end;
1037
1038 function DependencyListAsString(First: TPkgDependency;
1039 ListType: TPkgDependencyList): string;
1040 begin
1041 Result:='';
1042 while First<>nil do begin
1043 Result:=Result+First.AsString+LineEnding;
1044 First:=First.NextDependency[ListType];
1045 end;
1046 end;
1047
1048 procedure SortDependencyListAlphabetically(Dependencies: TFPList);
1049 var
1050 Count: Integer;
1051 i, j: Integer;
1052 Dependency1: TPkgDependency;
1053 Dependency2: TPkgDependency;
1054 Sorted: Boolean;
1055 begin
1056 if (Dependencies=nil) or (Dependencies.Count<2) then exit;
1057 // check if already sorted
1058 Count:=Dependencies.Count;
1059 Sorted:=true;
1060 for i:=0 to Count-2 do begin
1061 Dependency1:=TPkgDependency(Dependencies[i]);
1062 Dependency2:=TPkgDependency(Dependencies[i+1]);
1063 if Dependency1.Compare(Dependency2)>0 then begin
1064 Sorted:=false;
1065 break;
1066 end;
1067 end;
1068 if Sorted then exit;
1069 // bubble sort (slow, but dependency lists are normally sorted)
1070 for i:=0 to Count-2 do begin
1071 Dependency1:=TPkgDependency(Dependencies[i]);
1072 for j:=i+1 to Count-1 do begin
1073 Dependency2:=TPkgDependency(Dependencies[j]);
1074 if Dependency1.Compare(Dependency2)>0 then begin
1075 Dependencies.Exchange(i,j);
1076 Dependency1:=TPkgDependency(Dependencies[i]);
1077 end;
1078 end;
1079 end;
1080 end;
1081
1082 function StrToComponentBaseClass(const s: string): TPFComponentBaseClass;
1083 begin
1084 for Result:=low(TPFComponentBaseClass) to high(TPFComponentBaseClass) do
1085 if SysUtils.CompareText(PFComponentBaseClassNames[Result],s)=0 then exit;
1086 Result:=pfcbcNone;
1087 end;
1088
1089 function GetComponentBaseClass(aClass: TClass): TPFComponentBaseClass;
1090 begin
1091 Result:=pfcbcNone;
1092 if aClass=nil then exit;
1093 if aClass.InheritsFrom(TForm) then
1094 Result:=pfcbcForm
1095 else if aClass.InheritsFrom(TFrame) then
1096 Result:=pfcbcFrame
1097 else if aClass.InheritsFrom(TDataModule) then
1098 Result:=pfcbcDataModule
1099 else if aClass.InheritsFrom(TCustomForm) then
1100 Result:=pfcbcCustomForm;
1101 end;
1102
1103 function CompareLazPackageID(Data1, Data2: Pointer): integer;
1104 var
1105 Pkg1: TLazPackageID absolute Data1;
1106 Pkg2: TLazPackageID absolute Data2;
1107 begin
1108 Result:=Pkg1.Compare(Pkg2);
1109 end;
1110
1111 function CompareNameWithPackageID(Key, Data: Pointer): integer;
1112 var
1113 Name: String;
1114 Pkg: TLazPackageID;
1115 begin
1116 if Key<>nil then begin
1117 Name:=AnsiString(Key);
1118 Pkg:=TLazPackageID(Data);
1119 Result:=SysUtils.CompareText(Name,Pkg.Name);
1120 end else
1121 Result:=-1;
1122 end;
1123
1124 function ComparePkgIDMaskWithPackageID(Key, Data: Pointer): integer;
1125 var
1126 Pkg1: TLazPackageID absolute Key;
1127 Pkg2: TLazPackageID absolute Data;
1128 begin
1129 Result:=Pkg1.CompareMask(Pkg2);
1130 end;
1131
1132 function CompareLazPackageIDNames(Data1, Data2: Pointer): integer;
1133 var
1134 Pkg1: TLazPackageID absolute Data1;
1135 Pkg2: TLazPackageID absolute Data2;
1136 begin
1137 Result:=SysUtils.CompareText(Pkg1.Name,Pkg2.Name);
1138 end;
1139
1140 function CompareLazPackageTopologicallyAndName(Data1, Data2: Pointer): integer;
1141 var
1142 Pkg1: TLazPackage absolute Data1;
1143 Pkg2: TLazPackage absolute Data2;
1144 begin
1145 Result:=Pkg1.TopologicalLevel-Pkg2.TopologicalLevel;
1146 if Result<>0 then exit;
1147 Result:=SysUtils.CompareText(Pkg1.Name,Pkg2.Name);
1148 end;
1149
1150 function CompareNameWithPkgDependency(Key, Data: Pointer): integer;
1151 var
1152 PkgName: String;
1153 Dependency: TPkgDependency absolute Data;
1154 begin
1155 PkgName:=String(Key);
1156 Result:=SysUtils.CompareText(PkgName,Dependency.PackageName);
1157 end;
1158
1159 function ComparePkgDependencyNames(Data1, Data2: Pointer): integer;
1160 var
1161 Dependency1: TPkgDependency absolute Data1;
1162 Dependency2: TPkgDependency absolute Data2;
1163 begin
1164 Result:=SysUtils.CompareText(Dependency1.PackageName,Dependency2.PackageName);
1165 end;
1166
1167 function CompareUnitsTree(UnitTree1, UnitTree2: TPkgUnitsTree): integer;
1168 begin
1169 Result:=UnitTree1.LazPackage.Compare(UnitTree2.LazPackage);
1170 end;
1171
1172 function ComparePackageWithUnitsTree(Package: TLazPackage;
1173 UnitTree: TPkgUnitsTree): integer;
1174 begin
1175 Result:=Package.Compare(UnitTree.LazPackage);
1176 end;
1177
1178 function ComparePkgFilesAlphabetically(PkgFile1, PkgFile2: TPkgFile): integer;
1179 var
1180 ShortFilename1: String;
1181 ShortFilename2: String;
1182 File1IsInMainDir: Boolean;
1183 File2IsInMainDir: Boolean;
1184 begin
1185 ShortFilename1:=PkgFile1.GetShortFilename(true);
1186 ShortFilename2:=PkgFile2.GetShortFilename(true);
1187 // files in the main directory are higher
1188 File1IsInMainDir:=ExtractFilePath(ShortFilename1)='';
1189 File2IsInMainDir:=ExtractFilePath(ShortFilename2)='';
1190 if File1IsInMainDir xor File2IsInMainDir then begin
1191 if File1IsInMainDir then
1192 Result:=-1
1193 else
1194 Result:=1;
1195 exit;
1196 end;
1197 // compare short filenames without extension
1198 Result:=CompareFilenames(ChangeFileExt(ShortFilename1,''),
1199 ChangeFileExt(ShortFilename2,''));
1200 if Result<>0 then exit;
1201 // if one is a unit, then it is higher
1202 if (PkgFile1.Unit_Name<>'') and (PkgFile2.Unit_Name='') then begin
1203 Result:=-1;
1204 exit;
1205 end else if (PkgFile1.Unit_Name='') and (PkgFile2.Unit_Name<>'') then begin
1206 Result:=1;
1207 exit;
1208 end;
1209 // compare short filenames with extension
1210 Result:=CompareFilenames(ShortFilename1,ShortFilename2);
1211 if Result<>0 then exit;
1212 // compare filenames
1213 Result:=CompareFilenames(PkgFile1.FileName,PkgFile2.FileName);
1214 end;
1215
1216 function GetUsageOptionsList(PackageList: TFPList): TFPList;
1217 // returns a list of TPkgAdditionalCompilerOptions
1218 // from the list of TLazPackage
1219 var
1220 Cnt: Integer;
1221 i: Integer;
1222 begin
1223 if PackageList<>nil then begin
1224 Result:=TFPList.Create;
1225 Cnt:=PackageList.Count;
1226 for i:=0 to Cnt-1 do begin
1227 Result.Add(TLazPackage(PackageList[i]).UsageOptions);
1228 end;
1229 end else begin
1230 Result:=nil;
1231 end;
1232 end;
1233
1234 function FindDependencyByNameInList(First: TPkgDependency;
1235 ListType: TPkgDependencyList; const Name: string): TPkgDependency;
1236 begin
1237 Result:=First;
1238 while Result<>nil do begin
1239 if SysUtils.CompareText(Result.PackageName,Name)=0 then exit;
1240 Result:=Result.NextDependency[ListType];
1241 end;
1242 end;
1243
1244 function FindCompatibleDependencyInList(First: TPkgDependency;
1245 ListType: TPkgDependencyList; ComparePackage: TLazPackageID): TPkgDependency;
1246 begin
1247 Result:=First;
1248 while Result<>nil do begin
1249 if Result.IsCompatible(ComparePackage) then exit;
1250 Result:=Result.NextDependency[ListType];
1251 end;
1252 end;
1253
1254 function GetDependencyWithIndex(First: TPkgDependency;
1255 ListType: TPkgDependencyList; Index: integer): TPkgDependency;
1256 begin
1257 if Index<0 then RaiseGDBException('GetDependencyWithIndex');
1258 Result:=First;
1259 while (Result<>nil) and (Index>0) do begin
1260 Result:=Result.NextDependency[ListType];
1261 dec(Index);
1262 end;
1263 end;
1264
1265 function FindLowestPkgDependencyNodeWithName(const PkgName: string): TAVLTreeNode;
1266 begin
1267 Result:=nil;
1268 if PackageDependencies=nil then exit;
1269 Result:=PackageDependencies.FindLeftMostKey(PChar(PkgName),
1270 @CompareNameWithPkgDependency);
1271 end;
1272
1273 function FindNextPkgDependencyNodeWithSameName(
1274 Node: TAVLTreeNode): TAVLTreeNode;
1275 begin
1276 Result:=nil;
1277 if (Node=nil) or (PackageDependencies=nil) then exit;
1278 Result:=PackageDependencies.FindSuccessor(Node);
1279 if (Result<>nil)
1280 and (SysUtils.CompareText(TPkgDependency(Node.Data).PackageName,
1281 TPkgDependency(Result.Data).PackageName)<>0)
1282 then
1283 Result:=nil;
1284 end;
1285
1286 function GetDependencyOwnerAsString(Dependency: TPkgDependency): string;
1287 begin
1288 Result := '';
1289 OnGetDependencyOwnerDescription(Dependency,Result);
1290 end;
1291
1292 function GetDependencyOwnerDirectory(Dependency: TPkgDependency): string;
1293 begin
1294 Result := '';
1295 OnGetDependencyOwnerDirectory(Dependency,Result);
1296 end;
1297
1298 procedure PkgVersionLoadFromXMLConfig(Version: TPkgVersion;
1299 XMLConfig: TXMLConfig; const Path: string; FileVersion: integer);
1300 var
1301 NewMajor: Integer;
1302 NewMinor: Integer;
1303 NewRelease: Integer;
1304 NewBuild: Integer;
1305 begin
1306 if FileVersion=1 then ;
1307 NewMajor:=Version.VersionBound(XMLConfig.GetValue(Path+'Major',0));
1308 NewMinor:=Version.VersionBound(XMLConfig.GetValue(Path+'Minor',0));
1309 NewRelease:=Version.VersionBound(XMLConfig.GetValue(Path+'Release',0));
1310 NewBuild:=Version.VersionBound(XMLConfig.GetValue(Path+'Build',0));
1311 Version.SetValues(NewMajor,NewMinor,NewRelease,NewBuild,pvtBuild);
1312 end;
1313
1314 procedure PkgVersionSaveToXMLConfig(Version: TPkgVersion; XMLConfig: TXMLConfig;
1315 const Path: string);
1316 begin
1317 XMLConfig.SetDeleteValue(Path+'Major',Version.Major,0);
1318 XMLConfig.SetDeleteValue(Path+'Minor',Version.Minor,0);
1319 XMLConfig.SetDeleteValue(Path+'Release',Version.Release,0);
1320 XMLConfig.SetDeleteValue(Path+'Build',Version.Build,0);
1321 end;
1322
1323 procedure PkgVersionLoadFromXMLConfig(Version: TPkgVersion;
1324 XMLConfig: TXMLConfig);
1325 var
1326 Path: String;
1327 FileVersion: LongInt;
1328 begin
1329 Path:='Package/';
1330 FileVersion:=XMLConfig.GetValue(Path+'Version',0);
1331 PkgVersionLoadFromXMLConfig(Version,XMLConfig,Path+'Version/',FileVersion);
1332 end;
1333
1334 function dbgs(p: TPackageUpdatePolicy): string;
1335 begin
1336 Result:=GetEnumName(TypeInfo(p),ord(p));
1337 end;
1338
1339 function dbgs(p: TLazPackageType): string;
1340 begin
1341 Result:=LazPackageTypeIdents[p];
1342 end;
1343
1344 function PackagePathToStr(PathList: TFPList): string;
1345 var
1346 i: Integer;
1347 Item: TObject;
1348 Dep: TPkgDependency;
1349 begin
1350 Result:='';
1351 if PathList=nil then exit;
1352 for i:=0 to PathList.Count-1 do begin
1353 if i>0 then
1354 Result:=Result+' -> ';
1355 Item:=TObject(PathList[i]);
1356 if Item is TPkgDependency then begin
1357 Dep:=TPkgDependency(Item);
1358 Result:=Result+GetDependencyOwnerAsString(Dep);
1359 if i=PathList.Count-1 then
1360 Result:=Result+' -> '+Dep.AsString;
1361 end else if Item is TLazPackage then
1362 Result:=Result+TLazPackage(Item).Name
1363 else
1364 Result:=Result+DbgSName(Item);
1365 end;
1366 end;
1367
1368 function IndexOfDependencyInList(First: TPkgDependency;
1369 ListType: TPkgDependencyList; FindDependency: TPkgDependency): integer;
1370 var
1371 Dependency: TPkgDependency;
1372 begin
1373 Result:=-1;
1374 Dependency:=First;
1375 while Dependency<>nil do begin
1376 inc(Result);
1377 if Dependency=FindDependency then exit;
1378 Dependency:=Dependency.NextDependency[ListType];
1379 end;
1380 Result:=-1;
1381 end;
1382
1383 function GetFirstDependency(ListItem: TPkgDependency;
1384 ListType: TPkgDependencyList): TPkgDependency;
1385 begin
1386 Result:=ListItem;
1387 if Result=nil then exit;
1388 while Result.PrevDependency[ListType]<>nil do
1389 Result:=Result.PrevDependency[ListType];
1390 end;
1391
1392 function FindLowestPkgDependencyWithName(const PkgName: string): TPkgDependency;
1393 var
1394 ANode: TAVLTreeNode;
1395 begin
1396 ANode:=FindLowestPkgDependencyNodeWithName(PkgName);
1397 if ANode<>nil then
1398 Result:=TPkgDependency(ANode.Data)
1399 else
1400 Result:=nil;
1401 end;
1402
1403 { TPkgFile }
1404
1405 procedure TPkgFile.SetFilename(const AValue: string);
1406 var
1407 NewFilename: String;
1408 OldDirectory: String;
1409 begin
1410 NewFilename:=AValue;
1411 ForcePathDelims(NewFilename);
1412 if Filename=NewFilename then exit;
1413 fFilename:=NewFilename;
1414 fFullFilenameStamp:=CTInvalidChangeStamp;
1415 OldDirectory:=FDirectory;
1416 FDirectory:=ExtractFilePath(Filename);
1417 if OldDirectory<>FDirectory then begin
1418 if FSourceDirNeedReference then begin
1419 LazPackage.SourceDirectories.RemoveFilename(OldDirectory);
1420 LazPackage.SourceDirectories.AddFilename(FDirectory);
1421 end;
1422 end;
1423 UpdateUnitName;
1424 end;
1425
GetHasRegisterProcnull1426 function TPkgFile.GetHasRegisterProc: boolean;
1427 begin
1428 Result:=pffHasRegisterProc in FFlags;
1429 end;
1430
1431 procedure TPkgFile.SetAddToUsesPkgSection(const AValue: boolean);
1432 begin
1433 if AddToUsesPkgSection=AValue then exit;
1434 if AValue then
1435 Include(FFlags,pffAddToPkgUsesSection)
1436 else
1437 Exclude(FFlags,pffAddToPkgUsesSection);
1438 end;
1439
1440 procedure TPkgFile.SetAutoReferenceSourceDir(const AValue: boolean);
1441 begin
1442 if FAutoReferenceSourceDir=AValue then exit;
1443 FAutoReferenceSourceDir:=AValue;
1444 if FSourceDirNeedReference then
1445 UpdateSourceDirectoryReference;
1446 end;
1447
1448 procedure TPkgFile.SetRemoved(const AValue: boolean);
1449 begin
1450 if Removed=AValue then exit;
1451 inherited SetRemoved(AValue);
1452 FSourceDirNeedReference:=(FileType in PkgFileRealUnitTypes) and not Removed;
1453 UpdateSourceDirectoryReference;
1454 end;
1455
1456 procedure TPkgFile.SetDisableI18NForLFM(AValue: boolean);
1457 begin
1458 if DisableI18NForLFM=AValue then exit;
1459 inherited SetDisableI18NForLFM(AValue);
1460 LazPackage.Modified:=true;
1461 end;
1462
GetComponentsnull1463 function TPkgFile.GetComponents(Index: integer): TPkgComponent;
1464 begin
1465 Result:=TPkgComponent(FComponents[Index]);
1466 end;
1467
GetAddToUsesPkgSectionnull1468 function TPkgFile.GetAddToUsesPkgSection: boolean;
1469 begin
1470 Result:=pffAddToPkgUsesSection in FFlags;
1471 end;
1472
1473 procedure TPkgFile.SetFileType(const AValue: TPkgFileType);
1474 begin
1475 if FileType=AValue then exit;
1476 if (LazPackage<>nil) and (LazPackage.MainUnit=Self) then
1477 LazPackage.FMainUnit:=nil;
1478 inherited SetFileType(AValue);
1479 FSourceDirNeedReference:=(FileType in PkgFileRealUnitTypes) and not Removed;
1480 UpdateSourceDirectoryReference;
1481 if (FileType=pftMainUnit) and (LazPackage<>nil)
1482 and (LazPackage.MainUnit<>Self) then begin
1483 if LazPackage.MainUnit<>nil then
1484 LazPackage.MainUnit.FileType:=pftUnit;
1485 LazPackage.FMainUnit:=Self;
1486 end;
1487 end;
1488
1489 procedure TPkgFile.SetFlags(const AValue: TPkgFileFlags);
1490 begin
1491 if FFlags=AValue then exit;
1492 FFlags:=AValue;
1493 end;
1494
1495 procedure TPkgFile.SetHasRegisterProc(const AValue: boolean);
1496 begin
1497 if HasRegisterProc=AValue then exit;
1498 if AValue then
1499 Include(FFlags,pffHasRegisterProc)
1500 else
1501 Exclude(FFlags,pffHasRegisterProc);
1502 end;
1503
1504 procedure TPkgFile.SetUnitName(const AValue: string);
1505 begin
1506 if FUnitName=AValue then Exit;
1507 FUnitName:=AValue;
1508 end;
1509
1510 procedure TPkgFile.UpdateUnitName;
1511 var
1512 NewUnitName: String;
1513 begin
1514 if FilenameIsPascalUnit(Filename) then begin
1515 NewUnitName:=ExtractFileNameOnly(Filename);
1516 if SysUtils.CompareText(NewUnitName,FUnitName)<>0 then
1517 FUnitName:=NewUnitName;
1518 end else
1519 FUnitName:='';
1520 end;
1521
GetComponentListnull1522 function TPkgFile.GetComponentList: TFPList;
1523 begin
1524 if FComponents=nil then FComponents:=TFPList.Create;
1525 Result:=FComponents;
1526 end;
1527
GetInUsesnull1528 function TPkgFile.GetInUses: boolean;
1529 begin
1530 Result:=pffAddToPkgUsesSection in FFlags;
1531 end;
1532
1533 procedure TPkgFile.SetInUses(AValue: boolean);
1534 begin
1535 if InUses=AValue then exit;
1536 if AValue then
1537 Include(FFlags,pffAddToPkgUsesSection)
1538 else
1539 Exclude(FFlags,pffAddToPkgUsesSection);
1540 end;
1541
GetIDEPackagenull1542 function TPkgFile.GetIDEPackage: TIDEPackage;
1543 begin
1544 Result:=FPackage;
1545 end;
1546
GetFilenamenull1547 function TPkgFile.GetFilename: string;
1548 begin
1549 Result:=fFilename;
1550 end;
1551
HasRegisteredPluginsnull1552 function TPkgFile.HasRegisteredPlugins: boolean;
1553 begin
1554 Result:=ComponentCount>0;
1555 end;
1556
MakeSensenull1557 function TPkgFile.MakeSense: boolean;
1558 begin
1559 Result:=Filename<>'';
1560 end;
1561
1562 procedure TPkgFile.UpdateSourceDirectoryReference;
1563 begin
1564 if (not AutoReferenceSourceDir) or (FPackage=nil) then exit;
1565 if FSourceDirNeedReference then begin
1566 if not SourceDirectoryReferenced then begin
1567 LazPackage.SourceDirectories.AddFilename(FDirectory);
1568 FSourceDirectoryReferenced:=true;
1569 end;
1570 end else begin
1571 if SourceDirectoryReferenced then begin
1572 LazPackage.SourceDirectories.RemoveFilename(FDirectory);
1573 FSourceDirectoryReferenced:=false;
1574 end;
1575 end;
1576 end;
1577
GetFullFilenamenull1578 function TPkgFile.GetFullFilename: string;
1579 begin
1580 if fFullFilenameStamp<>CompilerParseStamp then begin
1581 fFullFilename:=Filename;
1582 fFullFilenameStamp:=CompilerParseStamp;
1583 if LazPackage<>nil then begin
1584 LazPackage.SubstitutePkgMacros(fFullFilename,false);
1585 fFullFilename:=TrimFilename(fFullFilename);
1586 LazPackage.LongenFilename(fFullFilename);
1587 end
1588 else begin
1589 IDEMacros.SubstituteMacros(fFullFilename);
1590 fFullFilename:=TrimAndExpandFilename(fFullFilename);
1591 end;
1592 end;
1593 Result:=fFullFilename;
1594 end;
1595
1596 constructor TPkgFile.Create(ThePackage: TLazPackage);
1597 begin
1598 inherited Create;
1599 Clear;
1600 FPackage:=ThePackage;
1601 FComponentPriority:=ComponentPriorityNormal;
1602 end;
1603
1604 destructor TPkgFile.Destroy;
1605 begin
1606 FreeThenNil(FComponents);
1607 if (LazPackage<>nil) then begin
1608 if (LazPackage.MainUnit=Self) then
1609 LazPackage.FMainUnit:=nil;
1610 if (not (lpfDestroying in LazPackage.Flags)) then begin
1611 if Removed then
1612 LazPackage.FRemovedFiles.Remove(Self)
1613 else
1614 LazPackage.FFiles.Remove(Self);
1615 end;
1616 end;
1617 inherited Destroy;
1618 end;
1619
1620 procedure TPkgFile.Clear;
1621 begin
1622 AutoReferenceSourceDir:=false;
1623 if (LazPackage=nil) or (not (lpfDestroying in LazPackage.Flags)) then begin
1624 inherited SetRemoved(false);
1625 fFilename:='';
1626 FDirectory:='';
1627 FFlags:=[];
1628 inherited SetFileType(pftUnit);
1629 FSourceDirectoryReferenced:=false;
1630 FSourceDirNeedReference:=true;
1631 end;
1632 FreeThenNil(FComponents);
1633 if (LazPackage<>nil) and (LazPackage.MainUnit=Self) then
1634 LazPackage.FMainUnit:=nil;
1635 end;
1636
1637 procedure TPkgFile.LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string;
1638 FileVersion: integer; AdjustPathDelims: boolean);
1639 var
1640 AFilename: String;
1641 CaseInsensitiveUnitName: String;
1642 begin
1643 if FileVersion=1 then ;
1644 Clear;
1645 AFilename:=SwitchPathDelims(XMLConfig.GetValue(Path+'Filename/Value',''),
1646 AdjustPathDelims);
1647 FPackage.LongenFilename(AFilename);
1648 Filename:=AFilename;
1649 FileType:=PkgFileTypeIdentToType(XMLConfig.GetValue(Path+'Type/Value',''));
1650 HasRegisterProc:=XMLConfig.GetValue(Path+'HasRegisterProc/Value',false);
1651 AddToUsesPkgSection:=XMLConfig.GetValue(Path+'AddToUsesPkgSection/Value',
1652 FileType in PkgFileUnitTypes);
1653 DisableI18NForLFM:=XMLConfig.GetValue(Path+'DisableI18NForLFM/Value',false);
1654 fUnitName:=XMLConfig.GetValue(Path+'UnitName/Value','');
1655 if FileType in PkgFileUnitTypes then begin
1656 // make sure the unitname makes sense
1657 CaseInsensitiveUnitName:=ExtractFileNameOnly(Filename);
1658 if SysUtils.CompareText(fUnitName,CaseInsensitiveUnitName)<>0 then
1659 fUnitName:=CaseInsensitiveUnitName;
1660 end;
1661 FResourceBaseClass:=StrToComponentBaseClass(
1662 XMLConfig.GetValue(Path+'ResourceBaseClass/Value',''));
1663 end;
1664
1665 procedure TPkgFile.SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string;
1666 UsePathDelim: TPathDelimSwitch);
1667 var
1668 TmpFilename: String;
1669 begin
1670 TmpFilename:=Filename;
1671 FPackage.ShortenFilename(TmpFilename,true);
1672 XMLConfig.SetDeleteValue(Path+'Filename/Value',
1673 SwitchPathDelims(TmpFilename,UsePathDelim),'');
1674 XMLConfig.SetDeleteValue(Path+'Type/Value',PkgFileTypeIdents[FileType],
1675 PkgFileTypeIdents[pftUnit]);
1676 XMLConfig.SetDeleteValue(Path+'HasRegisterProc/Value',HasRegisterProc,
1677 false);
1678 XMLConfig.SetDeleteValue(Path+'AddToUsesPkgSection/Value',AddToUsesPkgSection,
1679 FileType in PkgFileUnitTypes);
1680 XMLConfig.SetDeleteValue(Path+'DisableI18NForLFM/Value',DisableI18NForLFM,false);
1681 XMLConfig.SetDeleteValue(Path+'UnitName/Value',FUnitName,'');
1682 XMLConfig.SetDeleteValue(Path+'ResourceBaseClass/Value',
1683 PFComponentBaseClassNames[FResourceBaseClass],
1684 PFComponentBaseClassNames[pfcbcNone]);
1685 end;
1686
1687 procedure TPkgFile.ConsistencyCheck;
1688 begin
1689 if FPackage=nil then
1690 RaiseGDBException('TPkgFile.ConsistencyCheck FPackage=nil');
1691 if Filename='' then
1692 RaiseGDBException('TPkgFile.ConsistencyCheck FFilename=""');
1693 end;
1694
GetShortFilenamenull1695 function TPkgFile.GetShortFilename(UseUp: boolean): string;
1696 begin
1697 Result:=GetFullFilename;
1698 LazPackage.ShortenFilename(Result,UseUp);
1699 end;
1700
ComponentCountnull1701 function TPkgFile.ComponentCount: integer;
1702 begin
1703 if FComponents<>nil then
1704 Result:=FComponents.Count
1705 else
1706 Result:=0;
1707 end;
1708
1709 procedure TPkgFile.AddPkgComponent(APkgComponent: TPkgComponent);
1710 begin
1711 if FComponents=nil then FComponents:=TFPList.Create;
1712 FComponents.Add(APkgComponent);
1713 if LazPackage<>nil then
1714 LazPackage.AddPkgComponent(APkgComponent);
1715 end;
1716
1717 procedure TPkgFile.RemovePkgComponent(APkgComponent: TPkgComponent);
1718 begin
1719 if FComponents<>nil then
1720 FComponents.Remove(APkgComponent);
1721 if LazPackage<>nil then
1722 LazPackage.RemovePkgComponent(APkgComponent);
1723 end;
1724
GetResolvedFilenamenull1725 function TPkgFile.GetResolvedFilename: string;
1726 begin
1727 Result:=GetPhysicalFilenameCached(GetFullFilename,false);
1728 end;
1729
GetFileOwnernull1730 function TPkgFile.GetFileOwner: TObject;
1731 begin
1732 Result:=LazPackage;
1733 end;
1734
GetFileOwnerNamenull1735 function TPkgFile.GetFileOwnerName: string;
1736 begin
1737 if LazPackage<>nil then
1738 Result:=LazPackage.Name
1739 else
1740 Result:='';
1741 end;
1742
1743 { TPkgDependency }
1744
1745 procedure TPkgDependency.SetHoldPackage(const AValue: boolean);
1746 begin
1747 if FHoldPackage=AValue then exit;
1748 FHoldPackage:=AValue;
1749 if RequiredPackage<>nil then begin
1750 if FHoldPackage then
1751 inc(RequiredPackage.FHoldPackageCount)
1752 else
1753 dec(RequiredPackage.FHoldPackageCount);
1754 end;
1755 end;
1756
GetRequiredPackagenull1757 function TPkgDependency.GetRequiredPackage: TLazPackage;
1758 begin
1759 Result := TLazPackage(FRequiredPackage);
1760 end;
1761
1762 procedure TPkgDependency.SetRequiredPackage(AValue: TLazPackage);
1763 begin
1764 Assert((FDependencyType=pdtLazarus) or not assigned(AValue), 'Not possible to set a reference to a LazPackage into an FPMake-dependency');
1765 RequiredIDEPackage := AValue;
1766 end;
1767
1768 procedure TPkgDependency.SetPackageName(const AValue: string);
1769 begin
1770 if FPackageName=AValue then exit;
1771 if (PackageDependencies<>nil) and (FPackageName<>'') then
1772 AVLRemovePointer(PackageDependencies,Self);
1773 FPackageName:=AValue;
1774 if (PackageDependencies<>nil) and (FPackageName<>'') then
1775 PackageDependencies.Add(Self);
1776 FDefaultFilename:='';
1777 end;
1778
1779 constructor TPkgDependency.Create;
1780 begin
1781 inherited Create;
1782 end;
1783
1784 destructor TPkgDependency.Destroy;
1785 begin
1786 inherited Destroy;
1787 end;
1788
1789 procedure TPkgDependency.Clear;
1790 begin
1791 inherited Clear;
1792 FDefaultFilename:='';
1793 FPreferDefaultFilename:=false;
1794 end;
1795
1796 procedure TPkgDependency.LoadFromXMLConfig(XMLConfig: TXMLConfig;
1797 const Path: string; FileVersion: integer);
1798
1799 function LoadFilename(const SubPath: string): string;
1800 var
1801 BaseDir: String;
1802 begin
1803 Result:=GetForcedPathDelims(XMLConfig.GetValue(Path+SubPath,''));
1804 if (Result<>'') and (Owner<>nil)
1805 and (not FilenameIsAbsolute(Result)) then begin
1806 BaseDir:=GetDependencyOwnerDirectory(Self);
1807 if BaseDir<>'' then
1808 Result:=TrimFilename(AppendPathDelim(BaseDir)+Result);
1809 end;
1810 end;
1811
1812 begin
1813 if FileVersion=1 then ;
1814 Clear;
1815 PackageName:=XMLConfig.GetValue(Path+'PackageName/Value','');
1816 if SameText(XMLConfig.GetValue(Path+'DependencyType/Value',''), PkgDependencyTypeNames[pdtFPMake]) then
1817 DependencyType:=pdtFPMake
1818 else
1819 DependencyType:=pdtLazarus;
1820 PkgVersionLoadFromXMLConfig(MaxVersion,XMLConfig,Path+'MaxVersion/',FileVersion);
1821 PkgVersionLoadFromXMLConfig(MinVersion,XMLConfig,Path+'MinVersion/',FileVersion);
1822 if XMLConfig.GetValue(Path+'MaxVersion/Valid',false) then
1823 Include(FFlags,pdfMaxVersion);
1824 if XMLConfig.GetValue(Path+'MinVersion/Valid',false) then
1825 Include(FFlags,pdfMinVersion);
1826 FDefaultFilename:=LoadFilename('DefaultFilename/Value');
1827 PreferDefaultFilename:=XMLConfig.GetValue(Path+'DefaultFilename/Prefer',false);
1828 end;
1829
1830 procedure TPkgDependency.SaveToXMLConfig(XMLConfig: TXMLConfig;
1831 const Path: string; UsePathDelim: TPathDelimSwitch);
1832
1833 procedure SaveFilename(const aPath: string; AFilename: string);
1834 var
1835 BaseDir: String;
1836 begin
1837 if (AFilename<>'')
1838 and (Owner<>nil) then begin
1839 BaseDir:=GetDependencyOwnerDirectory(Self);
1840 if BaseDir<>'' then
1841 AFilename:=CreateRelativePath(AFilename,BaseDir);
1842 end;
1843 XMLConfig.SetDeleteValue(Path+aPath,SwitchPathDelims(AFilename,UsePathDelim),'');
1844 end;
1845
1846 begin
1847 XMLConfig.SetDeleteValue(Path+'PackageName/Value',PackageName,'');
1848 PkgVersionSaveToXMLConfig(MaxVersion,XMLConfig,Path+'MaxVersion/');
1849 PkgVersionSaveToXMLConfig(MinVersion,XMLConfig,Path+'MinVersion/');
1850 XMLConfig.SetDeleteValue(Path+'MaxVersion/Valid',pdfMaxVersion in FFlags,false);
1851 XMLConfig.SetDeleteValue(Path+'MinVersion/Valid',pdfMinVersion in FFlags,false);
1852 SaveFilename('DefaultFilename/Value',FDefaultFilename);
1853 XMLConfig.SetDeleteValue(Path+'DefaultFilename/Prefer',PreferDefaultFilename,false);
1854 XMLConfig.SetDeleteValue(Path+'DependencyType/Value',PkgDependencyTypeNames[DependencyType],PkgDependencyTypeNames[pdtLazarus]);
1855 end;
1856
Comparenull1857 function TPkgDependency.Compare(Dependency2: TPkgDependency): integer;
1858 begin
1859 Result:=SysUtils.CompareText(PackageName,Dependency2.PackageName);
1860 if Result<>0 then exit;
1861 Result:=MinVersion.Compare(Dependency2.MinVersion);
1862 if Result<>0 then exit;
1863 Result:=CompareBoolean(pdfMinVersion in Flags,
1864 pdfMinVersion in Dependency2.Flags);
1865 if Result<>0 then exit;
1866 Result:=MaxVersion.Compare(Dependency2.MaxVersion);
1867 if Result<>0 then exit;
1868 Result:=CompareBoolean(pdfMaxVersion in Flags,
1869 pdfMaxVersion in Dependency2.Flags);
1870 end;
1871
1872 procedure TPkgDependency.Assign(Source: TPkgDependency);
1873 begin
1874 PackageName:=Source.PackageName;
1875 Flags:=Source.Flags;
1876 MinVersion.Assign(Source.MinVersion);
1877 MaxVersion.Assign(Source.MaxVersion);
1878 end;
1879
1880 procedure TPkgDependency.Assign(Source: TLazPackageID);
1881 begin
1882 PackageName:=Source.Name;
1883 Flags:=[pdfMinVersion];
1884 MinVersion.Assign(Source.Version);
1885 end;
1886
1887 procedure TPkgDependency.ConsistencyCheck;
1888 begin
1889
1890 end;
1891
IsCompatiblenull1892 function TPkgDependency.IsCompatible(Pkg: TLazPackageID): boolean;
1893 begin
1894 Result:=IsCompatible(Pkg.Name,Pkg.Version);
1895 end;
1896
1897 procedure TPkgDependency.MakeCompatible(const PkgName: string;
1898 const Version: TPkgVersion);
1899 begin
1900 PackageName:=PkgName;
1901 if MinVersion.Compare(Version)>0 then MinVersion.Assign(Version);
1902 if MaxVersion.Compare(Version)<0 then MaxVersion.Assign(Version);
1903 end;
1904
AsStringnull1905 function TPkgDependency.AsString(WithOwner: boolean; WithDefaults: boolean): string;
1906 begin
1907 if Self=nil then
1908 exit('(nil)');
1909 Result:=FPackageName;
1910 if pdfMinVersion in FFlags then
1911 Result:=Result+' (>='+MinVersion.AsString+')';
1912 if pdfMaxVersion in FFlags then
1913 Result:=Result+' (<='+MaxVersion.AsString+')';
1914 if WithOwner and (Owner<>nil) then
1915 Result:=GetDependencyOwnerAsString(Self)+' uses '+Result;
1916 if WithDefaults then
1917 begin
1918 if DefaultFilename<>'' then begin
1919 Result+=', ';
1920 if PreferDefaultFilename then
1921 Result+='preferred'
1922 else
1923 Result+='default';
1924 Result+='="'+DefaultFilename+'"';
1925 end;
1926 end;
1927 end;
1928
NextUsedByDependencynull1929 function TPkgDependency.NextUsedByDependency: TPkgDependency;
1930 begin
1931 Result:=NextDependency[pdlUsedBy];
1932 end;
1933
PrevUsedByDependencynull1934 function TPkgDependency.PrevUsedByDependency: TPkgDependency;
1935 begin
1936 Result:=PrevDependency[pdlUsedBy];
1937 end;
1938
NextRequiresDependencynull1939 function TPkgDependency.NextRequiresDependency: TPkgDependency;
1940 begin
1941 Result:=NextDependency[pdlRequires];
1942 end;
1943
PrevRequiresDependencynull1944 function TPkgDependency.PrevRequiresDependency: TPkgDependency;
1945 begin
1946 Result:=PrevDependency[pdlRequires];
1947 end;
1948
1949 procedure TPkgDependency.AddUsedByDep(var FirstDependency: TPkgDependencyBase);
1950 begin
1951 AddToList(TPkgDependency(FirstDependency), pdlUsedBy);
1952 end;
1953
1954 procedure TPkgDependency.RemoveUsedByDep(var FirstDependency: TPkgDependencyBase);
1955 begin
1956 RemoveFromList(TPkgDependency(FirstDependency), pdlUsedBy);
1957 end;
1958
1959 procedure TPkgDependency.AddRequiresDep(var FirstDependency: TPkgDependencyBase);
1960 begin
1961 AddToList(TPkgDependency(FirstDependency), pdlRequires);
1962 end;
1963
1964 procedure TPkgDependency.RemoveRequiresDep(var FirstDependency: TPkgDependencyBase);
1965 begin
1966 RemoveFromList(TPkgDependency(FirstDependency), pdlRequires);
1967 end;
1968
1969 procedure TPkgDependency.AddToList(var FirstDependency: TPkgDependency;
1970 ListType: TPkgDependencyList);
1971 begin
1972 NextDependency[ListType]:=FirstDependency;
1973 FirstDependency:=Self;
1974 PrevDependency[ListType]:=nil;
1975 if NextDependency[ListType]<>nil then
1976 NextDependency[ListType].PrevDependency[ListType]:=Self;
1977 end;
1978
1979 procedure TPkgDependency.AddToEndOfList(var LastDependency: TPkgDependency;
1980 ListType: TPkgDependencyList);
1981 begin
1982 PrevDependency[ListType]:=LastDependency;
1983 LastDependency:=Self;
1984 NextDependency[ListType]:=nil;
1985 if PrevDependency[ListType]<>nil then
1986 PrevDependency[ListType].NextDependency[ListType]:=Self;
1987 end;
1988
1989 procedure TPkgDependency.RemoveFromList(var FirstDependency: TPkgDependency;
1990 ListType: TPkgDependencyList);
1991 begin
1992 if FirstDependency=Self then FirstDependency:=NextDependency[ListType];
1993 if NextDependency[ListType]<>nil then
1994 NextDependency[ListType].PrevDependency[ListType]:=PrevDependency[ListType];
1995 if PrevDependency[ListType]<>nil then
1996 PrevDependency[ListType].NextDependency[ListType]:=NextDependency[ListType];
1997 NextDependency[ListType]:=nil;
1998 PrevDependency[ListType]:=nil;
1999 end;
2000
MoveUpInListnull2001 function TPkgDependency.MoveUpInList(var FirstDependency: TPkgDependency;
2002 ListType: TPkgDependencyList): Boolean;
2003 var
2004 OldPrev: TPkgDependency;
2005 begin
2006 if (FirstDependency=Self) or (PrevDependency[ListType]=nil) then exit(False);
2007 OldPrev:=PrevDependency[ListType];
2008 if OldPrev.PrevDependency[ListType]<>nil then
2009 OldPrev.PrevDependency[ListType].NextDependency[ListType]:=Self;
2010 if NextDependency[ListType]<>nil then
2011 NextDependency[ListType].PrevDependency[ListType]:=OldPrev;
2012 OldPrev.NextDependency[ListType]:=NextDependency[ListType];
2013 PrevDependency[ListType]:=OldPrev.PrevDependency[ListType];
2014 NextDependency[ListType]:=OldPrev;
2015 OldPrev.PrevDependency[ListType]:=Self;
2016 if FirstDependency=OldPrev then FirstDependency:=Self;
2017 Result:=True;
2018 end;
2019
MoveDownInListnull2020 function TPkgDependency.MoveDownInList(var FirstDependency: TPkgDependency;
2021 ListType: TPkgDependencyList): Boolean;
2022 var
2023 OldNext: TPkgDependency;
2024 begin
2025 if (NextDependency[ListType]=nil) then exit(False);
2026 OldNext:=NextDependency[ListType];
2027 if OldNext.NextDependency[ListType]<>nil then
2028 OldNext.NextDependency[ListType].PrevDependency[ListType]:=Self;
2029 if PrevDependency[ListType]<>nil then
2030 PrevDependency[ListType].NextDependency[ListType]:=OldNext;
2031 OldNext.PrevDependency[ListType]:=PrevDependency[ListType];
2032 NextDependency[ListType]:=OldNext.NextDependency[ListType];
2033 PrevDependency[ListType]:=OldNext;
2034 OldNext.NextDependency[ListType]:=Self;
2035 if FirstDependency=Self then FirstDependency:=OldNext;
2036 Result:=True;
2037 end;
2038
MakeFilenameRelativeToOwnernull2039 function TPkgDependency.MakeFilenameRelativeToOwner(const AFilename: string): string;
2040 var
2041 BaseDir: String;
2042 begin
2043 Result:=AFilename;
2044 if (Result<>'')
2045 and (Owner<>nil) then begin
2046 BaseDir:=GetDependencyOwnerDirectory(Self);
2047 if BaseDir<>'' then
2048 Result:=CreateRelativePath(Result,BaseDir);
2049 end;
2050 end;
2051
FindDefaultFilenamenull2052 function TPkgDependency.FindDefaultFilename: string;
2053 var
2054 AFilename: String;
2055 CurDir: String;
2056 begin
2057 Result:='';
2058 AFilename:=TrimFilename(DefaultFilename);
2059 if (CompareFileExt(AFilename,'lpk')<>0)
2060 or (SysUtils.CompareText(ExtractFileNameOnly(AFilename),PackageName)<>0) then
2061 exit;
2062 if not FilenameIsAbsolute(AFilename) then begin
2063 CurDir:=GetDependencyOwnerDirectory(Self);
2064 if (CurDir<>'') then
2065 AFilename:=AppendPathDelim(CurDir)+AFilename;
2066 end;
2067 if not FilenameIsAbsolute(AFilename) then exit;
2068 AFilename:=CodeToolBoss.DirectoryCachePool.FindDiskFilename(AFilename);
2069 if not FileExistsCached(AFilename) then exit;
2070 Result:=AFilename;
2071 end;
2072
2073 { TPackageIDEOptions }
2074
2075 constructor TPackageIDEOptions.Create(APackage: TLazPackage);
2076 begin
2077 inherited Create;
2078 FPackage := APackage;
2079 end;
2080
2081 destructor TPackageIDEOptions.Destroy;
2082 begin
2083 inherited Destroy;
2084 end;
2085
2086 class function TPackageIDEOptions.GetInstance: TAbstractIDEOptions;
2087 begin
2088 if Package1<>nil then
2089 Result := Package1.IDEOptions
2090 else
2091 Result := nil;
2092 end;
2093
2094 class function TPackageIDEOptions.GetGroupCaption: string;
2095 begin
2096 Result := lisPckOptsPackageOptions;
2097 end;
2098
2099 { TLazPackage }
2100
2101 procedure TLazPackage.OnMacroListSubstitution(TheMacro: TTransferMacro;
2102 const MacroName: string; var s: string; const Data: PtrInt;
2103 var Handled, Abort: boolean; Depth: integer);
2104 var
2105 Values: TCTCfgScriptVariables;
2106 Macro: PCTCfgScriptVariable;
2107 var
2108 NewValue: String;
2109 begin
2110 if Data=CompilerOptionMacroPlatformIndependent then
2111 begin
2112 NewValue:=GetMakefileMacroValue(MacroName);
2113 if NewValue<>'' then begin
2114 s:=NewValue;
2115 Handled:=true;
2116 exit;
2117 end;
2118 end;
2119
2120 // check build macros
2121 if IsValidIdent(MacroName) then
2122 begin
2123 Values:=GetBuildMacroValues(CompilerOptions,true);
2124 if Values<>nil then begin
2125 Macro:=Values.GetVariable(PChar(MacroName));
2126 if Macro<>nil then
2127 begin
2128 s:=GetCTCSVariableAsString(Macro);
2129 //if MacroName='MyPackageOptions' then
2130 // debugln(['TLazPackage.OnMacroListSubstitution Pkg=',Name,' Macro=',MacroName,' Value="',s,'"']);
2131 Handled:=true;
2132 exit;
2133 end;
2134 end;
2135 end;
2136
2137 if s = '' then
2138 begin
2139 // check local macros
2140 if SysUtils.CompareText(MacroName,'PkgOutDir')=0 then begin
2141 Handled:=true;
2142 if Data=CompilerOptionMacroNormal then
2143 s:=CompilerOptions.ParsedOpts.GetParsedValue(pcosOutputDir)
2144 else
2145 s:=CompilerOptions.ParsedOpts.GetParsedPIValue(pcosOutputDir);
2146 exit;
2147 end
2148 else if SysUtils.CompareText(MacroName,'PkgDir')=0 then begin
2149 Handled:=true;
2150 s:=FDirectory;
2151 exit;
2152 end
2153 else if SysUtils.CompareText(MacroName,'PkgName')=0 then begin
2154 Handled:=true;
2155 s:=Name;
2156 exit;
2157 end
2158 else if SysUtils.CompareText(MacroName,'PkgIncPath')=0 then begin
2159 Handled:=true;
2160 s:=GetIncludePath(false);
2161 exit;
2162 end
2163 else if SysUtils.CompareText(MacroName,'PkgSrcPath')=0 then begin
2164 Handled:=true;
2165 s:=SourceDirectories.CreateSearchPathFromAllFiles;
2166 exit;
2167 end
2168 else if SysUtils.CompareText(MacroName,'PkgUnitPath')=0 then begin
2169 Handled:=true;
2170 s:=GetUnitPath(false);
2171 exit;
2172 end;
2173 end;
2174
2175 // check global macros
2176 GlobalMacroList.ExecuteMacro(MacroName,s,Data,Handled,Abort,Depth);
2177 end;
2178
2179 procedure TLazPackage.SetUserReadOnly(const AValue: boolean);
2180 begin
2181 if FUserReadOnly=AValue then exit;
2182 FUserReadOnly:=AValue;
2183 end;
2184
SubstitutePkgMacrosnull2185 function TLazPackage.SubstitutePkgMacros(const s: string;
2186 PlatformIndependent: boolean): string;
2187 begin
2188 Result:=s;
2189 if PlatformIndependent then
2190 FMacros.SubstituteStr(Result,CompilerOptionMacroPlatformIndependent)
2191 else
2192 FMacros.SubstituteStr(Result,CompilerOptionMacroNormal);
2193 end;
2194
2195 procedure TLazPackage.WriteInheritedUnparsedOptions;
2196 var
2197 OptionsList: TFPList;
2198 AddOptions: TAdditionalCompilerOptions;
2199 i: Integer;
2200 begin
2201 OptionsList:=nil;
2202 CompilerOptions.GetInheritedCompilerOptions(OptionsList);
2203 if OptionsList<>nil then begin
2204 for i:=0 to OptionsList.Count-1 do begin
2205 AddOptions:=TAdditionalCompilerOptions(OptionsList[i]);
2206 if (not (AddOptions is TAdditionalCompilerOptions)) then continue;
2207 DebugLn('TLazPackage.WriteInheritedUnparsedOptions ',
2208 (AddOptions.Owner as TLazPackage).IDAsString,
2209 ' UnitPath="',AddOptions.GetOption(icoUnitPath),'"');
2210 end;
2211 OptionsList.Free;
2212 end;
2213 end;
2214
GetAutoIncrementVersionOnBuildnull2215 function TLazPackage.GetAutoIncrementVersionOnBuild: boolean;
2216 begin
2217 Result:=lpfAutoIncrementVersionOnBuild in FFlags;
2218 end;
2219
GetCompilerOptionsnull2220 function TLazPackage.GetCompilerOptions: TPkgCompilerOptions;
2221 begin
2222 Result := TPkgCompilerOptions(FLazCompilerOptions);
2223 end;
2224
GetBaseCompilerOptionsnull2225 function TLazPackage.GetBaseCompilerOptions: TBaseCompilerOptions;
2226 // This satisfies the IProjPack interface requirement.
2227 begin
2228 Result := TBaseCompilerOptions(FLazCompilerOptions);
2229 end;
2230
GetComponentCountnull2231 function TLazPackage.GetComponentCount: integer;
2232 begin
2233 Result:=FComponents.Count;
2234 end;
2235
GetComponentsnull2236 function TLazPackage.GetComponents(Index: integer): TPkgComponent;
2237 begin
2238 Result:=TPkgComponent(FComponents[Index]);
2239 end;
2240
GetDirectoryExpandednull2241 function TLazPackage.GetDirectoryExpanded: string;
2242 begin
2243 if (FDirectoryExpandedChangeStamp<>CompilerParseStamp) then begin
2244 FDirectoryExpanded:=FDirectory;
2245 // use default macros (not package macros)
2246 if IDEMacros<>nil then
2247 IDEMacros.SubstituteMacros(FDirectoryExpanded);
2248 FDirectoryExpanded:=AppendPathDelim(TrimFilename(FDirectoryExpanded));
2249 FDirectoryExpandedChangeStamp:=CompilerParseStamp;
2250 end;
2251 Result:=FDirectoryExpanded;
2252 end;
2253
GetRemovedCountnull2254 function TLazPackage.GetRemovedCount: integer;
2255 begin
2256 Result:=FRemovedFiles.Count;
2257 end;
2258
GetRemovedPkgFilesnull2259 function TLazPackage.GetRemovedPkgFiles(Index: integer): TLazPackageFile;
2260 begin
2261 Result:=GetRemovedFiles(Index);
2262 end;
2263
2264 procedure TLazPackage.AssignOptions(Source: TPersistent);
2265 var
2266 aSource: TLazPackage;
2267 begin
2268 inherited AssignOptions(Source);
2269 if Source is TLazPackage then
2270 begin
2271 aSource:=TLazPackage(Source);
2272 UserReadOnly:=aSource.UserReadOnly;
2273 Translated:=aSource.Translated;
2274 StorePathDelim:=aSource.StorePathDelim;
2275 // ToDo: PublishOptions.AssignOptions(aSource.PublishOptions);
2276 Provides.Assign(aSource.Provides);
2277 POOutputDirectory:=aSource.POOutputDirectory;
2278 PackageType:=aSource.PackageType;
2279 OutputStateFile:=aSource.OutputStateFile;
2280 License:=aSource.License;
2281 FPDocPaths:=aSource.FPDocPaths;
2282 FPDocPackageName:=aSource.FPDocPackageName;
2283 IconFile:=aSource.IconFile;
2284 UsageOptions.AssignOptions(aSource.UsageOptions);
2285 EnableI18N:=aSource.EnableI18N;
2286 EnableI18NForLFM:=aSource.EnableI18NForLFM;
2287 Description:=aSource.Description;
2288 AutoUpdate:=aSource.AutoUpdate;
2289 AutoIncrementVersionOnBuild:=aSource.AutoIncrementVersionOnBuild;
2290 Author:=aSource.Author;
2291 AddToProjectUsesSection:=aSource.AddToProjectUsesSection;
2292 end;
2293 end;
2294
GetRemovedFilesnull2295 function TLazPackage.GetRemovedFiles(Index: integer): TPkgFile;
2296 begin
2297 If (Index >= 0) And (Index < FRemovedFiles.Count) Then
2298 Result:=TPkgFile(FRemovedFiles[Index])
2299 Else
2300 Result := NIL;
2301 end;
2302
GetDefineTemplatesnull2303 function TLazPackage.GetDefineTemplates: TProjPackDefineTemplates;
2304 begin
2305 Result:=FDefineTemplates;
2306 end;
2307
GetFileCountnull2308 function TLazPackage.GetFileCount: integer;
2309 begin
2310 Result:=FFiles.Count;
2311 end;
2312
GetPkgFilesnull2313 function TLazPackage.GetPkgFiles(Index: integer): TLazPackageFile;
2314 begin
2315 Result:=GetFiles(Index);
2316 end;
2317
GetFilesnull2318 function TLazPackage.GetFiles(Index: integer): TPkgFile;
2319 begin
2320 Result:=TPkgFile(FFiles[Index]);
2321 end;
2322
GetIDEOptionsnull2323 function TLazPackage.GetIDEOptions: TPackageIDEOptions;
2324 begin
2325 Result := TPackageIDEOptions(FIDEOptions);
2326 end;
2327
GetSourceDirectoriesnull2328 function TLazPackage.GetSourceDirectories: TFileReferenceList;
2329 begin
2330 Result:=FSourceDirectories;
2331 end;
2332
GetModifiednull2333 function TLazPackage.GetModified: boolean;
2334 begin
2335 Result:=(lpfModified in FFlags) or CompilerOptions.Modified;
2336 end;
2337
2338 procedure TLazPackage.SetAddToProjectUsesSection(const AValue: boolean);
2339 begin
2340 if FAddToProjectUsesSection=AValue then exit;
2341 FAddToProjectUsesSection:=AValue;
2342 Modified:=true;
2343 end;
2344
2345 procedure TLazPackage.SetAuthor(const AValue: string);
2346 begin
2347 if FAuthor=AValue then exit;
2348 FAuthor:=AValue;
2349 Modified:=true;
2350 end;
2351
2352 procedure TLazPackage.SetAutoIncrementVersionOnBuild(const AValue: boolean);
2353 begin
2354 if AutoIncrementVersionOnBuild=AValue then exit;
2355 if AValue then
2356 Include(FFlags,lpfAutoIncrementVersionOnBuild)
2357 else
2358 Exclude(FFlags,lpfAutoIncrementVersionOnBuild);
2359 Modified:=true;
2360 end;
2361
2362 procedure TLazPackage.SetAutoInstall(AValue: TPackageInstallType);
2363 begin
2364 if FAutoInstall=AValue then exit;
2365 FAutoInstall:=AValue;
2366 end;
2367
2368 procedure TLazPackage.SetAutoUpdate(const AValue: TPackageUpdatePolicy);
2369 begin
2370 if AValue=AutoUpdate then exit;
2371 FAutoUpdate:=AValue;
2372 Modified:=true;
2373 end;
2374
2375 procedure TLazPackage.SetDescription(const AValue: string);
2376 begin
2377 if FDescription=AValue then exit;
2378 FDescription:=AValue;
2379 Modified:=true;
2380 end;
2381
2382 procedure TLazPackage.SetEnableI18NForLFM(AValue: boolean);
2383 begin
2384 if FEnableI18NForLFM=AValue then Exit;
2385 FEnableI18NForLFM:=AValue;
2386 Modified:=true;
2387 end;
2388
2389 procedure TLazPackage.SetFileReadOnly(const AValue: boolean);
2390 begin
2391 if FFileReadOnly=AValue then exit;
2392 FFileReadOnly:=AValue;
2393 end;
2394
2395 procedure TLazPackage.SetFilename(const AValue: string);
2396 var
2397 NewFilename: String;
2398 begin
2399 NewFilename:=AValue;
2400 ForcePathDelims(NewFilename);
2401 if FFilename=NewFilename then exit;
2402 FFilename:=NewFilename;
2403 if (FFilename<>'') and (FFilename[length(FFilename)]=PathDelim) then
2404 FDirectory:=FFilename
2405 else
2406 FDirectory:=ExtractFilePath(FFilename);
2407 FDirectoryExpandedChangeStamp:=CTInvalidChangeStamp;
2408 FHasDirectory:=(FDirectory<>'') and (FDirectory[length(FDirectory)]=PathDelim);
2409 FHasStaticDirectory:=FHasDirectory and FilenameIsAbsolute(FDirectory);
2410 FUsageOptions.BaseDirectory:=FDirectory;
2411 CompilerOptions.BaseDirectory:=FDirectory;
2412 Modified:=true;
2413 end;
2414
2415 procedure TLazPackage.SetFlags(const AValue: TLazPackageFlags);
2416 var
2417 ChangedFlags: TLazPackageFlags;
2418 begin
2419 if FFlags=AValue then exit;
2420 ChangedFlags:=(FFlags-AValue)+(AValue-FFlags);
2421 FFlags:=AValue;
2422 if ChangedFlags*[lpfAutoIncrementVersionOnBuild]<>[] then
2423 Modified:=true;
2424 end;
2425
2426 procedure TLazPackage.SetFPDocPackageName(AValue: string);
2427 begin
2428 if FFPDocPackageName=AValue then Exit;
2429 FFPDocPackageName:=AValue;
2430 Modified:=true;
2431 end;
2432
2433 procedure TLazPackage.SetIconFile(const AValue: string);
2434 begin
2435 if FIconFile=AValue then exit;
2436 FIconFile:=AValue;
2437 Modified:=true;
2438 end;
2439
2440 procedure TLazPackage.SetInstalled(const AValue: TPackageInstallType);
2441 begin
2442 if FInstalled=AValue then exit;
2443 FInstalled:=AValue;
2444 end;
2445
2446 procedure TLazPackage.SetFPDocPaths(const AValue: string);
2447 var
2448 NewValue: String;
2449 begin
2450 NewValue:=TrimSearchPath(AValue,'');
2451 if FFPDocPaths=NewValue then exit;
2452 FFPDocPaths:=NewValue;
2453 Modified:=true;
2454 end;
2455
2456 procedure TLazPackage.SetLicense(const AValue: string);
2457 begin
2458 if FLicense=AValue then exit;
2459 FLicense:=AValue;
2460 Modified:=true;
2461 end;
2462
2463 procedure TLazPackage.SetLPKSource(const AValue: TCodeBuffer);
2464 begin
2465 if FLPKSource=AValue then exit;
2466 FLPKSource:=AValue;
2467 if LPKSource<>nil then
2468 FLPKSourceChangeStep:=LPKSource.ChangeStep;
2469 // do not change Filename here.
2470 // See TPkgManager.DoSavePackage and TPkgManager.DoOpenPackageFile
2471 // the LPKSource is the codebuffer last used during load/save, so it is not valid
2472 // for packages that were not yet loaded/saved or during renaming/loading/saving.
2473 end;
2474
2475 procedure TLazPackage.SetOutputStateFile(const AValue: string);
2476 var
2477 NewStateFile: String;
2478 begin
2479 NewStateFile:=TrimFilename(AValue);
2480 if FOutputStateFile=NewStateFile then exit;
2481 FOutputStateFile:=NewStateFile;
2482 end;
2483
2484 procedure TLazPackage.SetProvides(const AValue: TStrings);
2485 begin
2486 if (AValue=FProvides) or (FProvides.Equals(AValue)) then exit;
2487 FProvides.Assign(AValue);
2488 Modified:=true;
2489 end;
2490
2491 procedure TLazPackage.SetPOOutputDirectory(const AValue: string);
2492 var
2493 NewValue: String;
2494 begin
2495 NewValue:=TrimFilename(AValue);
2496 if FPOOutputDirectory=NewValue then exit;
2497 FPOOutputDirectory:=NewValue;
2498 Modified:=true;
2499 end;
2500
2501 procedure TLazPackage.SetEnableI18N(const AValue: boolean);
2502 begin
2503 if FEnableI18N=AValue then exit;
2504 FEnableI18N:=AValue;
2505 Modified:=true;
2506 end;
2507
2508 procedure TLazPackage.SetRegistered(const AValue: boolean);
2509 begin
2510 if FRegistered=AValue then exit;
2511 FRegistered:=AValue;
2512 end;
2513
2514 procedure TLazPackage.ModifySilently;
2515 begin
2516 if FModifiedLock>0 then exit;
2517 Include(FFlags,lpfModified);
2518 Exclude(FFlags,lpfSkipSaving);
2519 if FChangeStamp<High(FChangeStamp) then
2520 inc(FChangeStamp)
2521 else
2522 FChangeStamp:=low(FChangeStamp);
2523 if Assigned(FOnModifySilently) then
2524 FOnModifySilently(Self);
2525 end;
2526
2527 procedure TLazPackage.SetModified(const AValue: boolean);
2528 begin
2529 if AValue then begin
2530 if FModifiedLock>0 then exit;
2531 ModifySilently;
2532 end
2533 else begin
2534 FFlags:=FFlags-[lpfModified,lpfSkipSaving];
2535 PublishOptions.Modified:=false;
2536 CompilerOptions.Modified:=false;
2537 end;
2538 if Modified and (Editor<>nil) then
2539 Editor.UpdateAll(false);
2540 end;
2541
2542 procedure TLazPackage.SetName(const NewName: TComponentName);
2543 begin
2544 if Name=NewName then exit;
2545 inherited SetName(NewName);
2546 FDefineTemplates.IDChanged;
2547 Modified:=true;
2548 end;
2549
2550 procedure TLazPackage.SetPackageEditor(const AValue: TBasePackageEditor);
2551 begin
2552 if FPackageEditor=AValue then exit;
2553 FPackageEditor:=AValue;
2554 end;
2555
2556 procedure TLazPackage.SetPackageType(const AValue: TLazPackageType);
2557 begin
2558 if FPackageType=AValue then exit;
2559 FPackageType:=AValue;
2560 Modified:=true;
2561 end;
2562
2563 procedure TLazPackage.SetStorePathDelim(const AValue: TPathDelimSwitch);
2564 begin
2565 if FStorePathDelim=AValue then exit;
2566 FStorePathDelim:=AValue;
2567 end;
2568
2569 constructor TLazPackage.Create;
2570 begin
2571 inherited Create;
2572 FComponents:=TFPList.Create;
2573 FSourceDirectories:=TFileReferenceList.Create;
2574 FSourceDirectories.OnChanged:=@SourceDirectoriesChanged;
2575 FFiles:=TFPList.Create;
2576 FRemovedFiles:=TFPList.Create;
2577 FMacros:=TTransferMacroList.Create;
2578 FMacros.OnSubstitution:=@OnMacroListSubstitution;
2579 FIDEOptions:=TPackageIDEOptions.Create(Self);
2580 FLazCompilerOptions:=TPkgCompilerOptions.Create(Self);
2581 CompilerOptions.ParsedOpts.InvalidateParseOnChange:=true;
2582 CompilerOptions.ParsedOpts.OnLocalSubstitute:=@SubstitutePkgMacros;
2583 CompilerOptions.DefaultMakeOptionsFlags:=[ccloNoLinkerOpts];
2584 FUsageOptions:=TPkgAdditionalCompilerOptions.Create(Self);
2585 FUsageOptions.ParsedOpts.OnLocalSubstitute:=@SubstitutePkgMacros;
2586 FDefineTemplates:=TLazPackageDefineTemplates.Create(Self);
2587 fPublishOptions:=TPublishPackageOptions.Create(Self);
2588 FProvides:=TStringList.Create;
2589 Clear;
2590 FUsageOptions.ParsedOpts.InvalidateParseOnChange:=true;
2591 end;
2592
2593 destructor TLazPackage.Destroy;
2594 begin
2595 Include(FFlags,lpfDestroying);
2596 Clear;
2597 FreeAndNil(FOptionsBackup);
2598 FreeAndNil(fPublishOptions);
2599 FreeAndNil(FProvides);
2600 FreeAndNil(FDefineTemplates);
2601 FreeAndNil(FRemovedFiles);
2602 FreeAndNil(FFiles);
2603 FreeAndNil(FComponents);
2604 FreeAndNil(FLazCompilerOptions);
2605 FreeAndNil(FIDEOptions);
2606 FreeAndNil(FUsageOptions);
2607 FreeAndNil(FMacros);
2608 FreeAndNil(FSourceDirectories);
2609 inherited Destroy;
2610 end;
2611
2612 procedure TLazPackage.BackupOptions;
2613 begin
2614 if FOptionsBackup=nil then
2615 FOptionsBackup:=TLazPackage.Create;
2616 FOptionsBackup.AssignOptions(Self);
2617 FOptionsBackup.FFlags:=FOptionsBackup.FFlags-[lpfModified]+[lpfModified]*FFlags;
2618 FOptionsBackup.CompilerOptions.Modified:=CompilerOptions.Modified;
2619 end;
2620
2621 procedure TLazPackage.RestoreOptions;
2622 begin
2623 if FOptionsBackup=nil then exit;
2624 AssignOptions(FOptionsBackup);
2625 FFlags:=FFlags-[lpfModified]+[lpfModified]*FOptionsBackup.FFlags;
2626 CompilerOptions.Modified:=FOptionsBackup.CompilerOptions.Modified;
2627 end;
2628
2629 procedure TLazPackage.BeginUpdate;
2630 begin
2631 inc(FUpdateLock);
2632 FDefineTemplates.BeginUpdate;
2633 FSourceDirectories.BeginUpdate;
2634 end;
2635
2636 procedure TLazPackage.EndUpdate;
2637 begin
2638 if FUpdateLock=0 then RaiseGDBException('TLazPackage.EndUpdate');
2639 dec(FUpdateLock);
2640 FDefineTemplates.EndUpdate;
2641 FSourceDirectories.EndUpdate;
2642 end;
2643
2644 procedure TLazPackage.Clear;
2645 var
2646 i: Integer;
2647 begin
2648 // break used-by dependencies
2649 while FFirstUsedByDependency<>nil do
2650 FFirstUsedByDependency.RequiredPackage:=nil;
2651 // break and free removed dependencies
2652 while FFirstRemovedDependency<>nil do
2653 DeleteRemovedDependency(FFirstRemovedDependency);
2654 // break and free required dependencies
2655 while FFirstRequiredDependency<>nil do
2656 DeleteRequiredDependency(FFirstRequiredDependency);
2657 if not (lpfDestroying in FFlags) then begin
2658 FAddToProjectUsesSection:=false;
2659 FAuthor:='';
2660 FAutoInstall:=pitNope;
2661 FComponents.Clear;
2662 CompilerOptions.Clear;
2663 FDescription:='';
2664 FDirectory:='';
2665 FDirectoryExpandedChangeStamp:=CTInvalidChangeStamp;
2666 FEnableI18N:=false;
2667 FEnableI18NForLFM:=false;
2668 FPOOutputDirectory:='';
2669 FHasDirectory:=false;
2670 FHasStaticDirectory:=false;
2671 FVersion.Clear;
2672 FFilename:='';
2673 FIconFile:='';
2674 FInstalled:=pitNope;
2675 Name:='';
2676 FPackageType:=lptRunAndDesignTime;
2677 FRegistered:=false;
2678 FFPDocPaths:='';
2679 FFPDocPackageName:='';
2680 ClearCustomOptions;
2681 end;
2682 for i:=FComponents.Count-1 downto 0 do Components[i].Free;
2683 for i:=FRemovedFiles.Count-1 downto 0 do RemovedFiles[i].Free;
2684 FRemovedFiles.Clear;
2685 for i:=FFiles.Count-1 downto 0 do Files[i].Free;
2686 FFiles.Clear;
2687 FUsageOptions.Clear;
2688 fPublishOptions.Clear;
2689 FProvides.Clear;
2690 UpdateSourceDirectories;
2691 // set some nice start values
2692 if not (lpfDestroying in FFlags) then begin
2693 FFlags:=[lpfAutoIncrementVersionOnBuild];
2694 FAutoUpdate:=pupAsNeeded;
2695 FLazCompilerOptions.UnitOutputDirectory:=
2696 'lib'+PathDelim+'$(TargetCPU)-$(TargetOS)'+PathDelim;
2697 FUsageOptions.UnitPath:='$(PkgOutDir)';
2698 end else begin
2699 FFlags:=[lpfDestroying];
2700 end;
2701 FStorePathDelim:=pdsNone;
2702 end;
2703
2704 //function DbgS(PkgFileType: TPkgFileType): string;
2705 //begin
2706 // WriteStr(Result, PkgFileType);
2707 //end;
2708
2709 procedure TLazPackage.UpdateSourceDirectories;
2710 var
2711 Cnt: Integer;
2712 i: Integer;
2713 PkgFile: TPkgFile;
2714 begin
2715 Cnt:=FFiles.Count;
2716 for i:=0 to Cnt-1 do begin
2717 PkgFile:=Files[i];
2718 PkgFile.FSourceDirectoryReferenced:=false;
2719 end;
2720 fSourceDirectories.Clear;
2721 for i:=0 to Cnt-1 do begin
2722 PkgFile:=Files[i];
2723 PkgFile.AutoReferenceSourceDir:=true;
2724 PkgFile.UpdateSourceDirectoryReference;
2725 //debugln('TLazPackage.UpdateSourceDirectories A ',PkgFile.Filename,' ',
2726 // ' ',DbgS(PkgFile.FileType),' ',PkgFile.Removed,
2727 // ' HasPkg=',dbgs(PkgFile.LazPackage=Self),
2728 // ' Need=',PkgFile.FSourceDirNeedReference,
2729 // ' Is=',PkgFile.FSourceDirectoryReferenced);
2730 end;
2731 //debugln('TLazPackage.UpdateSourceDirectories B ',IDAsString,' ',FFiles.Count,' "',fSourceDirectories.CreateSearchPathFromAllFiles,'"');
2732 end;
2733
2734 procedure TLazPackage.VersionChanged(Sender: TObject);
2735 begin
2736 inherited VersionChanged(Sender);
2737 FDefineTemplates.IDChanged;
2738 Modified:=true;
2739 end;
2740
2741 procedure TLazPackage.SourceDirectoriesChanged(Sender: TObject);
2742 begin
2743 FDefineTemplates.SourceDirectoriesChanged;
2744 end;
2745
GetDirectorynull2746 function TLazPackage.GetDirectory: string;
2747 begin
2748 Result:=FDirectory;
2749 end;
2750
2751 procedure TLazPackage.LockModified;
2752 begin
2753 inc(FModifiedLock);
2754 end;
2755
2756 procedure TLazPackage.UnlockModified;
2757 begin
2758 if FModifiedLock<=0 then
2759 RaiseGDBException('TLazPackage.UnlockModified');
2760 dec(FModifiedLock);
2761 end;
2762
ReadOnlynull2763 function TLazPackage.ReadOnly: boolean;
2764 begin
2765 Result:=UserReadOnly or FileReadOnly;
2766 end;
2767
2768 procedure TLazPackage.LoadFromXMLConfig(XMLConfig: TXMLConfig;
2769 const Path: string);
2770 var
2771 FileVersion: integer;
2772 OldFilename: String;
2773 PathDelimChanged: boolean;
2774 Config: TXMLOptionsStorage;
2775
2776 procedure LoadFiles(const ThePath: string; List: TFPList);
2777 var
2778 i: Integer;
2779 NewCount: Integer;
2780 PkgFile: TPkgFile;
2781 begin
2782 NewCount:=XMLConfig.GetValue(ThePath+'Count',0);
2783 for i:=0 to NewCount-1 do begin
2784 PkgFile:=TPkgFile.Create(Self);
2785 PkgFile.LoadFromXMLConfig(XMLConfig,ThePath+'Item'+IntToStr(i+1)+'/',
2786 FileVersion,PathDelimChanged);
2787 if PkgFile.MakeSense then
2788 List.Add(PkgFile)
2789 else
2790 PkgFile.Free;
2791 end;
2792 end;
2793
2794 procedure LoadFlags(const ThePath: string);
2795 begin
2796 if XMLConfig.GetValue(ThePath+'AutoIncrementVersionOnBuild/Value',true) then
2797 Include(FFlags,lpfAutoIncrementVersionOnBuild)
2798 else
2799 Exclude(FFlags,lpfAutoIncrementVersionOnBuild);
2800 end;
2801
2802 begin
2803 Flags:=Flags+[lpfLoading];
2804 FileVersion:=XMLConfig.GetValue(Path+'Version',0);
2805 OldFilename:=Filename;
2806 BeginUpdate;
2807 Clear;
2808 Filename:=OldFilename;
2809 LockModified;
2810 StorePathDelim:=CheckPathDelim(XMLConfig.GetValue(Path+'PathDelim/Value','/'),PathDelimChanged);
2811 Name:=XMLConfig.GetValue(Path+'Name/Value','');
2812 FPackageType:=LazPackageTypeIdentToType(XMLConfig.GetValue(Path+'Type/Value',
2813 LazPackageTypeIdents[lptRunTime]));
2814 FAddToProjectUsesSection:=XMLConfig.GetValue(Path+'AddToProjectUsesSection/Value',
2815 FileVersion<4); // since version 4 the default is false
2816 FAuthor:=XMLConfig.GetValue(Path+'Author/Value','');
2817 FAutoUpdate:=NameToAutoUpdatePolicy(
2818 XMLConfig.GetValue(Path+'AutoUpdate/Value',''));
2819 if FileVersion<2 then
2820 CompilerOptions.LoadFromXMLConfig(XMLConfig,'CompilerOptions/')
2821 else
2822 CompilerOptions.LoadFromXMLConfig(XMLConfig,Path+'CompilerOptions/');
2823 FDescription:=XMLConfig.GetValue(Path+'Description/Value','');
2824 FLicense:=XMLConfig.GetValue(Path+'License/Value','');
2825 PkgVersionLoadFromXMLConfig(FVersion,XMLConfig,Path+'Version/',FileVersion);
2826 FIconFile:=SwitchPathDelims(XMLConfig.GetValue(Path+'IconFile/Value',''),
2827 PathDelimChanged);
2828 OutputStateFile:=SwitchPathDelims(
2829 XMLConfig.GetValue(Path+'OutputStateFile/Value',''),
2830 PathDelimChanged);
2831 FFPDocPaths:=SwitchPathDelims(XMLConfig.GetValue(Path+'LazDoc/Paths',''),
2832 PathDelimChanged);
2833 FFPDocPackageName:=XMLConfig.GetValue(Path+'LazDoc/PackageName','');
2834 // i18n
2835 if FileVersion<3 then begin
2836 FPOOutputDirectory := SwitchPathDelims(
2837 xmlconfig.GetValue(Path+'RST/OutDir', ''),PathDelimChanged);
2838 EnableI18N := FPOOutputDirectory <> '';
2839 end else begin
2840 EnableI18N := xmlconfig.GetValue(Path+'i18n/EnableI18N/Value', False);
2841 FPOOutputDirectory := SwitchPathDelims(
2842 xmlconfig.GetValue(Path+'i18n/OutDir/Value', ''),PathDelimChanged);
2843 end;
2844 EnableI18NForLFM:=xmlconfig.GetValue(Path+'i18n/EnableI18NForLFM/Value', false);
2845
2846 LoadFiles(Path+'Files/',FFiles);
2847 UpdateSourceDirectories;
2848 LoadFlags(Path);
2849 LoadPkgDependencyList(XMLConfig,Path+'RequiredPkgs/',
2850 FFirstRequiredDependency,pdlRequires,Self,false,false);
2851 FUsageOptions.LoadFromXMLConfig(XMLConfig,Path+'UsageOptions/',
2852 PathDelimChanged);
2853 fPublishOptions.LoadFromXMLConfig(XMLConfig,Path+'PublishOptions/',
2854 PathDelimChanged);
2855 LoadStringList(XMLConfig,FProvides,Path+'Provides/');
2856 Config:=TXMLOptionsStorage.Create(XMLConfig);
2857 try
2858 TConfigMemStorage(CustomOptions).LoadFromConfig(Config,Path+'CustomOptions/');
2859 finally
2860 Config.Free;
2861 end;
2862
2863 EndUpdate;
2864 Modified:=false;
2865 UnlockModified;
2866 Flags:=Flags-[lpfLoading];
2867 end;
2868
2869 procedure TLazPackage.SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
2870 var
2871 UsePathDelim: TPathDelimSwitch;
2872 Config: TXMLOptionsStorage;
2873
2874 function f(const AFilename: string): string;
2875 begin
2876 Result:=SwitchPathDelims(AFilename,UsePathDelim);
2877 end;
2878
2879 procedure SaveFiles(const ThePath: string; List: TFPList);
2880 var
2881 i: Integer;
2882 PkgFile: TPkgFile;
2883 begin
2884 XMLConfig.SetDeleteValue(ThePath+'Count',List.Count,0);
2885 for i:=0 to List.Count-1 do begin
2886 PkgFile:=TPkgFile(List[i]);
2887 PkgFile.SaveToXMLConfig(XMLConfig,ThePath+'Item'+IntToStr(i+1)+'/',UsePathDelim);
2888 end;
2889 end;
2890
2891 procedure SaveFlags(const ThePath: string);
2892 begin
2893 XMLConfig.SetDeleteValue(ThePath+'AutoIncrementVersionOnBuild/Value',
2894 AutoIncrementVersionOnBuild,true);
2895 end;
2896
2897 begin
2898 UsePathDelim:=StorePathDelim;
2899 XMLConfig.SetValue(Path+'Version',LazPkgXMLFileVersion);
2900 XMLConfig.SetDeleteValue(Path+'PathDelim/Value',PathDelimSwitchToDelim[UsePathDelim],'/');
2901 XMLConfig.SetDeleteValue(Path+'Name/Value',Name,'');
2902 XMLConfig.SetDeleteValue(Path+'Type/Value',LazPackageTypeIdents[FPackageType],
2903 LazPackageTypeIdents[lptRunTime]);
2904 XMLConfig.SetDeleteValue(Path+'AddToProjectUsesSection/Value',
2905 FAddToProjectUsesSection,false);
2906 XMLConfig.SetDeleteValue(Path+'Author/Value',FAuthor,'');
2907 XMLConfig.SetDeleteValue(Path+'AutoUpdate/Value',AutoUpdateNames[FAutoUpdate],
2908 AutoUpdateNames[pupAsNeeded]);
2909 CompilerOptions.SaveToXMLConfig(XMLConfig,Path+'CompilerOptions/');
2910 XMLConfig.SetDeleteValue(Path+'Description/Value',FDescription,'');
2911 XMLConfig.SetDeleteValue(Path+'License/Value',FLicense,'');
2912 PkgVersionSaveToXMLConfig(FVersion,XMLConfig,Path+'Version/');
2913 SaveFiles(Path+'Files/',FFiles);
2914 SaveFlags(Path);
2915 XMLConfig.SetDeleteValue(Path+'IconFile/Value',f(FIconFile),'');
2916 XMLConfig.SetDeleteValue(Path+'OutputStateFile/Value',f(OutputStateFile),'');
2917 XMLConfig.SetDeleteValue(Path+'LazDoc/Paths',f(FFPDocPaths),'');
2918 XMLConfig.SetDeleteValue(Path+'LazDoc/PackageName',FFPDocPackageName,'');
2919
2920 XMLConfig.SetDeleteValue(Path+'i18n/EnableI18N/Value', EnableI18N, false);
2921 XMLConfig.SetDeleteValue(Path+'i18n/OutDir/Value',f(FPOOutputDirectory), '');
2922 XMLConfig.SetDeleteValue(Path+'i18n/EnableI18NForLFM/Value', EnableI18NForLFM, false);
2923
2924 SavePkgDependencyList(XMLConfig,Path+'RequiredPkgs/',
2925 FFirstRequiredDependency,pdlRequires,UsePathDelim);
2926 FUsageOptions.SaveToXMLConfig(XMLConfig,Path+'UsageOptions/',UsePathDelim);
2927 fPublishOptions.SaveToXMLConfig(XMLConfig,Path+'PublishOptions/',UsePathDelim);
2928 SaveStringList(XMLConfig,FProvides,Path+'Provides/');
2929 Config:=TXMLOptionsStorage.Create(XMLConfig);
2930 try
2931 TConfigMemStorage(CustomOptions).SaveToConfig(Config,Path+'CustomOptions/');
2932 finally
2933 Config.Free;
2934 end;
2935 Modified:=false;
2936 end;
2937
2938 procedure TLazPackage.SaveToString(out s: string);
2939 var
2940 XMLConfig: TXMLConfig;
2941 ms: TMemoryStream;
2942 begin
2943 s:='';
2944 XMLConfig:=TXMLConfig.Create(nil);
2945 ms:=TMemoryStream.Create;
2946 try
2947 XMLConfig.Clear;
2948 SaveToXMLConfig(XMLConfig,'Package/');
2949 XMLConfig.WriteToStream(ms);
2950 ms.Position:=0;
2951 SetLength(s,ms.Size);
2952 if s<>'' then
2953 ms.Read(s[1],length(s));
2954 finally
2955 XMLConfig.Free;
2956 ms.Free;
2957 end;
2958 end;
2959
IsVirtualnull2960 function TLazPackage.IsVirtual: boolean;
2961 begin
2962 Result:=not FilenameIsAbsolute(Filename);
2963 end;
2964
HasDirectorynull2965 function TLazPackage.HasDirectory: boolean;
2966 begin
2967 Result:=FHasDirectory;
2968 end;
2969
HasStaticDirectorynull2970 function TLazPackage.HasStaticDirectory: boolean;
2971 begin
2972 Result:=FHasStaticDirectory;
2973 end;
2974
GetFullFilenamenull2975 function TLazPackage.GetFullFilename(ResolveMacros: boolean): string;
2976 begin
2977 Result:=FFilename;
2978 if ResolveMacros then
2979 GlobalMacroList.SubstituteStr(Result);
2980 end;
2981
2982 procedure TLazPackage.CheckInnerDependencies;
2983 begin
2984 // ToDo: make some checks like deactivating double requirements
2985 end;
2986
IsMakingSensenull2987 function TLazPackage.IsMakingSense: boolean;
2988 begin
2989 Result:=IsValidPkgName(Name);
2990 end;
2991
2992 procedure TLazPackage.ShortenFilename(var ExpandedFilename: string; UseUp: boolean);
2993 var
2994 PkgDir: String;
2995 CurPath: String;
2996 begin
2997 if (not HasDirectory) then exit;
2998 PkgDir:=DirectoryExpanded;
2999 if HasStaticDirectory and UseUp then
3000 ExpandedFilename:=CreateRelativePath(ExpandedFilename,PkgDir)
3001 else begin
3002 CurPath:=copy(ExtractFilePath(ExpandedFilename),1,length(PkgDir));
3003 if CompareFilenames(PkgDir,CurPath)=0 then begin
3004 ExpandedFilename:=copy(ExpandedFilename,length(CurPath)+1,
3005 length(ExpandedFilename)-length(CurPath));
3006 end;
3007 end;
3008 end;
3009
3010 procedure TLazPackage.LongenFilename(var AFilename: string);
3011 begin
3012 if not HasDirectory then exit;
3013 if not FilenameIsAbsolute(AFilename) then
3014 AFilename:=TrimFilename(DirectoryExpanded+AFilename);
3015 end;
3016
GetResolvedFilenamenull3017 function TLazPackage.GetResolvedFilename(ResolveMacros: boolean): string;
3018 begin
3019 Result:=GetPhysicalFilenameCached(GetFullFilename(ResolveMacros),false);
3020 end;
3021
GetSourceDirsnull3022 function TLazPackage.GetSourceDirs(WithPkgDir, WithoutOutputDir: boolean): string;
3023 begin
3024 Result:=SourceDirectories.CreateSearchPathFromAllFiles;
3025 if WithPkgDir then
3026 Result:=MergeSearchPaths(Result,Directory);
3027 if WithoutOutputDir then
3028 Result:=RemoveSearchPaths(Result,GetOutputDirectory);
3029 end;
3030
3031 procedure TLazPackage.IterateComponentClasses(Event: TIterateComponentClassesEvent;
3032 WithUsedPackages: boolean);
3033 var
3034 Cnt: Integer;
3035 i: Integer;
3036 Dependency: TPkgDependency;
3037 begin
3038 // iterate through components in this package
3039 Cnt:=ComponentCount;
3040 for i:=0 to Cnt-1 do Event(Components[i]);
3041 // iterate through all used/required packages
3042 if WithUsedPackages then begin
3043 Dependency:=FirstRequiredDependency;
3044 while Dependency<>nil do begin
3045 if Dependency.RequiredPackage<>nil then
3046 Dependency.RequiredPackage.IterateComponentClasses(Event,false);
3047 Dependency:=Dependency.NextRequiresDependency;
3048 end;
3049 end;
3050 end;
3051
3052 procedure TLazPackage.SetAllComponentPriorities(const p: TComponentPriority);
3053 var
3054 i: Integer;
3055 begin
3056 //debugln(['TLazPackage.SetAllComponentPriorities ',Name,' ',dbgs(p), ' FileCount=',FileCount]);
3057 for i:=0 to FileCount-1 do
3058 Files[i].ComponentPriority:=p;
3059 end;
3060
3061 procedure TLazPackage.ConsistencyCheck;
3062 begin
3063 CheckList(FRemovedFiles,true,true,true);
3064 CheckList(FFiles,true,true,true);
3065 CheckList(FComponents,true,true,true);
3066 end;
3067
ExtendUnitSearchPathnull3068 function TLazPackage.ExtendUnitSearchPath(NewUnitPaths: string): boolean;
3069 var
3070 CurUnitPaths: String;
3071 r: TModalResult;
3072 begin
3073 Result:=True;
3074 CurUnitPaths:=CompilerOptions.ParsedOpts.GetParsedValue(pcosUnitPath);
3075 NewUnitPaths:=RemoveSearchPaths(NewUnitPaths,CurUnitPaths);
3076 if NewUnitPaths='' then Exit;
3077 NewUnitPaths:=CreateRelativeSearchPath(NewUnitPaths,Directory);
3078 if NewUnitPaths='.' then Exit;
3079 r:=IDEMessageDialog(lisExtendUnitPath,
3080 Format(lisExtendUnitSearchPathOfPackageWith, [Name, #13, NewUnitPaths]),
3081 mtConfirmation, [mbYes, mbNo, mbCancel]);
3082 case r of
3083 mrYes: CompilerOptions.MergeToUnitPaths(NewUnitPaths);
3084 mrNo: ;
3085 else exit(false);
3086 end;
3087 end;
3088
ExtendIncSearchPathnull3089 function TLazPackage.ExtendIncSearchPath(NewIncPaths: string): boolean;
3090 var
3091 CurIncPaths: String;
3092 r: TModalResult;
3093 begin
3094 Result:=True;
3095 CurIncPaths:=CompilerOptions.ParsedOpts.GetParsedValue(pcosIncludePath);
3096 NewIncPaths:=RemoveSearchPaths(NewIncPaths,CurIncPaths);
3097 if NewIncPaths='' then Exit;
3098 NewIncPaths:=CreateRelativeSearchPath(NewIncPaths,Directory);
3099 if NewIncPaths='.' then Exit;
3100 r:=IDEMessageDialog(lisExtendIncludePath,
3101 Format(lisExtendIncludeFileSearchPathOfPackageWith, [Name, #13, NewIncPaths]),
3102 mtConfirmation, [mbYes, mbNo, mbCancel]);
3103 case r of
3104 mrYes: CompilerOptions.MergeToIncludePaths(NewIncPaths);
3105 mrNo: ;
3106 else exit(false);
3107 end;
3108 end;
3109
IndexOfPkgComponentnull3110 function TLazPackage.IndexOfPkgComponent(PkgComponent: TPkgComponent): integer;
3111 begin
3112 Result:=FComponents.IndexOf(PkgComponent);
3113 end;
3114
FindPkgFilenull3115 function TLazPackage.FindPkgFile(const AFilename: string; IgnoreRemoved,
3116 FindVirtualFile: boolean): TPkgFile;
3117 var
3118 TheFilename: String;
3119 Cnt: Integer;
3120 i: Integer;
3121 begin
3122 Result:=nil;
3123
3124 TheFilename:=AFilename;
3125
3126 Cnt:=FileCount;
3127 for i:=0 to Cnt-1 do begin
3128 Result:=Files[i];
3129 if (not FindVirtualFile) and (not FilenameIsAbsolute(Result.Filename)) then
3130 continue;
3131 if (CompareFilenames(Result.Filename,TheFilename)=0)
3132 or (CompareFilenames(Result.GetFullFilename,TheFilename)=0) then
3133 exit;
3134 end;
3135 if not IgnoreRemoved then begin
3136 Cnt:=RemovedFilesCount;
3137 for i:=0 to Cnt-1 do begin
3138 Result:=RemovedFiles[i];
3139 if (not FindVirtualFile) and (not FilenameIsAbsolute(Result.Filename)) then
3140 continue;
3141 if (CompareFilenames(Result.Filename,TheFilename)=0)
3142 or (CompareFilenames(Result.GetFullFilename,TheFilename)=0) then
3143 exit;
3144 end;
3145 end;
3146 Result:=nil;
3147 end;
3148
FindUnitWithRegisternull3149 function TLazPackage.FindUnitWithRegister(IgnorePkgFile: TPkgFile): TPkgFile;
3150 var
3151 Cnt: LongInt;
3152 i: Integer;
3153 begin
3154 Cnt:=FileCount;
3155 for i:=0 to Cnt-1 do begin
3156 Result:=Files[i];
3157 if IgnorePkgFile=Result then continue;
3158 if not (Result.FileType in PkgFileRealUnitTypes) then continue;
3159 if Result.HasRegisterProc then exit;
3160 end;
3161 Result:=nil;
3162 end;
3163
FindUnitnull3164 function TLazPackage.FindUnit(const TheUnitName: string): TPkgFile;
3165 begin
3166 Result:=FindUnit(TheUnitName,true);
3167 end;
3168
FindUnitnull3169 function TLazPackage.FindUnit(const TheUnitName: string;
3170 IgnoreRemoved: boolean): TPkgFile;
3171 begin
3172 Result:=FindUnit(TheUnitName,IgnoreRemoved,nil);
3173 end;
3174
FindUnitnull3175 function TLazPackage.FindUnit(const TheUnitName: string;
3176 IgnoreRemoved: boolean; IgnorePkgFile: TPkgFile): TPkgFile;
3177 var
3178 Cnt: Integer;
3179 i: Integer;
3180 begin
3181 if TheUnitName='' then exit(nil);
3182 Cnt:=FileCount;
3183 for i:=0 to Cnt-1 do begin
3184 Result:=Files[i];
3185 if IgnorePkgFile=Result then continue;
3186 if SysUtils.CompareText(Result.Unit_Name,TheUnitName)=0 then exit;
3187 end;
3188 if not IgnoreRemoved then begin
3189 Cnt:=RemovedFilesCount;
3190 for i:=0 to Cnt-1 do begin
3191 Result:=RemovedFiles[i];
3192 if IgnorePkgFile=Result then continue;
3193 if SysUtils.CompareText(Result.Unit_Name,TheUnitName)=0 then exit;
3194 end;
3195 end;
3196 Result:=nil;
3197 end;
3198
FindUsedUnitnull3199 function TLazPackage.FindUsedUnit(TheUnitName: string; IgnorePkgFile: TPkgFile
3200 ): TPkgFile;
3201 var
3202 i: Integer;
3203 begin
3204 for i:=0 to FileCount-1 do begin
3205 Result:=Files[i];
3206 if IgnorePkgFile=Result then continue;
3207 if not Result.AddToUsesPkgSection then continue;
3208 if not (Result.FileType in PkgFileRealUnitTypes) then continue;
3209 if SysUtils.CompareText(Result.Unit_Name,TheUnitName)=0 then exit;
3210 end;
3211 Result:=nil;
3212 end;
3213
FindRemovedPkgFilenull3214 function TLazPackage.FindRemovedPkgFile(const AFilename: string): TPkgFile;
3215 var
3216 Cnt: Integer;
3217 i: Integer;
3218 begin
3219 Cnt:=RemovedFilesCount;
3220 for i:=0 to Cnt-1 do begin
3221 Result:=RemovedFiles[i];
3222 if CompareFilenames(Result.Filename,AFilename)=0 then exit;
3223 end;
3224 Result:=nil;
3225 end;
3226
FindDependencyByNamenull3227 function TLazPackage.FindDependencyByName(const PackageName: string): TPkgDependency;
3228 begin
3229 Result:=FindDependencyByNameInList(FFirstRequiredDependency,pdlRequires,PackageName);
3230 end;
3231
FindRemovedDependencyByNamenull3232 function TLazPackage.FindRemovedDependencyByName(const PkgName: string): TPkgDependency;
3233 begin
3234 Result:=FindDependencyByNameInList(FFirstRemovedDependency,pdlRequires,PkgName);
3235 end;
3236
RequiredDepByIndexnull3237 function TLazPackage.RequiredDepByIndex(Index: integer): TPkgDependency;
3238 begin
3239 Result:=GetDependencyWithIndex(FFirstRequiredDependency,pdlRequires,Index);
3240 end;
3241
RemovedDepByIndexnull3242 function TLazPackage.RemovedDepByIndex(Index: integer): TPkgDependency;
3243 begin
3244 Result:=GetDependencyWithIndex(FFirstRemovedDependency,pdlRequires,Index);
3245 end;
3246
UsedByDepByIndexnull3247 function TLazPackage.UsedByDepByIndex(Index: integer): TPkgDependency;
3248 begin
3249 Result:=GetDependencyWithIndex(FFirstUsedByDependency,pdlUsedBy,Index);
3250 end;
3251
FindUsedByDepPrefernull3252 function TLazPackage.FindUsedByDepPrefer(Ignore: TPkgDependency): TPkgDependency;
3253 begin
3254 Result:=FFirstUsedByDependency;
3255 while (Result<>nil) do begin
3256 if Result.PreferDefaultFilename
3257 and (Result<>Ignore) then
3258 exit;
3259 Result:=Result.NextUsedByDependency;
3260 end;
3261 end;
3262
ProvidesPackagenull3263 function TLazPackage.ProvidesPackage(const AName: string): boolean;
3264 var
3265 i: Integer;
3266 begin
3267 if AName='' then exit(false);
3268 for i:=0 to Provides.Count-1 do
3269 if SysUtils.CompareText(Provides[i],AName)=0 then begin
3270 //DebugLn(['TLazPackage.ProvidesPackage AName=',AName,' Provides[i]="',Provides[i],'"']);
3271 exit(true);
3272 end;
3273 Result:=false;
3274 end;
3275
AddFilenull3276 function TLazPackage.AddFile(const NewFilename, NewUnitName: string;
3277 NewFileType: TPkgFileType; NewFlags: TPkgFileFlags;
3278 CompPriorityCat: TComponentPriorityCategory): TPkgFile;
3279 var
3280 NewComponentPriority: TComponentPriority;
3281 begin
3282 Result:=FindRemovedPkgFile(NewFilename);
3283 if Result=nil then begin
3284 Result:=TPkgFile.Create(Self);
3285 end else begin
3286 Result.AutoReferenceSourceDir:=false;
3287 FRemovedFiles.Remove(Result);
3288 Result.Removed:=false;
3289 end;
3290 with Result do begin
3291 Filename:=NewFilename;
3292 //debugln(['TLazPackage.AddFile Is=',Filename,' Should=',NewFilename]);
3293 Unit_Name:=NewUnitName;
3294 FileType:=NewFileType;
3295 Flags:=NewFlags;
3296 NewComponentPriority:=ComponentPriorityNormal;
3297 NewComponentPriority.Category:=CompPriorityCat;
3298 ComponentPriority:=NewComponentPriority;
3299 Removed:=false;
3300 AutoReferenceSourceDir:=true;
3301 end;
3302 FFiles.Add(Result);
3303 //debugln(['TLazPackage.AddFile Is=',Result.Filename,' Should=',NewFilename]);
3304 Modified:=true;
3305 end;
3306
AddFileByNamenull3307 function TLazPackage.AddFileByName(aFilename: string;
3308 var NewUnitPaths, NewIncPaths: String): Boolean;
3309 var
3310 NewFileType: TPkgFileType;
3311 NewUnitName: String;
3312 HasRegister: Boolean;
3313 NewFlags: TPkgFileFlags;
3314 Code: TCodeBuffer;
3315 CurDir: String;
3316 begin
3317 Result := True;
3318 aFilename:=CleanAndExpandFilename(aFileName);
3319 if not FileExistsUTF8(aFilename) then Exit(False);
3320 if DirPathExists(aFilename) then Exit(False);
3321 if FindPkgFile(aFilename,true,false)<>nil then Exit(False);
3322 NewFileType:=FileNameToPkgFileType(aFilename);
3323 NewFlags:=[];
3324 HasRegister:=false;
3325 NewUnitName:='';
3326 if (NewFileType=pftUnit) then begin
3327 Code:=CodeToolBoss.LoadFile(aFilename,true,false);
3328 NewUnitName:=CodeToolBoss.GetSourceName(Code,false);
3329 if NewUnitName='' then
3330 NewUnitName:=ExtractFileNameOnly(aFilename);
3331 if FindUsedUnit(NewUnitName)=nil then
3332 Include(NewFlags,pffAddToPkgUsesSection);
3333 CodeToolBoss.HasInterfaceRegisterProc(Code,HasRegister);
3334 if HasRegister then
3335 Include(NewFlags,pffHasRegisterProc);
3336 end;
3337 AddFile(aFilename,NewUnitName,NewFileType,NewFlags,cpNormal);
3338 CurDir:=ChompPathDelim(ExtractFilePath(aFilename));
3339 if NewFileType=pftUnit then
3340 NewUnitPaths:=MergeSearchPaths(NewUnitPaths,CurDir)
3341 else
3342 NewIncPaths:=MergeSearchPaths(NewIncPaths,CurDir);
3343 end;
3344
AddRemovedFilenull3345 function TLazPackage.AddRemovedFile(const NewFilename, NewUnitName: string;
3346 NewFileType: TPkgFileType; NewFlags: TPkgFileFlags;
3347 CompPriorityCat: TComponentPriorityCategory): TPkgFile;
3348 var
3349 NewComponentPriority: TComponentPriority;
3350 begin
3351 Result:=FindRemovedPkgFile(NewFilename);
3352 if Result=nil then begin
3353 Result:=TPkgFile.Create(Self);
3354 end;
3355 with Result do begin
3356 AutoReferenceSourceDir:=false;
3357 Filename:=NewFilename;
3358 Unit_Name:=NewUnitName;
3359 FileType:=NewFileType;
3360 Flags:=NewFlags;
3361 NewComponentPriority:=ComponentPriorityNormal;
3362 NewComponentPriority.Category:=CompPriorityCat;
3363 ComponentPriority:=NewComponentPriority;
3364 Removed:=false;
3365 AutoReferenceSourceDir:=true;
3366 end;
3367 FRemovedFiles.Add(Result);
3368 end;
3369
3370 procedure TLazPackage.DeleteFile(PkgFile: TPkgFile);
3371 begin
3372 PkgFile.Free;
3373 Modified:=true
3374 end;
3375
3376 procedure TLazPackage.RemoveFileSilently(PkgFile: TPkgFile);
3377 // Remove a file without setting the Modified flag. Caller must take care of it.
3378 begin
3379 FFiles.Remove(PkgFile);
3380 FRemovedFiles.Add(PkgFile);
3381 PkgFile.Removed:=true;
3382 end;
3383
3384 procedure TLazPackage.RemoveFile(PkgFile: TPkgFile);
3385 begin
3386 RemoveFileSilently(PkgFile);
3387 Modified:=true;
3388 end;
3389
3390 procedure TLazPackage.UnremovePkgFile(PkgFile: TPkgFile);
3391 begin
3392 FFiles.Add(PkgFile);
3393 FRemovedFiles.Remove(PkgFile);
3394 PkgFile.Removed:=false;
3395 end;
3396
RemoveNonExistingFilesnull3397 function TLazPackage.RemoveNonExistingFiles(RemoveFromUsesSection: boolean): boolean;
3398 // Param is ignored here, it is just to match with interface.
3399 var
3400 i: Integer;
3401 AFilename: String;
3402 begin
3403 Result:=false;
3404 i:=FileCount-1;
3405 while i>=0 do begin
3406 if i>=FileCount then continue;
3407 AFilename:=Files[i].GetResolvedFilename;
3408 if (AFilename='') or (not FileExistsCached(AFilename)) then
3409 begin
3410 RemoveFile(Files[i]);
3411 Result:=true;
3412 end;
3413 dec(i);
3414 end;
3415 end;
3416
GetFileDialogInitialDirnull3417 function TLazPackage.GetFileDialogInitialDir(const DefaultDirectory: string): string;
3418 begin
3419 Result:=AppendPathDelim(TrimFilename(DefaultDirectory));
3420 if (SourceDirectories.GetFileReference(Result)=nil)
3421 and DirPathExists(Directory) then
3422 Result:=Directory;
3423 end;
3424
3425 procedure TLazPackage.MoveFile(CurIndex, NewIndex: integer);
3426 begin
3427 if CurIndex=NewIndex then exit;
3428 FFiles.Move(CurIndex,NewIndex);
3429 Include(FFlags,lpfModified);
3430 if FChangeStamp<High(FChangeStamp) then
3431 inc(FChangeStamp)
3432 else
3433 FChangeStamp:=low(FChangeStamp);
3434 end;
3435
3436 procedure TLazPackage.SortFiles;
3437 var
3438 NewList: TFPList;
3439 Cnt: Integer;
3440 i: Integer;
3441 begin
3442 if FileCount=0 then exit;
3443 NewList:=TFPList.Create;
3444 try
3445 Cnt:=FileCount;
3446 for i:=0 to Cnt-1 do NewList.Add(FFiles[i]);
3447 NewList.Sort(TListSortCompare(@ComparePkgFilesAlphabetically));
3448 i:=Cnt-1;
3449 while (i>=0) and (NewList[i]=FFiles[i]) do dec(i);
3450 if i<0 then exit;
3451 FFiles.Clear;
3452 for i:= 0 to Cnt-1 do FFiles.Add(NewList[i]);
3453 Modified:=true;
3454 finally
3455 NewList.Free;
3456 end;
3457 end;
3458
FixFilesCaseSensitivitynull3459 function TLazPackage.FixFilesCaseSensitivity: boolean;
3460 var
3461 SrcDirs: TStringList;
3462
3463 function IndexOfFileInStringList(List: TStringList;
3464 const Filename: string; OnlyExact: boolean): integer;
3465 begin
3466 // first search for exact match
3467 Result:=List.Count-1;
3468 while (Result>=0) do begin
3469 if (Filename=List[Result]) then exit;
3470 dec(Result);
3471 end;
3472 if OnlyExact then exit;
3473 // then search for case insensitive match
3474 Result:=List.Count-1;
3475 while (Result>=0) and (SysUtils.CompareText(Filename,List[Result])<>0) do
3476 dec(Result);
3477 end;
3478
3479 function AddDirectoryListing(const ADirectory: string): TStringList;
3480 var
3481 SrcDirID: Integer;
3482 FileInfo: TSearchRec;
3483 begin
3484 if SrcDirs=nil then
3485 SrcDirs:=TStringList.Create;
3486 // search directory listing
3487 SrcDirID:=IndexOfFileInStringList(SrcDirs,ADirectory,true);
3488 if SrcDirID>=0 then begin
3489 Result:=TStringList(SrcDirs.Objects[SrcDirID]);
3490 exit;
3491 end;
3492 // create new directory listing
3493 Result:=TStringList.Create;
3494 if FindFirstUTF8(AppendPathDelim(ADirectory)+GetAllFilesMask,
3495 faAnyFile,FileInfo)=0
3496 then begin
3497 repeat
3498 // check if special file
3499 if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='')
3500 then continue;
3501 Result.Add(FileInfo.Name);
3502 //debugln('AddDirectoryListing ',FileInfo.Name);
3503 until FindNextUTF8(FileInfo)<>0;
3504 end;
3505 FindCloseUTF8(FileInfo);
3506 SrcDirs.AddObject(ADirectory,Result);
3507 end;
3508
3509 var
3510 Cnt: Integer;
3511 i: Integer;
3512 CurFile: TPkgFile;
3513 CurShortFilename: String;
3514 DirListID: LongInt;
3515 DirListing: TStringList;
3516 NewShortFilename: string;
3517 NewFilename: String;
3518 CurDir: String;
3519 AFilename: String;
3520 begin
3521 Result:=false;
3522 Cnt:=FileCount;
3523 SrcDirs:=nil;
3524 try
3525 for i:=0 to Cnt-1 do begin
3526 CurFile:=Files[i];
3527 //debugln('TLazPackage.FixFilesCaseSensitivity A ',dbgs(i),' CurFile.Filename=',CurFile.Filename);
3528 AFilename:=CurFile.GetFullFilename;
3529 CurShortFilename:=ExtractFilename(AFilename);
3530 CurDir:=ExtractFilePath(AFilename);
3531 DirListing:=AddDirectoryListing(CurDir);
3532 DirListID:=IndexOfFileInStringList(DirListing,CurShortFilename,false);
3533 //debugln('TLazPackage.FixFilesCaseSensitivity B ',dbgs(i),' CurShortFilename=',CurShortFilename,' DirListID=',dbgs(DirListID));
3534 if DirListID<0 then continue;
3535 NewShortFilename:=DirListing[DirListID];
3536 //debugln('TLazPackage.FixFilesCaseSensitivity New ',dbgs(i),' NewShortFilename=',NewShortFilename);
3537 if CurShortFilename<>NewShortFilename then begin
3538 // case changes
3539 NewFilename:=AppendPathDelim(ExtractFilePath(CurFile.Filename))+NewShortFilename;
3540 //debugln('TLazPackage.FixFilesCaseSensitivity New ',dbgs(i),' NewFilename=',NewFilename);
3541 CurFile.Filename:=NewFilename;
3542 Result:=true;
3543 end;
3544 end;
3545 if Result then
3546 Modified:=true;
3547 finally
3548 if SrcDirs<>nil then begin
3549 for i:=0 to SrcDirs.Count-1 do
3550 SrcDirs.Objects[i].Free;
3551 SrcDirs.Free;
3552 end;
3553 end;
3554 end;
3555
MainUnitHasPkgNamenull3556 function TLazPackage.MainUnitHasPkgName: boolean;
3557 begin
3558 Result:=(MainUnit=nil) or (SysUtils.CompareText(MainUnit.Unit_Name,Name)=0);
3559 end;
3560
3561 procedure TLazPackage.RemoveRemovedDependency(Dependency: TPkgDependency);
3562 begin
3563 Dependency.RemoveFromList(FFirstRemovedDependency,pdlRequires);
3564 Dependency.Removed:=false;
3565 end;
3566
3567 procedure TLazPackage.AddRequiredDependency(Dependency: TPkgDependency);
3568 begin
3569 Dependency.AddToList(FFirstRequiredDependency,pdlRequires);
3570 Dependency.Owner:=Self;
3571 Modified:=true;
3572 end;
3573
3574 procedure TLazPackage.AddPackageDependency(const PackageName: string);
3575 var
3576 Dependency: TPkgDependency;
3577 begin
3578 if FindDependencyByName(PackageName)<>nil then exit;
3579 Dependency:=TPkgDependency.Create;
3580 Dependency.PackageName:=PackageName;
3581 AddRequiredDependency(Dependency);
3582 end;
3583
3584 procedure TLazPackage.RemoveRequiredDepSilently(Dependency: TPkgDependency);
3585 // Remove a dependency without setting the Modified flag. Caller must take care of it.
3586 begin
3587 Dependency.RemoveFromList(FFirstRequiredDependency,pdlRequires);
3588 Dependency.RequiredPackage:=nil;
3589 Dependency.AddToList(FFirstRemovedDependency,pdlRequires);
3590 Dependency.Removed:=true;
3591 end;
3592
3593 procedure TLazPackage.RemoveRequiredDependency(Dependency: TPkgDependency);
3594 begin
3595 RemoveRequiredDepSilently(Dependency);
3596 Modified:=true;
3597 end;
3598
3599 procedure TLazPackage.DeleteRequiredDependency(Dependency: TPkgDependency);
3600 begin
3601 Dependency.RequiredPackage:=nil;
3602 Dependency.RemoveFromList(FFirstRequiredDependency,pdlRequires);
3603 Dependency.Free;
3604 end;
3605
3606 procedure TLazPackage.DeleteRemovedDependency(Dependency: TPkgDependency);
3607 begin
3608 Dependency.RequiredPackage:=nil;
3609 Dependency.RemoveFromList(FFirstRemovedDependency,pdlRequires);
3610 Dependency.Free;
3611 end;
3612
MoveRequiredDependencyUpnull3613 function TLazPackage.MoveRequiredDependencyUp(Dependency: TPkgDependency): Boolean;
3614 begin
3615 Result := Dependency.MoveUpInList(FFirstRequiredDependency,pdlRequires);
3616 end;
3617
MoveRequiredDependencyDownnull3618 function TLazPackage.MoveRequiredDependencyDown(Dependency: TPkgDependency): Boolean;
3619 begin
3620 Result := Dependency.MoveDownInList(FFirstRequiredDependency,pdlRequires);
3621 end;
3622
CreateDependencyWithOwnernull3623 function TLazPackage.CreateDependencyWithOwner(NewOwner: TObject;
3624 WithMinVersion: boolean): TPkgDependency;
3625 begin
3626 Result:=TPkgDependency.Create;
3627 with Result do begin
3628 Owner:=NewOwner;
3629 PackageName:=Self.Name;
3630 if WithMinVersion then begin
3631 MinVersion.Assign(Version);
3632 Flags:=[pdfMinVersion];
3633 end;
3634 end;
3635 end;
3636
AddComponentnull3637 function TLazPackage.AddComponent(PkgFile: TPkgFile; const Page: string;
3638 TheComponentClass: TComponentClass): TPkgComponent;
3639 begin
3640 Result:=TPkgComponent.Create(PkgFile,TheComponentClass,Page);
3641 end;
3642
3643 procedure TLazPackage.AddPkgComponent(APkgComponent: TPkgComponent);
3644 begin
3645 FComponents.Add(APkgComponent);
3646 end;
3647
3648 procedure TLazPackage.RemovePkgComponent(APkgComponent: TPkgComponent);
3649 begin
3650 FComponents.Remove(APkgComponent);
3651 end;
3652
Requiresnull3653 function TLazPackage.Requires(APackage: TLazPackage): boolean;
3654 begin
3655 Result:=FindCompatibleDependencyInList(FFirstRequiredDependency,pdlRequires,
3656 APackage)<>nil;
3657 end;
3658
3659 procedure TLazPackage.AddUsedByDependency(Dependency: TPkgDependencyBase);
3660 begin
3661 Dependency.AddUsedByDep(TPkgDependencyBase(FFirstUsedByDependency));
3662 if TPkgDependency(Dependency).HoldPackage then
3663 inc(FHoldPackageCount);
3664 end;
3665
3666 procedure TLazPackage.RemoveUsedByDependency(Dependency: TPkgDependencyBase);
3667 begin
3668 Dependency.RemoveUsedByDep(TPkgDependencyBase(FFirstUsedByDependency));
3669 if TPkgDependency(Dependency).HoldPackage then
3670 dec(FHoldPackageCount);
3671 end;
3672
3673 procedure TLazPackage.ChangeID(const NewName: string; NewVersion: TPkgVersion);
3674 begin
3675 Version.Assign(NewVersion);
3676 Name:=NewName;
3677 end;
3678
GetFPDocPackageNamenull3679 function TLazPackage.GetFPDocPackageName: string;
3680 begin
3681 if FPDocPackageName<>'' then
3682 Result:=FPDocPackageName
3683 else
3684 Result:=Name;
3685 end;
3686
GetOutputDirTypenull3687 function TLazPackage.GetOutputDirType: TPkgOutputDir;
3688 begin
3689 if (CompilerOptions<>nil)
3690 and (CompilerOptions.ParsedOpts<>nil)
3691 and (CompilerOptions.ParsedOpts.OutputDirectoryOverride<>'') then
3692 Result:=podFallback
3693 else
3694 Result:=podDefault;
3695 end;
3696
3697 procedure TLazPackage.GetAllRequiredPackages(var List, FPMakeList: TFPList;
3698 WithSelf: boolean; aFlags: TPkgIntfRequiredFlags;
3699 MinPolicy: TPackageUpdatePolicy);
3700 begin
3701 if Assigned(OnGetAllRequiredPackages) then
3702 OnGetAllRequiredPackages(Self,FirstRequiredDependency,List,FPMakeList,aFlags,MinPolicy);
3703 if WithSelf then begin
3704 if List=nil then List:=TFPList.Create;
3705 if List.IndexOf(Self)<0 then
3706 List.Insert(0,Self);
3707 end else if List<>nil then begin
3708 List.Remove(Self);
3709 if List.Count=0 then FreeAndNil(List);
3710 end;
3711 end;
3712
3713 procedure TLazPackage.GetInheritedCompilerOptions(var OptionsList: TFPList);
3714 var
3715 PkgList: TFPList; // list of TLazPackage
3716 FPMakeList: TFPList;
3717 begin
3718 PkgList:=nil;
3719 FPMakeList:=nil;
3720 GetAllRequiredPackages(PkgList,FPMakeList,false,[pirCompileOrder]);
3721 OptionsList:=GetUsageOptionsList(PkgList);
3722 PkgList.Free;
3723 FPMakeList.Free;
3724 end;
3725
GetCompileSourceFilenamenull3726 function TLazPackage.GetCompileSourceFilename: string;
3727 begin
3728 if MainUnit<>nil then
3729 Result:=ExtractFilename(MainUnit.GetFullFilename)
3730 else
3731 Result:=ChangeFileExt(ExtractFilename(Filename),'.pas');
3732 end;
3733
GetOutputDirectorynull3734 function TLazPackage.GetOutputDirectory(UseOverride: boolean = true): string;
3735 begin
3736 if HasDirectory then begin
3737 Result:=CompilerOptions.ParsedOpts.GetParsedValue(pcosOutputDir,UseOverride);
3738 end else
3739 Result:='';
3740 end;
3741
HasSeparateOutputDirectorynull3742 function TLazPackage.HasSeparateOutputDirectory: boolean;
3743 var
3744 VisitedPackages: TStringToStringTree;
3745 OutputDir: String;
3746
3747 function CheckDependency(ADependency: TPkgDependency): boolean;
3748 var
3749 aPkg: TLazPackage;
3750 Dir: String;
3751 SrcPaths: String;
3752 begin
3753 Result:=false;
3754 while ADependency<>nil do begin
3755 if ADependency.RequiredPackage<>nil then begin
3756 aPkg:=ADependency.RequiredPackage;
3757 if not VisitedPackages.Contains(aPkg.Name) then begin
3758 VisitedPackages[aPkg.Name]:='1';
3759 // check recursively
3760 if not CheckDependency(aPkg.FirstRequiredDependency) then exit;
3761 // check if required package has the same output directory
3762 Dir:=aPkg.GetOutputDirectory;
3763 if CompareFilenames(Dir,OutputDir)=0 then exit;
3764 // check if output directory is a sour directory of a required package
3765 SrcPaths:=aPkg.SourceDirectories.CreateSearchPathFromAllFiles;
3766 if (SrcPaths<>'')
3767 and (FindPathInSearchPath(PChar(OutputDir),length(OutputDir),
3768 PChar(SrcPaths),length(SrcPaths))<>nil)
3769 then exit;
3770 end;
3771 end;
3772 ADependency:=ADependency.NextRequiresDependency;
3773 end;
3774 Result:=true;
3775 end;
3776
3777 var
3778 SrcPaths: String;
3779 begin
3780 Result:=false;
3781 if CompilerOptions.UnitOutputDirectory='' then exit;
3782 OutputDir:=CompilerOptions.ParsedOpts.GetParsedValue(pcosOutputDir,false);
3783 if OutputDir='' then exit;
3784 SrcPaths:=SourceDirectories.CreateSearchPathFromAllFiles;
3785 if SrcPaths='' then exit(true);
3786 if FindPathInSearchPath(PChar(OutputDir),length(OutputDir),PChar(SrcPaths),length(SrcPaths))<>nil
3787 then exit;
3788 // check used packages
3789 VisitedPackages:=TStringToStringTree.Create(false);
3790 try
3791 if not CheckDependency(FirstRequiredDependency) then exit;
3792 finally
3793 VisitedPackages.Free;
3794 end;
3795 Result:=true;
3796 end;
3797
GetStateFilenamenull3798 function TLazPackage.GetStateFilename(UseOverride: boolean): string;
3799 begin
3800 Result:=AppendPathDelim(GetOutputDirectory(UseOverride))+Name+'.compiled';
3801 end;
3802
GetSrcFilenamenull3803 function TLazPackage.GetSrcFilename: string;
3804 begin
3805 if MainUnit<>nil then
3806 Result:=MainUnit.GetFullFilename
3807 else
3808 Result:=FDirectory+GetCompileSourceFilename;
3809 end;
3810
GetSrcPPUFilenamenull3811 function TLazPackage.GetSrcPPUFilename: string;
3812 begin
3813 Result:=AppendPathDelim(GetOutputDirectory)
3814 +ChangeFileExt(GetCompileSourceFilename,'.ppu');
3815 end;
3816
GetCompilerFilenamenull3817 function TLazPackage.GetCompilerFilename: string;
3818 begin
3819 Result:=CompilerOptions.ParsedOpts.GetParsedValue(pcosCompilerPath);
3820 end;
3821
GetPOOutDirectorynull3822 function TLazPackage.GetPOOutDirectory: string;
3823 begin
3824 Result:=TrimFilename(SubstitutePkgMacros(fPOOutputDirectory,false));
3825 LongenFilename(Result);
3826 IDEMacros.SubstituteMacros(Result);
3827 Result:=TrimFilename(Result);
3828 end;
3829
GetUnitPathnull3830 function TLazPackage.GetUnitPath(RelativeToBaseDir: boolean): string;
3831 begin
3832 Result:=CompilerOptions.GetUnitPath(RelativeToBaseDir);
3833 end;
3834
GetIncludePathnull3835 function TLazPackage.GetIncludePath(RelativeToBaseDir: boolean): string;
3836 begin
3837 Result:=CompilerOptions.GetIncludePath(RelativeToBaseDir);
3838 end;
3839
GetSrcPathnull3840 function TLazPackage.GetSrcPath(RelativeToBaseDir: boolean): string;
3841 begin
3842 Result:=CompilerOptions.GetSrcPath(RelativeToBaseDir);
3843 end;
3844
GetLastCompilerParamsnull3845 function TLazPackage.GetLastCompilerParams(o: TPkgOutputDir): string;
3846 begin
3847 Result:=LastCompile[o].Params;
3848 if LastCompile[o].ViaMakefile then begin
3849 Result:=StringReplace(Result,'$(CPU_TARGET)','$(TargetCPU)',[rfReplaceAll]);
3850 Result:=StringReplace(Result,'$(OS_TARGET)','$(TargetOS)',[rfReplaceAll]);
3851 Result:=StringReplace(Result,'$(LCL_PLATFORM)','$(LCLWidgetType)',[rfReplaceAll]);
3852 Result:=SubstitutePkgMacros(Result,false);
3853 end;
3854 end;
3855
NeedsDefineTemplatesnull3856 function TLazPackage.NeedsDefineTemplates: boolean;
3857 begin
3858 if IsVirtual or (lpfDestroying in Flags) or (Name='') then
3859 Result:=false
3860 else
3861 Result:=true;
3862 end;
3863
IndexOfPkgFilenull3864 function TLazPackage.IndexOfPkgFile(PkgFile: TPkgFile): integer;
3865 begin
3866 Result := FileCount - 1;
3867 if Result < 0 then
3868 Exit;
3869 while (Files[Result] <> PkgFile) do
3870 begin
3871 dec(Result);
3872 if Result < 0 then
3873 Exit;
3874 end;
3875 end;
3876
SearchShortFilenamenull3877 function TLazPackage.SearchShortFilename(const ShortFilename: string;
3878 SearchFlags: TSearchIDEFileFlags): TPkgFile;
3879 var
3880 SearchedFilename: String;
3881 i: Integer;
3882
3883 function FilenameFits(TheFilename: string): boolean;
3884 begin
3885 if siffIgnoreExtension in SearchFlags then
3886 TheFileName:=ExtractFileNameWithoutExt(TheFileName);
3887 //debugln('TLazPackage.SearchFile A ',SearchedFilename,' ',TheFilename);
3888 if siffCaseSensitive in SearchFlags then
3889 Result:=SearchedFilename=TheFilename
3890 else
3891 Result:=SysUtils.CompareText(SearchedFilename,TheFilename)=0;
3892 end;
3893
3894 begin
3895 SearchedFilename:=ShortFilename;
3896 if siffIgnoreExtension in SearchFlags then
3897 SearchedFilename:=ExtractFileNameWithoutExt(SearchedFilename);
3898
3899 // search in files
3900 for i:=0 to FileCount-1 do begin
3901 Result:=Files[i];
3902 if FilenameFits(Result.GetShortFilename(true)) then exit;
3903 end;
3904 Result:=nil;
3905 end;
3906
SearchFilenamenull3907 function TLazPackage.SearchFilename(const AFilename: string;
3908 SearchFlags: TSearchIDEFileFlags): TPkgFile;
3909 var
3910 SearchedFilename: String;
3911 i: Integer;
3912
3913 function FilenameFits(TheFilename: string): boolean;
3914 begin
3915 if siffIgnoreExtension in SearchFlags then
3916 TheFileName:=ExtractFileNameWithoutExt(TheFileName);
3917 //debugln('TLazPackage.SearchFile A ',SearchedFilename,' ',TheFilename);
3918 if siffCaseSensitive in SearchFlags then
3919 Result:=SearchedFilename=TheFilename
3920 else
3921 Result:=SysUtils.CompareText(SearchedFilename,TheFilename)=0;
3922 end;
3923
3924 begin
3925 SearchedFilename:=AFilename;
3926 if siffIgnoreExtension in SearchFlags then
3927 SearchedFilename:=ExtractFileNameWithoutExt(SearchedFilename);
3928
3929 // search in files
3930 for i:=0 to FileCount-1 do begin
3931 Result:=Files[i];
3932 if FilenameFits(Result.GetFullFilename) then exit;
3933 end;
3934 Result:=nil;
3935 end;
3936
3937 { TPkgComponent }
3938
3939 procedure TPkgComponent.SetPkgFile(const AValue: TPkgFile);
3940 begin
3941 if FPkgFile=AValue then exit;
3942 if (FPkgFile<>nil) then PkgFile.RemovePkgComponent(Self);
3943 FPkgFile:=AValue;
3944 if (FPkgFile<>nil) then PkgFile.AddPkgComponent(Self);
3945 end;
3946
3947 constructor TPkgComponent.Create(ThePkgFile: TPkgFile;
3948 TheComponentClass: TComponentClass; const ThePageName: string);
3949 begin
3950 inherited Create(TheComponentClass,ThePageName);
3951 PkgFile:=ThePkgFile;
3952 end;
3953
3954 destructor TPkgComponent.Destroy;
3955 begin
3956 PkgFile:=nil;
3957 inherited Destroy;
3958 end;
3959
GetUnitNamenull3960 function TPkgComponent.GetUnitName: string;
3961 var
3962 TIUnitName: String;
3963 begin
3964 Result:=PkgFile.Unit_Name;
3965 // compare with RTTI unit name
3966 if ComponentClass<>nil then begin
3967 TIUnitName:=GetClassUnitName(ComponentClass);
3968 if SysUtils.CompareText(TIUnitName,Result)<>0 then
3969 Result:=TIUnitName;
3970 end;
3971 end;
3972
GetPrioritynull3973 function TPkgComponent.GetPriority: TComponentPriority;
3974 begin
3975 Result:=PkgFile.ComponentPriority;
3976 end;
3977
3978 procedure TPkgComponent.ConsistencyCheck;
3979 begin
3980 inherited ConsistencyCheck;
3981 if FPkgFile=nil then
3982 RaiseGDBException('TIDEComponent.ConsistencyCheck FPkgFile=nil');
3983 if FPkgFile.LazPackage=nil then
3984 RaiseGDBException('TIDEComponent.ConsistencyCheck FPkgFile.LazPackage=nil');
3985 if FPkgFile.LazPackage.IndexOfPkgComponent(Self)<0 then
3986 RaiseGDBException('TIDEComponent.ConsistencyCheck FPkgFile.LazPackage.IndexOfPkgComponent(Self)<0');
3987 if PkgFile.FComponents=nil then
3988 RaiseGDBException('TIDEComponent.ConsistencyCheck PkgFile.FComponents=nil');
3989 if PkgFile.FComponents.IndexOf(Self)<0 then
3990 RaiseGDBException('TIDEComponent.ConsistencyCheck PkgFile.FComponents.IndexOf(Self)<0');
3991 end;
3992
3993 class function TPkgComponent.Images: TCustomImageList;
3994 begin
3995 Result := IDEImages.Images_24;
3996 end;
3997
HasIconnull3998 function TPkgComponent.HasIcon: boolean;
3999 begin
4000 Result:=RealPage.PageName<>'';
4001 end;
4002
ImageIndexnull4003 function TPkgComponent.ImageIndex: TImageIndex;
4004 begin
4005 Result := IDEImages.GetImageIndex(ComponentClass.ClassName, 24);
4006 if Result=-1 then
4007 Result := IDEImages.GetImageIndex('default', 24);
4008 end;
4009
CanBeCreatedInDesignernull4010 function TPkgComponent.CanBeCreatedInDesigner: boolean;
4011 begin
4012 Result:=(not PkgFile.Removed);
4013 end;
4014
4015 { TPkgCompilerOptions }
4016
4017 procedure TPkgCompilerOptions.LoadFromXMLConfig(AXMLConfig: TXMLConfig;
4018 const Path: string);
4019 begin
4020 inherited LoadFromXMLConfig(AXMLConfig,Path);
4021
4022 FSkipCompiler := AXMLConfig.GetValue(Path+'SkipCompiler/Value', False);
4023 end;
4024
4025 procedure TPkgCompilerOptions.SaveToXMLConfig(AXMLConfig: TXMLConfig; const Path: string);
4026 begin
4027 inherited SaveToXMLConfig(AXMLConfig,Path);
4028
4029 AXMLConfig.SetDeleteValue(Path+'SkipCompiler/Value', FSkipCompiler, False);
4030 end;
4031
4032 procedure TPkgCompilerOptions.SetLazPackage(const AValue: TLazPackage);
4033 begin
4034 if FLazPackage=AValue then exit;
4035 FLazPackage:=AValue;
4036 end;
4037
4038 procedure TPkgCompilerOptions.SetCustomOptions(const AValue: string);
4039 begin
4040 if CustomOptions=AValue then exit;
4041 InvalidateOptions;
4042 inherited SetCustomOptions(AValue);
4043 if LazPackage<>nil then
4044 LazPackage.DefineTemplates.CustomDefinesChanged;
4045 end;
4046
4047 procedure TPkgCompilerOptions.SetIncludePaths(const AValue: string);
4048 begin
4049 if IncludePath=AValue then exit;
4050 InvalidateOptions;
4051 inherited SetIncludePaths(AValue);
4052 end;
4053
4054 procedure TPkgCompilerOptions.SetLibraryPaths(const AValue: string);
4055 begin
4056 if Libraries=AValue then exit;
4057 InvalidateOptions;
4058 inherited SetLibraryPaths(AValue);
4059 end;
4060
4061 procedure TPkgCompilerOptions.SetLinkerOptions(const AValue: string);
4062 begin
4063 if LinkerOptions=AValue then exit;
4064 InvalidateOptions;
4065 inherited SetLinkerOptions(AValue);
4066 end;
4067
4068 procedure TPkgCompilerOptions.SetObjectPath(const AValue: string);
4069 begin
4070 if ObjectPath=AValue then exit;
4071 InvalidateOptions;
4072 inherited SetObjectPath(AValue);
4073 end;
4074
4075 procedure TPkgCompilerOptions.SetSrcPath(const AValue: string);
4076 begin
4077 if SrcPath=AValue then exit;
4078 InvalidateOptions;
4079 inherited SetSrcPath(AValue);
4080 end;
4081
4082 procedure TPkgCompilerOptions.SetUnitPaths(const AValue: string);
4083 begin
4084 if OtherUnitFiles=AValue then exit;
4085 InvalidateOptions;
4086 inherited SetUnitPaths(AValue);
4087 end;
4088
4089 procedure TPkgCompilerOptions.SetUnitOutputDir(const AValue: string);
4090 begin
4091 if UnitOutputDirectory=AValue then exit;
4092 InvalidateOptions;
4093 inherited SetUnitOutputDir(AValue);
4094 if LazPackage<>nil then
4095 LazPackage.DefineTemplates.OutputDirectoryChanged;
4096 end;
4097
4098 procedure TPkgCompilerOptions.SetConditionals(AValue: string);
4099 begin
4100 AValue:=UTF8Trim(AValue,[]);
4101 if Conditionals=AValue then exit;
4102 InvalidateOptions;
4103 inherited SetConditionals(AValue);
4104 end;
4105
4106 constructor TPkgCompilerOptions.Create(const AOwner: TObject);
4107 begin
4108 inherited Create(AOwner);
4109 if AOwner<>nil then
4110 FLazPackage := AOwner as TLazPackage;
4111 ParsedOpts.MacroValues.ProjValuesAvailable:=true;
4112 end;
4113
4114 class function TPkgCompilerOptions.GetGroupCaption: string;
4115 begin
4116 Result := dlgCompilerOptions;
4117 end;
4118
4119 class function TPkgCompilerOptions.GetInstance: TAbstractIDEOptions;
4120 begin
4121 if Package1<>nil then
4122 Result := Package1.CompilerOptions
4123 else
4124 Result := nil;
4125 end;
4126
IsActivenull4127 function TPkgCompilerOptions.IsActive: boolean;
4128 begin
4129 Result:=(LazPackage<>nil) and (LazPackage.CompilerOptions=Self);
4130 end;
4131
4132 procedure TPkgCompilerOptions.Clear;
4133 begin
4134 inherited Clear;
4135 FSkipCompiler:=false;
4136 end;
4137
4138 procedure TPkgCompilerOptions.GetInheritedCompilerOptions(
4139 var OptionsList: TFPList);
4140 begin
4141 if LazPackage<>nil then
4142 LazPackage.GetInheritedCompilerOptions(OptionsList);
4143 end;
4144
GetOwnerNamenull4145 function TPkgCompilerOptions.GetOwnerName: string;
4146 begin
4147 if LazPackage<>nil then
4148 Result:=LazPackage.IDAsString
4149 else
4150 Result:='';
4151 end;
4152
4153 procedure TPkgCompilerOptions.InvalidateOptions;
4154 begin
4155 if (LazPackage=nil) then exit;
4156 if LazPackage.UsageOptions=nil then RaiseGDBException('');
4157 if LazPackage.UsageOptions.ParsedOpts=nil then RaiseGDBException('');
4158 LazPackage.UsageOptions.ParsedOpts.InvalidateAll;
4159 end;
4160
GetDefaultMainSourceFileNamenull4161 function TPkgCompilerOptions.GetDefaultMainSourceFileName: string;
4162 begin
4163 if LazPackage<>nil then
4164 Result:=LazPackage.GetCompileSourceFilename
4165 else
4166 Result:='';
4167 if Result='' then
4168 Result:=inherited GetDefaultMainSourceFileName;
4169 end;
4170
CreateTargetFilenamenull4171 function TPkgCompilerOptions.CreateTargetFilename: string;
4172 begin
4173 Result:='';
4174 end;
4175
HasCompilerCommandnull4176 function TPkgCompilerOptions.HasCompilerCommand: boolean;
4177 begin
4178 Result:=(not SkipCompiler) and (CompilerPath<>'');
4179 end;
4180
4181 procedure TPkgCompilerOptions.Assign(Source: TPersistent);
4182 begin
4183 inherited Assign(Source);
4184 if Source is TPkgCompilerOptions
4185 then begin
4186 FSkipCompiler := TPkgCompilerOptions(Source).FSkipCompiler;
4187 end
4188 else begin
4189 FSkipCompiler := False;
4190 end;
4191 end;
4192
CreateDiffnull4193 function TPkgCompilerOptions.CreateDiff(CompOpts: TBaseCompilerOptions;
4194 Tool: TCompilerDiffTool): boolean;
4195 begin
4196 if (CompOpts is TPkgCompilerOptions) then begin
4197 Result:=Tool.AddDiff('SkipCompiler',FSkipCompiler,
4198 TPkgCompilerOptions(CompOpts).FSkipCompiler);
4199 end else begin
4200 Result:=true;
4201 if Tool<>nil then Tool.Differ:=true;
4202 end;
4203 Result:=Result or inherited CreateDiff(CompOpts, Tool);
4204 end;
4205
4206 { TPkgAdditionalCompilerOptions }
4207
4208 procedure TPkgAdditionalCompilerOptions.SetLazPackage(const AValue: TLazPackage);
4209 begin
4210 if FLazPackage=AValue then exit;
4211 FLazPackage:=AValue;
4212 end;
4213
4214 procedure TPkgAdditionalCompilerOptions.SetCustomOptions(const AValue: string);
4215 begin
4216 if AValue=CustomOptions then exit;
4217 inherited SetCustomOptions(AValue);
4218 LazPackage.Modified:=true;
4219 end;
4220
4221 procedure TPkgAdditionalCompilerOptions.SetIncludePath(const AValue: string);
4222 begin
4223 if AValue=IncludePath then exit;
4224 inherited SetIncludePath(AValue);
4225 LazPackage.Modified:=true;
4226 end;
4227
4228 procedure TPkgAdditionalCompilerOptions.SetLibraryPath(const AValue: string);
4229 begin
4230 if AValue=LibraryPath then exit;
4231 inherited SetLibraryPath(AValue);
4232 LazPackage.Modified:=true;
4233 end;
4234
4235 procedure TPkgAdditionalCompilerOptions.SetLinkerOptions(const AValue: string);
4236 begin
4237 if AValue=LinkerOptions then exit;
4238 inherited SetLinkerOptions(AValue);
4239 LazPackage.Modified:=true;
4240 end;
4241
4242 procedure TPkgAdditionalCompilerOptions.SetObjectPath(const AValue: string);
4243 begin
4244 if AValue=ObjectPath then exit;
4245 inherited SetObjectPath(AValue);
4246 LazPackage.Modified:=true;
4247 end;
4248
4249 procedure TPkgAdditionalCompilerOptions.SetUnitPath(const AValue: string);
4250 begin
4251 if AValue=UnitPath then exit;
4252 inherited SetUnitPath(AValue);
4253 LazPackage.Modified:=true;
4254 end;
4255
4256 procedure TPkgAdditionalCompilerOptions.SetSrcPath(const AValue: string);
4257 begin
4258 if AValue=SrcPath then exit;
4259 inherited SetSrcPath(AValue);
4260 LazPackage.Modified:=true;
4261 end;
4262
4263 constructor TPkgAdditionalCompilerOptions.Create(ThePackage: TLazPackage);
4264 begin
4265 inherited Create(ThePackage);
4266 FLazPackage:=ThePackage;
4267 end;
4268
4269 procedure TPkgAdditionalCompilerOptions.AssignOptions(Source: TObject);
4270 begin
4271 inherited AssignOptions(Source);
4272 if Source is TPkgAdditionalCompilerOptions then begin
4273 //Src:=TPkgAdditionalCompilerOptions(Source);
4274 // nothing to do
4275 end;
4276 end;
4277
GetOwnerNamenull4278 function TPkgAdditionalCompilerOptions.GetOwnerName: string;
4279 begin
4280 Result:=LazPackage.IDAsString;
4281 end;
4282
4283 function TPkgAdditionalCompilerOptions.
4284 GetBaseCompilerOptions: TBaseCompilerOptions;
4285 begin
4286 Result:=LazPackage.CompilerOptions;
4287 end;
4288
4289 { TLazPackageDefineTemplates }
4290
4291 constructor TLazPackageDefineTemplates.Create(AOwner: IProjPack);
4292 begin
4293 inherited Create(AOwner);
4294 Include(FFlags, ptfIsPackageTemplate);
4295 fLastSourceDirStamp:=CTInvalidChangeStamp;
4296 end;
4297
4298 destructor TLazPackageDefineTemplates.Destroy;
4299 begin
4300 inherited Destroy;
4301 end;
4302
4303 procedure TLazPackageDefineTemplates.ClearFlags;
4304 begin
4305 FFlags:=FFlags+[ptfIDChanged,ptfOutputDirChanged,ptfSourceDirsChanged,
4306 ptfCustomDefinesChanged];
4307 end;
4308
4309 procedure TLazPackageDefineTemplates.AllChanged;
4310 begin
4311 IDChanged;
4312 UpdateSrcDirIfDef;// always create the SrcDirIfDef for IDE add-ons
4313 SourceDirectoriesChanged;
4314 CustomDefinesChanged;
4315 OutputDirectoryChanged;
4316 end;
4317
4318 procedure TLazPackageDefineTemplates.UpdateMain;
4319 begin
4320 if (not Owner.NeedsDefineTemplates) or (not Active) then exit;
4321 // update the package block define template (the container for all other
4322 // define templates of the package)
4323 if FMain=nil then begin
4324 FMain:=CreatePackageTemplateWithID(Owner.IDAsWord);
4325 FMain.SetDefineOwner(Owner as TLazPackage,false);
4326 FMain.SetFlags([dtfAutoGenerated],[],false);
4327 end else
4328 FMain.Name:=Owner.IDAsWord;
4329 // ClearCache is here unnessary, because it is only a block
4330 end;
4331
4332 procedure TLazPackageDefineTemplates.UpdateSrcDirIfDef;
4333 var
4334 Changed: Boolean;
4335 NewVariable: String;
4336 UnitPathDefTempl: TDefineTemplate;
4337 IncPathDefTempl: TDefineTemplate;
4338 begin
4339 // create custom options
4340 // The custom options are enclosed by an IFDEF #PkgSrcMark<PckId> template.
4341 // Each source directory defines this variable, so that the settings can be
4342 // activated for each source directory by a simple DEFINE.
4343 if (FMain=nil) then UpdateMain;
4344 if FMain=nil then exit;
4345 if FSrcDirectories=nil then begin
4346 FSrcDirectories:=TDefineTemplate.Create('Source Directories',
4347 'Source Directories','','',
4348 da_Block);
4349 FMain.AddChild(FSrcDirectories);
4350 end;
4351 Changed:=false;
4352 if FSrcDirIf=nil then begin
4353 FSrcDirIf:=TDefineTemplate.Create('Source Directory Additions',
4354 'Additional defines for package source directories',
4355 '#PkgSrcMark'+Owner.IDAsWord, '', da_IfDef);
4356 FMain.AddChild(FSrcDirIf);
4357
4358 // create unit path template for this directory
4359 UnitPathDefTempl:=TDefineTemplate.Create('UnitPath', lisPkgDefsUnitPath,
4360 '#UnitPath','$(#UnitPath);$PkgUnitPath('+Owner.IDAsString+')',
4361 da_Define);
4362 FSrcDirIf.AddChild(UnitPathDefTempl);
4363 // create include path template for this directory
4364 IncPathDefTempl:=TDefineTemplate.Create('IncPath','Include Path',
4365 '#IncPath','$(#IncPath);$PkgIncPath('+Owner.IDAsString+')',
4366 da_Define);
4367 FSrcDirIf.AddChild(IncPathDefTempl);
4368
4369 Changed:=true;
4370 end else begin
4371 NewVariable:='#PkgSrcMark'+Owner.IDAsWord;
4372 if NewVariable<>FSrcDirIf.Variable then begin
4373 FSrcDirIf.Variable:=NewVariable;
4374 // unit path
4375 UnitPathDefTempl:=FSrcDirIf.FindChildByName('UnitPath');
4376 if UnitPathDefTempl<>nil then
4377 UnitPathDefTempl.Value:='$(#UnitPath);$PkgUnitPath('+Owner.IDAsString+')';
4378 // include path
4379 IncPathDefTempl:=FSrcDirIf.FindChildByName('IncPath');
4380 if IncPathDefTempl<>nil then
4381 IncPathDefTempl.Value:='$(#IncPath);$PkgIncPath('+Owner.IDAsString+')';
4382
4383 Changed:=true;
4384 end;
4385 end;
4386 if Changed then
4387 CodeToolBoss.DefineTree.ClearCache;
4388 end;
4389
4390 procedure TLazPackageDefineTemplates.UpdateOutputDirectory;
4391 var
4392 LazPackage: TLazPackage;
4393 begin
4394 if FMain=nil then UpdateMain;
4395 if FMain=nil then exit;
4396
4397 LazPackage := Owner as TLazPackage;
4398 if FOutputDir=nil then begin
4399 FOutputDir:=TDefineTemplate.Create(PkgOutputDirDefTemplName,
4400 lisPkgDefsOutputDirectory, '', LazPackage.GetOutputDirectory, da_Directory);
4401 FOutputDir.SetDefineOwner(LazPackage,false);
4402 FOutputDir.SetFlags([dtfAutoGenerated],[],false);
4403 DisableDefaultsInDirectories(FOutputDir,false);
4404 FMain.AddChild(FOutputDir);
4405 end else begin
4406 FOutputDir.Value:=LazPackage.GetOutputDirectory;
4407 end;
4408
4409 if (FOutPutSrcPath=nil)
4410 or (fLastOutputDirSrcPathIDAsString<>Owner.IDAsString) then begin
4411 fLastOutputDirSrcPathIDAsString:=Owner.IDAsString;
4412 FOutputSrcPath:=TDefineTemplate.Create('CompiledSrcPath',
4413 lisPkgDefsCompiledSrcPathAddition, CompiledSrcPathMacroName,
4414 '$PkgSrcPath('+fLastOutputDirSrcPathIDAsString+');'+'$('+CompiledSrcPathMacroName+')',
4415 da_Define);
4416 FOutputSrcPath.SetDefineOwner(LazPackage,false);
4417 FOutputSrcPath.SetFlags([dtfAutoGenerated],[],false);
4418 CodeToolBoss.DefineTree.ReplaceChild(FOutputDir,FOutputSrcPath,
4419 FOutputSrcPath.Name);
4420 end;
4421 end;
4422
4423 procedure TLazPackageDefineTemplates.UpdateSourceDirectories;
4424 var
4425 i: Integer;
4426 SrcDirDefTempl, SrcDirMarkDefTempl: TDefineTemplate;
4427 IDHasChanged: Boolean;
4428 CurUnitPath, SrcDirs: String;
4429 begin
4430 if (not Owner.NeedsDefineTemplates) or (not Active) then exit;
4431
4432 // quick check if something has changed
4433 IDHasChanged:=fLastSourceDirsIDAsString<>Owner.IDAsString;
4434 CurUnitPath:=Owner.BaseCompilerOptions.ParsedOpts.GetParsedValue(pcosUnitPath);
4435 SrcDirs:=Owner.SourceDirectories.CreateSearchPathFromAllFiles;
4436 CurUnitPath:=TrimSearchPath(SrcDirs+';'+CurUnitPath+';.',
4437 Owner.BaseCompilerOptions.BaseDirectory,true);
4438
4439 if (fLastSourceDirectories<>nil)
4440 and (fLastSourceDirStamp=Owner.SourceDirectories.TimeStamp)
4441 and (not IDHasChanged)
4442 and (CurUnitPath=fLastUnitPath) then
4443 exit;
4444 //debugln(['TLazPackageDefineTemplates.UpdateSourceDirectories ',LazPackage.Name,' CurUnitPath=',CurUnitPath]);
4445 fLastSourceDirStamp:=Owner.SourceDirectories.TimeStamp;
4446 fLastSourceDirsIDAsString:=Owner.IDAsString;
4447 fLastUnitPath:=CurUnitPath;
4448
4449 // clear old define templates
4450 if fLastSourceDirectories<>nil then begin
4451 for i:=0 to fLastSourceDirectories.Count-1 do begin
4452 SrcDirDefTempl:=TDefineTemplate(fLastSourceDirectories.Objects[i]);
4453 SrcDirDefTempl.Unbind;
4454 SrcDirDefTempl.Free;
4455 end;
4456 fLastSourceDirectories.Clear;
4457 end else
4458 fLastSourceDirectories:=TStringList.Create;
4459
4460 // build source directory define templates
4461 FreeAndNil(fLastSourceDirectories);
4462 fLastSourceDirectories:=SearchPathToList(CurUnitPath);
4463 if (fLastSourceDirectories.Count>0)
4464 and ((FSrcDirIf=nil) or IDHasChanged) then
4465 UpdateSrcDirIfDef;
4466 for i:=0 to fLastSourceDirectories.Count-1 do begin
4467 // create directory template
4468 SrcDirDefTempl:=TDefineTemplate.Create('Source Directory '+IntToStr(i+1),
4469 fLastSourceDirectories[i],'',fLastSourceDirectories[i],da_Directory);
4470 DisableDefaultsInDirectories(SrcDirDefTempl,false);
4471 fLastSourceDirectories.Objects[i]:=SrcDirDefTempl;
4472 // add package source directory marker
4473 SrcDirMarkDefTempl:=TDefineTemplate.Create('PkgSrcDirMark',
4474 lisPkgDefsSrcDirMark,'#PkgSrcMark'+Owner.IDAsWord,'',da_Define);
4475 SrcDirDefTempl.AddChild(SrcDirMarkDefTempl);
4476
4477 SrcDirDefTempl.SetDefineOwner(Owner as TLazPackage,false);
4478 SrcDirDefTempl.SetFlags([dtfAutoGenerated],[],false);
4479 // add directory
4480 FSrcDirectories.AddChild(SrcDirDefTempl);
4481 end;
4482 CodeToolBoss.DefineTree.ClearCache;
4483 end;
4484
4485 procedure TLazPackageDefineTemplates.UpdateDefinesForCustomDefines;
4486 var
4487 OptionsDefTempl: TDefineTemplate;
4488 NewCustomOptions: String;
4489 begin
4490 if (not Owner.NeedsDefineTemplates) or (not Active) then exit;
4491
4492 // check if something has changed
4493 NewCustomOptions:=Owner.BaseCompilerOptions.GetOptionsForCTDefines;
4494 if FLastCustomOptions=NewCustomOptions then exit;
4495
4496 FLastCustomOptions:=NewCustomOptions;
4497 OptionsDefTempl:=CodeToolBoss.DefinePool.CreateFPCCommandLineDefines(
4498 'Custom Options', FLastCustomOptions, false, Owner as TLazPackage);
4499 if OptionsDefTempl=nil then begin
4500 // no custom options -> delete old template
4501 if FSrcDirIf<>nil then begin
4502 if FSrcDirIf.DeleteChild('Custom Options') then
4503 CodeToolBoss.DefineTree.ClearCache;
4504 end;
4505 end else begin
4506 UpdateSrcDirIfDef;
4507 FSrcDirIf.ReplaceChild(OptionsDefTempl);
4508 CodeToolBoss.DefineTree.ClearCache;
4509 end;
4510 end;
4511
4512 { TBasePackageEditor }
4513
GetLazPackagenull4514 function TBasePackageEditor.GetLazPackage: TLazPackage;
4515 begin
4516 Result:=nil;
4517 end;
4518
4519 { TPublishPackageOptions }
4520
4521 procedure TPublishPackageOptions.DoOnModifyChange;
4522 begin
4523 if Modified then
4524 TLazPackage(Owner).Modified:=true;
4525 end;
4526
GetDefaultDestinationDirnull4527 function TPublishPackageOptions.GetDefaultDestinationDir: string;
4528 begin
4529 Result:='$(TestDir)/publishedpackage/';
4530 end;
4531
4532 { TPkgPairTree }
4533
4534 function ComparePkgPairs(Pair1, Pair2: Pointer): integer;
4535 begin
4536 Result:=TPkgPair(Pair1).Compare(TPkgPair(Pair2));
4537 end;
4538
4539 constructor TPkgPairTree.Create;
4540 begin
4541 inherited Create(@ComparePkgPairs);
4542 end;
4543
4544 destructor TPkgPairTree.Destroy;
4545 begin
4546 FreeAndClear;
4547 inherited Destroy;
4548 end;
4549
FindPairnull4550 function TPkgPairTree.FindPair(Pkg1, Pkg2: TLazPackage; IgnoreOrder: boolean): TPkgPair;
4551 var
4552 Comp: integer;
4553 ANode: TAVLTreeNode;
4554 begin
4555 ANode:=Root;
4556 while (ANode<>nil) do begin
4557 Result:=TPkgPair(ANode.Data);
4558 Comp:=Result.ComparePair(Pkg1,Pkg2);
4559 if Comp=0 then exit;
4560 if Comp>0 then begin
4561 ANode:=ANode.Left
4562 end else begin
4563 ANode:=ANode.Right
4564 end;
4565 end;
4566 if IgnoreOrder and (Pkg1<>Pkg2) then
4567 Result:=FindPair(Pkg2,Pkg1,false)
4568 else
4569 Result:=nil;
4570 end;
4571
AddPairnull4572 function TPkgPairTree.AddPair(Pkg1, Pkg2: TLazPackage): TPkgPair;
4573 begin
4574 Result:=TPkgPair.Create(Pkg1,Pkg2);
4575 Add(Result);
4576 end;
4577
AddPairIfNotExistsnull4578 function TPkgPairTree.AddPairIfNotExists(Pkg1, Pkg2: TLazPackage): TPkgPair;
4579 begin
4580 Result:=FindPair(Pkg1,Pkg2,true);
4581 if Result=nil then
4582 Result:=AddPair(Pkg1,Pkg2);
4583 end;
4584
4585 { TPkgPair }
4586
4587 constructor TPkgPair.Create(Pkg1, Pkg2: TLazPackage);
4588 begin
4589 Package1:=Pkg1;
4590 Package2:=Pkg2;
4591 end;
4592
ComparePairnull4593 function TPkgPair.ComparePair(Pkg1, Pkg2: TLazPackage): integer;
4594 begin
4595 Result:=Package1.Compare(Pkg1);
4596 if Result=0 then
4597 Result:=Package2.Compare(Pkg2);
4598 end;
4599
Comparenull4600 function TPkgPair.Compare(PkgPair: TPkgPair): integer;
4601 begin
4602 Result:=ComparePair(PkgPair.Package1,PkgPair.Package2);
4603 end;
4604
AsStringnull4605 function TPkgPair.AsString: string;
4606 begin
4607 Result:=Package1.IDAsString+' - '+Package2.IDAsString;
4608 end;
4609
4610 { TPkgUnitsTree }
4611
FindNodeWithUnitNamenull4612 function TPkgUnitsTree.FindNodeWithUnitName(const AUnitName: string): TAVLTreeNode;
4613 var
4614 Comp: integer;
4615 PkgFile: TPkgFile;
4616 begin
4617 Result:=Root;
4618 while (Result<>nil) do begin
4619 PkgFile:=TPkgFile(Result.Data);
4620 Comp:=SysUtils.CompareText(AUnitName,PkgFile.Unit_Name);
4621 if Comp=0 then exit;
4622 if Comp<0 then begin
4623 Result:=Result.Left
4624 end else begin
4625 Result:=Result.Right
4626 end;
4627 end;
4628 end;
4629
FindPkgFileWithUnitNamenull4630 function TPkgUnitsTree.FindPkgFileWithUnitName(const AUnitName: string): TPkgFile;
4631 var
4632 ANode: TAVLTreeNode;
4633 begin
4634 ANode:=FindNodeWithUnitName(AUnitName);
4635 if ANode=nil then
4636 Result:=nil
4637 else
4638 Result:=TPkgFile(ANode.Data);
4639 end;
4640
4641 function ComparePkgFilesUnitname(PkgFile1, PkgFile2: Pointer): integer;
4642 begin
4643 Result := SysUtils.CompareText(
4644 TPkgFile(PkgFile1).Unit_Name,
4645 TPkgFile(PkgFile2).Unit_Name);
4646 end;
4647
4648 constructor TPkgUnitsTree.Create(ThePackage: TLazPackage);
4649 begin
4650 fLazPackage:=ThePackage;
4651 inherited Create(@ComparePkgFilesUnitname);
4652 end;
4653
4654 initialization
4655 RegisterIDEOptionsGroup(GroupPackage, TPackageIDEOptions);
4656 RegisterIDEOptionsGroup(GroupPkgCompiler, TPkgCompilerOptions);
4657 PackageDependencies:=TAVLTree.Create(@ComparePkgDependencyNames);
4658
4659 finalization
4660 FreeThenNil(PackageDependencies);
4661
4662 end.
4663
4664