chelper: added whole header convertion (ctrl+shift+b)

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1281 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2010-08-13 06:16:55 +00:00
parent ec064bd16e
commit 5efd49f60b
3 changed files with 86 additions and 30 deletions

View File

@ -28,6 +28,7 @@ var
ConfigFile : AnsiString = ''; ConfigFile : AnsiString = '';
OutputFile : AnsiString = ''; OutputFile : AnsiString = '';
ConfigFileRO : Boolean = false; ConfigFileRO : Boolean = false;
ParseAll : Boolean = false;
function StringFromFile(const FileName: AnsiString): AnsiString; function StringFromFile(const FileName: AnsiString): AnsiString;
var var
@ -69,7 +70,8 @@ begin
end else if p='-o' then begin end else if p='-o' then begin
inc(i); inc(i);
OutputFile:=ParamStr(i); OutputFile:=ParamStr(i);
end; end else if p='-all' then
ParseAll:=True;
inc(i); inc(i);
end; end;
end; end;
@ -89,7 +91,7 @@ begin
InitSettings(cfg); InitSettings(cfg);
inps.LoadFromFile(ParamStr(ParamCount)); inps.LoadFromFile(ParamStr(ParamCount));
outs.Text:=ConvertCode(inps.Text, p, cfg); outs.Text:=ConvertCode(inps.Text, p, ParseAll, cfg);
if OutputFile<>'' then begin if OutputFile<>'' then begin
outs.Insert(0, Format('%d %d', [p.Y,p.X])); outs.Insert(0, Format('%d %d', [p.Y,p.X]));
outs.SaveToFile(OutputFile) outs.SaveToFile(OutputFile)

View File

@ -58,7 +58,7 @@ type
// 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; cfg: TConvertSettings = nil): AnsiString; function ConvertCode(const t: AnsiString; var endPoint: TPoint; AllText: Boolean; 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)
@ -146,6 +146,7 @@ type
wr : TCodeWriter; wr : TCodeWriter;
cfg : TConvertSettings; cfg : TConvertSettings;
WriteFunc : TFuncWriterProc; WriteFunc : TFuncWriterProc;
DebugEntities : Boolean;
constructor Create(ASettings: TConvertSettings); constructor Create(ASettings: TConvertSettings);
destructor Destroy; override; destructor Destroy; override;
procedure WriteCtoPas(cent: TEntity; comments: TList; const ParsedText: AnsiString); procedure WriteCtoPas(cent: TEntity; comments: TList; const ParsedText: AnsiString);
@ -385,7 +386,33 @@ begin
m.Free; m.Free;
end; end;
function ConvertCode(const t: AnsiString; var endPoint: TPoint; cfg: TConvertSettings): AnsiString; function GetEmptyLinesCount(const t: AnsiString; StartOfs, EndOfs: Integer): Integer;
var
i : Integer;
begin
i:=StartOfs;
if i<=0 then Exit;
Result:=0;
while (i<EndOfs) and (i<=length(t)) do begin
if t[i] in [#13,#10] then begin
inc(Result); inc(i);
if (i<=length(t)) and (t[i] in [#13,#10]) and (t[i]<>t[i-1]) then inc(i);
end;
inc(i);
end;
end;
function GetEmptyLines(const t: AnsiString; StartOfs, EndOfs: Integer): AnsiString;
var
i : Integer;
c : Integer;
begin
c:=GetEmptyLinesCount(t, StartOfs, EndOfs);
for i:=1 to c do Result:=Result+LineEnding;
end;
function ConvertCode(const t: AnsiString; var endPoint: TPoint; AllText: Boolean; cfg: TConvertSettings): AnsiString;
var var
p : TTextParser; p : TTextParser;
ent : TEntity; ent : TEntity;
@ -394,10 +421,13 @@ var
cnv : TCodeConvertor; cnv : TCodeConvertor;
macros : TCMacroHandler; macros : TCMacroHandler;
owncfg : Boolean; owncfg : Boolean;
lastsec : AnsiString; // last code section
ofs : Integer;
begin begin
Result:=''; Result:='';
ent:=nil; ent:=nil;
owncfg:=not Assigned(cfg); owncfg:=not Assigned(cfg);
lastsec:='';
if owncfg then cfg := TConvertSettings.Create; if owncfg then cfg := TConvertSettings.Create;
try try
macros:=TCMacroHandler.Create; macros:=TCMacroHandler.Create;
@ -407,12 +437,35 @@ begin
p := CreateCParser(t); p := CreateCParser(t);
p.MacroHandler:=macros; p.MacroHandler:=macros;
try try
repeat
try try
ofs := p.Index;
ent := ParseNextEntityOrComment(p); ent := ParseNextEntityOrComment(p);
except except
on E: Exception do Result:='error while parsing C-code: '+e.Message; ent:=nil;
end; end;
if Assigned(ent) then begin
cnv := TCodeConvertor.Create(cfg);
try
cnv.wr.Section:=lastsec;
if lastsec<>'' then cnv.wr.IncIdent;
cnv.WriteCtoPas(ent, p.Comments, t);
lastsec:=cnv.wr.Section;
except
on e: Exception do Result:=Result+LineEnding+ 'error while converting C code: ' + e.Message;
end;
Result := Result+GetEmptyLines(p.Buf, ofs, ent.Offset)+cnv.wr.Text;
cnv.Free;
end;
for i:=0 to p.Comments.Count-1 do TComment(p.Comments[i]).Free;
p.Comments.Clear;
until (ent=nil) or not AllText;
i := 1; i := 1;
le := 0; le := 0;
endPoint.X := 0; endPoint.X := 0;
@ -424,23 +477,11 @@ begin
end; end;
endPoint.X := p.Index - le + 1 + p.MacrosDelta; endPoint.X := p.Index - le + 1 + p.MacrosDelta;
if Assigned(ent) then begin
cnv := TCodeConvertor.Create(cfg);
try
cnv.WriteCtoPas(ent, p.Comments, t);
except
on e: Exception do Result:=Result+LineEnding+ 'error while converting C code: ' + e.Message;
end;
Result := cnv.wr.Text;
cnv.Free;
end else
Result:='unable to parse C expression';
finally finally
p.Free; p.Free;
macros.Free; macros.Free;
end; end;
except except
on e: Exception do Result:=Result+LineEnding+' internal error: '+ e.Message; on e: Exception do Result:=Result+LineEnding+' internal error: '+ e.Message;
@ -850,8 +891,10 @@ begin
WriteCommentToPas(cent as TComment) WriteCommentToPas(cent as TComment)
else if cent is TCPrepDefine then else if cent is TCPrepDefine then
WritePreprocessor(cent as TCPrepDefine) WritePreprocessor(cent as TCPrepDefine)
else else begin
if DebugEntities then
wr.Wln(cent.ClassName); wr.Wln(cent.ClassName);
end;
Breaker.Free; Breaker.Free;
end; end;

View File

@ -31,7 +31,7 @@ procedure Register;
implementation implementation
function DoExtConvert(const t: AnsiString; var EndPos: TPoint): AnsiString; function DoExtConvert(const t: AnsiString; ParseAll: Boolean; var EndPos: TPoint): AnsiString;
var var
p : TProcess; p : TProcess;
d : AnsiString; d : AnsiString;
@ -78,6 +78,7 @@ begin
if (DefineFile<>'') and FileExists(DefineFile) then if (DefineFile<>'') and FileExists(DefineFile) then
cmd:=cmd+' -defines "'+DefineFile+'" '; cmd:=cmd+' -defines "'+DefineFile+'" ';
cmd:=cmd+' -o "'+outp+'" '; cmd:=cmd+' -o "'+outp+'" ';
if ParseAll then cmd:=cmd+' -all ';
cmd:=cmd+'"'+inp+'"'; cmd:=cmd+'"'+inp+'"';
p.CommandLine:=cmd; p.CommandLine:=cmd;
@ -125,7 +126,7 @@ begin
end; end;
end; end;
function DoConvertCode(const t: AnsiString; var EndPoint: TPoint; var txt: AnsiString): Boolean; function DoConvertCode(const t: AnsiString; ParseAll: Boolean; var EndPoint: TPoint; var txt: AnsiString): Boolean;
begin begin
Result:=False; Result:=False;
if UseExtTool then begin if UseExtTool then begin
@ -134,7 +135,7 @@ begin
Exit; Exit;
end; end;
cconvconfig.SaveToFile(ConvFile, ConvSettings); cconvconfig.SaveToFile(ConvFile, ConvSettings);
txt:=DoExtConvert(t, EndPoint); txt:=DoExtConvert(t, ParseAll, EndPoint);
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)
@ -147,7 +148,7 @@ end;
var var
parsing : Boolean = False; parsing : Boolean = False;
procedure TryParse; procedure TryParse(ParseAll: Boolean);
var var
editor : TSourceEditorInterface; editor : TSourceEditorInterface;
i : Integer; i : Integer;
@ -172,7 +173,7 @@ 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, p, s) then if DoConvertCode(txt, ParseAll, p, s) then
begin begin
inc(p.Y, st.Y-1); inc(p.Y, st.Y-1);
st.X:=1; st.X:=1;
@ -187,9 +188,15 @@ end;
procedure OnCtoPasClick(Sender: TObject); procedure OnCtoPasClick(Sender: TObject);
begin begin
TryParse; TryParse(False);
end; end;
procedure OnCtoPasAllClick(Sender: TObject);
begin
TryParse(True);
end;
procedure OnCtoPasOptionsClick(Sender: TObject); procedure OnCtoPasOptionsClick(Sender: TObject);
begin begin
ShowConfigDialog; ShowConfigDialog;
@ -200,8 +207,12 @@ var
cmd : TIDEMenuCommand; cmd : TIDEMenuCommand;
begin begin
cmd:=RegisterIDEMenuCommand(itmSecondaryTools, 'CtoPas', 'C to Pascal', nil, @OnCtoPasClick); cmd:=RegisterIDEMenuCommand(itmSecondaryTools, 'CtoPas', 'C to Pascal', nil, @OnCtoPasClick);
RegisterIDEMenuCommand(itmSecondaryTools, 'CtoPas', 'C to Pascal Options', nil, @OnCtoPasOptionsClick);
if Assigned(cmd) and Assigned(cmd.MenuItem) then cmd.MenuItem.ShortCut:=ShortCut(VK_B, [ssCtrl]); if Assigned(cmd) and Assigned(cmd.MenuItem) then cmd.MenuItem.ShortCut:=ShortCut(VK_B, [ssCtrl]);
cmd:=RegisterIDEMenuCommand(itmSecondaryTools, 'CtoPas', 'C to Pascal all', nil, @OnCtoPasAllClick);
if Assigned(cmd) and Assigned(cmd.MenuItem) then cmd.MenuItem.ShortCut:=ShortCut(VK_B, [ssShift, ssCtrl]);
RegisterIDEMenuCommand(itmSecondaryTools, 'CtoPas', 'C to Pascal Options', nil, @OnCtoPasOptionsClick);
end; end;
procedure Register; procedure Register;