
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2197 8e941d3f-bd1b-0410-a28a-d453659cc2b4
183 lines
5.0 KiB
ObjectPascal
183 lines
5.0 KiB
ObjectPascal
{ C-to-Pas converter command-line utility part of Lazarus Chelper package
|
|
|
|
Copyright (C) 2010 Dmitry Boyarintsev skalogryz dot lists at gmail.com
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or (at your
|
|
option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; if not, write to the Free Software Foundation,
|
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
}
|
|
program cconvert;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
uses
|
|
SysUtils,Classes,
|
|
ctopasconvert, cparsertypes, cparserutils, cconvconfig, objcparsing,
|
|
commonsrcgen;
|
|
|
|
var
|
|
ConfigFile : AnsiString = '';
|
|
OutputFile : AnsiString = '';
|
|
ConfigFileRO : Boolean = false;
|
|
ParseAll : Boolean = false;
|
|
ShowCodeSize : Boolean = False; // show the size of code processed
|
|
isPascalUnit : Boolean = False; // convert to pascal unit
|
|
|
|
function StringFromFile(const FileName: AnsiString): AnsiString;
|
|
var
|
|
fs : TFileStream;
|
|
begin
|
|
Result:='';
|
|
if not FileExists(FileName) then Exit;
|
|
try
|
|
fs:=TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
|
|
try
|
|
SetLength(Result, fs.Size);
|
|
fs.Read(Result[1], fs.Size);
|
|
finally
|
|
fs.Free;
|
|
end;
|
|
except
|
|
end;
|
|
end;
|
|
|
|
procedure InitSettings(cfg: TConvertSettings);
|
|
var
|
|
i : Integer;
|
|
p : AnsiString;
|
|
fn : AnsiString;
|
|
begin
|
|
i:=1;
|
|
while i<=Paramcount do begin
|
|
p:=AnsiLowerCase(ParamStr(i));
|
|
if p='-cfg' then begin
|
|
inc(i);
|
|
fn:=Trim(Paramstr(i));
|
|
ConfigFile:=fn;
|
|
if FileExists(fn) then cconvconfig.LoadFromFile(fn, cfg);
|
|
end else if p='-ro' then
|
|
ConfigFileRO:=True
|
|
else if p='-defines' then begin
|
|
inc(i);
|
|
cfg.CustomDefines:=cfg.CustomDefines+' ' + StringFromFile(ParamStr(i));
|
|
end else if p='-o' then begin
|
|
inc(i);
|
|
OutputFile:=ParamStr(i);
|
|
end else if p='-all' then begin
|
|
ParseAll:=True
|
|
end else if p='-pasunit' then
|
|
isPascalUnit:=True;
|
|
inc(i);
|
|
end;
|
|
end;
|
|
|
|
procedure PrintHelp;
|
|
begin
|
|
writeln('cconvert - c to pascal convert utility');
|
|
writeln('possible options:');
|
|
writeln(' -all - convert the whole header to pascal, instead of a first entity');
|
|
writeln(' -o filename - specify the output file. if not specified, outputs to stdout');
|
|
writeln(' -ro - prevent the configuration file from modifications (adding new types, etc)');
|
|
writeln(' -cfg filename - specifies the configuration file');
|
|
writeln(' -defines filename - macros definition file. should be in C-preprocessor format');
|
|
writeln(' -showunparsed - writes out unprased entities by their classname (for debugging only)');
|
|
writeln(' -codesize - show two numbers of the code processed (used by Chelper)');
|
|
writeln(' -pasunit - generates a pascal unit');
|
|
end;
|
|
|
|
procedure ReadParams(var InputFileName: String);
|
|
var
|
|
i : integer;
|
|
s : string;
|
|
begin
|
|
for i:=1 to ParamCount do begin
|
|
s:=LowerCase(ParamStr(i));
|
|
if (s='-h') or (s='-help') or (s='-?') then begin
|
|
PrintHelp;
|
|
Halt;
|
|
end else if s='-showunparsed' then
|
|
DoDebugEntities:=True;
|
|
end;
|
|
InputFileName:=ParamStr(ParamCount);
|
|
end;
|
|
|
|
|
|
function GetPascalUnitName(const UnitName: String): String;
|
|
begin
|
|
Result:=ChangeFileExt(UnitName, '');
|
|
end;
|
|
|
|
procedure AddPascalUnit(outs: TStrings; const UnitName: String);
|
|
begin
|
|
if not Assigned(outs) then Exit;
|
|
outs.Insert(0, 'unit '+UnitName+';');
|
|
outs.Insert(1, '');
|
|
outs.Insert(2, 'interface');
|
|
outs.Add( 'implementation');
|
|
outs.Add( 'end.');
|
|
end;
|
|
|
|
var
|
|
inps, outs : TStringList;
|
|
i : Integer;
|
|
p : TPoint;
|
|
cfg : TConvertSettings;
|
|
err : TErrorInfo;
|
|
fn : String;
|
|
begin
|
|
if ParamCount=0 then Exit;
|
|
ReadParams(fn);
|
|
if not FileExists(fn) then begin
|
|
writeln('file doesn''t exist: ', fn);
|
|
Exit;
|
|
end;
|
|
|
|
|
|
inps := TStringList.Create;
|
|
outs := TStringList.Create;
|
|
|
|
cfg:=TConvertSettings.Create;
|
|
try
|
|
InitSettings(cfg);
|
|
|
|
inps.LoadFromFile(ParamStr(ParamCount));
|
|
outs.Text:=ConvertCode(inps.Text, p, ParseAll, err, cfg);;
|
|
|
|
if ShowCodeSize then 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 isPascalUnit then begin
|
|
AddPascalUnit(outs, GetPascalUnitName(fn));
|
|
end;
|
|
|
|
|
|
if OutputFile<>'' then
|
|
outs.SaveToFile(OutputFile)
|
|
else
|
|
for i:=0 to outs.Count-1 do
|
|
writeln(outs[i]);
|
|
finally
|
|
if not ConfigFileRO and (ConfigFile<>'') then begin
|
|
ForceDirectories(ExtractFilePath(ConfigFile));
|
|
try
|
|
cconvconfig.SaveToFile(ConfigFile, cfg);
|
|
except
|
|
end;
|
|
end;
|
|
cfg.Free;
|
|
inps.Free;
|
|
outs.Free;
|
|
end;
|
|
end.
|
|
|