diff --git a/components/chelper/cconvert.lpi b/components/chelper/cconvert.lpi
index f3632b324..e9a551dd4 100644
--- a/components/chelper/cconvert.lpi
+++ b/components/chelper/cconvert.lpi
@@ -34,7 +34,7 @@
-
+
@@ -45,6 +45,10 @@
+
+
+
+
diff --git a/components/chelper/cconvert.lpr b/components/chelper/cconvert.lpr
index 783d9e7e8..7ebea01b1 100644
--- a/components/chelper/cconvert.lpr
+++ b/components/chelper/cconvert.lpr
@@ -29,6 +29,7 @@ var
OutputFile : AnsiString = '';
ConfigFileRO : Boolean = false;
ParseAll : Boolean = false;
+ ShowCodeSize : Boolean = False; // show the size of code processed
function StringFromFile(const FileName: AnsiString): AnsiString;
var
@@ -80,11 +81,13 @@ 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(' -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)');
end;
procedure ReadParams(var InputFileName: String);
@@ -97,7 +100,8 @@ begin
if (s='-h') or (s='-help') or (s='-?') then begin
PrintHelp;
Halt;
- end;
+ end else if s='-showunparsed' then
+ DoDebugEntities:=True;
end;
InputFileName:=ParamStr(ParamCount);
end;
@@ -127,7 +131,8 @@ begin
inps.LoadFromFile(ParamStr(ParamCount));
outs.Text:=ConvertCode(inps.Text, p, ParseAll, err, cfg);;
- outs.Insert(0, Format('%d %d', [p.Y,p.X]));
+
+ 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 OutputFile<>'' then
diff --git a/components/chelper/cparsertypes.pas b/components/chelper/cparsertypes.pas
index 86b67973f..d9052136b 100755
--- a/components/chelper/cparsertypes.pas
+++ b/components/chelper/cparsertypes.pas
@@ -252,6 +252,7 @@ const
nk_Ref = 1;
nk_Array = 2;
nk_Func = 3;
+ nk_Block = 4;
type
TNameKind = Integer;
@@ -1676,14 +1677,19 @@ begin
Parser.NextToken;
if Parser.Token='const' then Parser.NextToken; // skip const qualifier
end;
+ end else if (Parser.Token='^') then begin
+ prefix:=TNamePart.Create(nk_Block);
+ Parser.NextToken;
end else
prefix:=nil;
+
+
if Parser.Token='(' then begin
Parser.NextToken;
id:=ParseNamePart(Parser);
ConsumeToken(Parser, ')');
- end else if (Parser.TokenType=tt_Ident) or (Parser.Token='^') then begin
+ end else if (Parser.TokenType=tt_Ident) then begin
id:=TNamePart.Create(nk_Ident);
id.id:=Parser.Token;
Parser.NextToken;
diff --git a/components/chelper/cparserutils.pas b/components/chelper/cparserutils.pas
index aea4fa5cf..9f2ae5b93 100644
--- a/components/chelper/cparserutils.pas
+++ b/components/chelper/cparserutils.pas
@@ -64,9 +64,10 @@ function GetIdPart(name: TNamePart): TNamePart;
function isNamePartPtrToFunc(part: TNamePart): Boolean; inline;
+function isAnyBlock(part: TNamePart): Boolean;
+
type
-
{ TLineBreaker }
TLineInfo = record
@@ -91,6 +92,11 @@ begin
Result:=Assigned(part) and (part.Kind=nk_Ref) and Assigned(part.owner) and (part.owner.kind=nk_Func);
end;
+function isAnyBlock(part: TNamePart): Boolean;
+begin
+ Result:=Assigned(part) and ((part.Kind=nk_Block) or isAnyBlock(part.child));
+end;
+
function isPtrToFunc(name: TNamePart): Boolean;
begin
Result := Assigned(name) and (name.Kind=nk_Func) and Assigned(name.child) and
diff --git a/components/chelper/ctopasconvert.pas b/components/chelper/ctopasconvert.pas
index abbf9a019..90c395f63 100644
--- a/components/chelper/ctopasconvert.pas
+++ b/components/chelper/ctopasconvert.pas
@@ -27,6 +27,9 @@ uses
cparsertypes, TextParsingUtils, codewriter, cparserutils,
objcparsing;
+var
+ DoDebugEntities : Boolean = False; // write parsed entities names if no converter found!?
+
type
{ TConvertSettings }
@@ -106,6 +109,9 @@ type
procedure Clear;
end;
+type
+ TConvertCheck = function (ent: TEntity): Boolean;
+
implementation
type
@@ -176,6 +182,8 @@ type
procedure WriteObjCProtocol(cent: TObjCProtocol);
procedure WriteObjCClasses(cent: TObjCClasses);
+ function CanConvert(ent: TEntity): Boolean;
+
procedure PushWriter;
procedure PopWriter;
public
@@ -548,7 +556,7 @@ begin
cfg:=ASettings;
wr:=TCodeWriter.Create;
WriteFunc:=@DefFuncWrite;
- DebugEntities := True;
+ DebugEntities := DoDebugEntities;
end;
destructor TCodeConvertor.Destroy;
@@ -648,6 +656,9 @@ var
PNames : array of AnsiString;
PTypes : array of AnsiString;
begin
+ if not CanConvert(m) then Exit;
+
+
if m.RetType=nil then ret:='id' else ret:=GetPasTypeName(m.RetType, m.RetName);
SetLength(PNames, length(m.Args));
SetLength(PTypes, length(m.Args));
@@ -811,6 +822,34 @@ begin
wr.WLn(cent.ClassList[i] +' = objcclass; external;');
end;
+
+function CanConvertObjCMethod(ent: TObjCMethod): Boolean;
+var
+ i : Integer;
+begin
+ Result:=True;
+ if not Assigned(ent) then Exit;
+ for i:=0 to length(ent.Args)-1 do
+ if Assigned(ent.Args[i].TypeName) and isAnyBlock(ent.Args[i].TypeName) then begin
+ Result:=False;
+ Exit;
+ end;
+end;
+
+function TCodeConvertor.CanConvert(ent: TEntity): Boolean;
+begin
+ Result:=Assigned(ent);
+ if not Result then Exit;
+
+
+ if ent is TVarFuncEntity then
+ begin
+ Result:=(not isAnyBlock(TVarFuncEntity(ent).FirstName)) and CanConvert(TVarFuncEntity(ent).RetType)
+ end else if ent is TObjCMethod then
+ Result:=CanConvertObjCMethod(TObjCMethod(ent));
+
+end;
+
procedure TCodeConvertor.PushWriter;
begin
if not Assigned(fWriters) then fWriters:=TList.Create;
@@ -1131,6 +1170,8 @@ procedure TCodeConvertor.WriteCtoPas(cent: TEntity; comments: TList; const Parse
var
tp : AnsiString;
begin
+ if not CanConvert(cent) then Exit;
+
CmtList:=comments;
Breaker:=TLineBreaker.Create;
Breaker.SetText(ParsedText);