*parsing function type structure field fixed... some testing is still is needed, *supported config file sections are exteneded

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@440 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2008-04-25 13:47:19 +00:00
parent 252d362cfa
commit aa43c0f2c5
4 changed files with 481 additions and 76 deletions

View File

@ -5,7 +5,6 @@
parsing objc header unit parsing objc header unit
} }
unit ObjCParserTypes; unit ObjCParserTypes;
interface interface
@ -117,6 +116,33 @@ type
_Params : AnsiString; _Params : AnsiString;
end; 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 } { TEnumValue }
@ -154,9 +180,9 @@ type
_Name : AnsiString; _Name : AnsiString;
_IsArray : Boolean; _IsArray : Boolean;
_ArraySize : AnsiSTring; _ArraySize : AnsiSTring;
_BitSize : Integer; _BitSize : Integer;
_Type : TEntity; _Type : TEntity;
_TypeName : AnsiString; _TypeName : AnsiString;
end; end;
{ TStructTypeDef } { TStructTypeDef }
@ -179,7 +205,6 @@ type
public public
_Name : AnsiString; _Name : AnsiString;
//todo: remove //todo: remove
_isPointer : Boolean;
end; end;
{ TTypeDef } { 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 ParseTypeDef(Owner: TEntity; AParser: TTextParser): TEntity;
function ParseCVarDef(AParser: TTextParser; var Name: AnsiString; var isArray: Boolean; var ArraySize:AnsiString): Boolean; 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 FreeEntity(Item: TEntity);
procedure ParseCNumeric(const S: AnsiString; var idx: integer; var NumStr: AnsiSTring); procedure ParseCNumeric(const S: AnsiString; var idx: integer; var NumStr: AnsiSTring);
@ -364,10 +392,11 @@ begin
AParser.Index := AParser.TokenPos; AParser.Index := AParser.TokenPos;
Ent := ParseTypeDef(Owner, AParser); Ent := ParseTypeDef(Owner, AParser);
Result := Assigned(ent); Result := Assigned(ent);
AParser.FindNextToken(s, tt); if Result then begin
Result := (tt=tt_Symbol) and (s = ';'); AParser.FindNextToken(s, tt);
Result := (tt=tt_Symbol) and (s = ';');
end;
end; end;
end; end;
// isPointer returned the * is declared // isPointer returned the * is declared
@ -459,6 +488,18 @@ begin
end; end;
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 (* ANSI C reserved words
auto break case char const continue default do double else enum auto break case char const continue default do double else enum
@ -471,12 +512,22 @@ var
s : AnsiString; s : AnsiString;
tt : TTokenType; tt : TTokenType;
res : Boolean; res : Boolean;
i : Integer;
begin begin
Result := nil; Result := nil;
res := AParser.FindNextToken(s, tt); res := AParser.FindNextToken(s, tt);
if not Res or (tt <> tt_Ident) then Exit; if not Res or (tt <> tt_Ident) then Exit;
i := AParser.TokenPos;
s := AnsiLowerCase(s); 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 if s = 'enum' then
Result := TEnumTypeDef.Create(Owner) Result := TEnumTypeDef.Create(Owner)
else if s = 'struct' then else if s = 'struct' then
@ -487,7 +538,11 @@ begin
Result := TTypeDef.Create(Owner); Result := TTypeDef.Create(Owner);
AParser.Index := AParser.TokenPos; 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; end;
function LastEntity(ent: TEntity): TEntity; function LastEntity(ent: TEntity): TEntity;
@ -1412,6 +1467,7 @@ begin
if not ((tt = tt_Symbol) and (s = '{')) then begin if not ((tt = tt_Symbol) and (s = '{')) then begin
AParser.Index := i; AParser.Index := i;
ParsePointerDef(AParser, _isPointer, _isPointerRef); ParsePointerDef(AParser, _isPointer, _isPointerRef);
Result := true;
Exit; Exit;
end; end;
@ -1469,6 +1525,7 @@ function TStructField.DoParse(AParser: TTextParser): Boolean;
var var
tt : TTokenType; tt : TTokenType;
s : AnsiString; s : AnsiString;
fnc : TFunctionTypeDef;
// fld : TStructField; // fld : TStructField;
begin begin
Result := false; Result := false;
@ -1481,21 +1538,55 @@ begin
AParser.SetError(ErrExpectStr('Identifier', s)); AParser.SetError(ErrExpectStr('Identifier', s));
Exit; Exit;
end;} end;}
Result := ParseCVarDef(AParser, _Name, _IsArray, _ArraySize );
if not Result then Exit;
AParser.FindNextToken(s, tt); 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); AParser.FindNextToken(s, tt);
if tt <> tt_Numeric then begin if (tt <> tt_Symbol) and (s <> ')') then begin
AParser.SetError(ErrExpectStr('number', s)); AParser.SetError(ErrExpectStr(')', s));
Result := false;
Exit; Exit;
end; end;
CVal(s, _BitSize);
end else Result := fnc.Parse(AParser);
end else begin
AParser.Index := AParser.TokenPos; AParser.Index := AParser.TokenPos;
Result := true; Result := ParseCVarDef(AParser, _Name, _IsArray, _ArraySize );
//success: (tt = tt_Symbol) and (s = ';') 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; end;
{ TTypeDef } { 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. end.

View File

@ -46,6 +46,8 @@ type
IgnoreIncludes : TStringList; IgnoreIncludes : TStringList;
DefineReplace : TReplaceList; DefineReplace : TReplaceList;
TypeDefReplace : TReplaceList; // replaces for C types TypeDefReplace : TReplaceList; // replaces for C types
PtrTypeReplace : TReplaceList; // replaces for C types pointers
IgnoreTokens : TStringList; IgnoreTokens : TStringList;
ConvertPrefix : TStringList; ConvertPrefix : TStringList;
@ -243,7 +245,10 @@ begin
'v': 'v':
if l = 'void' then begin if l = 'void' then begin
if not isPointer then Result := '' if not isPointer then Result := ''
else Result := 'Pointer'; else begin
Result := 'Pointer';
Exit;
end;
end; end;
'i': 'i':
if l = 'id' then Result := 'objc.id' if l = 'id' then Result := 'objc.id'
@ -262,14 +267,19 @@ begin
'f': 'f':
if l = 'float' then Result := 'Single'; if l = 'float' then Result := 'Single';
end; end;
if Result = objcType then begin if Result = objcType then begin
r := ConvertSettings.TypeDefReplace[objcType]; if isPointer then r := ConvertSettings.PtrTypeReplace[objcType]
if r <> '' then Result := r; else r := ConvertSettings.TypeDefReplace[objcType];
if r <> '' then
Result := r;
end; end;
if isPointer then
if isPointer then begin
if ((objctype = 'char') or (objctype = 'const char')) then if ((objctype = 'char') or (objctype = 'const char')) then
Result := 'PChar' Result := 'PChar'
end;
end; end;
function IsMethodConstructor(cl: TClassDef; m: TClassMethodDef): Boolean; function IsMethodConstructor(cl: TClassDef; m: TClassMethodDef): Boolean;
@ -847,11 +857,58 @@ begin
end; 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); procedure WriteOutRecordField(AField: TStructField; const Prefix: AnsiString; subs: TStrings);
var var
pastype : AnsiString; pastype : AnsiString;
nm : AnsiString; nm : AnsiString;
i : Integer; i : Integer;
begin begin
//todo:! //todo:!
if Assigned(AField._Type) then begin if Assigned(AField._Type) then begin
@ -867,7 +924,12 @@ begin
subs[i] := nm; subs[i] := nm;
end; end;
end else begin end else begin
pastype := ObjCToDelphiType( AField._TypeName, IsTypePointer(AField._Type, false));
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); nm := FixIfReserved(AField._Name);
if (AField._IsArray) and (AField._ArraySize <> '') then if (AField._IsArray) and (AField._ArraySize <> '') then
subs.Add(Prefix + Format('%s : array [0..%s-1] of %s;', [nm, AField._ArraySize, pastype])) subs.Add(Prefix + Format('%s : array [0..%s-1] of %s;', [nm, AField._ArraySize, pastype]))
@ -947,11 +1009,13 @@ begin
end; end;
function WriteOutTypeDefName(const NewType, FromType: AnsiSTring; isPointer: Boolean): AnsiString; function WriteOutTypeDefName(const NewType, FromType: AnsiSTring; isPointer: Boolean): AnsiString;
var
wrType: AnsiString;
begin begin
if not isPointer then wrType := ObjCToDelphiType(fromType, isPointer);
Result := Format('%s = %s;', [NewType, FromType]) Result := Format('%s = %s;', [NewType, wrType]);
else {else
Result := Format('%s = ^%s;', [NewType, FromType]); Result := Format('%s = ^%s;', [NewType, wrType]);}
case GetObjCVarType(FromType) of case GetObjCVarType(FromType) of
vt_FloatPoint: ConvertSettings.FloatTypes.Add(NewType); vt_FloatPoint: ConvertSettings.FloatTypes.Add(NewType);
@ -1069,7 +1133,7 @@ begin
if cl._SuperClass <> '' then begin if cl._SuperClass <> '' then begin
subs.Add(s + '('+cl._SuperClass+')'); subs.Add(s + '('+cl._SuperClass+')');
subs.Add(' public'); subs.Add(' public');
subs.Add(' function getClass: objc.id; override;'); subs.Add(' class function getClass: objc.id; override;');
end else begin end else begin
subs.Add(s + '{from category '+ cl._Category +'}'); subs.Add(s + '{from category '+ cl._Category +'}');
subs.Add(' public'); subs.Add(' public');
@ -1256,7 +1320,7 @@ end;
const const
ClassMethodCaller : array [ Boolean] of AnsiString = ( ClassMethodCaller : array [ Boolean] of AnsiString = (
'Handler', 'getClass' 'Handle', 'getClass'
); );
// writes out a method to implementation section // writes out a method to implementation section
@ -1265,20 +1329,34 @@ var
s : AnsiString; s : AnsiString;
typeName : AnsiString; typeName : AnsiString;
cl : TClassDef; cl : TClassDef;
tp : TObjcConvertVarType;
res : AnsiString;
callobj : AnsiString; callobj : AnsiString;
mnm : AnsiString;
begin begin
cl := TClassDef(mtd.Owner); cl := TClassDef(mtd.Owner);
callobj := ClassMethodCaller[mtd._IsClassMethod]; 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; s := 'Result := ' + s;
ObjCMethodToProcType(mtd, typeName, subs); ObjCMethodToProcType(mtd, typeName, subs);
subs.Add('var'); subs.Add('var');
subs.Add( subs.Add(
Format(' vmethod: %s;', [typeName])); Format(' vmethod: %s;', [typeName]));
subs.Add('begin'); subs.Add('begin');
subs.Add( subs.Add(
Format(' vmethod := %s(@objc_msgSend);', [typeName])); Format(' vmethod := %s(@objc_msgSend);', [typeName]));
subs.Add( subs.Add(
@ -1368,7 +1446,7 @@ begin
end; end;
subs.Add(''); subs.Add('');
subs.Add(GetProcFuncHead('getClass', cl._ClassName, '', 'objc.id')); subs.Add('class ' + GetProcFuncHead('getClass', cl._ClassName, '', 'objc.id'));
subs.Add('begin'); subs.Add('begin');
subs.Add( subs.Add(
Format(' Result := objc_getClass(Str%s_%s);', [cl._ClassName, cl._ClassName])); Format(' Result := objc_getClass(Str%s_%s);', [cl._ClassName, cl._ClassName]));
@ -1526,14 +1604,11 @@ begin
FastPack(ent.Items); FastPack(ent.Items);
end; end;
procedure FixEmptyStruct(var ent: TEntity);
begin
end;
procedure AppleHeaderFix(ent : TEntity); procedure AppleHeaderFix(ent : TEntity);
var var
i : Integer; i : Integer;
obj : TEntity; obj : TEntity;
prm : TObjCParameterDef;
begin begin
// i := 0; // i := 0;
for i := 0 to ent.Items.Count - 1 do begin for i := 0 to ent.Items.Count - 1 do begin
@ -1552,15 +1627,20 @@ begin
if IsPascalReserved(TParamDescr(obj)._Descr) then if IsPascalReserved(TParamDescr(obj)._Descr) then
TParamDescr(obj)._Descr := '_'+TParamDescr(obj)._Descr; TParamDescr(obj)._Descr := '_'+TParamDescr(obj)._Descr;
end else if (obj is TObjCParameterDef) then begin end else if (obj is TObjCParameterDef) then begin
if IsPascalReserved(TObjCParameterDef(obj)._Name) then prm := TObjCParameterDef(obj);
TObjCParameterDef(obj)._Name := '_' + TObjCParameterDef(obj)._Name; 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;
end; end;
// packing list, removing nil references. // packing list, removing nil references.
FastPack(ent.Items); FastPack(ent.Items);
FixObjCClassTypeDef(ent);
FixEmptyStruct(ent);
for i := 0 to ent.Items.Count - 1 do for i := 0 to ent.Items.Count - 1 do
AppleHeaderFix( TEntity(ent.Items[i])); AppleHeaderFix( TEntity(ent.Items[i]));
@ -1608,6 +1688,8 @@ begin
if hdr.Items.Count <= 0 then Exit; if hdr.Items.Count <= 0 then Exit;
AppleHeaderFix(hdr); AppleHeaderFix(hdr);
FixObjCClassTypeDef(hdr);
// .inc header-comment is the first comment entity in .h file , if any // .inc header-comment is the first comment entity in .h file , if any
if TObject(hdr.Items[0]) is TComment then begin if TObject(hdr.Items[0]) is TComment then begin
cmt := TComment(hdr.Items[0]); cmt := TComment(hdr.Items[0]);
@ -1654,6 +1736,7 @@ begin
IgnoreIncludes.CaseSensitive := false; IgnoreIncludes.CaseSensitive := false;
DefineReplace := TReplaceList.Create; DefineReplace := TReplaceList.Create;
TypeDefReplace := TReplaceList.Create; // replaces for default types TypeDefReplace := TReplaceList.Create; // replaces for default types
PtrTypeReplace := TReplaceList.Create; // replaces for C types pointers
ConvertPrefix := TStringList.Create; ConvertPrefix := TStringList.Create;
FloatTypes := TStringList.Create; FloatTypes := TStringList.Create;
@ -1676,6 +1759,7 @@ begin
IgnoreTokens.Free; IgnoreTokens.Free;
IgnoreIncludes.Free; IgnoreIncludes.Free;
TypeDefReplace.Free; TypeDefReplace.Free;
PtrTypeReplace.Free;
DefineReplace.Free; DefineReplace.Free;
ConvertPrefix.Free; ConvertPrefix.Free;
inherited Destroy; inherited Destroy;
@ -1701,6 +1785,7 @@ begin
TypeDefReplace['unsigned char'] := 'byte'; TypeDefReplace['unsigned char'] := 'byte';
TypeDefReplace['uint8_t'] := 'byte'; TypeDefReplace['uint8_t'] := 'byte';
PtrTypeReplace['uint8_t'] := 'PByte';
TypeDefReplace['short'] := 'SmallInt'; TypeDefReplace['short'] := 'SmallInt';
TypeDefReplace['short int'] := 'SmallInt'; TypeDefReplace['short int'] := 'SmallInt';
@ -1715,15 +1800,26 @@ begin
TypeDefReplace['NSInteger'] := 'Integer'; TypeDefReplace['NSInteger'] := 'Integer';
TypeDefReplace['unsigned'] := 'LongWord'; TypeDefReplace['unsigned'] := 'LongWord';
PtrTypeReplace['unsigned'] := 'PLongWord';
TypeDefReplace['unsigned int'] := 'LongWord'; TypeDefReplace['unsigned int'] := 'LongWord';
TypeDefReplace['uint32_t'] := 'LongWord'; TypeDefReplace['uint32_t'] := 'LongWord';
TypeDefReplace['NSUInteger'] := 'LongWord'; TypeDefReplace['NSUInteger'] := 'LongWord';
TypeDefReplace['long long'] := 'Int64'; 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'; TypeDefReplace['unsigned long long'] := 'Int64';
PtrTypeReplace['unsigned long long'] := 'PInt64';
TypeDefReplace['int64_t'] := 'Int64'; TypeDefReplace['int64_t'] := 'Int64';
PtrTypeReplace['int64_t'] := 'PInt64';
TypeDefReplace['uint64_t'] := 'Int64'; TypeDefReplace['uint64_t'] := 'Int64';
PtrTypeReplace['uint64_t'] := 'PInt64';
TypeDefReplace['float'] := 'Single'; TypeDefReplace['float'] := 'Single';
TypeDefReplace['CGFloat'] := 'Single'; TypeDefReplace['CGFloat'] := 'Single';

View File

@ -13,7 +13,7 @@
<IconPath Value="./"/> <IconPath Value="./"/>
<TargetFileExt Value=".exe"/> <TargetFileExt Value=".exe"/>
<UseAppBundle Value="False"/> <UseAppBundle Value="False"/>
<ActiveEditorIndexAtStart Value="0"/> <ActiveEditorIndexAtStart Value="1"/>
</General> </General>
<VersionInfo> <VersionInfo>
<ProjectVersion Value=""/> <ProjectVersion Value=""/>
@ -34,18 +34,18 @@
<Unit0> <Unit0>
<Filename Value="objcparser.pas"/> <Filename Value="objcparser.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="Project1"/> <UnitName Value="objcparser"/>
<CursorPos X="18" Y="8"/> <CursorPos X="1" Y="409"/>
<TopLine Value="1"/> <TopLine Value="388"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="80"/> <UsageCount Value="81"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit0> </Unit0>
<Unit1> <Unit1>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<UnitName Value="ObjCParserUtils"/> <UnitName Value="ObjCParserUtils"/>
<CursorPos X="1" Y="63"/> <CursorPos X="1" Y="1353"/>
<TopLine Value="57"/> <TopLine Value="1334"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<UsageCount Value="37"/> <UsageCount Value="37"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -53,12 +53,12 @@
<Unit2> <Unit2>
<Filename Value="ObjCParserTypes.pas"/> <Filename Value="ObjCParserTypes.pas"/>
<UnitName Value="ObjCParserTypes"/> <UnitName Value="ObjCParserTypes"/>
<CursorPos X="1" Y="8"/> <CursorPos X="9" Y="517"/>
<TopLine Value="1"/> <TopLine Value="517"/>
<EditorIndex Value="2"/> <EditorIndex Value="2"/>
<UsageCount Value="37"/> <UsageCount Value="37"/>
<Bookmarks Count="1"> <Bookmarks Count="1">
<Item0 X="1" Y="612" ID="0"/> <Item0 X="1" Y="626" ID="0"/>
</Bookmarks> </Bookmarks>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit2> </Unit2>
@ -119,7 +119,7 @@
<UnitName Value="pascodeutils"/> <UnitName Value="pascodeutils"/>
<CursorPos X="1" Y="13"/> <CursorPos X="1" Y="13"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<UsageCount Value="77"/> <UsageCount Value="78"/>
</Unit11> </Unit11>
<Unit12> <Unit12>
<Filename Value="../appkit/NSWindow.inc"/> <Filename Value="../appkit/NSWindow.inc"/>
@ -190,7 +190,7 @@
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<CursorPos X="44" Y="16"/> <CursorPos X="44" Y="16"/>
<TopLine Value="11"/> <TopLine Value="11"/>
<UsageCount Value="58"/> <UsageCount Value="59"/>
<SyntaxHighlighter Value="C++"/> <SyntaxHighlighter Value="C++"/>
</Unit22> </Unit22>
<Unit23> <Unit23>
@ -277,19 +277,23 @@
<UsageCount Value="9"/> <UsageCount Value="9"/>
</Unit35> </Unit35>
</Units> </Units>
<JumpHistory Count="3" HistoryIndex="2"> <JumpHistory Count="4" HistoryIndex="3">
<Position1> <Position1>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<Caret Line="7" Column="49" TopLine="1"/> <Caret Line="1830" Column="49" TopLine="1823"/>
</Position1> </Position1>
<Position2> <Position2>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1529" Column="30" TopLine="1518"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position2> </Position2>
<Position3> <Position3>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<Caret Line="68" Column="33" TopLine="57"/> <Caret Line="94" Column="12" TopLine="83"/>
</Position3> </Position3>
<Position4>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position4>
</JumpHistory> </JumpHistory>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -5,13 +5,14 @@
main parser unit main parser unit
} }
program Project1; program objcparser;
{$ifdef fpc} {$ifdef fpc}
{$mode delphi}{$H+} {$mode delphi}{$H+}
{$else} {$else}
{$APPTYPE CONSOLE} {$APPTYPE CONSOLE}
{$endif} {$endif}
uses uses
Classes, IniFiles, Classes, IniFiles,
SysUtils, SysUtils,
@ -30,6 +31,25 @@ type
constructor Create(AHeader: TObjCHeader); constructor Create(AHeader: TObjCHeader);
end; 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); procedure TPrecompileHandler.OnPrecompile(Sender: TObject);
var var
parser : TTextParser; parser : TTextParser;
@ -84,6 +104,29 @@ begin
hdr := AHeader; hdr := AHeader;
end; 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; function ReadAndParseFile(const FileName: AnsiString; outdata: TStrings; var Err: AnsiString): Boolean;
var var
hdr : TObjCHeader; hdr : TObjCHeader;
@ -91,6 +134,7 @@ var
prec : TPrecompileHandler ; prec : TPrecompileHandler ;
s : AnsiString; s : AnsiString;
i, cnt : integer; i, cnt : integer;
upini : TIniFile;
begin begin
Result :=false; Result :=false;
if not FileExists(FileName) then begin if not FileExists(FileName) then begin
@ -130,6 +174,15 @@ begin
except except
end; end;
if updIni <> '' then begin
upIni := TIniFile.Create(updIni);
try
UpdateIniWithEntity(ConvertSettings, upIni, hdr);
finally
upIni.Free;
end;
end;
WriteOutIncludeFile(hdr, outdata); WriteOutIncludeFile(hdr, outdata);
finally finally
parser.TokenTable.Free; parser.TokenTable.Free;
@ -185,7 +238,6 @@ begin
writeln(' converted!'); writeln(' converted!');
end else begin end else begin
writeln('Error: ', err); writeln('Error: ', err);
readln;
end; end;
until FindNext(srch) <> 0; until FindNext(srch) <> 0;
@ -227,6 +279,14 @@ begin
end; end;
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); procedure ReadIniFile(Settings: TConvertSettings; const FileName: AnsiString);
var var
ini : TIniFile; ini : TIniFile;
@ -234,16 +294,59 @@ var
a, b : AnsiString; a, b : AnsiString;
i : Integer; i : Integer;
begin begin
// uikit.ini
if not FileExists(FileName) then begin
writeln('//ini file is not found');
Exit;
end;
ini := TIniFile.Create(FileName); ini := TIniFile.Create(FileName);
values := TStringList.Create; values := TStringList.Create;
try try
ini.ReadSection('TypeReplace', values); values.Clear;
{ ini.ReadSection('TypeReplace', values);
for i := 0 to values.Count - 1 do begin for i := 0 to values.Count - 1 do begin
a := values.ValueFromIndex[i]; a := values.ValueFromIndex[i];
b := values.Values[a]; b := values.Values[a];
if b <> '' then begin
ense
Settings.TypeDefReplace[a] := b; 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; 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 finally
values.Free; values.Free;
ini.Free; ini.Free;
@ -273,7 +376,7 @@ begin
FileName := ParamStr(i); FileName := ParamStr(i);
end; end;
vlm := Params.Values['settings']; vlm := Params.Values['ini'];
if vlm <> '' then if vlm <> '' then
ReadIniFile(Settings, vlm); ReadIniFile(Settings, vlm);
@ -282,15 +385,12 @@ begin
Settings.ConvertPrefix.Add ('{%mainunit '+vlm+'}'); Settings.ConvertPrefix.Add ('{%mainunit '+vlm+'}');
vlm := Params.Values['ignoreinclude']; vlm := Params.Values['ignoreinclude'];
if vlm <> '' then begin if vlm <> '' then
AddSpaceSeparated(vlm, Settings.IgnoreIncludes); AddSpaceSeparated(vlm, Settings.IgnoreIncludes);
{for i := 0 to Settings.IgnoreIncludes.Count - 1 do begin
vlm := Settings.IgnoreIncludes[i]; vlm := Params.Values['updini'];
vlm := Copy(vlm, 1, length(vlm) - length(ExtractFileExt(vlm))); if vlm <> '' then
vlm := vlm + '.inc'; updIni := vlm;
Settings.IgnoreIncludes[i] := vlm;
end;}
end;
finally finally
Params.Free; Params.Free;
@ -304,6 +404,7 @@ var
err : AnsiString = ''; err : AnsiString = '';
i : integer; i : integer;
begin begin
try try
GetConvertSettings(ConvertSettings, inpf); GetConvertSettings(ConvertSettings, inpf);