123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- unit fpmakecreatefile;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils,
- fpmakeParseJSon,
- fpTemplate,
- fpmkunit;
- procedure CreateFile(AOutputFileName: string; ATemplate: TStringList; APackages: TPackages; ASkipBackup, ACreateDir: boolean);
- function TemplateParser: TTemplateParser;
- implementation
- type
- { TfpmakeTemplateParser }
- TfpmakeTemplateParser = class(TTemplateParser)
- public
- constructor Create;
- Procedure OnGetParamProc(Sender : TObject; Const TagString : String; TagParams:TStringList; Out ReplaceText : String);
- end;
- var
- GTemplateParser: TTemplateParser;
- resourcestring
- SErrDelBackupFailed = 'Error: Delete of old backup file "%s" failed.';
- SErrCreateDirFailed = 'Error: Could not create the directory for file "%s".';
- SErrNoSuchDirectory = 'Error: Directory of file "%s" does not exists. User -p to force creation.';
- SErrBackupFailed = 'Error: Backup of file "%s" to "%s" failed.';
- SBackupCreated = 'Saved old "%s" to "%s"';
- function GetConditionalAdd(const Value: string; CPUs: TCPUS; OSes: TOSes; const AddName: string): string;
- begin
- if (CPUs <> AllCPUs) and (OSes <> AllOSes) then
- result := result + ' '+AddName+'('''+Value+''','+ExtCPUsToString(CPUs)+','+ExtOSesToString(OSes)+');' + LineEnding
- else if (CPUs <> AllCPUs) then
- result := result + ' '+AddName+'('''+Value+''','+ExtCPUsToString(CPUs)+');' + LineEnding
- else if (OSes <> AllOSes) then
- result := result + ' '+AddName+'('''+Value+''','+ExtOSesToString(OSes)+');' + LineEnding
- else
- result := result + ' '+AddName+'('''+Value+''');' + LineEnding;
- end;
- function GetConditionalStringsMacro(ACondStrings: TConditionalStrings; APropName: string): string;
- var
- ADependency: TConditionalString;
- i: Integer;
- begin
- if ACondStrings.Count=0 then
- Exit;
- if ACondStrings.Count=1 then
- begin
- ADependency := ACondStrings[0];
- result := result + GetConditionalAdd(ADependency.Value, ADependency.CPUs, ADependency.OSes,APropName+'.Add');
- end
- else
- begin
- result := ' with '+APropName+' do' + LineEnding +
- ' begin'+LineEnding;
- for i := 0 to ACondStrings.Count-1 do
- begin
- ADependency := ACondStrings[i];
- result := result + GetConditionalAdd(ADependency.Value, ADependency.CPUs, ADependency.OSes,' Add');
- end;
- result := result +
- ' end;' + LineEnding;
- end;
- end;
- function GetConditionalPackagePropertiesMacro(APackage: TPackage): string;
- begin
- result := '';
- if APackage.CPUs<>AllCPUs then
- result := result + ' P.CPUs := '+ExtCPUSToString(APackage.CPUs)+';'+LineEnding;
- if APackage.OSes<>AllOSes then
- result := result + ' P.OSes := '+ExtOSesToString(APackage.OSes)+';'+LineEnding;
- end;
- function GetTargetsMacro(aTargets: TTargets): string;
- var
- ATarget: TTarget;
- i: Integer;
- d: integer;
- begin
- if aTargets.Count=0 then
- Exit;
- result := ' with P.Targets do' + LineEnding +
- ' begin'+LineEnding;
- for i := 0 to aTargets.Count-1 do
- begin
- ATarget := aTargets.Items[i] as TTarget;
- result := result + GetConditionalAdd(ATarget.Name + ATarget.Extension, ATarget.CPUs, ATarget.OSes,' T := AddUnit');
- if atarget.ResourceStrings then
- result := result + ' T.Resourcestrings := True;'+LineEnding;
- for d := 0 to aTarget.Dependencies.Count-1 do
- begin
- if ATarget.Dependencies[d].DependencyType=depInclude then
- result := result + ' T.Dependencies.AddInclude('''+ATarget.Dependencies[d].Value+''');'+LineEnding
- else if ATarget.Dependencies[d].DependencyType=depUnit then
- result := result + ' T.Dependencies.AddUnit('''+ATarget.Dependencies[d].Value+''');'+LineEnding
- else
- result := result + ' T.Dependencies.Add('''+ATarget.Dependencies[d].Value+''');'+LineEnding;
- end;
- end;
- result := result +
- ' end;';
- end;
- procedure CreateFile(AOutputFileName: string; ATemplate: TStringList; APackages: TPackages; ASkipBackup, ACreateDir: boolean);
- Var
- Fout : Text;
- S,BFN : String;
- I : Integer;
- PackageNr: Integer;
- APackage: TPackage;
- begin
- If (AOutputFileName<>'')
- and FileExists(AOutputFileName)
- and not ASkipBackup then
- begin
- BFN:=ChangeFileExt(AOutputFileName,'.bak');
- If FileExists(BFN) and not DeleteFile(BFN) then
- begin
- Writeln(StdErr,Format(SErrDelBackupFailed,[BFN]));
- Halt(1);
- end;
- If not RenameFile(AOutputFileName,BFN) then
- begin
- Writeln(StdErr,Format(SErrBackupFailed,[AOutputFileName,BFN]));
- Halt(1);
- end
- else
- Writeln(Format(SBackupCreated,[ExtractFileName(AOutputFileName),ExtractFileName(BFN)]));
- end;
- if (AOutputFileName<>'') and (ExtractFilePath(AOutputFileName)<>'') and not DirectoryExists(ExtractFilePath(AOutputFileName)) then
- begin
- if ACreateDir then
- begin
- if not ForceDirectories(ExtractFilePath(AOutputFileName)) then
- begin
- Writeln(StdErr,Format(SErrCreateDirFailed,[AOutputFileName]));
- Halt(1);
- end;
- end
- else
- begin
- Writeln(StdErr,Format(SErrNoSuchDirectory,[AOutputFileName]));
- Halt(1);
- end;
- end;
- Assign(Fout,AOutputFileName);
- Rewrite(FOut);
- Try
- for PackageNr := 0 to APackages.Count-1 do
- begin
- APackage := APackages.Items[PackageNr] as TPackage;
- TemplateParser.Values['packagename'] := APackage.Name;
- TemplateParser.Values['directory'] := APackage.Directory;
- TemplateParser.Values['version'] := APackage.Version;
- TemplateParser.Values['author'] := APackage.Author;
- TemplateParser.Values['license'] := APackage.License;
- TemplateParser.Values['homepageurl'] := APackage.HomepageURL;
- TemplateParser.Values['downloadurl'] := APackage.DownloadURL;
- TemplateParser.Values['email'] := APackage.Email;
- TemplateParser.Values['description'] := APackage.Description;
- TemplateParser.Values['needlibc'] := BoolToStr(APackage.NeedLibC,'true','false');
- TemplateParser.Values['conditionalpackageproperties'] := GetConditionalPackagePropertiesMacro(APackage);
- TemplateParser.Values['packagedependencies'] := GetConditionalStringsMacro(APackage.Dependencies, 'P.Dependencies');
- TemplateParser.Values['packagesourcepaths'] := GetConditionalStringsMacro(APackage.SourcePath, 'P.SourcePath');
- TemplateParser.Values['targets'] := GetTargetsMacro(APackage.Targets);
- For I:=0 to ATemplate.Count-1 do
- begin
- S:=ATemplate[i];
- S := TemplateParser.ParseString(S);
- Writeln(FOut,S);
- end;
- end;
- Finally
- Close(Fout);
- end;
- end;
- function TemplateParser: TTemplateParser;
- begin
- if not assigned(GTemplateParser) then
- begin
- GTemplateParser := TfpmakeTemplateParser.Create;
- GTemplateParser.StartDelimiter:='%';
- GTemplateParser.EndDelimiter:='%';
- GTemplateParser.ParamStartDelimiter:='(';
- GTemplateParser.ParamEndDelimiter:=')';
- GTemplateParser.Values['PWD'] := GetCurrentDir;
- GTemplateParser.Values['BUILDDATE'] := DateToStr(Date);
- GTemplateParser.Values['BUILDTIME'] := TimeToStr(Time);
- end;
- result := GTemplateParser;
- end;
- { TfpmakeTemplateParser }
- constructor TfpmakeTemplateParser.Create;
- begin
- inherited create;
- AllowTagParams := True;
- OnReplaceTag := @OnGetParamProc;
- end;
- procedure TfpmakeTemplateParser.OnGetParamProc(Sender : TObject; Const TagString : String; TagParams:TStringList; Out ReplaceText : String);
- var
- i: Integer;
- s: string;
- begin
- if TagString = 'quotedstr' then
- begin
- i := TagParams.Count;
- ReplaceText:='';
- for i := 0 to TagParams.Count-1 do
- begin
- GetParam(TagParams[i],s);
- ReplaceText:=ReplaceText + quotedstr(s);
- end;
- end
- else
- GetParam(TagString,ReplaceText);
- end;
- initialization
- GTemplateParser := nil
- finalization
- GTemplateParser.Free;
- end.
|