mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-30 10:29:29 +02:00
codetools: c file merger: options to merge all
git-svn-id: trunk@29559 -
This commit is contained in:
parent
d4ab1e76ea
commit
4f644760d6
@ -320,6 +320,12 @@ type
|
||||
end;
|
||||
PCHFileLink = ^TCHFileLink;
|
||||
|
||||
TCHFileMergeFlag = (
|
||||
chfmfIgnoreIncludes, // do not merge at includes, but simply append
|
||||
chfmfAll // merge all files, otherwise merge only the first
|
||||
);
|
||||
TCHFileMergeFlags = set of TCHFileMergeFlag;
|
||||
|
||||
TCHeaderFileMerger = class
|
||||
private
|
||||
procedure AddLink(aMergedPos: integer; aCode: TCodeBuffer; aSrcPos: integer);
|
||||
@ -331,8 +337,10 @@ type
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure Clear;
|
||||
procedure Merge(SourceFiles: TStrings; CodeCache: TCodeCache);
|
||||
procedure Merge(SourceBuffers: TFPList { list of TCodeBuffer });
|
||||
procedure Merge(SourceFiles: TStrings; CodeCache: TCodeCache;
|
||||
const Flags: TCHFileMergeFlags);
|
||||
procedure Merge(SourceBuffers: TFPList { list of TCodeBuffer };
|
||||
const Flags: TCHFileMergeFlags);
|
||||
function MergedPosToOriginal(MergedPos: integer;
|
||||
out Code: TCodeBuffer; out CodePos: integer): boolean;
|
||||
function MergedPosToOriginal(MergedX, MergedY: integer;
|
||||
@ -471,7 +479,7 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCHeaderFileMerger.Merge(SourceFiles: TStrings;
|
||||
CodeCache: TCodeCache);
|
||||
CodeCache: TCodeCache; const Flags: TCHFileMergeFlags);
|
||||
var
|
||||
SourceBuffers: TFPList;
|
||||
i: Integer;
|
||||
@ -486,13 +494,14 @@ begin
|
||||
raise Exception.Create('TCHeaderFileCombine.Combine: ERROR loading file '+SourceFiles[i]);
|
||||
SourceBuffers.Add(Buf);
|
||||
end;
|
||||
Merge(SourceBuffers);
|
||||
Merge(SourceBuffers,Flags);
|
||||
finally
|
||||
SourceBuffers.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCHeaderFileMerger.Merge(SourceBuffers: TFPList);
|
||||
procedure TCHeaderFileMerger.Merge(SourceBuffers: TFPList;
|
||||
const Flags: TCHFileMergeFlags);
|
||||
var
|
||||
MergedBuffers: TFPList; // list of TCodeBuffer
|
||||
StrStream: TStringStream;
|
||||
@ -523,34 +532,36 @@ var
|
||||
begin
|
||||
MergedBuffers.Add(Code);
|
||||
MergePos:=1;
|
||||
for i:=0 to Code.LineCount-1 do begin
|
||||
Line:=Code.GetLine(i);
|
||||
if length(Line)<length('#include')+2 then continue;
|
||||
if copy(Line,1,length('#include'))<>'#include' then continue;
|
||||
if not (Line[length('#include')+1] in [' ',#9]) then continue;
|
||||
IncludeParam:=Trim(copy(Line,length('#include')+1,length(Line)));
|
||||
if (IncludeParam<>'') and (IncludeParam[1] in ['<','"']) then
|
||||
IncludeParam:=copy(IncludeParam,2,length(IncludeParam)-2);
|
||||
if IncludeParam<>'' then begin
|
||||
// for example: glib/gutils.h
|
||||
//debugln(['TCHeaderFileMerger.Merge Param=',IncludeParam]);
|
||||
// search file in list
|
||||
for j:=1 to SourceBuffers.Count-1 do begin
|
||||
IncCode:=TCodeBuffer(SourceBuffers[j]);
|
||||
IncFilename:=IncCode.Filename;
|
||||
if CompareFilenames(IncludeParam,
|
||||
RightStr(IncFilename,length(IncludeParam)))<>0 then continue;
|
||||
if (length(IncFilename)=length(IncludeParam))
|
||||
or (IncFilename[length(IncFilename)-length(IncludeParam)]=PathDelim)
|
||||
then begin
|
||||
// include file found
|
||||
if MergedBuffers.IndexOf(IncCode)<0 then begin
|
||||
debugln(['TCHeaderFileMerger.Merge file '+IncFilename+' into '+Code.Filename]);
|
||||
Append('/* h2pas: merged '+IncludeParam+' into '+ExtractFileName(Code.Filename)+' */'+LineEnding);
|
||||
Append(Code,MergePos,Code.GetLineStart(i));
|
||||
MergePos:=Code.GetLineStart(i+1);
|
||||
Parse(IncCode);
|
||||
Append('/* h2pas: end of merged '+IncludeParam+' into '+ExtractFileName(Code.Filename)+' */'+LineEnding);
|
||||
if not (chfmfIgnoreIncludes in Flags) then begin
|
||||
for i:=0 to Code.LineCount-1 do begin
|
||||
Line:=Code.GetLine(i);
|
||||
if length(Line)<length('#include')+2 then continue;
|
||||
if copy(Line,1,length('#include'))<>'#include' then continue;
|
||||
if not (Line[length('#include')+1] in [' ',#9]) then continue;
|
||||
IncludeParam:=Trim(copy(Line,length('#include')+1,length(Line)));
|
||||
if (IncludeParam<>'') and (IncludeParam[1] in ['<','"']) then
|
||||
IncludeParam:=copy(IncludeParam,2,length(IncludeParam)-2);
|
||||
if IncludeParam<>'' then begin
|
||||
// for example: glib/gutils.h
|
||||
//debugln(['TCHeaderFileMerger.Merge Param=',IncludeParam]);
|
||||
// search file in list
|
||||
for j:=1 to SourceBuffers.Count-1 do begin
|
||||
IncCode:=TCodeBuffer(SourceBuffers[j]);
|
||||
IncFilename:=IncCode.Filename;
|
||||
if CompareFilenames(IncludeParam,
|
||||
RightStr(IncFilename,length(IncludeParam)))<>0 then continue;
|
||||
if (length(IncFilename)=length(IncludeParam))
|
||||
or (IncFilename[length(IncFilename)-length(IncludeParam)]=PathDelim)
|
||||
then begin
|
||||
// include file found
|
||||
if MergedBuffers.IndexOf(IncCode)<0 then begin
|
||||
debugln(['TCHeaderFileMerger.Merge file '+IncFilename+' into '+Code.Filename]);
|
||||
Append('/* h2pas: merged '+IncludeParam+' into '+ExtractFileName(Code.Filename)+' */'+LineEnding);
|
||||
Append(Code,MergePos,Code.GetLineStart(i));
|
||||
MergePos:=Code.GetLineStart(i+1);
|
||||
Parse(IncCode);
|
||||
Append('/* h2pas: end of merged '+IncludeParam+' into '+ExtractFileName(Code.Filename)+' */'+LineEnding);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -561,12 +572,17 @@ var
|
||||
Append(LineEnding);
|
||||
end;
|
||||
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Clear;
|
||||
MergedBuffers:=TFPList.Create;
|
||||
StrStream:=TStringStream.Create('');
|
||||
try
|
||||
Parse(TCodeBuffer(SourceBuffers[0]));
|
||||
for i:=0 to SourceBuffers.Count-1 do begin
|
||||
Parse(TCodeBuffer(SourceBuffers[i]));
|
||||
if not (chfmfAll in Flags) then break;
|
||||
end;
|
||||
finally
|
||||
CombinedSource:=TCodeBuffer.Create;
|
||||
CombinedSource.Source:=StrStream.DataString;
|
||||
|
@ -49,14 +49,15 @@ var
|
||||
Filenames: TStringList;
|
||||
Src: String;
|
||||
Merger: TCHeaderFileMerger;
|
||||
MergeFiles: Boolean;
|
||||
MergeAll: Boolean;
|
||||
MergeFlags: TCHFileMergeFlags;
|
||||
begin
|
||||
Merger:=nil;
|
||||
try
|
||||
Tool:=TH2PasTool.Create;
|
||||
Filenames:=TStringList.Create;
|
||||
OutputFilename:=CleanAndExpandFilename(AppendPathDelim(GetCurrentDir)+'h2pasoutput.pas');
|
||||
MergeFiles:=false;
|
||||
MergeAll:=false;
|
||||
for i:=1 to Paramcount do begin
|
||||
Param:=ParamStr(i);
|
||||
if copy(Param,1,2)='-d' then
|
||||
@ -65,13 +66,15 @@ begin
|
||||
Tool.Undefines.Add(copy(Param,3,255),'')
|
||||
else if copy(Param,1,2)='-o' then
|
||||
OutputFilename:=CleanAndExpandFilename(Param)
|
||||
else if Param='--merge' then
|
||||
MergeFiles:=true
|
||||
else if Param='--merge-all' then
|
||||
MergeAll:=true
|
||||
else if copy(Param,1,1)='-' then begin
|
||||
writeln('Usage: ',ParamStr(0),' [--merge] [-d<definesymbol>]... [-u<undefinesymbol>]... <main header filename> <sub header file> ... -o<Outputfilename>');
|
||||
writeln('Usage: ',ParamStr(0),' [--merge-all] [-d<definesymbol>]... [-u<undefinesymbol>]... <main header filename> <sub header file> ... -o<Outputfilename>');
|
||||
writeln();
|
||||
writeln(' Note: if --merge is given the sub header files are merged recursively into the main header at the #include directives.');
|
||||
writeln(' Sub header files which are not used by any #include directive are not merged.');
|
||||
writeln(' Scans for include directives and inserts given sub include files.');
|
||||
writeln('');
|
||||
writeln(' --merge-all');
|
||||
writeln(' Merge all given files. Normally only files needed by the main header files are merged.');
|
||||
Halt;
|
||||
end else begin
|
||||
Filename:=CleanAndExpandFilename(Param);
|
||||
@ -86,28 +89,19 @@ begin
|
||||
Filenames.Add(CleanAndExpandFilename(GetCurrentDir+'/scanexamples/test.h'));
|
||||
|
||||
// Step 1: load all input files
|
||||
if MergeFiles then begin
|
||||
Merger:=TCHeaderFileMerger.Create;
|
||||
Merger.Merge(Filenames,CodeToolBoss.SourceCache);
|
||||
//Merger.WriteDebugReport;
|
||||
Src:=Merger.CombinedSource.Source;
|
||||
{writeln;
|
||||
writeln('======Combined c header files================');
|
||||
writeln(Src);
|
||||
writeln('=============================================');}
|
||||
end else begin
|
||||
Src:='';
|
||||
for i:=0 to Filenames.Count-1 do begin
|
||||
Filename:=Filenames[i];
|
||||
CCode:=CodeToolBoss.LoadFile(Filename,false,false);
|
||||
if CCode=nil then
|
||||
raise Exception.Create('loading failed '+Filename);
|
||||
Tool.UndefineEnclosingIFNDEF(CCode);
|
||||
if Src<>'' then
|
||||
Src:=Src+LineEnding;
|
||||
Src:=Src+CCode.Source;
|
||||
end;
|
||||
end;
|
||||
Merger:=TCHeaderFileMerger.Create;
|
||||
MergeFlags:=[];
|
||||
if MergeAll then Include(MergeFlags,chfmfAll);
|
||||
Merger.Merge(Filenames,CodeToolBoss.SourceCache,MergeFlags);
|
||||
//Merger.WriteDebugReport;
|
||||
Src:=Merger.CombinedSource.Source;
|
||||
{writeln;
|
||||
writeln('======Combined c header files================');
|
||||
writeln(Src);
|
||||
writeln('=============================================');}
|
||||
|
||||
// ToDo:
|
||||
// Tool.UndefineEnclosingIFNDEF(CCode);
|
||||
|
||||
// Step 2: create a temporary file
|
||||
Filename:='h2pasoutput.pas';
|
||||
|
Loading…
Reference in New Issue
Block a user