IDE, codetools: fixed parsing compiler time stamps

git-svn-id: trunk@10554 -
This commit is contained in:
mattias 2007-02-01 09:55:30 +00:00
parent bf735e87cf
commit 346794aaae
3 changed files with 101 additions and 116 deletions

View File

@ -2774,7 +2774,6 @@ function TDefinePool.CreateFPCTemplate(
// To get reliable values the compiler itself is asked for // To get reliable values the compiler itself is asked for
var var
LastDefTempl: TDefineTemplate; LastDefTempl: TDefineTemplate;
ShortUpTestFile: string;
procedure AddTemplate(NewDefTempl: TDefineTemplate); procedure AddTemplate(NewDefTempl: TDefineTemplate);
begin begin
@ -2825,90 +2824,60 @@ var
procedure ProcessOutputLine(var Line: string); procedure ProcessOutputLine(var Line: string);
var var
SymbolName, SymbolValue, UpLine, NewPath: string; SymbolName, SymbolValue, UpLine, NewPath: string;
i, len, curpos, remain: integer; i, len, curpos: integer;
begin begin
len := length(Line); len := length(Line);
if len <= 6 then Exit; // shortest match if len <= 6 then Exit; // shortest match
CurPos := 1; CurPos := 1;
// strip timestamp e.g. [0.306]
remain:=len;
// strip timestamp
if Line[CurPos] = '[' then begin if Line[CurPos] = '[' then begin
repeat repeat
inc(CurPos); inc(CurPos);
if CurPos > len then Exit; if CurPos > len then Exit;
until line[CurPos] = ']'; until line[CurPos] = ']';
Inc(CurPos, 2); //skip space also Inc(CurPos, 2); //skip space also
remain := len - CurPos + 1; if len - CurPos < 6 then Exit; // shortest match
if remain <= 6 then Exit; // shortest match
end; end;
UpLine:=UpperCaseStr(Line); UpLine:=UpperCaseStr(Line);
// check for filename
i := length(ShortUpTestFile);
if (remain > i) and (StrLComp(@ShortUpTestFile[1], @UpLine[CurPos], i) = 0) then begin
Inc(Curpos, i);
if Line[CurPos] <> '(' then Exit; // no linenumbers ??
// strip linenumbers
repeat
inc(CurPos);
if CurPos > len then Exit;
until Line[CurPos] = ')';
repeat
inc(CurPos);
if CurPos > len then Exit;
until Line[CurPos] <> ' ';
Dec(CurPos);
remain := len - CurPos + 1;
if remain <= 6 then Exit; // shortest match
end;
case UpLine[CurPos] of case UpLine[CurPos] of
'M': begin 'M':
if StrLComp(@UpLine[CurPos], 'MACRO ', 6) <> 0 then Exit; // no macro if StrLComp(@UpLine[CurPos], 'MACRO ', 6) = 0 then begin
Inc(CurPos, 6); // no macro
Dec(remain, 6); Inc(CurPos, 6);
if (remain > 9) and (StrLComp(@UpLine[CurPos], 'DEFINED: ', 9) = 0) then begin if (StrLComp(@UpLine[CurPos], 'DEFINED: ', 9) = 0) then begin
Inc(CurPos, 9); Inc(CurPos, 9);
Dec(remain, 9); SymbolName:=copy(UpLine, CurPos, len);
SymbolName:=copy(UpLine, CurPos, remain); DefineSymbol(SymbolName,'');
DefineSymbol(SymbolName,''); Exit;
Exit; end;
if (StrLComp(@UpLine[CurPos], 'UNDEFINED: ', 11) = 0) then begin
Inc(CurPos, 11);
SymbolName:=copy(UpLine,CurPos,len);
UndefineSymbol(SymbolName);
Exit;
end;
// MACRO something...
i := CurPos;
while (i <= len) and (Line[i]<>' ') do inc(i);
SymbolName:=copy(UpLine,CurPos,i-CurPos);
CurPos := i + 1; // skip space
if StrLComp(@UpLine[CurPos], 'SET TO ', 7) = 0 then begin
Inc(CurPos, 7);
SymbolValue:=copy(Line, CurPos, len);
DefineSymbol(SymbolName, SymbolValue);
end;
end; end;
'U':
if (remain > 11) and (StrLComp(@UpLine[CurPos], 'UNDEFINED: ', 11) = 0) then begin if (StrLComp(@UpLine[CurPos], 'USING UNIT PATH: ', 17) = 0) then begin
Inc(CurPos, 11);
Dec(remain, 11);
SymbolName:=copy(UpLine,CurPos,remain);
UndefineSymbol(SymbolName);
Exit;
end;
// MACRO something...
i := CurPos;
while (i <= len) and (Line[i]<>' ') do inc(i);
SymbolName:=copy(UpLine,CurPos,i-CurPos);
CurPos := i + 1; // skip space
remain := len - CurPos + 1;
if remain < 7 then Exit;
if StrLComp(@UpLine[CurPos], 'SET TO ', 7) = 0 then begin
Inc(CurPos, 7);
Dec(remain, 7);
SymbolValue:=copy(Line, CurPos, remain);
DefineSymbol(SymbolName, SymbolValue);
end;
end;
'U': begin
if (remain > 17) and (StrLComp(@UpLine[CurPos], 'USING UNIT PATH: ', 17) = 0) then begin
Inc(CurPos, 17); Inc(CurPos, 17);
Dec(remain, 17); NewPath:=copy(Line,CurPos,len);
NewPath:=copy(Line,CurPos,Remain);
if not FilenameIsAbsolute(NewPath) then if not FilenameIsAbsolute(NewPath) then
NewPath:=ExpandFileName(NewPath); NewPath:=ExpandFileName(NewPath);
{$IFDEF VerboseFPCSrcScan} {$IFDEF VerboseFPCSrcScan}
@ -2916,7 +2885,6 @@ var
{$ENDIF} {$ENDIF}
UnitSearchPath:=UnitSearchPath+NewPath+';'; UnitSearchPath:=UnitSearchPath+NewPath+';';
end; end;
end;
end; end;
end; end;
@ -2945,14 +2913,13 @@ begin
SetLength(Buf,1024); SetLength(Buf,1024);
Step:='Init'; Step:='Init';
try try
CmdLine:=CompilerPath+' -va -vs- '; CmdLine:=CompilerPath+' -va ';
if FileExistsCached(EnglishErrorMsgFilename) then if FileExistsCached(EnglishErrorMsgFilename) then
CmdLine:=CmdLine+'-Fr'+EnglishErrorMsgFilename+' '; CmdLine:=CmdLine+'-Fr'+EnglishErrorMsgFilename+' ';
if CompilerOptions<>'' then if CompilerOptions<>'' then
CmdLine:=CmdLine+CompilerOptions+' '; CmdLine:=CmdLine+CompilerOptions+' ';
CmdLine:=CmdLine+TestPascalFile; CmdLine:=CmdLine+TestPascalFile;
//DebugLn('TDefinePool.CreateFPCTemplate CmdLine="',CmdLine,'"'); //DebugLn('TDefinePool.CreateFPCTemplate CmdLine="',CmdLine,'"');
ShortUpTestFile := UpperCaseStr(ExtractFileName(TestPascalFile));
TheProcess := TProcess.Create(nil); TheProcess := TProcess.Create(nil);
TheProcess.CommandLine := CmdLine; TheProcess.CommandLine := CmdLine;

View File

@ -34,7 +34,7 @@
<Unit1> <Unit1>
<Filename Value="scanexamples/simpleunit1.pas"/> <Filename Value="scanexamples/simpleunit1.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="SimpleUnit1"/> <UnitName Value="S"/>
</Unit1> </Unit1>
</Units> </Units>
</ProjectOptions> </ProjectOptions>

View File

@ -416,21 +416,28 @@ var i, j, FilenameEndPos: integer;
LineNumberEndPos: LongInt; LineNumberEndPos: LongInt;
AbsFilename: String; AbsFilename: String;
function CheckForCompilingState: boolean; function CompStr(const SubStr, s: string; Position: integer): boolean;
begin
Result:=(SubStr<>'') and (length(s)>=(Position+length(SubStr)-1))
and (strlcomp(PChar(Pointer(@s[Position])),
PChar(Pointer(SubStr)),length(SubStr))=0);
end;
function CheckForCompilingState(p: integer): boolean;
var var
AFilename: string; AFilename: string;
begin begin
Result:=false; Result:=false;
if ('Compiling '=copy(s,1,length('Compiling '))) then begin if CompStr('Compiling ',s,p) then begin
// for example 'Compiling ./subdir/unit1.pas' // for example 'Compiling ./subdir/unit1.pas'
fLastMessageType:=omtFPC; fLastMessageType:=omtFPC;
fLastErrorType:=etNone; fLastErrorType:=etNone;
// add path to history // add path to history
if fCompilingHistory=nil then fCompilingHistory:=TStringList.Create; if fCompilingHistory=nil then fCompilingHistory:=TStringList.Create;
i:=length('Compiling '); inc(p,length('Compiling '));
if (length(s)>=i+2) and (s[i+1]='.') and (s[i+2]=PathDelim) then if (length(s)>=i+1) and (s[i]='.') and (s[i+1]=PathDelim) then
inc(i,2); inc(i,2);
AFilename:=TrimFilename(copy(s,i+1,length(s)-i)); AFilename:=TrimFilename(copy(s,i,length(s)));
fCompilingHistory.Add(AFilename); fCompilingHistory.Add(AFilename);
CurrentMessageParts.Values['Stage']:='FPC'; CurrentMessageParts.Values['Stage']:='FPC';
CurrentMessageParts.Values['Type']:='Compiling'; CurrentMessageParts.Values['Type']:='Compiling';
@ -439,11 +446,10 @@ var i, j, FilenameEndPos: integer;
end; end;
end; end;
function CheckForAssemblingState: boolean; function CheckForAssemblingState(p: integer): boolean;
begin begin
Result:=false; Result:=false;
if ('Assembling '=copy(s,1,length('Assembling '))) if CompStr('Assembling ',s,p) then begin
then begin
fLastMessageType:=omtFPC; fLastMessageType:=omtFPC;
fLastErrorType:=etNone; fLastErrorType:=etNone;
CurrentMessageParts.Values['Stage']:='FPC'; CurrentMessageParts.Values['Stage']:='FPC';
@ -452,27 +458,27 @@ var i, j, FilenameEndPos: integer;
end; end;
end; end;
function CheckForUrgentMessages: boolean; function CheckForUrgentMessages(p: integer): boolean;
var var
NewLine: String; NewLine: String;
LastFile: string; LastFile: string;
FullFilename: String; FullFilename: String;
begin begin
Result:=false; Result:=false;
if ('Fatal: '=copy(s,1,length('Fatal: '))) if CompStr('Fatal: ',s,p)
or ('Panic'=copy(s,1,length('Panic'))) or CompStr('Panic',s,p)
or ('Error: '=copy(s,1,length('Error: '))) or CompStr('Error: ',s,p)
or ('Closing script ppas.sh'=s) or CompStr('Closing script ppas.sh',s,p)
then begin then begin
// always show fatal, panic and linker errors // always show fatal, panic and linker errors
fLastMessageType:=omtFPC; fLastMessageType:=omtFPC;
if ('Panic'=copy(s,1,length('Panic'))) then if CompStr('Panic',s,p) then
fLastErrorType:=etPanic fLastErrorType:=etPanic
else if ('Fatal: '=copy(s,1,length('Fatal: '))) then else if CompStr('Fatal: ',s,p) then
fLastErrorType:=etFatal fLastErrorType:=etFatal
else if ('Error: '=copy(s,1,length('Error: '))) then else if CompStr('Error: ',s,p) then
fLastErrorType:=etError fLastErrorType:=etError
else if ('Closing script ppas.sh'=s) then begin else if CompStr('Closing script ppas.sh',s,p) then begin
// linker error // linker error
fLastMessageType:=omtLinker; fLastMessageType:=omtLinker;
fLastErrorType:=etFatal; fLastErrorType:=etFatal;
@ -483,7 +489,7 @@ var i, j, FilenameEndPos: integer;
CurrentMessageParts.Values['Stage']:='FPC'; CurrentMessageParts.Values['Stage']:='FPC';
CurrentMessageParts.Values['Type']:=ErrorTypeNames[fLastErrorType]; CurrentMessageParts.Values['Type']:=ErrorTypeNames[fLastErrorType];
NewLine:=s; NewLine:=copy(s,p,length(s));
if fLastErrorType in [etPanic,etFatal] then begin if fLastErrorType in [etPanic,etFatal] then begin
// fatal and panic errors are not very informative // fatal and panic errors are not very informative
// -> prepend current file // -> prepend current file
@ -512,11 +518,11 @@ var i, j, FilenameEndPos: integer;
end; end;
end; end;
function CheckForNoteMessages: boolean; function CheckForNoteMessages(p: integer): boolean;
begin begin
Result:=false; Result:=false;
if ('Note: '=copy(s,1,length('Note: '))) then begin if CompStr('Note: ',s,p) then begin
DoAddFilteredLine(s); DoAddFilteredLine(copy(s,p,length(s)));
fLastErrorType:=etNote; fLastErrorType:=etNote;
CurrentMessageParts.Values['Stage']:='FPC'; CurrentMessageParts.Values['Stage']:='FPC';
CurrentMessageParts.Values['Type']:=ErrorTypeNames[fLastErrorType]; CurrentMessageParts.Values['Type']:=ErrorTypeNames[fLastErrorType];
@ -543,17 +549,13 @@ var i, j, FilenameEndPos: integer;
function CheckForString(const Str: string; var p: integer; function CheckForString(const Str: string; var p: integer;
const Find: string): boolean; const Find: string): boolean;
begin begin
Result:=(p+length(Find)-1<=length(Str)) Result:=CompStr(Find,Str,p);
and (CompareText(Find,copy(s,p,length(Find)))=0);
if Result then inc(p,length(Find)); if Result then inc(p,length(Find));
end; end;
function CheckForLineProgress: boolean; function CheckForLineProgress(p: integer): boolean;
var
p: Integer;
begin begin
Result:=false; Result:=false;
p:=1;
if not CheckForNumber(s,p) then exit; if not CheckForNumber(s,p) then exit;
if not CheckForChar(s,p,' ') then exit; if not CheckForChar(s,p,' ') then exit;
if not CheckForNumber(s,p) then exit; if not CheckForNumber(s,p) then exit;
@ -564,12 +566,12 @@ var i, j, FilenameEndPos: integer;
// I don't think it should be shown in filtered lines: DoAddFilteredLine(s); // I don't think it should be shown in filtered lines: DoAddFilteredLine(s);
end; end;
function CheckForLinesCompiled: boolean; function CheckForLinesCompiled(p: integer): boolean;
var var
p: Integer; OldStart: LongInt;
begin begin
Result:=false; Result:=false;
p:=1; OldStart:=p;
if not CheckForNumber(s,p) then exit; if not CheckForNumber(s,p) then exit;
if not CheckForString(s,p,' Lines compiled, ') then exit; if not CheckForString(s,p,' Lines compiled, ') then exit;
if not CheckForNumber(s,p) then exit; if not CheckForNumber(s,p) then exit;
@ -579,7 +581,7 @@ var i, j, FilenameEndPos: integer;
Result:=true; Result:=true;
if (CompilerOptions<>nil) if (CompilerOptions<>nil)
and (CompilerOptions.ShowAll or CompilerOptions.ShowSummary) then and (CompilerOptions.ShowAll or CompilerOptions.ShowSummary) then
DoAddFilteredLine(s); DoAddFilteredLine(copy(s,OldStart,length(s)));
end; end;
{ For example: { For example:
@ -589,12 +591,12 @@ var i, j, FilenameEndPos: integer;
Stack space reserved: 262144 bytes Stack space reserved: 262144 bytes
Stack space commited: 4096 bytes Stack space commited: 4096 bytes
} }
function CheckForExecutableInfo: boolean; function CheckForExecutableInfo(p: integer): boolean;
var var
p: Integer; OldStart: LongInt;
begin begin
Result:=false; Result:=false;
p:=1; OldStart:=p;
if not (CheckForString(s,p,'Size of Code: ') or if not (CheckForString(s,p,'Size of Code: ') or
CheckForString(s,p,'Size of initialized data: ') or CheckForString(s,p,'Size of initialized data: ') or
CheckForString(s,p,'Size of uninitialized data: ') or CheckForString(s,p,'Size of uninitialized data: ') or
@ -606,44 +608,60 @@ var i, j, FilenameEndPos: integer;
Result:=true; Result:=true;
if (CompilerOptions<>nil) if (CompilerOptions<>nil)
and (CompilerOptions.ShowAll or CompilerOptions.ShowExecInfo) then and (CompilerOptions.ShowAll or CompilerOptions.ShowExecInfo) then
DoAddFilteredLine(s); DoAddFilteredLine(copy(s,OldStart,length(s)));
end; end;
{ For example: { For example:
linkerror.o(.text$_main+0x9):linkerror.pas: undefined reference to `NonExistingFunction' linkerror.o(.text$_main+0x9):linkerror.pas: undefined reference to `NonExistingFunction'
} }
function CheckForLinkingErrors: boolean; function CheckForLinkingErrors(p: integer): boolean;
var
OldStart: LongInt;
begin begin
Result:=false; Result:=false;
OldStart:=p;
while (p<=length(s)) and (s[p] in ['0'..'9','a'..'z','A'..'Z','_']) do
inc(p);
if not CompStr('.o(',s,p) then exit;
Result:=true;
DoAddFilteredLine(copy(s,OldStart,length(s)));
end; end;
begin begin
Result:=false; Result:=false;
if s='' then exit; if s='' then exit;
i:=1;
// skip time [0.000]
if (s<>'') and (s[1]='[') then begin
inc(i);
while (i<=length(s)) and (s[i] in ['0'..'9','.']) do inc(i);
if (i<=length(s)) and (s[i]=']') then inc(i);
while (i<=length(s)) and (s[i] in [' ']) do inc(i);
end;
// check for 'Compiling <filename>' // check for 'Compiling <filename>'
Result:=CheckForCompilingState; Result:=CheckForCompilingState(i);
if Result then exit; if Result then exit;
// check for 'Assembling <filename>' // check for 'Assembling <filename>'
Result:=CheckForAssemblingState; Result:=CheckForAssemblingState(i);
if Result then exit; if Result then exit;
// check for 'Fatal: ', 'Panic: ', 'Error: ', 'Closing script ppas.sh' // check for 'Fatal: ', 'Panic: ', 'Error: ', 'Closing script ppas.sh'
Result:=CheckForUrgentMessages; Result:=CheckForUrgentMessages(i);
if Result then exit; if Result then exit;
// check for 'Note: ' // check for 'Note: '
Result:=CheckForNoteMessages; Result:=CheckForNoteMessages(i);
if Result then exit; if Result then exit;
// check for '<line> <kb>/<kb>'... // check for '<line> <kb>/<kb>'...
Result:=CheckForLineProgress; Result:=CheckForLineProgress(i);
if Result then exit; if Result then exit;
// check for '<int> Lines compiled, <int>.<int> sec' // check for '<int> Lines compiled, <int>.<int> sec'
Result:=CheckForLinesCompiled; Result:=CheckForLinesCompiled(i);
if Result then exit; if Result then exit;
// check for -vx output // check for -vx output
Result:=CheckForExecutableInfo; Result:=CheckForExecutableInfo(i);
if Result then exit; if Result then exit;
// check for linking errors // check for linking errors
Result:=CheckForLinkingErrors; Result:=CheckForLinkingErrors(i);
if Result then exit; if Result then exit;
// search for round bracket open // search for round bracket open