You've already forked lazarus-ccr
*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:
@ -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 }
|
||||
|
||||
@ -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);
|
||||
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,6 +1538,36 @@ begin
|
||||
AParser.SetError(ErrExpectStr('Identifier', s));
|
||||
Exit;
|
||||
end;}
|
||||
|
||||
AParser.FindNextToken(s, tt);
|
||||
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_Symbol) and (s <> ')') then begin
|
||||
AParser.SetError(ErrExpectStr(')', s));
|
||||
Result := false;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result := fnc.Parse(AParser);
|
||||
|
||||
|
||||
end else begin
|
||||
AParser.Index := AParser.TokenPos;
|
||||
Result := ParseCVarDef(AParser, _Name, _IsArray, _ArraySize );
|
||||
if not Result then Exit;
|
||||
|
||||
@ -1492,10 +1579,14 @@ begin
|
||||
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.
|
||||
|
@ -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;
|
||||
@ -847,11 +857,58 @@ begin
|
||||
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
|
||||
@ -867,7 +924,12 @@ begin
|
||||
subs[i] := nm;
|
||||
end;
|
||||
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);
|
||||
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';
|
||||
|
@ -13,7 +13,7 @@
|
||||
<IconPath Value="./"/>
|
||||
<TargetFileExt Value=".exe"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ActiveEditorIndexAtStart Value="0"/>
|
||||
<ActiveEditorIndexAtStart Value="1"/>
|
||||
</General>
|
||||
<VersionInfo>
|
||||
<ProjectVersion Value=""/>
|
||||
@ -34,18 +34,18 @@
|
||||
<Unit0>
|
||||
<Filename Value="objcparser.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="Project1"/>
|
||||
<CursorPos X="18" Y="8"/>
|
||||
<TopLine Value="1"/>
|
||||
<UnitName Value="objcparser"/>
|
||||
<CursorPos X="1" Y="409"/>
|
||||
<TopLine Value="388"/>
|
||||
<EditorIndex Value="0"/>
|
||||
<UsageCount Value="80"/>
|
||||
<UsageCount Value="81"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<UnitName Value="ObjCParserUtils"/>
|
||||
<CursorPos X="1" Y="63"/>
|
||||
<TopLine Value="57"/>
|
||||
<CursorPos X="1" Y="1353"/>
|
||||
<TopLine Value="1334"/>
|
||||
<EditorIndex Value="1"/>
|
||||
<UsageCount Value="37"/>
|
||||
<Loaded Value="True"/>
|
||||
@ -53,12 +53,12 @@
|
||||
<Unit2>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<UnitName Value="ObjCParserTypes"/>
|
||||
<CursorPos X="1" Y="8"/>
|
||||
<TopLine Value="1"/>
|
||||
<CursorPos X="9" Y="517"/>
|
||||
<TopLine Value="517"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<UsageCount Value="37"/>
|
||||
<Bookmarks Count="1">
|
||||
<Item0 X="1" Y="612" ID="0"/>
|
||||
<Item0 X="1" Y="626" ID="0"/>
|
||||
</Bookmarks>
|
||||
<Loaded Value="True"/>
|
||||
</Unit2>
|
||||
@ -119,7 +119,7 @@
|
||||
<UnitName Value="pascodeutils"/>
|
||||
<CursorPos X="1" Y="13"/>
|
||||
<TopLine Value="1"/>
|
||||
<UsageCount Value="77"/>
|
||||
<UsageCount Value="78"/>
|
||||
</Unit11>
|
||||
<Unit12>
|
||||
<Filename Value="../appkit/NSWindow.inc"/>
|
||||
@ -190,7 +190,7 @@
|
||||
<IsPartOfProject Value="True"/>
|
||||
<CursorPos X="44" Y="16"/>
|
||||
<TopLine Value="11"/>
|
||||
<UsageCount Value="58"/>
|
||||
<UsageCount Value="59"/>
|
||||
<SyntaxHighlighter Value="C++"/>
|
||||
</Unit22>
|
||||
<Unit23>
|
||||
@ -277,19 +277,23 @@
|
||||
<UsageCount Value="9"/>
|
||||
</Unit35>
|
||||
</Units>
|
||||
<JumpHistory Count="3" HistoryIndex="2">
|
||||
<JumpHistory Count="4" HistoryIndex="3">
|
||||
<Position1>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="7" Column="49" TopLine="1"/>
|
||||
<Caret Line="1830" Column="49" TopLine="1823"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1529" Column="30" TopLine="1518"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="68" Column="33" TopLine="57"/>
|
||||
<Caret Line="94" Column="12" TopLine="83"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position4>
|
||||
</JumpHistory>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@ -5,13 +5,14 @@
|
||||
|
||||
main parser unit
|
||||
}
|
||||
program Project1;
|
||||
program objcparser;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}{$H+}
|
||||
{$else}
|
||||
{$APPTYPE CONSOLE}
|
||||
{$endif}
|
||||
|
||||
uses
|
||||
Classes, IniFiles,
|
||||
SysUtils,
|
||||
@ -30,6 +31,25 @@ type
|
||||
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);
|
||||
|
Reference in New Issue
Block a user