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,11 +437,34 @@ begin
p := CreateCParser(t); p := CreateCParser(t);
p.MacroHandler:=macros; p.MacroHandler:=macros;
try try
try repeat
ent := ParseNextEntityOrComment(p); try
except ofs := p.Index;
on E: Exception do Result:='error while parsing C-code: '+e.Message; ent := ParseNextEntityOrComment(p);
end; except
ent:=nil;
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;
@ -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
wr.Wln(cent.ClassName); if DebugEntities then
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;