You've already forked lazarus-ccr
chelper: added parser error reports
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1291 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -8,6 +8,7 @@
|
|||||||
<MainUnitHasTitleStatement Value="False"/>
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
</Flags>
|
</Flags>
|
||||||
<SessionStorage Value="InProjectDir"/>
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
<UseAppBundle Value="False"/>
|
<UseAppBundle Value="False"/>
|
||||||
<ResourceType Value="res"/>
|
<ResourceType Value="res"/>
|
||||||
</General>
|
</General>
|
||||||
|
@ -22,7 +22,7 @@ program cconvert;
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils,Classes,
|
SysUtils,Classes,
|
||||||
ctopasconvert,cparsertypes,cparserutils,cconvconfig, objcparsing;
|
ctopasconvert,cparsertypes, cparserutils,cconvconfig, objcparsing;
|
||||||
|
|
||||||
var
|
var
|
||||||
ConfigFile : AnsiString = '';
|
ConfigFile : AnsiString = '';
|
||||||
@ -81,6 +81,7 @@ var
|
|||||||
i : Integer;
|
i : Integer;
|
||||||
p : TPoint;
|
p : TPoint;
|
||||||
cfg : TConvertSettings;
|
cfg : TConvertSettings;
|
||||||
|
err : TErrorInfo;
|
||||||
begin
|
begin
|
||||||
if ParamCount=0 then Exit;
|
if ParamCount=0 then Exit;
|
||||||
inps := TStringList.Create;
|
inps := TStringList.Create;
|
||||||
@ -91,15 +92,15 @@ begin
|
|||||||
InitSettings(cfg);
|
InitSettings(cfg);
|
||||||
|
|
||||||
inps.LoadFromFile(ParamStr(ParamCount));
|
inps.LoadFromFile(ParamStr(ParamCount));
|
||||||
outs.Text:=ConvertCode(inps.Text, p, ParseAll, cfg);
|
outs.Text:=ConvertCode(inps.Text, p, ParseAll, err, cfg);;
|
||||||
if OutputFile<>'' then begin
|
outs.Insert(0, Format('%d %d', [p.Y,p.X]));
|
||||||
outs.Insert(0, Format('%d %d', [p.Y,p.X]));
|
if err.isError then outs.Insert(0, Format('error %d %d %s',[err.ErrorPos.Y, err.ErrorPos. X, err.ErrorMsg]) );
|
||||||
|
|
||||||
|
if OutputFile<>'' then
|
||||||
outs.SaveToFile(OutputFile)
|
outs.SaveToFile(OutputFile)
|
||||||
end else begin
|
else
|
||||||
writeln(p.Y,' ',p.X);
|
|
||||||
for i:=0 to outs.Count-1 do
|
for i:=0 to outs.Count-1 do
|
||||||
writeln(outs[i]);
|
writeln(outs[i]);
|
||||||
end;
|
|
||||||
finally
|
finally
|
||||||
if not ConfigFileRO and (ConfigFile<>'') then begin
|
if not ConfigFileRO and (ConfigFile<>'') then begin
|
||||||
ForceDirectories(ExtractFilePath(ConfigFile));
|
ForceDirectories(ExtractFilePath(ConfigFile));
|
||||||
|
@ -290,7 +290,8 @@ var
|
|||||||
ParseNextEntity: function (AParser: TTextParser): TEntity = nil;
|
ParseNextEntity: function (AParser: TTextParser): TEntity = nil;
|
||||||
ParseNamePart : function (Parser: TTextParser): TNamePart = nil;
|
ParseNamePart : function (Parser: TTextParser): TNamePart = nil;
|
||||||
|
|
||||||
function ParseNextCEntity(AParser: TTextParser): TEntity;
|
function ParseNextCEntity(AParser: TTextParser): TEntity; // default ParseNextEntity
|
||||||
|
function ParseCNamePart(Parser: TTextParser): TNamePart; // default ParseNamePart
|
||||||
|
|
||||||
function ParseCExpression(AParser: TTextParser; var ExpS: AnsiString): Boolean;
|
function ParseCExpression(AParser: TTextParser; var ExpS: AnsiString): Boolean;
|
||||||
procedure ParseCNumeric(const S: AnsiString; var idx: integer; var NumStr: AnsiSTring);
|
procedure ParseCNumeric(const S: AnsiString; var idx: integer; var NumStr: AnsiSTring);
|
||||||
@ -1500,12 +1501,16 @@ begin
|
|||||||
Result:=v;
|
Result:=v;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if AParser.Token<>';' then ErrorExpect(AParser,';');
|
if AParser.Token<>';' then begin
|
||||||
|
Result.Free;
|
||||||
|
Result:=nil;
|
||||||
|
ErrorExpect(AParser,';');
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ErrorExpect(Parser:TTextParser;const Expect:AnsiString);
|
procedure ErrorExpect(Parser:TTextParser;const Expect:AnsiString);
|
||||||
begin
|
begin
|
||||||
Parser.SetError('Excepcted: '+ Expect);
|
Parser.SetError('expected: "'+ Expect + '" but "'+Parser.Token+'" found');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ConsumeToken(Parser:TTextParser;const Token:AnsiString):Boolean;
|
function ConsumeToken(Parser:TTextParser;const Token:AnsiString):Boolean;
|
||||||
@ -1718,6 +1723,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function isEndOfName(APArser: TTextParser): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=(AParser.TokenType=tt_Symbol) and (AParser.Token[1] in [';',')',',']);
|
||||||
|
end;
|
||||||
|
|
||||||
function ParseNames(Parser: TTextParser; var NameType: TEntity; Names: TList; AllowMultipleNames: Boolean): Boolean;
|
function ParseNames(Parser: TTextParser; var NameType: TEntity; Names: TList; AllowMultipleNames: Boolean): Boolean;
|
||||||
var
|
var
|
||||||
Name : TNamePart;
|
Name : TNamePart;
|
||||||
@ -1750,10 +1760,10 @@ begin
|
|||||||
Result:=True;
|
Result:=True;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
done:=(Parser.Token<>',') and (Parser.Token=')');
|
done:=isEndOfName(Parser);
|
||||||
if not done then begin
|
if not done then begin
|
||||||
if Parser.Token <> ',' then begin
|
if Parser.Token <> ',' then begin
|
||||||
ErrorExpect(Parser, ')');
|
ErrorExpect(Parser, ';');
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
Parser.NextToken;
|
Parser.NextToken;
|
||||||
|
@ -61,10 +61,16 @@ type
|
|||||||
function GetTypeName(const CTypeName: AnsiString): Ansistring;
|
function GetTypeName(const CTypeName: AnsiString): Ansistring;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TErrorInfo = record
|
||||||
|
isError : Boolean;
|
||||||
|
ErrorMsg : AnsiString; // error message
|
||||||
|
ErrorPos : TPoint; // position in ORIGINAL (not-macrosed) text
|
||||||
|
end;
|
||||||
|
|
||||||
// endPoint contains
|
// endPoint contains
|
||||||
// Y - line number (starting from 1),
|
// Y - line number (starting from 1),
|
||||||
// X - column (starting from 1);
|
// X - column (starting from 1);
|
||||||
function ConvertCode(const t: AnsiString; var endPoint: TPoint; AllText: Boolean; cfg: TConvertSettings = nil): AnsiString;
|
function ConvertCode(const t: AnsiString; var endPoint: TPoint; AllText: Boolean; var ParseError: TErrorInfo; cfg: TConvertSettings = nil): AnsiString;
|
||||||
|
|
||||||
// converts C-expression to Pascal expression, replace symbols with pascal equvialents.
|
// converts C-expression to Pascal expression, replace symbols with pascal equvialents.
|
||||||
// WARN: * the function doesn't handle macroses (treats them as identifiers)
|
// WARN: * the function doesn't handle macroses (treats them as identifiers)
|
||||||
@ -291,7 +297,7 @@ begin
|
|||||||
PrecompEnd:=-1;
|
PrecompEnd:=-1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ParseNextEntityOrComment(AParser: TTextParser; cmt: TStopComment): TEntity;
|
function ParseNextEntityOrComment(AParser: TTextParser; cmt: TStopComment; var ParseError: TErrorInfo): TEntity;
|
||||||
var
|
var
|
||||||
ent : TEntity;
|
ent : TEntity;
|
||||||
entidx : Integer;
|
entidx : Integer;
|
||||||
@ -313,6 +319,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if (not Assigned(Result)) or (Assigned(ent) and (ent.Offset<Result.Offset)) then begin
|
if (not Assigned(Result)) or (Assigned(ent) and (ent.Offset<Result.Offset)) then begin
|
||||||
|
if AParser.Errors.Count>0 then begin
|
||||||
|
ParseError.ErrorPos.X:=AParser.TokenPos;
|
||||||
|
ParseError.ErrorMsg:=AParser.Errors[0];
|
||||||
|
ParseError.isError:=True;
|
||||||
|
end;
|
||||||
Result:=ent;
|
Result:=ent;
|
||||||
AParser.Index:=entidx;
|
AParser.Index:=entidx;
|
||||||
end;
|
end;
|
||||||
@ -428,19 +439,20 @@ begin
|
|||||||
for i:=1 to c do Result:=Result+LineEnding;
|
for i:=1 to c do Result:=Result+LineEnding;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ConvertCode(const t: AnsiString; var endPoint: TPoint; AllText: Boolean; cfg: TConvertSettings): AnsiString;
|
function ConvertCode(const t: AnsiString; var endPoint: TPoint; AllText: Boolean; var ParseError: TErrorInfo; cfg: TConvertSettings): AnsiString;
|
||||||
var
|
var
|
||||||
p : TTextParser;
|
p : TTextParser;
|
||||||
ent : TEntity;
|
ent : TEntity;
|
||||||
i : integer;
|
|
||||||
le : integer;
|
|
||||||
cnv : TCodeConvertor;
|
cnv : TCodeConvertor;
|
||||||
macros : TCMacroHandler;
|
macros : TCMacroHandler;
|
||||||
owncfg : Boolean;
|
owncfg : Boolean;
|
||||||
lastsec : AnsiString; // last code section
|
lastsec : AnsiString; // last code section
|
||||||
ofs : Integer;
|
ofs : Integer;
|
||||||
cmt : TStopComment;
|
cmt : TStopComment;
|
||||||
|
i : Integer;
|
||||||
|
succidx : Integer;
|
||||||
begin
|
begin
|
||||||
|
FillChar(ParseError, sizeof(ParseError), 0);
|
||||||
Result:='';
|
Result:='';
|
||||||
ent:=nil;
|
ent:=nil;
|
||||||
owncfg:=not Assigned(cfg);
|
owncfg:=not Assigned(cfg);
|
||||||
@ -460,14 +472,20 @@ begin
|
|||||||
|
|
||||||
try
|
try
|
||||||
repeat
|
repeat
|
||||||
|
cmt.Clear;
|
||||||
try
|
try
|
||||||
ofs := p.Index;
|
ofs := p.Index;
|
||||||
p.NextToken;
|
p.NextToken;
|
||||||
ent := ParseNextEntityOrComment(p, cmt);
|
ent := ParseNextEntityOrComment(p, cmt, ParseError);
|
||||||
except
|
except
|
||||||
ent:=nil;
|
ent:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if ParseError.isError then
|
||||||
|
Break
|
||||||
|
else
|
||||||
|
succidx:=p.Index + p.MacrosDelta;
|
||||||
|
|
||||||
if Assigned(ent) then begin
|
if Assigned(ent) then begin
|
||||||
cnv := TCodeConvertor.Create(cfg);
|
cnv := TCodeConvertor.Create(cfg);
|
||||||
try
|
try
|
||||||
@ -498,16 +516,11 @@ begin
|
|||||||
|
|
||||||
until (ent=nil) or not AllText;
|
until (ent=nil) or not AllText;
|
||||||
|
|
||||||
i := 1;
|
|
||||||
le := 0;
|
OffsetToLinePos(t, succidx, endPoint);
|
||||||
endPoint.X := 0;
|
|
||||||
endPoint.Y := 0;
|
if ParseError.isError then
|
||||||
while i < p.Index do begin
|
OffsetToLinePos(t, ParseError.ErrorPos.X + p.MacrosDelta, ParseError.ErrorPos);
|
||||||
Inc(endPoint.Y);
|
|
||||||
le := i;
|
|
||||||
SkipLine(p.Buf, i);
|
|
||||||
end;
|
|
||||||
endPoint.X := p.Index - le + 1 + p.MacrosDelta;
|
|
||||||
|
|
||||||
finally
|
finally
|
||||||
p.Free;
|
p.Free;
|
||||||
|
@ -304,7 +304,8 @@ begin
|
|||||||
if AParser.Token='>' then AParser.NextToken;
|
if AParser.Token='>' then AParser.NextToken;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if ParseMethods(AParser, p.Methods, objcend) then Result:=p;
|
if ParseMethods(AParser, p.Methods, objcend) then
|
||||||
|
Result:=p;
|
||||||
if AParser.Token<>objcend then ErrorExpect(AParser, objcend);
|
if AParser.Token<>objcend then ErrorExpect(AParser, objcend);
|
||||||
finally
|
finally
|
||||||
if not Assigned(Result) then p.Free;
|
if not Assigned(Result) then p.Free;
|
||||||
|
@ -22,6 +22,9 @@ unit TextParsingUtils;
|
|||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Types;
|
||||||
|
|
||||||
type
|
type
|
||||||
TCharSet = set of Char;
|
TCharSet = set of Char;
|
||||||
|
|
||||||
@ -50,6 +53,8 @@ function SkipCommentBlock(const s: AnsiString; var index: Integer; const closecm
|
|||||||
|
|
||||||
function SkipLine(const s: AnsiString; var index: Integer): AnsiString;
|
function SkipLine(const s: AnsiString; var index: Integer): AnsiString;
|
||||||
|
|
||||||
|
function OffsetToLinePos(const t: AnsiString; Offset: Integer; var P: TPoint): AnsiString;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
||||||
@ -147,5 +152,21 @@ begin
|
|||||||
inc(index);
|
inc(index);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function OffsetToLinePos(const t: AnsiString; Offset: Integer; var P: TPoint): AnsiString;
|
||||||
|
var
|
||||||
|
i, le : Integer;
|
||||||
|
begin
|
||||||
|
i := 1;
|
||||||
|
le := 0;
|
||||||
|
P.X := 0;
|
||||||
|
P.Y := 0;
|
||||||
|
while i < Offset do begin
|
||||||
|
Inc(P.Y);
|
||||||
|
le := i;
|
||||||
|
SkipLine(t, i);
|
||||||
|
end;
|
||||||
|
P.X := Offset - le + 1;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -24,14 +24,44 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Dialogs, LCLType, LCLIntf, Forms,
|
Classes, SysUtils, Dialogs, LCLType, LCLIntf, Forms,
|
||||||
Menus, MenuIntf, SrcEditorIntf, process, LazIDEIntf,
|
Menus, MenuIntf, SrcEditorIntf, process, LazIDEIntf, IDEMsgIntf,
|
||||||
extconvdialog, converteridesettings, cconvconfig;
|
extconvdialog, converteridesettings, cconvconfig;
|
||||||
|
|
||||||
procedure Register;
|
procedure Register;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function DoExtConvert(const t: AnsiString; ParseAll: Boolean; var EndPos: TPoint): AnsiString;
|
type
|
||||||
|
TErrorInfo = record
|
||||||
|
isError : Boolean;
|
||||||
|
Error : AnsiString;
|
||||||
|
ErrorPos : TPoint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function GetErrorInfo(const errstr: AnsiString; var error: TerrorInfo): Boolean;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
d : AnsiString;
|
||||||
|
err : Integer;
|
||||||
|
begin
|
||||||
|
i:=Pos('error ', errstr);
|
||||||
|
error.isError:=i>0;
|
||||||
|
Result:=error.isError;
|
||||||
|
if not error.isError then Exit;
|
||||||
|
|
||||||
|
d:=Copy(errstr, 7, length(errstr)-6);
|
||||||
|
i:=Pos(' ', d);
|
||||||
|
Val( copy(d, 1, i-1), error.ErrorPos.Y, err);
|
||||||
|
d:=Copy(d, i+1, length(d));
|
||||||
|
|
||||||
|
i:=Pos(' ', d);
|
||||||
|
Val( copy(d, 1, i-1), error.ErrorPos.X, err);
|
||||||
|
|
||||||
|
error.Error:=Copy(d, i+1, length(d));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function DoExtConvert(const t: AnsiString; ParseAll: Boolean; var EndPos: TPoint; var error: TErrorInfo): AnsiString;
|
||||||
var
|
var
|
||||||
p : TProcess;
|
p : TProcess;
|
||||||
d : AnsiString;
|
d : AnsiString;
|
||||||
@ -104,7 +134,10 @@ begin
|
|||||||
try
|
try
|
||||||
st.LoadFromFile(outp);
|
st.LoadFromFile(outp);
|
||||||
if st.Count=0 then Exit;
|
if st.Count=0 then Exit;
|
||||||
|
i:=0;
|
||||||
d:=st[0];
|
d:=st[0];
|
||||||
|
if GetErrorInfo(d, error) then d:=st[1];
|
||||||
|
|
||||||
if d='' then Exit;
|
if d='' then Exit;
|
||||||
i:=Pos(' ', d);
|
i:=Pos(' ', d);
|
||||||
if i>=1 then begin
|
if i>=1 then begin
|
||||||
@ -126,7 +159,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function DoConvertCode(const t: AnsiString; ParseAll: Boolean; var EndPoint: TPoint; var txt: AnsiString): Boolean;
|
function DoConvertCode(const t: AnsiString; ParseAll: Boolean; var EndPoint: TPoint; var txt: AnsiString; var error: TErrorInfo): Boolean;
|
||||||
begin
|
begin
|
||||||
Result:=False;
|
Result:=False;
|
||||||
if UseExtTool then begin
|
if UseExtTool then begin
|
||||||
@ -135,7 +168,7 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
cconvconfig.SaveToFile(ConvFile, ConvSettings);
|
cconvconfig.SaveToFile(ConvFile, ConvSettings);
|
||||||
txt:=DoExtConvert(t, ParseAll, EndPoint);
|
txt:=DoExtConvert(t, ParseAll, EndPoint, error);
|
||||||
Result:=(EndPoint.X>=0) and (EndPoint.Y>=0);
|
Result:=(EndPoint.X>=0) and (EndPoint.Y>=0);
|
||||||
|
|
||||||
if Result then cconvconfig.LoadFromFile(ConvFile, ConvSettings)
|
if Result then cconvconfig.LoadFromFile(ConvFile, ConvSettings)
|
||||||
@ -156,6 +189,9 @@ var
|
|||||||
s : AnsiString;
|
s : AnsiString;
|
||||||
p : TPoint;
|
p : TPoint;
|
||||||
st : TPoint;
|
st : TPoint;
|
||||||
|
err : TErrorInfo;
|
||||||
|
line : TIDEMessageLine;
|
||||||
|
parts : TStringList;
|
||||||
begin
|
begin
|
||||||
if parsing then Exit;
|
if parsing then Exit;
|
||||||
if not Assigned(SourceEditorManagerIntf) or not Assigned(SourceEditorManagerIntf.ActiveEditor) then Exit;
|
if not Assigned(SourceEditorManagerIntf) or not Assigned(SourceEditorManagerIntf.ActiveEditor) then Exit;
|
||||||
@ -173,13 +209,34 @@ begin
|
|||||||
for i:=i to editor.Lines.Count-1 do
|
for i:=i to editor.Lines.Count-1 do
|
||||||
txt:=txt+editor.Lines[i]+#10;
|
txt:=txt+editor.Lines[i]+#10;
|
||||||
|
|
||||||
if DoConvertCode(txt, ParseAll, p, s) then
|
if Assigned(IDEMessagesWindow) then IDEMessagesWindow.Clear;
|
||||||
|
|
||||||
|
if DoConvertCode(txt, ParseAll, p, s, err) then
|
||||||
begin
|
begin
|
||||||
inc(p.Y, st.Y-1);
|
if p.Y>0 then begin
|
||||||
st.X:=1;
|
inc(p.Y, st.Y-1);
|
||||||
editor.ReplaceText(st, p, s);
|
st.X:=1;
|
||||||
if Assigned(CtoPasConfig) then
|
editor.ReplaceText(st, p, s);
|
||||||
CtoPasConfig.SettingsToUI;
|
if Assigned(CtoPasConfig) then
|
||||||
|
CtoPasConfig.SettingsToUI;
|
||||||
|
end;
|
||||||
|
if err.isError then begin
|
||||||
|
inc(err.ErrorPos.Y, st.Y-1);
|
||||||
|
if Assigned(IDEMessagesWindow) then begin
|
||||||
|
s:=Format('%s(%d,%d) Chelper: %s', [ExtractFileName(editor.FileName), err.ErrorPos.Y,err.ErrorPos.X, err.Error]);
|
||||||
|
parts:=TStringList.Create;
|
||||||
|
try
|
||||||
|
parts.Values['Type']:='Chelper';
|
||||||
|
parts.Values['Filename']:=editor.FileName;
|
||||||
|
parts.Values['Line']:=IntToStr(err.ErrorPos.Y);
|
||||||
|
parts.Values['Column']:=IntToStr(err.ErrorPos.X);
|
||||||
|
IDEMessagesWindow.AddMsg(s, ExtractFileDir(editor.FileName), -1, parts);
|
||||||
|
finally
|
||||||
|
parts.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
editor.CursorTextXY:=err.ErrorPos;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
parsing:=False;
|
parsing:=False;
|
||||||
@ -215,6 +272,43 @@ begin
|
|||||||
RegisterIDEMenuCommand(itmSecondaryTools, 'CtoPas', 'C to Pascal Options', nil, @OnCtoPasOptionsClick);
|
RegisterIDEMenuCommand(itmSecondaryTools, 'CtoPas', 'C to Pascal Options', nil, @OnCtoPasOptionsClick);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TChelperJumper }
|
||||||
|
|
||||||
|
TChelperJumper = class(TIDEMsgQuickFixItem)
|
||||||
|
constructor Create;
|
||||||
|
procedure Execute(const Msg: TIDEMessageLine; Step: TIMQuickFixStep); override;
|
||||||
|
function IsApplicable(Line: TIDEMessageLine): boolean; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TChelperJumper.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
Name:='Chelper code jumper';
|
||||||
|
Caption:='Chelper code jumper';
|
||||||
|
Steps:=[imqfoJump]
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChelperJumper.IsApplicable(Line: TIDEMessageLine): boolean;
|
||||||
|
begin
|
||||||
|
Result:=Assigned(Line) and Assigned(Line.Parts) and (Line.Parts.Values['Type']='Chelper');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChelperJumper.Execute(const Msg: TIDEMessageLine; Step: TIMQuickFixStep);
|
||||||
|
var
|
||||||
|
fn : AnsiString;
|
||||||
|
ln : Integer;
|
||||||
|
cl : Integer;
|
||||||
|
begin
|
||||||
|
if Step=imqfoJump then begin
|
||||||
|
if Msg.Parts.Values['Type']<>'Chelper' then Exit;
|
||||||
|
Msg.GetSourcePosition(fn, ln, cl);
|
||||||
|
LazarusIDE.DoOpenFileAndJumpToPos(fn, Point(cl, ln), -1, -1, -1, [ofOnlyIfExists,ofRegularFile,ofVirtualFile]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure Register;
|
procedure Register;
|
||||||
var
|
var
|
||||||
pth : AnsiString;
|
pth : AnsiString;
|
||||||
@ -225,6 +319,7 @@ begin
|
|||||||
LoadFromFile(ConvFile, ConvSettings);
|
LoadFromFile(ConvFile, ConvSettings);
|
||||||
ReadIDESettings(ConvFile);
|
ReadIDESettings(ConvFile);
|
||||||
if DefineFile='' then DefineFile:=pth+'cconvdefines.h';
|
if DefineFile='' then DefineFile:=pth+'cconvdefines.h';
|
||||||
|
RegisterIDEMsgQuickFix(TChelperJumper.Create);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
Reference in New Issue
Block a user