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);