diff --git a/bindings/pascocoa/parser/ObjCParserTypes.pas b/bindings/pascocoa/parser/ObjCParserTypes.pas
index a20eda4c6..2c410d986 100755
--- a/bindings/pascocoa/parser/ObjCParserTypes.pas
+++ b/bindings/pascocoa/parser/ObjCParserTypes.pas
@@ -5,7 +5,6 @@
parsing objc header unit
}
-
unit ObjCParserTypes;
interface
@@ -117,6 +116,33 @@ type
_Params : AnsiString;
end;
+ { TFunctionParam }
+ TFunctionParam = class(TEntity)
+ protected
+ function DoParse(AParser: TTextParser): Boolean; override;
+ public
+ _Type : TEntity;
+ _Name : AnsiString;
+ _IsAny : Boolean;
+ end;
+
+ { TFunctionParamsList }
+
+ TFunctionParamsList = class(TEntity)
+ protected
+ function DoParse(AParser: TTextParser): Boolean; override;
+ end;
+
+ TFunctionTypeDef = class(TEntity)
+ protected
+ function DoParse(APArser: TTextParser): Boolean; override;
+ public
+ _ResultType : TEntity;
+ _ParamsList : TFunctionParamsList;
+
+ _isPointer : Boolean;
+ _isPointerRef : Boolean;
+ end;
{ TEnumValue }
@@ -154,9 +180,9 @@ type
_Name : AnsiString;
_IsArray : Boolean;
_ArraySize : AnsiSTring;
- _BitSize : Integer;
- _Type : TEntity;
- _TypeName : AnsiString;
+ _BitSize : Integer;
+ _Type : TEntity;
+ _TypeName : AnsiString;
end;
{ TStructTypeDef }
@@ -179,7 +205,6 @@ type
public
_Name : AnsiString;
//todo: remove
- _isPointer : Boolean;
end;
{ TTypeDef }
@@ -309,6 +334,9 @@ function ScanTo(const s: AnsiString; var index: Integer; const ch: TCharSet): An
function ParseTypeDef(Owner: TEntity; AParser: TTextParser): TEntity;
function ParseCVarDef(AParser: TTextParser; var Name: AnsiString; var isArray: Boolean; var ArraySize:AnsiString): Boolean;
+function GetTypeNameFromEntity(Entity: TEntity): AnsiString;
+function IsTypeDefIsPointer(Entity: TEntity): Boolean;
+
procedure FreeEntity(Item: TEntity);
procedure ParseCNumeric(const S: AnsiString; var idx: integer; var NumStr: AnsiSTring);
@@ -364,10 +392,11 @@ begin
AParser.Index := AParser.TokenPos;
Ent := ParseTypeDef(Owner, AParser);
Result := Assigned(ent);
- AParser.FindNextToken(s, tt);
- Result := (tt=tt_Symbol) and (s = ';');
+ if Result then begin
+ AParser.FindNextToken(s, tt);
+ Result := (tt=tt_Symbol) and (s = ';');
+ end;
end;
-
end;
// isPointer returned the * is declared
@@ -459,6 +488,18 @@ begin
end;
end;
+function IsTypeDefIsPointer(Entity: TEntity): Boolean;
+begin
+ Result := false;
+ if Assigned(Entity) then begin
+ if Entity is TStructTypeDef then // hmm... a common ancsessotor should be used?
+ Result := TStructTypeDef(Entity)._isPointer
+ else if Entity is TTypeDef then begin
+ Result := TTypeDef(Entity)._isPointer;
+ end;
+ end;
+end;
+
(* ANSI C reserved words
auto break case char const continue default do double else enum
@@ -471,12 +512,22 @@ var
s : AnsiString;
tt : TTokenType;
res : Boolean;
+ i : Integer;
begin
Result := nil;
res := AParser.FindNextToken(s, tt);
if not Res or (tt <> tt_Ident) then Exit;
-
+
+ i := AParser.TokenPos;
s := AnsiLowerCase(s);
+ if (s = 'const') {or (s = 'volatile')} then begin
+ res := AParser.FindNextToken(s, tt);
+ if s <> 'struct' then begin
+ AParser.TokenPos := i;
+ AParser.Index := i;
+ end;
+ end;
+
if s = 'enum' then
Result := TEnumTypeDef.Create(Owner)
else if s = 'struct' then
@@ -487,7 +538,11 @@ begin
Result := TTypeDef.Create(Owner);
AParser.Index := AParser.TokenPos;
- if Assigned(Result) then Result.Parse(AParser);
+ if Assigned(Result) then
+ if not Result.Parse(AParser) then begin
+ Result.Free;
+ Result := nil;
+ end;
end;
function LastEntity(ent: TEntity): TEntity;
@@ -1412,6 +1467,7 @@ begin
if not ((tt = tt_Symbol) and (s = '{')) then begin
AParser.Index := i;
ParsePointerDef(AParser, _isPointer, _isPointerRef);
+ Result := true;
Exit;
end;
@@ -1469,6 +1525,7 @@ function TStructField.DoParse(AParser: TTextParser): Boolean;
var
tt : TTokenType;
s : AnsiString;
+ fnc : TFunctionTypeDef;
// fld : TStructField;
begin
Result := false;
@@ -1481,21 +1538,55 @@ begin
AParser.SetError(ErrExpectStr('Identifier', s));
Exit;
end;}
- Result := ParseCVarDef(AParser, _Name, _IsArray, _ArraySize );
- if not Result then Exit;
AParser.FindNextToken(s, tt);
- if (tt = tt_Symbol) and (s = ':') then begin
+ if (tt=tt_Symbol) and (s = '(') then begin
+ fnc := TFunctionTypeDef.Create(Self);
+ fnc._ResultType := _Type;
+ _Type := fnc;
+ _TypeName := '';
+
+ ParsePointerDef(AParser, fnc._isPointer, fnc._isPointerRef);
+ Result := ParseCVarDef(AParser, _Name, _IsArray, _ArraySize );
+ if not Result then Exit;
+ //AParser.FindNextToken(_Name, tt);
+ {if (tt <> tt_Ident) then begin
+ AParser.SetError( ErrExpectStr('Identifier', _Name));
+ Result := false;
+ Exit;
+ end;}
+
AParser.FindNextToken(s, tt);
- if tt <> tt_Numeric then begin
- AParser.SetError(ErrExpectStr('number', s));
+ if (tt <> tt_Symbol) and (s <> ')') then begin
+ AParser.SetError(ErrExpectStr(')', s));
+ Result := false;
Exit;
end;
- CVal(s, _BitSize);
- end else
+
+ Result := fnc.Parse(AParser);
+
+
+ end else begin
AParser.Index := AParser.TokenPos;
- Result := true;
- //success: (tt = tt_Symbol) and (s = ';')
+ Result := ParseCVarDef(AParser, _Name, _IsArray, _ArraySize );
+ if not Result then Exit;
+
+ AParser.FindNextToken(s, tt);
+ if (tt = tt_Symbol) and (s = ':') then begin
+ AParser.FindNextToken(s, tt);
+ if tt <> tt_Numeric then begin
+ AParser.SetError(ErrExpectStr('number', s));
+ Exit;
+ end;
+ CVal(s, _BitSize);
+ end else if (tt = tt_Symbol) and (s = '(') then begin
+ //
+ end else
+ AParser.Index := AParser.TokenPos;
+ Result := true;
+ //success: (tt = tt_Symbol) and (s = ';')
+ end;
+
end;
{ TTypeDef }
@@ -1675,4 +1766,117 @@ end;
+{ TFunctionParamsList }
+
+function TFunctionParamsList.DoParse(AParser: TTextParser): Boolean;
+var
+ s : AnsiString;
+ tt : TTokenType;
+ ent : TEntity;
+ i : Integer;
+begin
+ Result := (AParser.FindNextToken(s, tt)) and (tt=tt_Symbol) and (s = '(');
+ if not Result then begin
+ AParser.SetError( ErrExpectStr('(', s));
+ Exit;
+ end;
+ Result := AParser.FindNextToken(s, tt);
+
+ if not Result then begin
+ AParser.SetError( ErrExpectStr(')', s));
+ Exit;
+ end;
+
+ i := AParser.TokenPos;
+ if (tt = tt_Ident) and (s='void') then begin
+ AParser.FindNextToken(s, tt);
+ if not ((tt = tt_Symbol) and (s = ')')) then
+ AParser.Index := i;
+ end else
+ AParser.Index := i;
+
+ while (s <> ')') do begin
+ ent := TFunctionParam.Create(Self);
+ Result := ent.Parse(AParser);
+ if not Result then begin
+ ent.Free;
+ Exit;
+ end;
+ Items.Add(ent);
+ AParser.FindNextToken(s, tt);
+ if (s <> ')') then begin
+ if not ((tt=tt_Symbol) and (s = ',')) then
+ AParser.Index := AParser.TokenPos;
+ end;
+ end;
+
+ Result := true;
+end;
+
+function isAnyParam(AParser: TTextParser): Boolean;
+var
+ i : integer;
+ s : AnsiString;
+ tt : TTokenType;
+begin
+ Result := false;
+ i := AParser.Index;
+ if AParser.FindNextToken(s, tt) and (s = '.') then
+ if AParser.FindNextToken(s, tt) and (s = '.') then
+ if AParser.FindNextToken(s, tt) and (s = '.') then
+ Result := true;
+ if not Result then AParser.Index := i;
+end;
+
+{ TFunctionParam }
+
+function TFunctionParam.DoParse(AParser: TTextParser): Boolean;
+var
+ s : AnsiString;
+ tt : TTokenType;
+begin
+ _IsAny := isAnyParam(AParser);
+ if _IsAny then begin
+ Result := true;
+ Exit;
+ end;
+
+ _Type := ParseTypeDef(Self, AParser);
+ if not Assigned(_Type) then begin
+ AParser.SetError( ErrExpectStr('type identifier', '' ));
+ Result := false;
+ Exit;
+ end;
+ AParser.FindNextToken(s, tt);
+
+ if tt <> tt_Ident then
+ AParser.Index := AParser.TokenPos
+ else
+ _Name := s;
+ Result:=true;
+end;
+
+{ TFunctionTypeDef }
+
+function TFunctionTypeDef.DoParse(AParser: TTextParser): Boolean;
+var
+ s : AnsiString;
+ tt : TTokenType;
+begin
+ _ParamsList := TFunctionParamsList.Create(Self);
+ Items.Add(_ParamsList);
+
+ AParser.FindNextToken(s, tt);
+ if (tt = tt_Symbol) and (s = '(') then begin
+ AParser.Index := AParser.TokenPos;
+ Result := _ParamsList.Parse(AParser);
+ end else if (tt = tt_Symbol) and (s = ';') then begin
+ AParser.Index := AParser.TokenPos;
+ Result := true;
+ end else begin
+ AParser.SetError(ErrExpectStr('(', s));
+ Result := false;
+ end;
+end;
+
end.
diff --git a/bindings/pascocoa/parser/ObjCParserUtils.pas b/bindings/pascocoa/parser/ObjCParserUtils.pas
index 512216dd8..ccfce2d2e 100755
--- a/bindings/pascocoa/parser/ObjCParserUtils.pas
+++ b/bindings/pascocoa/parser/ObjCParserUtils.pas
@@ -46,6 +46,8 @@ type
IgnoreIncludes : TStringList;
DefineReplace : TReplaceList;
TypeDefReplace : TReplaceList; // replaces for C types
+ PtrTypeReplace : TReplaceList; // replaces for C types pointers
+
IgnoreTokens : TStringList;
ConvertPrefix : TStringList;
@@ -243,7 +245,10 @@ begin
'v':
if l = 'void' then begin
if not isPointer then Result := ''
- else Result := 'Pointer';
+ else begin
+ Result := 'Pointer';
+ Exit;
+ end;
end;
'i':
if l = 'id' then Result := 'objc.id'
@@ -262,14 +267,19 @@ begin
'f':
if l = 'float' then Result := 'Single';
end;
+
+
if Result = objcType then begin
- r := ConvertSettings.TypeDefReplace[objcType];
- if r <> '' then Result := r;
+ if isPointer then r := ConvertSettings.PtrTypeReplace[objcType]
+ else r := ConvertSettings.TypeDefReplace[objcType];
+ if r <> '' then
+ Result := r;
end;
- if isPointer then
+
+ if isPointer then begin
if ((objctype = 'char') or (objctype = 'const char')) then
Result := 'PChar'
-
+ end;
end;
function IsMethodConstructor(cl: TClassDef; m: TClassMethodDef): Boolean;
@@ -839,19 +849,66 @@ begin
s := subs[subs.Count - 1];
Delete(s, 1, length(Prefix + ' '));
subs.Delete(subs.Count - 1);
- subs[subs.Count - 1] := subs[subs.Count - 1] + s;
+ subs[subs.Count - 1] := subs[subs.Count - 1] + s;
end;
- inc(n);
+ inc(n);
end;
end;
end;
+function CParamsListToPascalStr(Params: TFunctionParamsList): AnsiString;
+var
+ i : integer;
+ num : Integer;
+ prm : TFunctionParam;
+ vs : AnsiString;
+begin
+ Result := '';
+ num := 1;
+ for i := 0 to Params.Items.Count - 1 do
+ if TObject(Params.Items[i]) is TFunctionParam then begin
+ prm := TFunctionParam(Params.Items[i]);
+ if prm._IsAny then Continue;
+ vs := ObjCToDelphiType( GetTypeNameFromEntity(prm._Type), IsTypeDefIsPointer(prm._Type));
+ if prm._Name = ''
+ then vs := '_param'+IntToStr(num) + ': ' + vs
+ else vs := prm._Name + ': ' + vs;
+ if Result <> '' then
+ Result := Result + '; ' + vs
+ else
+ Result := vs;
+ inc(num);
+ end;
+end;
+
+function CToDelphiFuncType(AFuncType: TFunctionTypeDef): AnsiString;
+var
+ restype : AnsiString;
+ fntype : AnsiString;
+ isptr : Boolean;
+begin
+ if not Assigned(AFuncType._ResultType) then begin
+ isptr := false;
+ fntype := 'int';
+ end else if (AFuncType._ResultType is TTypeDef) then begin
+ isptr := TTypeDef(AFuncType._ResultType)._IsPointer;
+ fntype := TTypeDef(AFuncType._ResultType)._Name;
+ end else begin
+ isptr := false;
+ fntype := '{todo: not implemented... see .h file for type}';
+ end;
+ restype := ObjCToDelphiType(fntype, isptr);
+ Result := GetProcFuncHead('', '', CParamsListToPascalStr(AFuncType._ParamsList), restype);
+ Result := Copy(Result, 1, length(Result) - 1);
+end;
+
procedure WriteOutRecordField(AField: TStructField; const Prefix: AnsiString; subs: TStrings);
var
pastype : AnsiString;
nm : AnsiString;
i : Integer;
+
begin
//todo:!
if Assigned(AField._Type) then begin
@@ -866,8 +923,13 @@ begin
nm := Prefix + Format('%s : %s', [AField._Name, nm]);
subs[i] := nm;
end;
- end else begin
- pastype := ObjCToDelphiType( AField._TypeName, IsTypePointer(AField._Type, false));
+ end else begin
+
+ if (AField._Type is TFunctionTypeDef) then
+ pastype := CToDelphiFuncType(AField._Type as TFunctionTypeDef)
+ else
+ pastype := ObjCToDelphiType(AField._TypeName, IsTypePointer(AField._Type, false));
+
nm := FixIfReserved(AField._Name);
if (AField._IsArray) and (AField._ArraySize <> '') then
subs.Add(Prefix + Format('%s : array [0..%s-1] of %s;', [nm, AField._ArraySize, pastype]))
@@ -947,11 +1009,13 @@ begin
end;
function WriteOutTypeDefName(const NewType, FromType: AnsiSTring; isPointer: Boolean): AnsiString;
+var
+ wrType: AnsiString;
begin
- if not isPointer then
- Result := Format('%s = %s;', [NewType, FromType])
- else
- Result := Format('%s = ^%s;', [NewType, FromType]);
+ wrType := ObjCToDelphiType(fromType, isPointer);
+ Result := Format('%s = %s;', [NewType, wrType]);
+ {else
+ Result := Format('%s = ^%s;', [NewType, wrType]);}
case GetObjCVarType(FromType) of
vt_FloatPoint: ConvertSettings.FloatTypes.Add(NewType);
@@ -1069,7 +1133,7 @@ begin
if cl._SuperClass <> '' then begin
subs.Add(s + '('+cl._SuperClass+')');
subs.Add(' public');
- subs.Add(' function getClass: objc.id; override;');
+ subs.Add(' class function getClass: objc.id; override;');
end else begin
subs.Add(s + '{from category '+ cl._Category +'}');
subs.Add(' public');
@@ -1256,7 +1320,7 @@ end;
const
ClassMethodCaller : array [ Boolean] of AnsiString = (
- 'Handler', 'getClass'
+ 'Handle', 'getClass'
);
// writes out a method to implementation section
@@ -1265,20 +1329,34 @@ var
s : AnsiString;
typeName : AnsiString;
cl : TClassDef;
-
+ tp : TObjcConvertVarType;
+ res : AnsiString;
callobj : AnsiString;
+ mnm : AnsiString;
begin
cl := TClassDef(mtd.Owner);
callobj := ClassMethodCaller[mtd._IsClassMethod];
- s := Format('vmethod(%s, sel_registerName(PChar(Str%s_%s)), %s)', [callobj, cl._ClassName, RefixName(mtd._Name), GetParamsNames(mtd)]);
- if ObjCToDelphiType(mtd.GetResultType._Name, mtd.GetResultType._IsPointer) <> '' then
+ res := GetMethodResultType(mtd);
+ mnm := RefixName(mtd._Name);
+ //s := Format('vmethod(%s, sel_registerName(PChar(Str%s_%s)), %s)', [callobj, cl._ClassName, RefixName(mtd._Name), GetParamsNames(mtd)]);
+ tp := GetObjCVarType(res);
+ case tp of
+ vt_Int: s := Format('objc_msgSend(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]);
+ vt_FloatPoint: s := Format('objc_msgSend_fpret(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]);
+ vt_Struct: s := Format('objc_msgSend_stret(@Result, %s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]);
+ end;
+
+ if (ObjCToDelphiType(mtd.GetResultType._Name, mtd.GetResultType._IsPointer) <> '') and (tp <> vt_Struct) then
s := 'Result := ' + s;
ObjCMethodToProcType(mtd, typeName, subs);
subs.Add('var');
subs.Add(
Format(' vmethod: %s;', [typeName]));
subs.Add('begin');
+
+
+
subs.Add(
Format(' vmethod := %s(@objc_msgSend);', [typeName]));
subs.Add(
@@ -1368,7 +1446,7 @@ begin
end;
subs.Add('');
- subs.Add(GetProcFuncHead('getClass', cl._ClassName, '', 'objc.id'));
+ subs.Add('class ' + GetProcFuncHead('getClass', cl._ClassName, '', 'objc.id'));
subs.Add('begin');
subs.Add(
Format(' Result := objc_getClass(Str%s_%s);', [cl._ClassName, cl._ClassName]));
@@ -1526,14 +1604,11 @@ begin
FastPack(ent.Items);
end;
-procedure FixEmptyStruct(var ent: TEntity);
-begin
-end;
-
procedure AppleHeaderFix(ent : TEntity);
var
i : Integer;
obj : TEntity;
+ prm : TObjCParameterDef;
begin
// i := 0;
for i := 0 to ent.Items.Count - 1 do begin
@@ -1552,15 +1627,20 @@ begin
if IsPascalReserved(TParamDescr(obj)._Descr) then
TParamDescr(obj)._Descr := '_'+TParamDescr(obj)._Descr;
end else if (obj is TObjCParameterDef) then begin
- if IsPascalReserved(TObjCParameterDef(obj)._Name) then
- TObjCParameterDef(obj)._Name := '_' + TObjCParameterDef(obj)._Name;
+ prm := TObjCParameterDef(obj);
+ if ConvertSettings.ObjCTypes.IndexOf(prm._Res._Name) >= 0 then
+ prm._Res._Name := Format('objc.id {%s}', [prm._Res._Name] );
+ if IsPascalReserved(prm._Name) then
+ prm._Name := '_' + prm._Name;
+
+ end else if (obj is TStructField) then begin
+ if ConvertSettings.ObjCTypes.IndexOf(TStructField(obj)._TypeName) >= 0 then
+ prm._Res._Name := 'objc.id';
end;
end;
// packing list, removing nil references.
FastPack(ent.Items);
- FixObjCClassTypeDef(ent);
- FixEmptyStruct(ent);
for i := 0 to ent.Items.Count - 1 do
AppleHeaderFix( TEntity(ent.Items[i]));
@@ -1608,6 +1688,8 @@ begin
if hdr.Items.Count <= 0 then Exit;
AppleHeaderFix(hdr);
+ FixObjCClassTypeDef(hdr);
+
// .inc header-comment is the first comment entity in .h file , if any
if TObject(hdr.Items[0]) is TComment then begin
cmt := TComment(hdr.Items[0]);
@@ -1654,6 +1736,7 @@ begin
IgnoreIncludes.CaseSensitive := false;
DefineReplace := TReplaceList.Create;
TypeDefReplace := TReplaceList.Create; // replaces for default types
+ PtrTypeReplace := TReplaceList.Create; // replaces for C types pointers
ConvertPrefix := TStringList.Create;
FloatTypes := TStringList.Create;
@@ -1676,6 +1759,7 @@ begin
IgnoreTokens.Free;
IgnoreIncludes.Free;
TypeDefReplace.Free;
+ PtrTypeReplace.Free;
DefineReplace.Free;
ConvertPrefix.Free;
inherited Destroy;
@@ -1701,6 +1785,7 @@ begin
TypeDefReplace['unsigned char'] := 'byte';
TypeDefReplace['uint8_t'] := 'byte';
+ PtrTypeReplace['uint8_t'] := 'PByte';
TypeDefReplace['short'] := 'SmallInt';
TypeDefReplace['short int'] := 'SmallInt';
@@ -1715,15 +1800,26 @@ begin
TypeDefReplace['NSInteger'] := 'Integer';
TypeDefReplace['unsigned'] := 'LongWord';
+ PtrTypeReplace['unsigned'] := 'PLongWord';
+
TypeDefReplace['unsigned int'] := 'LongWord';
TypeDefReplace['uint32_t'] := 'LongWord';
TypeDefReplace['NSUInteger'] := 'LongWord';
TypeDefReplace['long long'] := 'Int64';
- TypeDefReplace['singned long long'] := 'Int64';
+ PtrTypeReplace['long long'] := 'PInt64';
+
+ TypeDefReplace['signed long long'] := 'Int64';
+ PtrTypeReplace['signed long long'] := 'PInt64';
+
TypeDefReplace['unsigned long long'] := 'Int64';
+ PtrTypeReplace['unsigned long long'] := 'PInt64';
+
TypeDefReplace['int64_t'] := 'Int64';
+ PtrTypeReplace['int64_t'] := 'PInt64';
+
TypeDefReplace['uint64_t'] := 'Int64';
+ PtrTypeReplace['uint64_t'] := 'PInt64';
TypeDefReplace['float'] := 'Single';
TypeDefReplace['CGFloat'] := 'Single';
diff --git a/bindings/pascocoa/parser/objcparser.lpi b/bindings/pascocoa/parser/objcparser.lpi
index 0c816924e..1f7ab6dc3 100755
--- a/bindings/pascocoa/parser/objcparser.lpi
+++ b/bindings/pascocoa/parser/objcparser.lpi
@@ -13,7 +13,7 @@
-
+
@@ -34,18 +34,18 @@
-
-
-
+
+
+
-
+
-
-
+
+
@@ -53,12 +53,12 @@
-
-
+
+
-
+
@@ -119,7 +119,7 @@
-
+
@@ -190,7 +190,7 @@
-
+
@@ -277,19 +277,23 @@
-
+
-
+
-
+
-
+
+
+
+
+
diff --git a/bindings/pascocoa/parser/objcparser.pas b/bindings/pascocoa/parser/objcparser.pas
index 64ed8f3a9..fd692f2fe 100755
--- a/bindings/pascocoa/parser/objcparser.pas
+++ b/bindings/pascocoa/parser/objcparser.pas
@@ -5,13 +5,14 @@
main parser unit
}
-program Project1;
+program objcparser;
{$ifdef fpc}
{$mode delphi}{$H+}
{$else}
{$APPTYPE CONSOLE}
{$endif}
+
uses
Classes, IniFiles,
SysUtils,
@@ -29,7 +30,26 @@ type
procedure OnComment(Sender: TObject; const Comment: AnsiString);
constructor Create(AHeader: TObjCHeader);
end;
-
+
+var
+ updIni : AnsiString = '';
+ noConvert : Boolean = false;
+
+function FindMax(const c: array of Integer; len: Integer): Integer;
+var
+ i : integer;
+ mn : Integer;
+begin
+ Result := -1;
+ if len = 0 then Exit;
+
+ mn := 0;
+ for i := 1 to len - 1 do begin
+ if c[i] < c[mn] then mn := i;
+ end;
+ Result := mn;
+end;
+
procedure TPrecompileHandler.OnPrecompile(Sender: TObject);
var
parser : TTextParser;
@@ -84,6 +104,29 @@ begin
hdr := AHeader;
end;
+procedure UpdateIniWithEntity(Sets: TConvertSettings; Ini: TIniFile; Entity: TEntity);
+var
+ cnv : AnsiString;
+ i : Integer;
+begin
+ if Entity is TClassDef then begin
+ Ini.WriteString('TypeDefs', TClassDef(Entity)._ClassName, 'objcclass');
+ end else if Entity is TStructTypeDef then begin
+ Ini.WriteString('TypeDefs', TStructTypeDef(Entity)._Name, 'struct');
+ end else if Entity is TTypeNameDef then begin
+ if Assigned(Sets) then begin
+ cnv := AnsiLowerCase(ObjCToDelphiType(TTypeNameDef(Entity)._Inherited, false ));
+ if (cnv = 'float') or (cnv = 'double') then
+ Ini.WriteString('TypeDefs', TTypeNameDef(Entity)._TypeName, 'float')
+ else if (cnv = 'Int64') then
+ Ini.WriteString('TypeDefs', TTypeNameDef(Entity)._TypeName, 'struct')
+ end;
+ end;
+
+ for i := 0 to Entity.Items.Count - 1 do
+ UpdateIniWithEntity(Sets, Ini, Entity.Items[i]);
+end;
+
function ReadAndParseFile(const FileName: AnsiString; outdata: TStrings; var Err: AnsiString): Boolean;
var
hdr : TObjCHeader;
@@ -91,6 +134,7 @@ var
prec : TPrecompileHandler ;
s : AnsiString;
i, cnt : integer;
+ upini : TIniFile;
begin
Result :=false;
if not FileExists(FileName) then begin
@@ -130,6 +174,15 @@ begin
except
end;
+
+ if updIni <> '' then begin
+ upIni := TIniFile.Create(updIni);
+ try
+ UpdateIniWithEntity(ConvertSettings, upIni, hdr);
+ finally
+ upIni.Free;
+ end;
+ end;
WriteOutIncludeFile(hdr, outdata);
finally
parser.TokenTable.Free;
@@ -185,7 +238,6 @@ begin
writeln(' converted!');
end else begin
writeln('Error: ', err);
- readln;
end;
until FindNext(srch) <> 0;
@@ -227,6 +279,14 @@ begin
end;
end;
+
+function isNameofPointer(const name: AnsiString): Boolean;
+begin
+ Result := false;
+ if name = '' then Exit;
+ Result := name[length(name)] = '*';
+end;
+
procedure ReadIniFile(Settings: TConvertSettings; const FileName: AnsiString);
var
ini : TIniFile;
@@ -234,16 +294,59 @@ var
a, b : AnsiString;
i : Integer;
begin
+// uikit.ini
+ if not FileExists(FileName) then begin
+ writeln('//ini file is not found');
+ Exit;
+ end;
ini := TIniFile.Create(FileName);
values := TStringList.Create;
try
- ini.ReadSection('TypeReplace', values);
+ values.Clear;
+{ ini.ReadSection('TypeReplace', values);
for i := 0 to values.Count - 1 do begin
a := values.ValueFromIndex[i];
b := values.Values[a];
+ if b <> '' then begin
+ ense
Settings.TypeDefReplace[a] := b;
+ end;}
+
+ values.Clear;
+ //ini.ReadSectionValues('ReplaceToken', values);
+ ini.ReadSection('ReplaceToken', values);
+ for i := 0 to values.Count - 1 do begin
+ a := Values[i];
+ b := ini.ReadString('ReplaceToken', a, '');
+ if b ='' then
+ Settings.IgnoreTokens.Add(a);
end;
+
+ values.Clear;
+ ini.ReadSection('TypeDefs', values);
+ for i := 0 to values.Count - 1 do begin
+ a := Values[i];
+ b := AnsiLowerCase(ini.ReadString('TypeDefs', a, ''));
+ if b = 'objcclass' then
+ Settings.ObjCTypes.Add(a)
+ else if b = 'struct' then
+ Settings.StructTypes.Add(a)
+ else if b = 'float' then
+ Settings.FloatTypes.Add(a);
+ end;
+
+ values.Clear;
+ ini.ReadSection('TypeReplace', values);
+ for i := 0 to values.Count - 1 do begin
+ a := Values[i];
+ b := ini.ReadString('TypeReplace', a, '');
+ if isNameofPointer(a) then
+ Settings.PtrTypeReplace[ Copy(a, 1, length(a) - 1)] := b
+ else
+ Settings.TypeDefReplace[a] := b
+ end;
+
finally
values.Free;
ini.Free;
@@ -273,7 +376,7 @@ begin
FileName := ParamStr(i);
end;
- vlm := Params.Values['settings'];
+ vlm := Params.Values['ini'];
if vlm <> '' then
ReadIniFile(Settings, vlm);
@@ -282,15 +385,12 @@ begin
Settings.ConvertPrefix.Add ('{%mainunit '+vlm+'}');
vlm := Params.Values['ignoreinclude'];
- if vlm <> '' then begin
+ if vlm <> '' then
AddSpaceSeparated(vlm, Settings.IgnoreIncludes);
- {for i := 0 to Settings.IgnoreIncludes.Count - 1 do begin
- vlm := Settings.IgnoreIncludes[i];
- vlm := Copy(vlm, 1, length(vlm) - length(ExtractFileExt(vlm)));
- vlm := vlm + '.inc';
- Settings.IgnoreIncludes[i] := vlm;
- end;}
- end;
+
+ vlm := Params.Values['updini'];
+ if vlm <> '' then
+ updIni := vlm;
finally
Params.Free;
@@ -304,6 +404,7 @@ var
err : AnsiString = '';
i : integer;
+
begin
try
GetConvertSettings(ConvertSettings, inpf);