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