From 5efd49f60b8324e3cac40a6d3e6ccb4324d3a73d Mon Sep 17 00:00:00 2001 From: skalogryz Date: Fri, 13 Aug 2010 06:16:55 +0000 Subject: [PATCH] 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 --- components/chelper/cconvert.lpr | 6 +- components/chelper/ctopasconvert.pas | 85 ++++++++++++++++++++------- components/chelper/tosourceeditor.pas | 25 +++++--- 3 files changed, 86 insertions(+), 30 deletions(-) diff --git a/components/chelper/cconvert.lpr b/components/chelper/cconvert.lpr index c0769101f..2affa914e 100644 --- a/components/chelper/cconvert.lpr +++ b/components/chelper/cconvert.lpr @@ -28,6 +28,7 @@ var ConfigFile : AnsiString = ''; OutputFile : AnsiString = ''; ConfigFileRO : Boolean = false; + ParseAll : Boolean = false; function StringFromFile(const FileName: AnsiString): AnsiString; var @@ -69,7 +70,8 @@ begin end else if p='-o' then begin inc(i); OutputFile:=ParamStr(i); - end; + end else if p='-all' then + ParseAll:=True; inc(i); end; end; @@ -89,7 +91,7 @@ begin InitSettings(cfg); inps.LoadFromFile(ParamStr(ParamCount)); - outs.Text:=ConvertCode(inps.Text, p, cfg); + outs.Text:=ConvertCode(inps.Text, p, ParseAll, cfg); if OutputFile<>'' then begin outs.Insert(0, Format('%d %d', [p.Y,p.X])); outs.SaveToFile(OutputFile) diff --git a/components/chelper/ctopasconvert.pas b/components/chelper/ctopasconvert.pas index e7e1e0b54..96dfceb03 100644 --- a/components/chelper/ctopasconvert.pas +++ b/components/chelper/ctopasconvert.pas @@ -58,7 +58,7 @@ type // endPoint contains // Y - line number (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. // WARN: * the function doesn't handle macroses (treats them as identifiers) @@ -146,6 +146,7 @@ type wr : TCodeWriter; cfg : TConvertSettings; WriteFunc : TFuncWriterProc; + DebugEntities : Boolean; constructor Create(ASettings: TConvertSettings); destructor Destroy; override; procedure WriteCtoPas(cent: TEntity; comments: TList; const ParsedText: AnsiString); @@ -385,7 +386,33 @@ begin m.Free; 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 (it[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 p : TTextParser; ent : TEntity; @@ -394,10 +421,13 @@ var cnv : TCodeConvertor; macros : TCMacroHandler; owncfg : Boolean; + lastsec : AnsiString; // last code section + ofs : Integer; begin Result:=''; ent:=nil; owncfg:=not Assigned(cfg); + lastsec:=''; if owncfg then cfg := TConvertSettings.Create; try macros:=TCMacroHandler.Create; @@ -407,11 +437,34 @@ begin p := CreateCParser(t); p.MacroHandler:=macros; try - try - ent := ParseNextEntityOrComment(p); - except - on E: Exception do Result:='error while parsing C-code: '+e.Message; - end; + repeat + try + ofs := p.Index; + ent := ParseNextEntityOrComment(p); + 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; le := 0; @@ -424,23 +477,11 @@ begin end; 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 p.Free; macros.Free; - end; except on e: Exception do Result:=Result+LineEnding+' internal error: '+ e.Message; @@ -850,8 +891,10 @@ begin WriteCommentToPas(cent as TComment) else if cent is TCPrepDefine then WritePreprocessor(cent as TCPrepDefine) - else - wr.Wln(cent.ClassName); + else begin + if DebugEntities then + wr.Wln(cent.ClassName); + end; Breaker.Free; end; diff --git a/components/chelper/tosourceeditor.pas b/components/chelper/tosourceeditor.pas index 4751241b6..d485706b0 100644 --- a/components/chelper/tosourceeditor.pas +++ b/components/chelper/tosourceeditor.pas @@ -31,7 +31,7 @@ procedure Register; implementation -function DoExtConvert(const t: AnsiString; var EndPos: TPoint): AnsiString; +function DoExtConvert(const t: AnsiString; ParseAll: Boolean; var EndPos: TPoint): AnsiString; var p : TProcess; d : AnsiString; @@ -78,6 +78,7 @@ begin if (DefineFile<>'') and FileExists(DefineFile) then cmd:=cmd+' -defines "'+DefineFile+'" '; cmd:=cmd+' -o "'+outp+'" '; + if ParseAll then cmd:=cmd+' -all '; cmd:=cmd+'"'+inp+'"'; p.CommandLine:=cmd; @@ -125,7 +126,7 @@ begin 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 Result:=False; if UseExtTool then begin @@ -134,7 +135,7 @@ begin Exit; end; cconvconfig.SaveToFile(ConvFile, ConvSettings); - txt:=DoExtConvert(t, EndPoint); + txt:=DoExtConvert(t, ParseAll, EndPoint); Result:=(EndPoint.X>=0) and (EndPoint.Y>=0); if Result then cconvconfig.LoadFromFile(ConvFile, ConvSettings) @@ -147,7 +148,7 @@ end; var parsing : Boolean = False; -procedure TryParse; +procedure TryParse(ParseAll: Boolean); var editor : TSourceEditorInterface; i : Integer; @@ -172,7 +173,7 @@ begin for i:=i to editor.Lines.Count-1 do txt:=txt+editor.Lines[i]+#10; - if DoConvertCode(txt, p, s) then + if DoConvertCode(txt, ParseAll, p, s) then begin inc(p.Y, st.Y-1); st.X:=1; @@ -187,9 +188,15 @@ end; procedure OnCtoPasClick(Sender: TObject); begin - TryParse; + TryParse(False); end; +procedure OnCtoPasAllClick(Sender: TObject); +begin + TryParse(True); +end; + + procedure OnCtoPasOptionsClick(Sender: TObject); begin ShowConfigDialog; @@ -200,8 +207,12 @@ var cmd : TIDEMenuCommand; begin 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]); + + 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; procedure Register;