home *** CD-ROM | disk | FTP | other *** search
- unit uBuildingObject;
- interface
- uses classes, uRCBuilder, uSelectDir;
-
- type
-
- TCompileNotify = Procedure(const aSourcefile, Info : string) of object;
- TCompileStartNotify = Procedure(const aSourceFile, aDestFile, aErrMsg : string) of object;
- TCompileEndNotify = Procedure(const aSourceFile, aDestFile, aErrMsg : string; aSuccess : boolean; alines, ahints, awarnings, aerrors, afatal : integer) of object;
- TProjectNotify = Procedure(const aProjectName : string; aOK, aErr, alines, ahints, awarnings, aerrors, afatal : integer) of object;
- TCompileTypeEnum = (ctRC, ctDPR, ctDLL, ctDPK);
-
- TCompileClass = class(tobject)
- private
- fResourceHandler : TResourceHandler;
- fCompileType : TCompileTypeEnum;
- fOptions : string;
- fProjectDir : string;
- fInFile, fOutFile, ferrMsg, fcmdline : string;
- fsuccess : boolean;
- fLines, fHints, fWarn, fErr, fFatal : integer;
- fEndTime: TdateTime;
- fStartTime: TdateTime;
- fResults: tstringlist;
- fSummary: tstringlist;
- fConfigFile : tstringlist;
- fDPKOptions : tstringlist;
- fDPKItself : tstringlist;
- fOnCompile : TcompileNotify;
- fSourceFullFileName: string;
- fDestinationFullFileName: string;
- fMS: word;
- fSeconds: word;
- fMinutes: word;
- fhours: word;
- fOnIconfileNotFound: TResourceHandlerMissingFileNotify;
- procedure MassageResults(var alist : tstringlist);
- // strip out lines in which we find a digit followed by a paranthesis 'n)' at the end of the line
- procedure ProcessResults;
- Procedure ProcessDPKOptions(DPKFile : string);
- protected
- Procedure DoCompileNotify(const info : string);
- public
- destructor destroy; override;
- Function Execute : boolean;
- Property Options : string read fOptions write fOptions;
- Property InFile : string read fInfile write fInFile;
- Property OutFile : string read fOutfile write fOutfile;
- Property ErrMsg : string read fErrMsg write fErrMsg;
- Property Success : boolean read fSuccess write fSuccess;
- Property Lines : integer read fLines write fLines;
- Property Hints : integer read fHints write fHints;
- Property Warnings : integer read fWarn write fWarn;
- Property Errors : integer read fErr write fErr;
- Property Fatals : integer read fFatal write fFatal;
- Property ConfigFile : tstringlist read fConfigFile write fConfigFile;
- Property DPKOptions : tstringlist read fDPKOptions write fDPKOptions;
- Property Results : tstringlist read fResults write fResults;
- Property Summary : tstringlist read fSummary write fSummary;
- Property StartTime : TdateTime read fStartTime write fStartTime;
- Property EndTime : TdateTime read fEndTime write fEndTime;
- Property Hours : word read fhours write fhours;
- Property Minutes : word read fMinutes write fMinutes;
- Property Seconds : word read fSeconds write fSeconds;
- Property MilleSeconds : word read fMS write fMS;
- Property CompileType : TCompileTypeEnum read fCompileType write fCompileType;
- Property ProjectDir : string read fProjectDir write fProjectDir;
- Property SourceFullFileName : string read fSourceFullFileName write fSourceFullFileName;
- Property DestinationFullFileName : string read fDestinationFullFileName write fDestinationFullFileName;
- Property OnCompile : TCompileNotify read fOnCompile write fOnCompile;
- Property ResourceHandler : TResourceHandler read fResourceHandler write fResourceHandler;
- Property OnIconFileNotFound : TResourceHandlerMissingFileNotify read fOnIconfileNotFound write fOnIconfileNotfound;
- end;
-
- TBuilderClass = class(Tcomponent)
- private
- fHaltNow : boolean;
- fCompiler : TCompileClass;
- fResourceHandler : TResourceHandler;
- fProjectDir: string;
- fProjectName: string;
- fConfigFile: tstringlist;
- fConfigWithPath : tstringlist;
- fLibraryFile: tstringlist;
- fProjectList: tstringlist;
- fOnCompileEnd: TCompileEndNotify;
- fOnCompileStart: TCompileStartNotify;
- fOnCompileEvent: TCompileNotify;
- fOnProjectDone: TProjectNotify;
- fOnProjectStart: TCompileNotify;
- fProjectResults: tstringlist;
- fProjectSummary: tstringlist;
- fCompileEventStash : tstringlist;
- fOnProjectHalt: TCompileNotify;
- fFatal: integer;
- fHints: integer;
- fLines: integer;
- fWarn: integer;
- fErr: integer;
- fOKs: integer;
- fErrs: integer;
- fProjectStart : tdatetime;
- fIncrementBuild: boolean;
- fAutoIncrement: boolean;
- fIncrementComment: boolean;
- fNotAlreadyIncremented : boolean;
- fCheckVersion : boolean;
- fMinimize: boolean;
- fVerInfoInVerFile : boolean;
- FHaltOnError : boolean;
- fDPKOptions: tstringlist;
- Function SetUpProject: boolean;
- procedure PrepareLibPath(var libPathList: tstringlist);
- function computeprojecttime: string;
- Procedure PrepareResourceFile(const aSourcePath : string);
- procedure setAutoIncrement(const Value: boolean);
- procedure setIncrementBuild(const Value: boolean);
- procedure SaveResourceFile(const aSourcePath: string);
- function DetermineCompileType: TCompileTypeEnum;
- // make sure the libpath is less than 1024, or make it into multiple lines, each of which shorter than 1024
- protected
- Procedure doCompileEnd;
- Procedure doCompileStart;
- Procedure HandleCompileEvent(const aSourcefile, Info : string);
- Procedure DoProjectDone;
- Procedure DoProjectHalt(const info : string);
- Procedure HandleResourceHandlerError(const filename, info : string);
- Procedure DoAutoIncrement(const aSourcePath : string);
-
-
- public
- constructor create(aOwner : tcomponent); override;
- destructor destroy; override;
- function execute : boolean;
- Function InitializeProject(const aProjectDir : string): boolean;
- function SaveProjectSettings: boolean;
- function IsIndependentRCFile(filename: string): boolean;
-
- Property ProjectList : tstringlist read fProjectList write fProjectList;
- Property LibraryFile : tstringlist read fLibraryFile write fLibraryFile;
- Property ConfigFile : tstringlist read fConfigFile write fconfigFile;
- Property DPKOptions : tstringlist read fDPKOptions write fDPKOptions;
- Property ProjectResults : tstringlist read fProjectResults write fProjectResults;
- Property ProjectSummary : tstringlist read fProjectSummary write fProjectSummary;
- Property Lines : integer read fLines write fLines;
- Property Hints : integer read fHints write fHints;
- Property Warnings : integer read fWarn write fWarn;
- Property Errors : integer read fErr write fErr;
- Property Fatals : integer read fFatal write fFatal;
- Property OKs : integer read fOKs write fOKs;
- Property Errs : integer read fErrs write fErrs;
- Property HaltNow : boolean read fHaltNow write fHaltNow;
-
- published
- Property ProjectName : string read fProjectName write fProjectName;
- Property ProjectDir : string read fProjectDir write fProjectDir;
- Property ResourceHandler : TResourceHandler read fResourceHandler write fResourceHandler;
- Property IncrementComment : boolean read fIncrementComment write fIncrementComment;
- Property AutoIncrement : boolean read fAutoIncrement write setAutoIncrement;
- Property MinimizeOnBuild : boolean read fMinimize write fMinimize;
- Property CheckVersion : boolean read fCheckVersion write fCheckVersion;
- Property ActualVerInfoInVerFile : boolean read fVerInfoInVerFile write fVerInfoInVerFile;
- Property HaltOnError : boolean read FHaltOnError write FHaltOnError;
-
- Property OnCompileEvent : TCompileNotify read fOnCompileEvent write fOnCompileEvent;
- Property OnCompileStart : TCompileStartNotify read fOnCompileStart write fOnCompileStart;
- Property OnCompileEnd : TCompileEndNotify read fOnCompileEnd write fOnCompileEnd;
- Property OnProjectStart : TCompileNotify read fOnProjectStart write fOnProjectStart;
- Property OnProjectDone : TProjectNotify read fOnProjectDone write fOnProjectDone;
- Property OnProjectHalt : TCompileNotify read fOnProjectHalt write fOnProjectHalt;
- end;
-
- const
- cDPR = 'DPR';
- cTotDump = 'Dump.dat';
- cProjectList = 'Files.ini';
- cConfig = 'Base.cfg';
- cLibraryPath = 'Library.Path';
- cResourceMask = 'Resource.mask';
- cversion='version';
- cOptions='options';
- cDPKOptions='DPKOptions';
- cAutoIncrement='AutoIncrement';
- cIncrementComment='IncrementComment';
- cCheckVersion='CheckVersion';
- cMinimize='MinimizeOnBuild';
- cVerInfoInVerFile='PutActualVerInfoInVerFile';
- cHaltOnError='HaltOnError';
-
-
- //DONE: make sure events firing only when needed
- //DONE: test project and file versioning so that file versions used only when project version is defaulted.
- //DONE: Project version overrides blanks in file version stuff
- //TODO -cBuilder object: add DLL processing
- //todo -cBuilder object: add DPK processing
-
-
- implementation
- uses Windows, Inifiles, FileCtrl, sysutils, forms, DOSToMemo, fincrement;//, uVersionInformation;
-
- { TCompileClass }
-
- destructor TCompileClass.destroy;
- begin
- fResults.free;
- fSummary.free;
- fConfigFile.free;
- fDPKOptions.free;
- fDPKItself.free;
- inherited;
- end;
-
- procedure TCompileClass.DoCompileNotify(const info: string);
- begin
- fResults.add('Compile Notify: '+info);
- if assigned(fOnCompile)
- then fOnCompile(fSourceFullFileName, info);
- end;
-
- Function TCompileClass.Execute : boolean;
- var tmp : string;
- begin
- result := true;
- fResults.clear;
- fSummary.clear;
- Lines := 0;
- Hints := 0;
- Warnings := 0;
- Errors := 0;
- Fatals := 0;
- try
- chdir(fProjectDir);
- except
- on e:exception do begin
- tmp := 'chdir to project path, '+fProjectDir+ ' failed: '+e.message;
- DoCompileNotify(tmp);
- result := false;
- exit;
- end;
- end;
- ForceDirectories(ExtractFilePath(fDestinationFullFileName));
- try
- chdir(extractFilePath(fSourceFullFileName));
- except
- on e:exception do begin
- tmp := 'chdir to '+fSourceFullFileName+'failed: '#13#10+e.message;
- DoCompileNotify(tmp);
- result := false;
- exit;
- end;
- end;
- //todo: set up stuff for dll, dpk processing
- //todo: handle non-version information type .res files
- if fCompileType in [ctDPR, ctDPK]
- then try
- tmp := changeFileExt(fSourceFullFileName, '.cfg');
- fConfigFile.saveToFile(tmp);
- tmp := changeFileExt(fSourceFullFileName, '.res');
- if not fileExists(tmp)
- then begin
- tmp := 'RES file missing: '+tmp;
- fSummary.add(tmp);
- DoCompileNotify(tmp);
- //exit;
- end;
- if fCompileType = ctDPK
- then begin
- tmp := changeFileExt(fSourceFullFileName, '.dpk');
- fDPKItself.loadFromFile(tmp);
- ProcessDPKOptions(tmp);
- end;
- except
- on e:exception do begin
- tmp := 'Failed to replace '+tmp+' '+e.message;
- fsummary.add(tmp);
- DoCompileNotify(tmp);
- end;
- end;
- tmp := ExtractFileName(fSourceFullFileName);
- case fCompileType of
- ctRC : fcmdline := 'BRCC32.exe -v -fo'+ChangeFileExt(tmp, '.RES')+' '+tmp;
- ctDPR : fcmdline := 'DCC32.exe '+ExtractFileName(fSourceFullFileName) + ' -E'+ExtractShortPathName(ExtractFilePath(fDestinationFullFileName));//+'"' ;
- ctDPK : fcmdline := 'DCC32.exe '+ExtractFileName(fSourceFullFileName) + ' -E'+ExtractShortPathName(ExtractFilePath(fDestinationFullFileName));//+'"' ;
- end;
- fStartTime := Now;
- fSuccess := CreateDOSProcessRedirected(fcmdline, finfile, foutfile, ferrmsg);
- ProcessResults;
- fEndTime := Now;
- DecodeTime(fEndTime - fstartTime, fHours, fMinutes, fSeconds, fMS);
- tmp := ' Time: '+ Format('%.2f seconds', [fms / 1000.0 + fSeconds + 60 * (fMinutes + fHours * 60)]);
- fResults.add(tmp);
- //fSummary.add(' ');
- //fResults.add(tmp);
- fResults.add('Done: '+ ExtractFileName(fSourceFullFileName));
- chDir(fProjectDir);
- end;
-
- procedure TCompileClass.ProcessResults;
- var i : integer;
- tmp : string;
- begin
- fResults.LoadFromFile(foutfile);
- ferrmsg := fresults[fresults.count-1];
- if Not fSuccess
- then fresults.insert(0, format('xxxxx>'#13#10'DCC Failed to load: '+fcmdline+ ' Error Code %d', [GetLastError])+': ' +ferrmsg)
- else begin
- fresults.insert(0, fcmdline);
- case fCompileType of
- ctDPR, ctDPK : if pos(' lines, ', ferrmsg) > 0
- then begin
- flines := StrtoInt(trim(copy(ferrmsg, 1, pos(' lines', ferrmsg))));
- //ferrmsg := 'OK '+ExtractFileName(fDestinationFullFileName)+': '+ferrmsg;
- fSuccess := true;
- end
- else begin
- if (pos('Error: ', ferrmsg) = 1)
- and
- (pos('RES', ferrmsg) <> 0)
- then fSuccess := true // compiled without version information or icon
- else fSuccess := false;
- //ferrmsg := 'ERR '+ferrmsg;
- end;
- ctRC : if pos('New File:', ferrmsg) > 0
- then begin
- flines := 1; //StrtoInt(trim(copy(errmsg, 1, pos(' lines', errmsg))));
- //ferrmsg := 'OK resource file built: '+ExtractFileName(fDestinationFullFileName);
- fSuccess := true;
- end
- else begin
- //ferrmsg := 'ERR failed to build '+ExtractFileName(fDestinationFullFileName)+' '+ferrmsg;
- fSuccess := false;
- end;
- end; // case
- //fSummary.add(' '+fErrMsg);
- MassageResults(fresults);
- fresults.add(fErrMsg);
- for i := 0 to fResults.count-1 do begin
- if pos('Hint:', fResults[i]) > 0
- then inc(fHints);
- if pos('Warning:', fResults[i]) > 0
- then inc(fWarn);
- if pos('Error:', fResults[i]) > 0
- then inc(fErr);
- if pos('Fatal:', fResults[i]) > 0
- then inc(fFatal);
- end;
- tmp := 'Lines: '+IntToStr(flines)+ ', Hints: '+IntToStr(Hints)+ ', Warnings: '+IntToStr(fWarn)+', Errors: '+IntToStr(fErr)+', Fatal: '+IntToStr(fFatal);
- if fSuccess
- then tmp := 'OK: '+ExtractFileName(fDestinationFullFileName)+' '+tmp
- else tmp := 'ERR: '+ExtractFileName(fDestinationFullFileName)+' '+ferrmsg+' '+tmp;
- fsummary.add(tmp);
- //fResults.add(tmp);
- //DoCompileNotify(fErrMsg+#13#10+tmp);
- end;
-
- // fResults.insert(0,' ');
- // fResults.insert(0,' ');
- end;
-
-
- procedure TCompileClass.MassageResults(var alist : tstringlist);
- var i : integer;
- tmp : string;
- begin
- if fCompileType = ctRC
- then begin
- for i := alist.count-1 downto 0 do begin
- if (pos('Lines:', alist[i]) = 1) or (pos('New File:', alist[i]) = 1)
- then alist.delete(i);
- end;
- end
- else begin
- for i := alist.count-1 downto 0 do begin
- tmp := trim(alist[i]);
- if tmp = ''
- then alist.delete(i)
- else begin
- system.delete(tmp, 1, length(tmp)-2);
- if tmp[2] = ')'
- then if tmp[1] in ['1','2','3','4','5','6','7','8','9','0']
- then alist.delete(i);
- end;
- end;
- end;
- end;
-
-
-
-
-
- procedure TCompileClass.ProcessDPKOptions(DPKFile: string);
- begin
- // replace options found in fDPKItself with those found in fDPKOptions, then save .dpk
-
- end;
-
- { TBuilderClass }
-
- constructor TBuilderClass.create(aOwner: tcomponent);
- begin
- inherited;
- fResourceHandler := TResourceHandler.create(self);
- fResourceHandler.OnResourceError := HandleResourceHandlerError;
- fCompiler := TCompileClass.create;
- with fCompiler do begin
- Results:= tstringlist.create;
- Summary:= tstringlist.create;
- configFile := tstringlist.create;
- fDPKOptions := tstringlist.create;
- fDPKItself := tstringlist.create;
- end;
- fCompiler.ResourceHandler := fResourceHandler;
- fProjectResults := tstringlist.create;
- fProjectSummary := tstringlist.create;
- fCompileEventStash := tstringlist.create;
- fProjectList := tstringlist.create;
- fConfigFile := tstringlist.create;
- fConfigWithPath := tstringlist.create;
- fLibraryFile := tstringlist.create;
- end;
-
- destructor TBuilderClass.destroy;
- begin
- fCompiler.free;
- fResourceHandler.free;
- fProjectResults.free;
- fProjectSummary.free;
- fCompileEventStash.free;
- fProjectList.free;
- fConfigFile.free;
- fConfigWithPath.free;
- fLibraryFile.free;
- inherited;
- end;
-
-
- procedure TBuilderClass.doCompileEnd;
- begin
- if assigned(fOnCompileEnd)
- then fOnCompileEnd(fCompiler.SourceFullFileName, fCompiler.DestinationFullFileName, fCompiler.ErrMsg, fCompiler.success,
- fCompiler.lines, fCompiler.hints, fCompiler.Warnings, fCompiler.Errors, fCompiler.Fatals);
- if not fCompiler.success
- then DoProjectHalt(fCompiler.errMsg);
- end;
-
- procedure TBuilderClass.HandleCompileEvent(const aSourcefile, Info: string);
- var tmp : string;
- begin
- tmp := aSourceFile;
- if trim(aSourceFile) = ''
- then tmp := ExtractFileName(fCompiler.SourceFullFileName);
- if assigned(fOnCompileEvent)
- then fOnCompileEvent(tmp, Info);
- fCompileEventStash.add('Compile Event '+tmp+' '+info);
- end;
-
- procedure TBuilderClass.doCompileStart;
- begin
- if assigned(fOnCompileStart)
- then fOnCompileStart(fCompiler.SourceFullFileName, fCompiler.DestinationFullFileName, fCompiler.ErrMsg);
- ProjectResults.add(#13#10+'Start: '+fCompiler.SourceFullFileName +#13#10+' --> '+fCompiler.DestinationFullFileName+#13#10+' --> '+fCompiler.ErrMsg);
- end;
-
- function TBuilderClass.computeprojecttime : string;
- var fHours, fMinutes, fSeconds, fMS : word;
- begin
- DecodeTime(now - fprojectStart, fHours, fMinutes, fSeconds, fMS);
- result := ' Time: '+ Format('%.2f seconds', [fms / 1000.0 + fSeconds + 60 * (fMinutes + fHours * 60)]);
- end;
-
- procedure TBuilderClass.DoProjectDone;
- begin
- ProjectSummary.add(#13#10+'Builder done: '+ComputeProjectTime);
- ProjectSummary.add('Final result is '+IntToStr(fOKs)+' OK, '+IntToStr(fErrs)+' ERR. Lines: '+IntToStr(flines)+ ', Hints: '+IntToStr(fHints)+ ', Warnings: '+IntToStr(fWarn)+', Errors: '+IntToStr(fErr)+', Fatal: '+IntToStr(fFatal));
- if assigned(fOnProjectDone)
- then fOnProjectDone(fProjectName, fOKs, fErrs, fLines, fHints, fWarn, fErr, fFatal);
- end;
-
- procedure TBuilderClass.DoProjectHalt(const info : string);
- begin
- if Assigned(fOnProjectHalt)
- then fOnProjectHalt(fProjectName, info);
- if FHaltOnError
- then begin
- //fHaltNow := true;
- ProjectSummary.add(#13#10+'Project Halted: '+ComputeProjectTime);
- ProjectSummary.add('ProjectHalted: '+info);
- end
- else ProjectSummary.add('Project would have been halted: '+info);
- end;
-
- function TBUilderClass.IsIndependentRCFile(filename : string) : boolean;
- var i,numoccur : integer;
- LookForPath : string;
- found : boolean;
- begin
- LookForPath := UpperCase(changeFileExt(filename, '.'));
- numOccur := 0;
- for i := 0 to fProjectList.count-1 do
- if LookForPath = uppercase(changeFileExt(fProjectList.values[fProjectList.names[i]], '.'))
- then inc(numOccur);
- result := NumOccur = 1;
- end;
-
- function TBUilderClass.DetermineCompileType : TCompileTypeEnum;
- var TmpFileName : string;
- begin
- if pos('.RC', UpperCase(fCompiler.SourceFullFileName)) <> 0
- then begin
- result := ctRC;
- If not IsIndependentRCFile(fCompiler.SourceFullFileName)
- then begin
- TmpFileName := ChangefileExt(fCompiler.SourceFullFileName, '.VER');
- PrepareResourceFile(TmpFileName);
- if fAutoIncrement
- then DoAutoIncrement(TmpFileName);
- SaveResourceFile(TmpFileName);
- end;
- end
- else result := ctDPR
- end;
-
- function TBuilderClass.execute: boolean;
- var i : integer;
- tmp : string;
- begin
- result := true;
- try
- fHaltNow := false;
- fNotAlreadyIncremented := true;
- fProjectResults.clear;
- fProjectSummary.clear;
- tmp := 'Build defined in '+fprojectDir + ' started '+FormatDateTime('ddd, dd mmm yyyy hh:nn:ss', now)+#13#10;
- fProjectStart := now;
- fProjectSummary.add(tmp);
- if assigned(fOnProjectStart)
- then fOnProjectStart(tmp, '');
- FProjectSummary.SaveToFile('started.dat');
- fCompiler.InFile := SlashSep(fProjectDir,'started.dat');
- fCompiler.Outfile := SlashSep(fProjectDir, cTotDump);
- fCompiler.ProjectDir := fProjectDir;
- fCompiler.OnCompile := HandleCompileEvent;
- fCompiler.configfile.assign(fConfigWithPath);
- flines := 0;
- fHints := 0;
- fWarn := 0;
- fErr := 0;
- fFatal := 0;
- fOKs := 0;
- fErrs := 0;
- for i := 0 to fProjectList.count-1 do begin
- if fHaltNow then break;
- fCompileEventStash.clear;
- fCompiler.DestinationFullFileName := fProjectList.names[i];
- fCompiler.SourceFullFileName := fProjectList.values[fProjectList.names[i]];
- fCompiler.compileType := DetermineCompileType;
- fCompiler.ErrMsg := 'Compile started '+FormatDateTime('ddd, dd mmm yyyy hh:nn:ss', now);
- doCompileStart;
- if fCompiler.Execute
- then begin
- if fCompiler.Success
- then begin
- Inc(fOKs);
- if fCompiler.compiletype in [ctDPR, ctDLL, ctDPK]
- then begin
- fResourceHandler.ClearSettings;
- fResourceHandler.GetVersionInfoFromProgram(fCompiler.DestinationFullFileName);
- fCompiler.Summary.add(fResourceHandler.VersionSummary);
- fCompiler.Summary.add(' ');
- if fCheckVersion
- then begin
- fResourceHandler.ClearSettings;
- fResourceHandler.GetVersionInfoFromProgram(fCompiler.DestinationFullFileName);
- fCompiler.Results.add(fResourceHandler.DisplayRCData(' from '+fCompiler.DestinationFullFileName));
- end;
- end;
- end
- else Inc(fErrs);
- fLines := fLines+fCompiler.Lines;
- fWarn := fWarn+fCompiler.Warnings;
- fHints :=fHints+fCompiler.Hints;
- fErr := fErr+fCompiler.Errors;
- fFatal := fFatal+fCompiler.Fatals;
- end
- else begin
- Inc(fErrs);
- end;
- DoCompileEnd; // IntToStr(OKs)+' OK, '+IntToStr(Errs)+' ERR. Lines: '+IntToStr(Totlines)+ ', Hints: '+IntToStr(TotHints)+ ', Warnings: '+IntToStr(TotWarn)+', Errors: '+IntToStr(TotErr)+', Fatal: '+IntToStr(TotFat);
- ProjectResults.addStrings(fCompiler.Results);
- ProjectResults.addStrings(fCompileEventStash);
- ProjectSummary.addStrings(fCompiler.Summary);
- end;
- DoProjectDone;
- ProjectResults.insert(0, ProjectSummary.text);
- ProjectResults.savetofile(cTotDump);
- except
- on e:exception do begin
- DoProjectHalt('Exception thrown in Builder: '+e.message);
- result := false;
- end;
- end;
-
- end;
-
-
-
- procedure TBuilderClass.PrepareLibPath(var libPathList : tstringlist);
- // make sure the libpath is less than 1024, or make it into multiple lines, each of which shorter than 1024
- var i : integer;
- tmp, workChunk : string;
- begin
- tmp := stringREplace(libPathList.text, #13#10, ';', [rfReplaceAll]);
- If length(tmp) < 1023
- then begin
- libPathList.clear;
- libPathList.add('-U"'+tmp+'"');
- libPathList.add('-I"'+tmp+'"');
- libPathList.add('-R"'+tmp+'"');
- libPathList.add('-O"'+tmp+'"');
- end
- else begin
- libPathList.clear;
- while tmp <> '' do begin
- workChunk := copy(tmp, 1, 1000);
- for i := length(workCHunk) downto 1 do
- if workChunk[i] = ';'
- then begin
- workChunk := copy(tmp, 1, i-1);
- tmp := copy(tmp, i+1, 20000);
- break;
- end;
- if trim(tmp) = ';' then tmp := '';
- libPathList.add('-U"'+WorkChunk+'"');
- libPathList.add('-I"'+WorkChunk+'"');
- libPathList.add('-R"'+WorkChunk+'"');
- libPathList.add('-O"'+WorkChunk+'"');
- end;
- end;
- end;
-
-
-
- Function TBuilderClass.SetUpProject: boolean;
- var tmpsl : tstringlist;
- begin
- result := true;
- tmpsl := tstringlist.create;
- try
- try
- chdir(fProjectDir);
- except
- on e:exception do begin
- DoProjectHalt('chdir to project path, '+fProjectDir+ ' failed: '+#13#10+e.message);
- DoProjectDone;
- result := false;
- end;
- end;
- if fileexists(cLibraryPath)
- then fLibraryFile.loadfromfile(cLibrarypath)
- else begin
- Try
- tmpsl.LoadFromFile(slashSep(extractFilePath(application.exename), 'Default.path'));
- tmpsl.SaveToFile(SlashSep(fProjectDir, cLibraryPath));
- fLibraryFile.assign(tmpsl);
- except
- DoProjectHalt('Could not create '+cLibraryPath);
- result := false;
- end;
- end;
- if fileexists(cResourceMask)
- then fResourceHandler.Mask.loadfromfile(cResourceMask)
- else begin
- Try
- tmpsl.LoadFromFile(slashSep(extractFilePath(application.exename), 'Default.mask'));
- tmpsl.SaveToFile(SlashSep(fProjectDir, cResourceMask));
- fResourceHandler.Mask.assign(tmpsl);
- except
- DoProjectHalt('Could not create '+cResourceMask);
- result := false;
- end;
- end;
- if fileexists(cConfig)
- then fConfigFile.loadfromfile(cConfig)
- else begin
- try
- tmpsl.LoadFromFile(slashSep(extractFilePath(application.exename), 'Default.config'));
- tmpsl.SaveToFile(SlashSep(fProjectDir, cConfig));
- fConfigFile.assign(tmpsl);
- except
- DoProjectHalt('Could not create '+cConfig);
- result := false;
- end;
- end;
- fConfigWithPath.assign(fConfigFile);
- tmpsl.assign(fLibraryFile);
- PrepareLibPath(tmpsl);
- fConfigWithPath.addstrings(tmpsl);
- fProjectList.clear;
- if not FileExists(cProjectList)
- then begin
- try
- tmpsl.LoadFromFile(slashSep(extractFilePath(application.exename), 'Default.Files'));
- tmpsl.SaveToFile(SlashSep(fProjectDir, cProjectList));
- except
- DoProjectHalt('Could not create '+cProjectList);
- result := false;
- end;
- end;
- if FileExists(cProjectList)
- then with tinifile.create(SlashSep(fprojectdir,cProjectList)) do begin
- readSectionValues(cDPR, fProjectList);
- fAutoIncrement := readBool(cOptions, cAutoIncrement, false);
- fIncrementComment := ReadBool(cOptions, cIncrementComment, false);
- fMinimize := readBool(cOptions, cMinimize, false);
- fCheckVersion := ReadBool(cOptions, cCheckVersion, false);
- fVerInfoInVerFile := readbool(cOptions, cVerInfoInVerFile, false);
- FHaltOnError := readbool(cOptions, cHaltOnError, false);
- UpdateFile;
- free;
- end;
- finally
- tmpsl.free;
- end;
- end;
-
- Function TBuilderClass.InitializeProject(const aProjectDir : string): boolean;
- begin
- result := true;
- fProjectDir := aProjectdir;
- try
- result := ForceDirectories(fProjectDir);
- chdir(fProjectDir);
- except
- on e:exception do begin
- DoProjectHalt('chdir to project path, '+fProjectDir+ ' failed: '+e.message);
- DoProjectDone;
- result := false;
- exit;
- end;
- end;
- SetUpProject;
- end;
-
-
- function TBuilderClass.SaveProjectSettings: boolean;
- var i : integer;
- begin
- result := true;
- try
- chdir(fProjectDir);
- except
- on e:exception do begin
- DoProjectHalt('chdir to project path, '+fProjectDir+ ' failed: '+e.message);
- DoProjectDone;
- result := false;
- exit;
- end;
- end;
- fLibraryFile.SaveToFile(cLibrarypath);
- fConfigFile.SaveToFile(cConfig);
- with tinifile.create(SlashSep(fprojectdir,cProjectList)) do begin
- EraseSection(cDPR);
- for i := 0 to fProjectlist.count-1 do
- writestring(cDPR, fProjectList.names[i], fProjectList.values[fProjectList.names[i]]);
- writebool(cOptions, cAutoIncrement, fAutoIncrement);
- writebool(cOptions, cIncrementComment, fIncrementComment);
- writebool(cOptions, cCheckVersion, fCheckVersion);
- writebool(cOptions, cMinimize, fMinimize);
- writebool(cOptions, cVerInfoInVerFile, fVerInfoInVerFile);
- writebool(cOptions, cHaltOnError, FHaltOnError);
- UpdateFile;
- free;
- end;
- end;
-
-
- procedure TBuilderClass.HandleResourceHandlerError(const filename, info: string);
- begin
- HandleCompileEvent('Resource Error: for '+filename, info);
- if not fResourceHandler.Success
- then DoProjectHalt('Resource Error for '+filename + ': ' + info);
- end;
-
- procedure TBuilderClass.setAutoIncrement(const Value: boolean);
- begin
- fAutoIncrement := Value;
- end;
-
- procedure TBuilderClass.setIncrementBuild(const Value: boolean);
- begin
- fIncrementBuild := Value;
- end;
-
- procedure TBuilderClass.PrepareResourceFile(const aSourcePath : string);
- begin
- fResourceHandler.PrepareResourceData(aSourcePath, SlashSep(fprojectdir,cProjectList))
- end;
-
- Procedure TBuilderClass.SaveResourceFile(const aSourcePath : string);
- begin
- if fVerInfoInVerFile
- then fResourceHandler.SaveSettings(aSourcePath, 'LastCompiledWith');
- fREsourceHandler.RCMaskFileName := SlashSep(fprojectdir,cResourceMask);
- fResourceHandler.RCfileName := ChangeFileExt(aSourcePath, '.RC');
- fResourceHandler.WriteRCFile;
- end;
-
-
- procedure TBuilderClass.DoAutoIncrement(const aSourcePath : string);
- var locFileBuild, locProductBuild : integer;
- locComment : string;
- begin
- locFileBuild := StrToInt(FResourceHandler.VersionInfo[reBuild]);
- locProductBuild := StrtoInt(FResourceHandler.VersionInfo[reProductBuild]);
- locComment := FresourceHandler.VersionInfo[reComments];
- If fIncrementComment
- then begin
- SetIncrement(locFilebuild, locProductBuild, locComment);
- end
- else begin
- inc(LocFileBuild);
- inc(locProductBuild);
- end;
- fResourceHandler.VersionInfo[rebuild] := IntToStr(locFileBuild);
- fResourceHandler.VersionInfo[reProductbuild] := IntToStr(locProductBuild);
- //todo -cBuilderObject: If no changes in files.ini or *.ver, do not save
-
- If fNotAlreadyIncremented
- then with tinifile.create(SlashSep(fprojectdir,cProjectList)) do begin
- if FResourceHandler.VersionSource[reBuild] = rsProject
- then WriteString(cVersion, 'Build', fResourceHandler.VersionInfo[rebuild]);
- if FResourceHandler.VersionSource[reProductBuild] = rsProject
- then WriteString(cVersion, 'ProductBuild', fResourceHandler.VersionInfo[reProductBuild]);
- if fIncrementComment and (FResourceHandler.VersionSource[reComments] = rsProject)
- then WriteString(cVersion, 'Comments', fResourceHandler.VersionInfo[reComments]);
- UpdateFile;
- free;
- fNotAlreadyIncremented := false;
- end;
- try
- with tinifile.create(aSourcePath) do begin
- if FResourceHandler.VersionSource[reBuild] = rsFile
- then WriteString(cVersion, 'Build', fResourceHandler.VersionInfo[rebuild]);
- if FResourceHandler.VersionSource[reProductBuild] = rsFile
- then WriteString(cVersion, 'ProductBuild', fResourceHandler.VersionInfo[reProductBuild]);
- if fIncrementComment and (FResourceHandler.VersionSource[reComments] = rsFile)
- then WriteString(cVersion, 'Comments', fResourceHandler.VersionInfo[reComments]);
- UpdateFile;
- free;
- end;
- PrepareResourceFile(aSourcePath);
- except
- on e:exception do begin
- fResourceHandler.DoFileError(asourcePath, 'Could not save: '+e.message);
- end;
- end;
- end;
-
- end.
-
- (*
-
- begin
- try
- fHaltNow := false;
- st := now;
- bb_halt.enabled := true;
- // in file not really needed, but easier to specify something rather than rewrite the supporting function.
- InFile := extractFilePath(application.exename)+'builder.ini';
- // keep the dump file in the project directory
- Outfile := SlashSep(fProjectDir, cTotDump);
- tmpsl := tstringlist.create;
- configFile := tstringlist.create;
- PathFile := tstringlist.create;
- results := tstringlist.create;
- summary := tstringlist.create;
- summary.add('Build started '+FormatDateTime('ddd, dd mmm yyyy hh:nn:ss', now)+#13#10);
- lb_exe.itemindex := 0;
- A_saveProjectExecute(Sender);
- chdir(fProjectdir);
- PathFile.loadfromfile('Library.path');
- PrepareLibPath(Pathfile);
- ConfigFile.loadfromfile('Base.cfg');
- ConfigFile.addstrings(PathFile);
- subLines := 0;
- totlines := 0;
- subHints := 0;
- totHints := 0;
- subWarn := 0;
- totWarn := 0;
- subErr := 0;
- totErr := 0;
- subFat := 0;
- totFat := 0;
- OKs := 0;
- Errs := 0;
- lb_result.items.clear;
- lb_result.color := clWhite;
- A_viewCompilerOptionsHelp.Checked := false;
- l_progress.caption := 'Starting project '+fprojectdir;
- LB_exe.itemindex := 0;
- for i := 0 to fexeList.count-1 do begin
- if fHaltNow then break;
- subLines := 0;
- subHints := 0;
- subWarn := 0;
- subErr := 0;
- subFat := 0;
- LB_exeClick(sender);
- ForceDirectories(ExtractFilePath(m_destination.text));
- try
- chdir(extractFilePath(m_source.text));
- except
- on e:exception do begin
- tmp := 'chdir to '+m_source.text+'failed: '#13#10+e.message;
- showmessage(tmp);
- summary.add(tmp);
- end;
- end;
- //todo: set up stuff for dpk processing
- //todo: test rc stuff
-
- tmp := changeFileExt(lb_exe.items[i], '.cfg');
- try
- ConfigFile.saveToFile(tmp);
- except
- on e:exception do begin
- tmp := 'Failed to replace '+tmp+' '+e.message;
- summary.add(tmp);
- showmessage(tmp);
- end;
- end;
- tmp := ExtractFileName(m_source.text);
- if pos('.RC', uppercase(tmp)) > 0
- then cmdline := 'BRCC32.exe -v -f'+m_destination.text+' '+tmp
- else cmdline := 'DCC32.exe '+ExtractFileName(m_source.text) + ' -E'+ExtractFilePath(m_destination.text) ;
- l_progress.caption := 'compiling '+ ExtractFileName(m_source.text);
- Application.processMessages;
- success := CreateDOSProcessRedirected(cmdline, infile, outfile, errmsg);
- lb_result.items.LoadFromFile(outfile);
- if Not Success
- then lb_result.items.insert(0, format('xxxxx>'#13#10'DCC Failed to load: '+cmdline+ #13#10' Error Code %d', [GetLastError])+#13#10+errmsg)
- else begin
- lb_result.items.insert(0, 'DCC started: '+cmdline);
- lb_result.items.insert(0, '=====>');
- errmsg := lb_result.items[lb_result.items.count-1];
- if pos(' lines, ', errmsg) > 0
- then begin
- totlines := totlines + StrtoInt(trim(copy(errmsg, 1, pos(' lines', errmsg))));
- errmsg := 'OK '+lb_exe.items[i]+': '+errmsg;
- Inc(Oks);
- {MOHAboutDialog1.Filename :=m_destination.text;
- MOHAboutDialog1.refresh;
- for j := 0 to MOHAboutDialog1.versionDetails.count-1 do
- lb_result.items.add(MOHAboutDialog1.VersionDetails[j]);
- }
- end
- else begin
- errmsg := 'ERR '+errmsg;
- inc(errs);
- end;
- tmpsl.assign(lb_result.items);
- MassageResults(tmpsl);
- lb_result.items.assign(tmpsl);
- for j := 0 to tmpsl.count-1 do begin
- if pos('Hint:', tmpsl[j]) > 0
- then inc(subHints);
- if pos('Warning:', tmpsl[j]) > 0
- then inc(subWarn);
- if pos('Error:', tmpsl[j]) > 0
- then inc(subErr);
- if pos('Fatal:', tmpsl[j]) > 0
- then inc(subFat);
- end;
- TotLines := TotLines+SubLines;
- TotWarn := TotWarn+SubWarn;
- TotHints :=TotHints+SubHints;
- TotErr := TotErr+SubErr;
- TotFat := TotFat+SubFat;
- tmp := IntToStr(OKs)+' OK, '+IntToStr(Errs)+' ERR. Lines: '+IntToStr(Totlines)+ ', Hints: '+IntToStr(TotHints)+ ', Warnings: '+IntToStr(TotWarn)+', Errors: '+IntToStr(TotErr)+', Fatal: '+IntToStr(TotFat);
- StatusBar1.simpleText := tmp;
- Application.processMessages;
- lb_result.items.insert(0, tmp);
- lb_result.items.insert(0, errmsg);
- lb_result.items.insert(0, '----------------------------');
- summary.add(errmsg);
- summary.add(' '+tmp);
- summary.add(' ');
- results.addstrings(lb_result.items);
- end;
- lb_exe.itemindex := lb_exe.itemindex + 1;
- if lb_exe.itemindex = lb_exe.items.count
- then break;
- end;
- et := now;
- DecodeTime(et - st, h, m, s, ms);
- tmp := 'Final result is '+IntToStr(OKs)+' OK, '+IntToStr(Errs)+' ERR. Lines: '+IntToStr(TotLines)+ ', Hints: '+IntToStr(TotHints)+ ', Warnings: '+IntToStr(TotWarn)+', Errors: '+IntToStr(TotErr)+', Fatal: '+IntToStr(TotFat);
- summary.add(' ');
- summary.add(tmp);
- summary.add(' Time: '+ Format('%.2f', [ms / 1000.0 + s + 60 * (m + h * 60)]));
- StatusBar1.simpleText := tmp;
- summary.add(#13#10'details...');
- for i := summary.count-1 downto 0 do
- results.insert(0, summary[i]);
- // results.insert(0, summary.text);
- // MassageResults(results);
- lb_result.items.assign(results);
- chdir(fProjectdir);
- lb_result.items.savetofile(outfile);
- l_progress.caption := 'Memo saved to '+outfile;
- except
- on e:exception do begin
- results.Insert(0, 'Exception thrown: '+#13#10+e.message+#13#10);
- lb_result.items.assign(results);
- lb_result.items.saveToFile(outfile);
- end;
- end;
- bb_halt.enabled := false;
- results.Free;
- tmpsl.free;
- configFile.free;
- PathFile.free;
- summary.free;
-
-
- end.
- *)
-