IDEIntf: added flag mlfStdError to external tool messages, issue #34996

git-svn-id: trunk@60320 -
This commit is contained in:
mattias 2019-02-03 21:24:49 +00:00
parent 510abc8ab6
commit 699e606af8
4 changed files with 68 additions and 19 deletions

View File

@ -103,6 +103,7 @@ type
TAbstractExternalTool = class; TAbstractExternalTool = class;
TMessageLineFlag = ( TMessageLineFlag = (
mlfStdErr,
mlfLeftToken, // position is about left token, otherwise right token mlfLeftToken, // position is about left token, otherwise right token
mlfFixed, // reason for the messages was resolved, e.g. quick fixed mlfFixed, // reason for the messages was resolved, e.g. quick fixed
mlfHiddenByIDEDirective, mlfHiddenByIDEDirective,
@ -297,7 +298,7 @@ type
procedure Init; virtual; // called after macros resolved, before starting thread (main thread) procedure Init; virtual; // called after macros resolved, before starting thread (main thread)
procedure InitReading; virtual; // called if process started, before first line (worker thread) procedure InitReading; virtual; // called if process started, before first line (worker thread)
procedure Done; virtual; // called after process stopped (worker thread) procedure Done; virtual; // called after process stopped (worker thread)
procedure ReadLine(Line: string; OutputIndex: integer; var Handled: boolean); virtual; abstract; // (worker thread) procedure ReadLine(Line: string; OutputIndex: integer; IsStdErr: boolean; var Handled: boolean); virtual; abstract; // (worker thread)
function CreateMsgLine(OutputIndex: integer): TMessageLine; // (worker thread) function CreateMsgLine(OutputIndex: integer): TMessageLine; // (worker thread)
procedure AddMsgLine(MsgLine: TMessageLine); virtual; // (worker thread) procedure AddMsgLine(MsgLine: TMessageLine); virtual; // (worker thread)
property Tool: TAbstractExternalTool read FTool;// set when added to a tool property Tool: TAbstractExternalTool read FTool;// set when added to a tool
@ -360,8 +361,8 @@ type
TDefaultParser = class(TExtToolParser) TDefaultParser = class(TExtToolParser)
public public
procedure ReadLine(Line: string; OutputIndex: integer; var Handled: boolean procedure ReadLine(Line: string; OutputIndex: integer; IsStdErr: boolean;
); override; var Handled: boolean); override;
class function DefaultSubTool: string; override; class function DefaultSubTool: string; override;
class function GetLocalizedParserName: string; override; class function GetLocalizedParserName: string; override;
class function Priority: integer; override; class function Priority: integer; override;
@ -997,7 +998,7 @@ end;
{ TDefaultParser } { TDefaultParser }
procedure TDefaultParser.ReadLine(Line: string; OutputIndex: integer; procedure TDefaultParser.ReadLine(Line: string; OutputIndex: integer;
var Handled: boolean); IsStdErr: boolean; var Handled: boolean);
var var
MsgLine: TMessageLine; MsgLine: TMessageLine;
begin begin
@ -1006,6 +1007,8 @@ begin
MsgLine:=CreateMsgLine(OutputIndex); MsgLine:=CreateMsgLine(OutputIndex);
MsgLine.Msg:=Line; MsgLine.Msg:=Line;
MsgLine.Urgency:=mluImportant; MsgLine.Urgency:=mluImportant;
if IsStdErr then
MsgLine.Flags:=MsgLine.Flags+[mlfStdErr];
AddMsgLine(MsgLine); AddMsgLine(MsgLine);
end; end;

View File

@ -166,6 +166,7 @@ type
fLineToMsgID: TPatternToMsgIDs; fLineToMsgID: TPatternToMsgIDs;
fMissingFPCMsgItem: TFPCMsgItem; fMissingFPCMsgItem: TFPCMsgItem;
fMsgID: Integer; // current message id given by ReadLine (-vq) fMsgID: Integer; // current message id given by ReadLine (-vq)
fMsgIsStdErr: boolean;
fMsgItemCantFindUnitUsedBy: TFPCMsgItem; fMsgItemCantFindUnitUsedBy: TFPCMsgItem;
fMsgItemCompilationAborted: TFPCMsgItem; fMsgItemCompilationAborted: TFPCMsgItem;
fMsgItemErrorWhileCompilingResources: TFPCMsgItem; fMsgItemErrorWhileCompilingResources: TFPCMsgItem;
@ -193,6 +194,7 @@ type
function CheckForWindresErrors(p: PChar): boolean; function CheckForWindresErrors(p: PChar): boolean;
function CheckForLinkerErrors(p: PChar): boolean; function CheckForLinkerErrors(p: PChar): boolean;
function CheckForAssemblerErrors(p: PChar): boolean; function CheckForAssemblerErrors(p: PChar): boolean;
function CheckForUnspecificStdErr(p: PChar): boolean;
function CreateMsgLine: TMessageLine; function CreateMsgLine: TMessageLine;
procedure AddLinkingMessages; procedure AddLinkingMessages;
procedure AddResourceMessages; procedure AddResourceMessages;
@ -232,7 +234,8 @@ type
procedure Init; override; // called after macros resolved, before starting thread (main thread) procedure Init; override; // called after macros resolved, before starting thread (main thread)
procedure InitReading; override; // called when process started, before first line (worker thread) procedure InitReading; override; // called when process started, before first line (worker thread)
procedure Done; override; // called after process stopped (worker thread) procedure Done; override; // called after process stopped (worker thread)
procedure ReadLine(Line: string; OutputIndex: integer; var Handled: boolean); override; procedure ReadLine(Line: string; OutputIndex: integer; IsStdErr: boolean;
var Handled: boolean); override;
procedure AddMsgLine(MsgLine: TMessageLine); override; procedure AddMsgLine(MsgLine: TMessageLine); override;
procedure ImproveMessages(aPhase: TExtToolParserSyncPhase); override; procedure ImproveMessages(aPhase: TExtToolParserSyncPhase); override;
function GetFPCMsgIDPattern(MsgID: integer): string; override; function GetFPCMsgIDPattern(MsgID: integer): string; override;
@ -1549,6 +1552,19 @@ begin
AddMsgLine(MsgLine); AddMsgLine(MsgLine);
end; end;
function TIDEFPCParser.CheckForUnspecificStdErr(p: PChar): boolean;
var
MsgLine: TMessageLine;
begin
if not fMsgIsStdErr then exit(false);
Result:=true;
MsgLine:=CreateMsgLine;
MsgLine.SubTool:=SubToolFPC;
MsgLine.Urgency:=mluError;
MsgLine.Msg:=p;
AddMsgLine(MsgLine);
end;
function TIDEFPCParser.CheckForInfos(p: PChar): boolean; function TIDEFPCParser.CheckForInfos(p: PChar): boolean;
function ReadFPCLogo(PatternItem: PPatternToMsgID; function ReadFPCLogo(PatternItem: PPatternToMsgID;
@ -1625,6 +1641,8 @@ function TIDEFPCParser.CreateMsgLine: TMessageLine;
begin begin
Result:=inherited CreateMsgLine(fOutputIndex); Result:=inherited CreateMsgLine(fOutputIndex);
Result.MsgID:=fMsgID; Result.MsgID:=fMsgID;
if fMsgIsStdErr then
Result.Flags:=Result.Flags+[mlfStdErr];
end; end;
procedure TIDEFPCParser.AddLinkingMessages; procedure TIDEFPCParser.AddLinkingMessages;
@ -2905,7 +2923,7 @@ begin
end; end;
procedure TIDEFPCParser.ReadLine(Line: string; OutputIndex: integer; procedure TIDEFPCParser.ReadLine(Line: string; OutputIndex: integer;
var Handled: boolean); IsStdErr: boolean; var Handled: boolean);
{ returns true, if it is a compiler message { returns true, if it is a compiler message
Examples for freepascal compiler messages: Examples for freepascal compiler messages:
Compiling <filename> Compiling <filename>
@ -2927,6 +2945,7 @@ begin
p:=PChar(Line); p:=PChar(Line);
fOutputIndex:=OutputIndex; fOutputIndex:=OutputIndex;
fMsgID:=0; fMsgID:=0;
fMsgIsStdErr:=IsStdErr;
// skip time [0.000] // skip time [0.000]
if (p^='[') and (p[1] in ['0'..'9']) then begin if (p^='[') and (p[1] in ['0'..'9']) then begin
@ -2984,6 +3003,9 @@ begin
// check for assembler errors // check for assembler errors
if CheckForAssemblerErrors(p) then exit; if CheckForAssemblerErrors(p) then exit;
// last: check for unknown std error
if CheckForUnspecificStdErr(p) then exit;
{$IFDEF VerboseFPCParser} {$IFDEF VerboseFPCParser}
debugln('TFPCParser.ReadLine UNKNOWN: ',Line); debugln('TFPCParser.ReadLine UNKNOWN: ',Line);
{$ENDIF} {$ENDIF}

View File

@ -58,7 +58,8 @@ type
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure InitReading; override; procedure InitReading; override;
procedure ReadLine(Line: string; OutputIndex: integer; var Handled: boolean); override; procedure ReadLine(Line: string; OutputIndex: integer; IsStdErr: boolean;
var Handled: boolean); override;
class function DefaultSubTool: string; override; class function DefaultSubTool: string; override;
class function Priority: integer; override; class function Priority: integer; override;
end; end;
@ -245,7 +246,7 @@ begin
end; end;
procedure TIDEMakeParser.ReadLine(Line: string; OutputIndex: integer; procedure TIDEMakeParser.ReadLine(Line: string; OutputIndex: integer;
var Handled: boolean); IsStdErr: boolean; var Handled: boolean);
{ returns true, if it is a make/gmake message { returns true, if it is a make/gmake message
Examples for make messages: Examples for make messages:
make[1]: Entering directory `<filename>' make[1]: Entering directory `<filename>'
@ -283,7 +284,13 @@ begin
MsgLine:=CreateMsgLine(OutputIndex); MsgLine:=CreateMsgLine(OutputIndex);
MsgLine.SubTool:=SubToolMake; MsgLine.SubTool:=SubToolMake;
if IsStdErr then
begin
MsgLine.Urgency:=mluImportant;
MsgLine.Flags:=MsgLine.Flags+[mlfStdErr];
end else begin
MsgLine.Urgency:=mluVerbose; MsgLine.Urgency:=mluVerbose;
end;
MsgLine.Msg:=Line; MsgLine.Msg:=Line;
if p^='[' then if p^='[' then
@ -324,7 +331,12 @@ begin
MsgLine:=CreateMsgLine(OutputIndex); MsgLine:=CreateMsgLine(OutputIndex);
MsgLine.SubTool:=SubToolMake; MsgLine.SubTool:=SubToolMake;
if IsStdErr then begin
MsgLine.Urgency:=mluImportant;
MsgLine.Flags:=MsgLine.Flags+[mlfStdErr];
end else begin
MsgLine.Urgency:=mluVerbose; MsgLine.Urgency:=mluVerbose;
end;
MsgLine.Msg:=Line; MsgLine.Msg:=Line;
AddMsgLine(MsgLine); AddMsgLine(MsgLine);
exit; exit;
@ -345,7 +357,12 @@ begin
Handled:=true; Handled:=true;
MsgLine:=CreateMsgLine(OutputIndex); MsgLine:=CreateMsgLine(OutputIndex);
MsgLine.SubTool:=SubToolMake; MsgLine.SubTool:=SubToolMake;
if IsStdErr then begin
MsgLine.Urgency:=mluImportant;
MsgLine.Flags:=MsgLine.Flags+[mlfStdErr];
end else begin
MsgLine.Urgency:=mluVerbose; MsgLine.Urgency:=mluVerbose;
end;
MsgLine.Msg:=Line; MsgLine.Msg:=Line;
AddMsgLine(MsgLine); AddMsgLine(MsgLine);
end; end;

View File

@ -306,7 +306,7 @@ var
OldOutputCount: LongInt; OldOutputCount: LongInt;
OldMsgCount: LongInt; OldMsgCount: LongInt;
Parser: TExtToolParser; Parser: TExtToolParser;
NeedSynchronize: Boolean; NeedSynchronize, IsStdErr: Boolean;
MsgLine: TMessageLine; MsgLine: TMessageLine;
LineStr: String; LineStr: String;
begin begin
@ -327,17 +327,20 @@ begin
for Line:=OldOutputCount to WorkerOutput.Count-1 do begin for Line:=OldOutputCount to WorkerOutput.Count-1 do begin
Handled:=false; Handled:=false;
LineStr:=WorkerOutput[Line]; LineStr:=WorkerOutput[Line];
IsStdErr:=WorkerOutput.Objects[Line]<>nil;
for i:=0 to ParserCount-1 do begin for i:=0 to ParserCount-1 do begin
{$IFDEF VerboseExtToolAddOutputLines} {$IFDEF VerboseExtToolAddOutputLines}
DebuglnThreadLog(['TExternalTool.AddOutputLines ',DbgSName(Parsers[i]),' Line="',WorkerOutput[Line],'" READLINE ...']); DebuglnThreadLog(['TExternalTool.AddOutputLines ',DbgSName(Parsers[i]),' Line="',WorkerOutput[Line],'" READLINE ...']);
{$ENDIF} {$ENDIF}
Parsers[i].ReadLine(LineStr,Line,Handled); Parsers[i].ReadLine(LineStr,Line,IsStdErr,Handled);
if Handled then break; if Handled then break;
end; end;
if (not Handled) then begin if (not Handled) then begin
MsgLine:=WorkerMessages.CreateLine(Line); MsgLine:=WorkerMessages.CreateLine(Line);
MsgLine.Msg:=LineStr; // use raw output as default msg MsgLine.Msg:=LineStr; // use raw output as default msg
MsgLine.Urgency:=mluDebug; MsgLine.Urgency:=mluDebug;
if IsStdErr then
MsgLine.Flags:=MsgLine.Flags+[mlfStdErr];
WorkerMessages.Add(MsgLine); WorkerMessages.Add(MsgLine);
end; end;
end; end;
@ -1420,7 +1423,8 @@ var
var var
Buf: string; Buf: string;
function ReadInputPipe(aStream: TInputPipeStream; var LineBuf: string): boolean; function ReadInputPipe(aStream: TInputPipeStream; var LineBuf: string;
IsStdErr: boolean): boolean;
// true if some bytes have been read // true if some bytes have been read
var var
Count: DWord; Count: DWord;
@ -1439,6 +1443,9 @@ var
while i<=Count do begin while i<=Count do begin
if Buf[i] in [#10,#13] then begin if Buf[i] in [#10,#13] then begin
LineBuf:=LineBuf+copy(Buf,StartPos,i-StartPos); LineBuf:=LineBuf+copy(Buf,StartPos,i-StartPos);
if IsStdErr then
fLines.AddObject(LineBuf,fLines)
else
fLines.Add(LineBuf); fLines.Add(LineBuf);
LineBuf:=''; LineBuf:='';
if (i<Count) and (Buf[i+1] in [#10,#13]) and (Buf[i]<>Buf[i+1]) if (i<Count) and (Buf[i+1] in [#10,#13]) and (Buf[i]<>Buf[i+1])
@ -1544,11 +1551,11 @@ begin
LastUpdate:=GetTickCount64; LastUpdate:=GetTickCount64;
while (Tool<>nil) and (Tool.Stage=etsRunning) do begin while (Tool<>nil) and (Tool.Stage=etsRunning) do begin
if Tool.ReadStdOutBeforeErr then begin if Tool.ReadStdOutBeforeErr then begin
HasOutput:=ReadInputPipe(Tool.Process.Output,OutputLine) HasOutput:=ReadInputPipe(Tool.Process.Output,OutputLine,false)
or ReadInputPipe(Tool.Process.Stderr,StdErrLine); or ReadInputPipe(Tool.Process.Stderr,StdErrLine,true);
end else begin end else begin
HasOutput:=ReadInputPipe(Tool.Process.Stderr,StdErrLine) HasOutput:=ReadInputPipe(Tool.Process.Stderr,StdErrLine,true)
or ReadInputPipe(Tool.Process.Output,OutputLine); or ReadInputPipe(Tool.Process.Output,OutputLine,false);
end; end;
if (not HasOutput) then begin if (not HasOutput) then begin
// no more pending output // no more pending output