You've already forked lazarus-ccr
chelper: updated the parsing (use includes first) and then parse the body. Added IgnoreDirectives option to force skipping of directives
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4013 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -40,6 +40,7 @@ var
|
||||
isVerbose : Boolean = false;
|
||||
DoIncludes : Boolean = true;
|
||||
|
||||
IgnoreDefines : TStringList = nil;
|
||||
IncludePath : TStringList = nil; // adjustement for include paths
|
||||
|
||||
procedure NormalizePath(var pth: string);
|
||||
@ -51,7 +52,24 @@ begin
|
||||
pth[i]:=DirectorySeparator;
|
||||
end;
|
||||
|
||||
function isIncludePath(const include: string; var pth: string): Boolean;
|
||||
procedure AddStringsFromFile(st: TStrings; const fn: string);
|
||||
var
|
||||
add : TstringList;
|
||||
begin
|
||||
if not FileExists(fn) then Exit;
|
||||
try
|
||||
add := TstringList.Create;
|
||||
try
|
||||
add.LoadFromFile(fn);
|
||||
st.AddStrings(add);
|
||||
finally
|
||||
add.Free;
|
||||
end;
|
||||
except
|
||||
end;
|
||||
end;
|
||||
|
||||
function isIncludePath(const include: string; var pth: string; isSystemPath: Boolean): Boolean;
|
||||
var
|
||||
i : integer;
|
||||
p : string;
|
||||
@ -65,7 +83,11 @@ begin
|
||||
i:=IncludePath.IndexOfName(p);
|
||||
|
||||
Result:=i>=0;
|
||||
if not Result then Exit;
|
||||
if not Result then begin
|
||||
// always include empty path, even if it was not specified
|
||||
if p ='.' then Result:=not isSystemPath;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
v:=IncludePath.ValueFromIndex[i];
|
||||
if p<>'' then p:=IncludeTrailingPathDelimiter(p);
|
||||
@ -119,6 +141,9 @@ begin
|
||||
writeln(' physical path is used to specify the actual physical path on the hard drive.');
|
||||
writeln(' if not specified, the current directory is assumed as a location for the header');
|
||||
writeln(' -verbose - verbose output');
|
||||
writeln(' -id %name_of_define%');
|
||||
writeln(' -id @%filename% ');
|
||||
writeln(' - the macros name or file name constaining the list of defines to be ignored ');
|
||||
end;
|
||||
|
||||
procedure ConsumeIncludePath(const s: string);
|
||||
@ -188,6 +213,14 @@ begin
|
||||
end else if s='-ip' then begin
|
||||
inc(i);
|
||||
ConsumeIncludePath( Trim(SafeParamStr(i)) );
|
||||
end else if s='-ig' then begin
|
||||
inc(i);
|
||||
fn:=Trim(SafeParamStr(i));
|
||||
if (fn<>'') then begin
|
||||
if (fn[1]='@')
|
||||
then AddStringsFromFile(IgnoreDefines, Copy(fn,2,length(fn)))
|
||||
else IgnoreDefines.Add(fn);
|
||||
end;
|
||||
end else
|
||||
files.Add(ss);
|
||||
inc(i);
|
||||
@ -463,7 +496,8 @@ begin
|
||||
|
||||
while i<files.Count do begin
|
||||
fn:=files[i];
|
||||
//writeln('i = ',i,' ',fn);
|
||||
log(fn);
|
||||
log('reading');
|
||||
|
||||
hdr:=THeaderFile(files.Objects[i]);
|
||||
if not Assigned(hdr) then begin
|
||||
@ -480,48 +514,28 @@ begin
|
||||
finally
|
||||
txt.Free;
|
||||
end;
|
||||
log('preprocing %s ', [fn]);
|
||||
buf:=PreprocGlobal(buf, hdr.fileOfs, hdr.cmts);
|
||||
//writeln('?parseri!');
|
||||
ParseDirectives(buf, hdr.pres);
|
||||
|
||||
applied.Clear;
|
||||
//writeln('?preproc!');
|
||||
buf:=PreprocessHeader(buf, hdr.pres, inp.parser.MacroHandler, hdr.fileOfs, applied);
|
||||
buf:=PreprocessHeader(buf, hdr.pres, inp.parser.MacroHandler, hdr.fileOfs, IgnoreDefines, applied);
|
||||
log('preprocing done');
|
||||
hdr.text:=Buf;
|
||||
|
||||
ResetText(inp, buf);
|
||||
|
||||
//writeln('?handler = ', PtrUInt(inp.parser.MacroHandler));
|
||||
//DebugMacros(inp.parser.MacroHandler);
|
||||
//writeln('parsing entities');
|
||||
|
||||
if not ParseCEntities(inp, hdr.ents, ot) then begin
|
||||
//writeln('error:');
|
||||
writeln('Parsing error at ', fn,' (',ot.error.ErrorPos.y,':',ot.error.ErrorPos.X,')');
|
||||
writeln(ot.error.ErrorMsg);
|
||||
|
||||
ReleaseList(hdr.Ents);
|
||||
inc(i);
|
||||
|
||||
SaveDebugToFile(inp.parser.Buf
|
||||
+LineEnding+'----'+LineEnding+
|
||||
buf
|
||||
, fn,
|
||||
Format('Parsing error at "%s" (%d:%d)'#13#10'%s',
|
||||
[fn, ot.error.ErrorPos.y, ot.error.ErrorPos.X,ot.error.ErrorMsg]));
|
||||
|
||||
Continue;
|
||||
end;
|
||||
hdr.text:=inp.parser.Buf;
|
||||
|
||||
AssignIntComments(hdr.ents);
|
||||
|
||||
if DoIncludes then
|
||||
//writeln('kokoke: applied');
|
||||
if DoIncludes then begin
|
||||
Log ('checking included headers');
|
||||
for j:=0 to applied.Count-1 do
|
||||
if TObject(applied[j]) is TCPrepInclude then begin
|
||||
ic:=TCPrepInclude(applied[j]);
|
||||
if isIncludePath(ic.Included, fn) then begin
|
||||
if isIncludePath(ic.Included, fn, ic.isSysFile) then begin
|
||||
Log('adding %s to headers list', [ic.Included]);
|
||||
fi:=Files.IndexOf(fn);
|
||||
if not FileExists(fn) then begin
|
||||
log('warning: incluide file %s not found', [fn]);
|
||||
Continue;
|
||||
end;
|
||||
|
||||
if fi<0 then
|
||||
// GetIncludeFN(ic.Included) is a hack not to add UIKit.h twice
|
||||
fi:=Files.IndexOf( GetIncludeFN(ic.Included) );
|
||||
@ -532,29 +546,64 @@ begin
|
||||
hh.usedBy:=hdr.inclOrder;
|
||||
fi:=Files.AddObject(fn, hh);
|
||||
end else begin
|
||||
log('%s is already in the list ', [ic.Included]);
|
||||
hh:=THeaderFile(Files.Objects[fi]);
|
||||
// fi<>0 is a hack not to add reassing UIKit.h twice
|
||||
if (hh.usedBy=0) and (fi<>0) then hh.usedBy:=i;
|
||||
end;
|
||||
inc(THeaderFile(Files.Objects[fi]).useCount);
|
||||
|
||||
end;
|
||||
end;
|
||||
end else
|
||||
Log('%s is not suggested for inclusion or a system header', [ic.Included]);
|
||||
end; {if CPreInclude}
|
||||
end;
|
||||
|
||||
inc(i);
|
||||
log('');
|
||||
end;
|
||||
//writeln('done!');
|
||||
|
||||
log('');
|
||||
if isVerbose then begin
|
||||
log('files count = ', files.Count);
|
||||
log('original order');
|
||||
log('total header files count ', files.Count);
|
||||
log('parsing order:');
|
||||
DebugHeaders(files);
|
||||
end;
|
||||
|
||||
log('files order after usage resolving');
|
||||
log('');
|
||||
log('files order after usage resolving: ');
|
||||
ResortByUsage(files);
|
||||
if isVerbose then DebugHeaders(files);
|
||||
|
||||
log('macros:');
|
||||
DebugMacros(inp.mmaker.hnd);
|
||||
|
||||
log('');
|
||||
log('parsing files');
|
||||
for i:=0 to files.count-1 do begin
|
||||
hdr := THeaderFile(files.Objects[i]);
|
||||
Log(files[i]);
|
||||
Log('parsing, header length %d bytes', [length(hdr.text)]);
|
||||
ResetText(inp, hdr.text);
|
||||
//writeln(hdr.text);
|
||||
if not ParseCEntities(inp, hdr.ents, ot) then begin
|
||||
writeln('error:');
|
||||
writeln('Parsing error at ', fn,' (',ot.error.ErrorPos.y,':',ot.error.ErrorPos.X,')');
|
||||
writeln(ot.error.ErrorMsg);
|
||||
|
||||
ReleaseList(hdr.Ents);
|
||||
|
||||
SaveDebugToFile(inp.parser.Buf
|
||||
+LineEnding+'----'+LineEnding+
|
||||
buf
|
||||
, fn,
|
||||
Format('Parsing error at "%s" (%d:%d)'#13#10'%s',
|
||||
[fn, ot.error.ErrorPos.y, ot.error.ErrorPos.X,ot.error.ErrorMsg]));
|
||||
end; // else
|
||||
log('done!');
|
||||
|
||||
//AssignIntComments(hdr.ents);
|
||||
end;
|
||||
|
||||
//writeln('cout = ', files.Count);
|
||||
for i:=0 to files.Count-1 do begin
|
||||
hdr:=THeaderFile(files.Objects[i]);
|
||||
@ -564,6 +613,7 @@ begin
|
||||
writeln(res);
|
||||
end;
|
||||
|
||||
|
||||
{writeln('alphabet!');
|
||||
TSTringList(files).Sort;
|
||||
DebugHeaders(files);}
|
||||
@ -587,6 +637,7 @@ begin
|
||||
cfg:=TConvertSettings.Create;
|
||||
fns:=TStringList.Create;
|
||||
IncludePath:=TStringList.Create;
|
||||
IgnoreDefines:=TStringList.Create;
|
||||
try
|
||||
ReadParams(fns, cfg);
|
||||
if isPrintHelp then begin
|
||||
@ -605,6 +656,7 @@ begin
|
||||
cfg.Free;
|
||||
fns.Free;
|
||||
IncludePath.Free;
|
||||
IgnoreDefines.Free;
|
||||
end;
|
||||
end.
|
||||
|
||||
|
@ -435,7 +435,7 @@ function ParseEnum(AParser: TTextParser): TEnumType;
|
||||
|
||||
function PreprocGlobal(const buf: string; fs: TFileOffsets; ent: TList): string;
|
||||
procedure ParseDirectives(const s: string; entList: TList);
|
||||
function PreprocessHeader(const s: string; entList: TList; macros: TCMacroHandler; fs: TFileOffsets; appliedEnt: TList = nil): string;
|
||||
function PreprocessHeader(const s: string; entList: TList; macros: TCMacroHandler; fs: TFileOffsets; IgnoreDefines: TStrings; appliedEnt: TList = nil): string;
|
||||
procedure CPrepDefineToMacrosHandler(def: TCPrepDefine; mh: TCMacroHandler);
|
||||
|
||||
procedure DebugEnList(entlist: TList);
|
||||
@ -738,6 +738,7 @@ begin
|
||||
x.PushToken(Parser.Token, Parser.TokenType);
|
||||
until not Parser.NextToken;
|
||||
|
||||
Result:=x;
|
||||
end;
|
||||
|
||||
procedure ParseCNumeric(const S: AnsiString; var idx: integer; var NumStr: AnsiSTring);
|
||||
@ -2450,7 +2451,7 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
function PreprocessHeader(const s: string; entList: TList; macros: TCMacroHandler; fs: TFileOffsets; appliedEnt: TList): string;
|
||||
function PreprocessHeader(const s: string; entList: TList; macros: TCMacroHandler; fs: TFileOffsets; IgnoreDefines: TStrings; appliedEnt: TList): string;
|
||||
var
|
||||
isCondMet : Boolean;
|
||||
lvl : Integer;
|
||||
@ -2482,6 +2483,7 @@ var
|
||||
stSub : Integer;
|
||||
endSub : integer;
|
||||
hasElse : Boolean;
|
||||
nm : string;
|
||||
begin
|
||||
i:=stInd;
|
||||
while (i<=endInd) do begin
|
||||
@ -2493,8 +2495,11 @@ var
|
||||
if Assigned(appliedEnt) then appliedEnt.Add(ent);
|
||||
|
||||
SetFeedOfs( ent.EndOffset );
|
||||
CPrepDefineToMacrosHandler( TCPrepDefine(ent), macros );
|
||||
nm:=TCPrepDefine(ent)._Name;
|
||||
if not Assigned(IgnoreDefines) or (IgnoreDefines.IndexOf(nm) <0) then
|
||||
CPrepDefineToMacrosHandler( TCPrepDefine(ent), macros );
|
||||
inc(i);
|
||||
|
||||
end else if ent is TCPrepIf then begin
|
||||
dif:=TCPrepIf(ent);
|
||||
cndst:=nil; // condition start
|
||||
|
Reference in New Issue
Block a user