From 7169bfbc64dc436e8b01fc51c1bca92203bd2ece Mon Sep 17 00:00:00 2001 From: skalogryz Date: Mon, 9 Mar 2015 18:39:18 +0000 Subject: [PATCH] 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 --- components/chelper/cconvert.lpr | 136 +++++++++++++++++++--------- components/chelper/cparsertypes.pas | 11 ++- 2 files changed, 102 insertions(+), 45 deletions(-) diff --git a/components/chelper/cconvert.lpr b/components/chelper/cconvert.lpr index e82793a7f..c32736532 100644 --- a/components/chelper/cconvert.lpr +++ b/components/chelper/cconvert.lpr @@ -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 i0 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. diff --git a/components/chelper/cparsertypes.pas b/components/chelper/cparsertypes.pas index 16afd2ad0..1dde73573 100755 --- a/components/chelper/cparsertypes.pas +++ b/components/chelper/cparsertypes.pas @@ -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