+ fixed bugs noted by Josef Ryan (inproper function body, bugs with preprocessor).
+ modifications in the units structure. - replaced usage IgnoreTokens (and removed) with TokenReplace git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@732 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
6f8dd5936a
commit
aa2708fd56
@ -105,7 +105,7 @@ type
|
||||
|
||||
Stack : TList;
|
||||
Errors : TStringList;
|
||||
IgnoreTokens : TStringList;
|
||||
//IgnoreTokens : TStringList;
|
||||
MacroHandler : TMacroHandler;
|
||||
|
||||
UseCommentEntities : Boolean;
|
||||
@ -182,7 +182,7 @@ type
|
||||
end;
|
||||
|
||||
TCPrepElIf = TCPrepIf;
|
||||
|
||||
|
||||
TCPrepPragma = class(TCPrepocessor)
|
||||
_Text : AnsiString;
|
||||
function DoParse(AParser: TTextParser): Boolean; override;
|
||||
@ -228,9 +228,10 @@ type
|
||||
function DoParse(AParser: TTextParser): Boolean; override;
|
||||
function ParseAfterTypeName(AParser: TTextParser): Boolean;
|
||||
public
|
||||
_Type : TEntity;
|
||||
_Name : AnsiString;
|
||||
_isConst : Boolean;
|
||||
_Type : TEntity;
|
||||
_Name : AnsiString;
|
||||
_isConst : Boolean;
|
||||
_isExtern : Boolean;
|
||||
end;
|
||||
|
||||
{ TFunctionParam }
|
||||
@ -254,7 +255,7 @@ type
|
||||
TFunctionTypeDef = class(TEntity)
|
||||
protected
|
||||
function DoParse(APArser: TTextParser): Boolean; override;
|
||||
public
|
||||
public
|
||||
_ResultType : TEntity;
|
||||
_ParamsList : TFunctionParamsList;
|
||||
|
||||
@ -262,6 +263,15 @@ type
|
||||
_isPointerRef : Boolean;
|
||||
end;
|
||||
|
||||
TCCodeSection = class(TEntity)
|
||||
protected
|
||||
function DoParse(AParser: TTextParser): Boolean; override;
|
||||
public
|
||||
_RawText : AnsiSTring;
|
||||
end;
|
||||
|
||||
TFunctionBody = class(TCCodeSection);
|
||||
|
||||
{ TFunctionDef }
|
||||
|
||||
TFunctionDef = class(TEntity)
|
||||
@ -274,9 +284,11 @@ type
|
||||
_Name : AnsiString;
|
||||
_isPointer : Boolean;
|
||||
_isPointerRef : Boolean;
|
||||
_isExternal : Boolean;
|
||||
_CallConv : TCallingConv;
|
||||
end;
|
||||
_isExternal : Boolean;
|
||||
_isInLine : Boolean;
|
||||
_CallConv : TCallingConv;
|
||||
_Body : TFunctionBody; // can be nil!
|
||||
end;
|
||||
|
||||
|
||||
{ TEnumValue }
|
||||
@ -462,9 +474,7 @@ type
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
TCHeader = class(TEntity);
|
||||
TCHeader = class(TEntity); // it's CCodeSection ??
|
||||
|
||||
{ TObjCHeader }
|
||||
|
||||
@ -482,6 +492,7 @@ const
|
||||
WhiteSpaceChars : TCharSet = [#10,#13,#32,#9];
|
||||
|
||||
// utility functions
|
||||
function SkipEndOfLineChars(const Src: AnsiString; idx: integer): Integer;
|
||||
|
||||
function ParseSeq(Parser: TTextParser; const OpenSeq, CloseSeq: AnsiString): AnsiString;
|
||||
|
||||
@ -544,18 +555,29 @@ implementation
|
||||
var
|
||||
CustomList : TList = nil;
|
||||
|
||||
function SkipEndOfLineChars(const Src: AnsiString; idx: integer): Integer;
|
||||
begin
|
||||
if idx < length(Src) then begin
|
||||
if (Src[idx] = #10) and (Src[idx+1]=#13) then inc(idx)
|
||||
else if (Src[idx] = #13) and (Src[idx+1]=#10) then inc(idx);
|
||||
end;
|
||||
Result := idx+1;
|
||||
end;
|
||||
|
||||
function IsCReserved(const Token: AnsiString): Boolean;
|
||||
begin
|
||||
if Token = '' then begin
|
||||
Result := false;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result := true;
|
||||
case Token[1] of
|
||||
'c': begin
|
||||
'c':
|
||||
if Token = 'const' then Exit;
|
||||
end;
|
||||
'e':
|
||||
if Token = 'extern' then Exit;
|
||||
'i':
|
||||
if Token = 'inline' then Exit;
|
||||
end;
|
||||
|
||||
Result := false;
|
||||
@ -933,7 +955,7 @@ begin
|
||||
Line := 1;
|
||||
Stack := TList.Create;
|
||||
Errors := TStringList.Create;
|
||||
IgnoreTokens := TStringList.Create;
|
||||
//IgnoreTokens := TStringList.Create;
|
||||
UsePrecompileEntities := true;
|
||||
Comments := TList.Create;
|
||||
end;
|
||||
@ -941,7 +963,7 @@ end;
|
||||
destructor TTextParser.Destroy;
|
||||
begin
|
||||
Comments.Free;
|
||||
IgnoreTokens.Free;
|
||||
//IgnoreTokens.Free;
|
||||
Errors.Free;
|
||||
Stack.Free;
|
||||
inherited Destroy;
|
||||
@ -1138,8 +1160,10 @@ begin
|
||||
ScanTo(Buf, index, EoLnChars);
|
||||
SkipSingleEoLnChars;
|
||||
|
||||
end else if not (IsSubStr(TokenTable.Precompile, Buf, Index) and HandlePrecomiler) then begin // 1. check is Compiler directive is found
|
||||
if (Buf[index] in TokenTable.Symbols) then begin // 2. symbol has been found, so it's not an ident
|
||||
end else begin
|
||||
if (IsSubStr(TokenTable.Precompile, Buf, Index) and HandlePrecomiler) then
|
||||
// 1. check is Preprocessor directive is found
|
||||
else if (Buf[index] in TokenTable.Symbols) then begin // 2. symbol has been found, so it's not an ident
|
||||
if (not (Buf[index] in blck)) or (not SkipComments) then begin // 2.1 check if comment is found (comment prefixes match to the symbols)
|
||||
Result := true; // 2.2 check if symbol is found
|
||||
if (Buf[index] = '.') and (index < length(Buf)) and (Buf[index+1] in ['0'..'9']) then begin
|
||||
@ -1181,14 +1205,14 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
if Result and (IgnoreTokens.Count > 0) then
|
||||
{if Result and (IgnoreTokens.Count > 0) then
|
||||
if IgnoreTokens.IndexOf(Token) >= 0 then begin
|
||||
if Assigned(OnIgnoreToken) then
|
||||
OnIgnoreToken(Self, Token);
|
||||
Result := false;
|
||||
TokenType := tt_None;
|
||||
Token := '';
|
||||
end;
|
||||
end;}
|
||||
|
||||
if (Token <> '') and (TokenType = tt_Ident) and Result then begin
|
||||
TokenPos := Index - length(Token);
|
||||
@ -1258,7 +1282,7 @@ var
|
||||
m : AnsiString;
|
||||
begin
|
||||
Result := false;
|
||||
if ProcessingMacro or not assigned(MacroHandleR) then Exit;
|
||||
if ProcessingMacro or not Assigned(MacroHandler) then Exit;
|
||||
|
||||
ProcessingMacro := true;
|
||||
try
|
||||
@ -1462,48 +1486,42 @@ var
|
||||
isfunc : Boolean;
|
||||
tt : TTokenType;
|
||||
s : AnsiString;
|
||||
// rep : integer;
|
||||
v : TVariable;
|
||||
fn : TFunctionDef;
|
||||
isext : Boolean;
|
||||
|
||||
v : TVariable;
|
||||
fn : TFunctionDef;
|
||||
idx : Integer;
|
||||
|
||||
Modifiers : TStringList;
|
||||
ent : TEntity;
|
||||
|
||||
begin
|
||||
Modifiers := TStringList.Create;
|
||||
Result := false;
|
||||
idx := AParser.TokenPos;
|
||||
Result := false;
|
||||
Modifiers := TStringList.Create;
|
||||
ctype:=nil;
|
||||
fn := nil;
|
||||
try
|
||||
AParser.FindNextToken(s, tt);
|
||||
isext := false;
|
||||
if s = 'extern' then begin
|
||||
isext := true;
|
||||
end else
|
||||
AParser.Index := AParser.TokenPos;
|
||||
repeat
|
||||
if not AParser.FindNextToken(s, tt) or (tt <> tt_Ident) then begin
|
||||
Result := false;
|
||||
Exit;
|
||||
end;
|
||||
if isCReserved (s) then begin
|
||||
Modifiers.Add(s); // C reserved tokens cannot be name of a function
|
||||
s := '';
|
||||
end;
|
||||
until s <> '';
|
||||
|
||||
AParser.Index := AParser.TokenPos;
|
||||
|
||||
ctype := TTypeDef.Create(nil);
|
||||
Result := ctype.Parse(AParser);
|
||||
if not Result then begin
|
||||
ctype.Free;
|
||||
Exit;
|
||||
end;
|
||||
if not Result then Exit;
|
||||
|
||||
// expecting name of Variable or Function name
|
||||
repeat
|
||||
AParser.FindNextToken(_name, tt);
|
||||
if isCReserved (_name) then begin
|
||||
Modifiers.Add(_name);
|
||||
_name := '';
|
||||
end;
|
||||
until _name <> '';
|
||||
if tt <> tt_Ident then begin
|
||||
|
||||
if not AParser.FindNextToken(_name, tt) or (tt <> tt_Ident) then begin
|
||||
Result := false;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
//rep := AParser.TokenPos;
|
||||
|
||||
AParser.FindNextToken(s, tt);
|
||||
@ -1513,21 +1531,35 @@ begin
|
||||
fn := TFunctionDef.Create(Owner);
|
||||
fn._ResultType := ctype;
|
||||
fn._Name := _name;
|
||||
fn._IsExternal := isext;
|
||||
fn._IsExternal := Modifiers.IndexOf('extern')>=0;
|
||||
fn._isInline := Modifiers.IndexOf('inline')>=0;
|
||||
fn.ParseParams(AParser);
|
||||
owner.Items.Add(fn);
|
||||
ent := fn;
|
||||
end else begin
|
||||
v := TVariable.Create(Owner);
|
||||
v._Type := ctype;
|
||||
v._Name := _name;
|
||||
owner.Items.add(v);
|
||||
v._isExtern := Modifiers.IndexOf('extern')>=0;
|
||||
ent := v;
|
||||
AParser.Index := AParser.TokenPos;
|
||||
end;
|
||||
AParser.FindNextToken(s, tt);
|
||||
|
||||
Result := (tt = tt_Symbol) and (s = ';');
|
||||
if isfunc and not Result and Assigned(fn) then begin
|
||||
AParser.Index := AParser.TokenPos;
|
||||
fn._Body := TFunctionBody.Create(fn);
|
||||
Result := fn._Body.Parse(AParser);
|
||||
end;
|
||||
|
||||
if Result then owner.Items.Add(ent)
|
||||
else ent.Free;
|
||||
|
||||
finally
|
||||
if not Result then
|
||||
if not Result then begin
|
||||
ctype.Free;
|
||||
AParser.Index := idx;
|
||||
end;
|
||||
Modifiers.Free;
|
||||
end;
|
||||
end;
|
||||
@ -1588,7 +1620,7 @@ begin
|
||||
AParser.Index := AParser.TokenPos;
|
||||
TSkip(ent)._Skip := SkipLine(AParser.Buf, AParser.Index);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if Assigned(ent) then Items.Add(ent);
|
||||
end;
|
||||
@ -2555,7 +2587,7 @@ end;
|
||||
|
||||
{ TFunctionDef }
|
||||
|
||||
function TFunctionDef.DoParse(APArser: TTextParser): Boolean;
|
||||
function TFunctionDef.DoParse(AParser: TTextParser): Boolean;
|
||||
var
|
||||
s : AnsiString;
|
||||
tt : TTokenType;
|
||||
@ -2575,8 +2607,17 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
if not Assigned(_ParamsList) then
|
||||
_ParamsList := TFunctionParamsList.Create(Self);
|
||||
_ParamsList := TFunctionParamsList.Create(Self); // an empty param list
|
||||
Result := true;
|
||||
|
||||
AParser.FindNextToken(s, tt);
|
||||
if (tt = tt_Symbol) and (s = '{') then begin
|
||||
AParser.Index := AParser.TokenPos;
|
||||
_Body := TFunctionBody.Create(Self);
|
||||
_Body.Parse(AParser);
|
||||
end else
|
||||
AParser.Index := AParser.TokenPos;
|
||||
|
||||
end;
|
||||
|
||||
function TFunctionDef.ParseParams(AParser: TTextParser): Boolean;
|
||||
@ -2733,7 +2774,7 @@ var
|
||||
tt : TTokenType;
|
||||
begin
|
||||
AParser.FindNextToken(s, tt);
|
||||
Result := (s = '#if') or (s = '#ifdef') or (s = '#elif');
|
||||
Result := (s = '#if') or (s = '#ifdef') or (s = '#elif') or (s = '#ifndef');
|
||||
_Cond := SkipLine(AParser.buf, AParser.Index);
|
||||
end;
|
||||
|
||||
@ -2947,6 +2988,34 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function TCCodeSection.DoParse(AParser: TTextParser): Boolean;
|
||||
var
|
||||
s : String;
|
||||
tt : TTokenType;
|
||||
braces : Integer;
|
||||
idx : Integer;
|
||||
begin
|
||||
AParser.FindNextToken(s, tt);
|
||||
Result := (tt = tt_Symbol) and (s = '{');
|
||||
if not Result then begin
|
||||
AParser.SetError(ErrExpectStr('{', s));
|
||||
Exit;
|
||||
end;
|
||||
idx := AParser.TokenPos;
|
||||
|
||||
braces := 1; // brace opened
|
||||
while braces > 0 do begin
|
||||
AParser.FindNextToken(s, tt);
|
||||
// todo: c expressions and declarations parsing
|
||||
if s = '{' then inc(braces) // another brace opened
|
||||
else if s = '}' then dec(braces); // brace closed
|
||||
end;
|
||||
Result := true;
|
||||
_RawText := Copy(APArser.Buf, idx, AParser.Index - idx);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
initialization
|
||||
|
||||
finalization
|
||||
|
@ -43,6 +43,7 @@ type
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure GetReplaces(strings: TStrings);
|
||||
property Replace[const s: AnsiString]: AnsiString read GetReplace write SetReplace; default;
|
||||
property CaseSensetive: Boolean read GetCaseSense write SetCaseSense;
|
||||
end;
|
||||
@ -58,8 +59,9 @@ type
|
||||
DefineReplace : TReplaceList;
|
||||
TypeDefReplace : TReplaceList; // replaces for C types
|
||||
PtrTypeReplace : TReplaceList; // replaces for C types pointers
|
||||
TokenReplace : TReplaceList;
|
||||
|
||||
IgnoreTokens : TStringList;
|
||||
//IgnoreTokens : TStringList; //todo: Remote. Use TokenReplace instead
|
||||
|
||||
ConvertPrefix : TStringList;
|
||||
|
||||
@ -110,7 +112,6 @@ function GetMethodStr(cl: TClassDef; m: TClassMethodDef; ForImplementation: Bool
|
||||
function GetProcFuncHead(const FuncName, OfClass, Params, ResType: AnsiString; const FuncDest: AnsiString = ''): AnsiString;
|
||||
function GetMethodParams(const m: TClassMethodDef; NamesOnly: Boolean): AnsiString;
|
||||
function GetMethodResultType(const m: TClassMethodDef): AnsiString;
|
||||
function IsPascalReserved(const s: AnsiString): Boolean;
|
||||
|
||||
function IsPascalFloatType(const TypeName: AnsiString): Boolean;
|
||||
|
||||
@ -162,43 +163,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
// 'result' is considered reserved word!
|
||||
function IsPascalReserved(const s: AnsiString): Boolean;
|
||||
var
|
||||
ls : AnsiString;
|
||||
begin
|
||||
//todo: a hash table should be used!
|
||||
Result := false;
|
||||
if s = '' then Exit;
|
||||
ls := AnsiLowerCase(s);
|
||||
case ls[1] of
|
||||
'a': Result := (ls = 'absolute') or (ls = 'abstract') or (ls = 'and') or (ls = 'array') or (ls = 'as') or (ls= 'asm') or (ls = 'assembler');
|
||||
'b': Result := (ls = 'begin') or (ls = 'break');
|
||||
'c': Result := (ls = 'cdecl') or (ls = 'class') or (ls = 'const') or (ls = 'constructor') or (ls = 'continue') or (ls = 'cppclass');
|
||||
'd': Result := (ls = 'deprecated') or (ls = 'destructor') or (ls = 'div') or (ls = 'do') or (ls = 'downto');
|
||||
'e': Result := (ls = 'else') or (ls = 'end') or (ls = 'except') or (ls = 'exit') or (ls = 'export') or (ls = 'exports') or (ls = 'external');
|
||||
'f': Result := (ls = 'fail') or (ls = 'false') or (ls = 'far') or (ls = 'file') or (ls = 'finally') or (ls = 'for') or (ls = 'forward') or (ls = 'function');
|
||||
'g': Result := (ls = 'goto');
|
||||
'i':
|
||||
Result := (ls = 'if') or (ls = 'implementation') or (ls = 'in') or (ls = 'index') or (ls = 'inherited') or (ls = 'initialization') or (ls = 'inline')
|
||||
or (ls = 'interface') or (ls = 'interrupt') or (ls = 'is');
|
||||
'l': Result := (ls = 'label') or (ls = 'library');
|
||||
'm': Result := (ls = 'mod');
|
||||
'n': Result := {(ls = 'name') or} (ls = 'near') or (ls = 'nil') or (ls = 'not');
|
||||
'o': Result := (ls = 'object') or (ls = 'of') or (ls = 'on') or (ls = 'operator') or (ls = 'or') or (ls = 'otherwise');
|
||||
'p':
|
||||
Result := (ls = 'packed') or (ls = 'popstack') or (ls = 'private') or (ls = 'procedure') or (ls = 'program') or (ls = 'property')
|
||||
or (ls = 'protected') or (ls = 'public');
|
||||
'r': Result := (ls = 'raise') or (ls = 'record') or (ls = 'reintroduce') or (ls = 'repeat') or (ls = 'result');
|
||||
's': Result := (ls = 'self') or (ls = 'set') or (ls = 'shl') or (ls = 'shr') or (ls = 'stdcall') or (ls = 'string');
|
||||
't': Result := (ls = 'then') or (ls = 'to') or (ls = 'true') or (ls = 'try') or (ls = 'type');
|
||||
'u': Result := (ls = 'unimplemented') or (ls = 'unit') or (ls = 'until') or (ls = 'uses');
|
||||
'v': Result := (ls = 'var') or (ls = 'virtual');
|
||||
'w': Result := (ls = 'while') or (ls = 'with');
|
||||
'x': Result := (ls = 'xor');
|
||||
end;
|
||||
end;
|
||||
|
||||
function FixIfReserved(const AName: AnsiString; NotUse: TStrings = nil): AnsiString;
|
||||
begin
|
||||
Result := AName;
|
||||
@ -441,7 +405,7 @@ begin
|
||||
//todo: still, i don't like it...
|
||||
Result :='';
|
||||
i := 1;
|
||||
ScanWhile(s, i, [#32, #9]);
|
||||
ScanWhile(s, i, InvsChars);
|
||||
vs := Copy(s, i, length(s) - i + 1);
|
||||
if vs = '' then Exit;
|
||||
|
||||
@ -487,11 +451,11 @@ var
|
||||
vs : AnsiString;
|
||||
begin
|
||||
i := 1;
|
||||
ScanWhile(prm, i, [#32, #9]);
|
||||
ScanWhile(prm, i, InvsChars);
|
||||
if prm[i] = '!' then begin
|
||||
isDef := false;
|
||||
inc(i);
|
||||
ScanWhile(prm, i, [#32, #9]);
|
||||
ScanWhile(prm, i, InvsChars);
|
||||
end else
|
||||
isDef :=true;
|
||||
vs := Copy(prm, i, length(prm) - i + 1);
|
||||
@ -551,12 +515,8 @@ begin
|
||||
i := 1;
|
||||
while i <= length(AComment) do begin
|
||||
// scan for multylined comments
|
||||
cmtln := ScanTo(AComment, i, [#10, #13]);
|
||||
if i < length(AComment) then begin
|
||||
if (AComment[i] = #10) and (AComment[i+1] = #13) then inc(i)
|
||||
else if (AComment[i] = #13) and (AComment[i+1] = #10) then inc(i);
|
||||
end;
|
||||
inc(i);
|
||||
cmtln := ScanTo(AComment, i, EoLnChars);
|
||||
i := SkipEndOfLineChars(AComment, i);
|
||||
|
||||
// break long comments into lines
|
||||
j := 1;
|
||||
@ -564,7 +524,7 @@ begin
|
||||
k := j;
|
||||
inc(j, 80);
|
||||
if j > length(cmtln) then j := length(cmtln);
|
||||
ScanTo(cmtln, j, [#32, #10, #13, #9]);
|
||||
ScanTo(cmtln, j, WhiteSpaceChars);
|
||||
subs.Add(Prefix + '// ' + Copy(cmtln, k, j - k));
|
||||
inc(j);
|
||||
end;
|
||||
@ -709,24 +669,27 @@ var
|
||||
i : Integer;
|
||||
begin
|
||||
i := 1;
|
||||
ScanWhile(s, i, [#9, #32, #10, #13]);
|
||||
ScanWhile(s, i, WhiteSpaceChars);
|
||||
if i < length(s) then begin
|
||||
DefWhat := ScanTo(s, i, [#9, #32, #10, #13]);
|
||||
ScanWhile(s, i, [#9, #32]);
|
||||
DefWhat := ScanTo(s, i, WhiteSpaceChars);
|
||||
ScanWhile(s, i, InvsChars);
|
||||
DefTo := Copy(s, i, length(s) - i + 1);
|
||||
end else
|
||||
DefTo := '';
|
||||
end;
|
||||
|
||||
procedure WriteOutPrecompDefine(const Prec: TPrecompiler; Prefix: AnsiString; st: TStrings);
|
||||
procedure WriteOutPrecompDefine(const Prec: TPrecompiler; Prefix: AnsiString; st: TStrings; var IsConstant: Boolean);
|
||||
var
|
||||
a, b: AnsiString;
|
||||
begin
|
||||
IsConstant:=false;
|
||||
if Prec._Directive = '#define' then begin
|
||||
ParseDefine(Prec._Params, a, b);
|
||||
if b <> ''
|
||||
then st.Add(Prefix + Format('%s = %s;', [a, b]))
|
||||
else st.Add(Prefix + Format('{$define %s}', [a]));
|
||||
if b <> '' then begin
|
||||
st.Add(Prefix + Format('%s = %s;', [a, b]));
|
||||
IsConstant:=True;
|
||||
end else
|
||||
st.Add(Prefix + Format('{$define %s}', [a]));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -905,9 +868,15 @@ begin
|
||||
end;
|
||||
|
||||
restype := ObjCToDelphiType(fntype, isptr);
|
||||
s:= GetProcFuncHead(f._Name, '', CParamsListToPascalStr(f._ParamsList), restype) + ' ' + ConvertSettings.GetCallConv(true);
|
||||
s:= GetProcFuncHead(f._Name, '', CParamsListToPascalStr(f._ParamsList), restype) + ' ';
|
||||
|
||||
if f._isInLine then s := s + ' inline; '
|
||||
else s:=s+ConvertSettings.GetCallConv(true);
|
||||
|
||||
st.Add(s);
|
||||
s := Format(' external name ''%s%s'';', [ConvertSettings.ExternFuncPrefix, f._Name]);
|
||||
if f._isExternal then
|
||||
s := Format(' external name ''%s%s'';', [ConvertSettings.ExternFuncPrefix, f._Name]);
|
||||
|
||||
st.Add(s);
|
||||
end;
|
||||
|
||||
@ -1168,6 +1137,8 @@ var
|
||||
cmt : TStringList;
|
||||
cl : TClassDef;
|
||||
clName : String;
|
||||
isConstant : Boolean;
|
||||
b : Boolean;
|
||||
|
||||
PasSection : String;
|
||||
|
||||
@ -1189,17 +1160,19 @@ begin
|
||||
subs := TStringList.Create;
|
||||
consts := TStringList.Create;
|
||||
cmt := TStringList.Create;
|
||||
isConstant := false;
|
||||
try
|
||||
for i := 0 to hdr.Items.Count - 1 do
|
||||
if Assigned(hdr.Items[i]) then
|
||||
if (TObject(hdr.Items[i]) is TPrecompiler) then begin
|
||||
WriteOutIfDefPrecompiler(TPrecompiler(hdr.Items[i]), SpacePrefix, st);
|
||||
WriteOutPrecompInclude(TPrecompiler(hdr.Items[i]), st);
|
||||
WriteOutPrecompDefine(TPrecompiler(hdr.Items[i]), ' ', subs);
|
||||
WriteOutPrecompDefine(TPrecompiler(hdr.Items[i]), ' ', subs, b);
|
||||
isConstant := isConstant or b;
|
||||
end;
|
||||
|
||||
if subs.Count > 0 then begin
|
||||
st.Add('const');
|
||||
if isConstant then StartSection('const');
|
||||
st.AddStrings(subs);
|
||||
subs.Clear;
|
||||
end;
|
||||
@ -1215,7 +1188,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
for i := 0 to hdr.Items.Count - 1 do
|
||||
if Assigned(hdr.Items[i]) then begin
|
||||
|
||||
@ -1671,9 +1643,54 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure WriteOutFuncitionToImplemenation(f: TFunctionDef; st: TStrings);
|
||||
var
|
||||
restype : AnsiString;
|
||||
fntype : AnsiString;
|
||||
isptr : Boolean;
|
||||
s : AnsiString;
|
||||
txt : AnsiString;
|
||||
line : AnsiString;
|
||||
idx : Integer;
|
||||
begin
|
||||
if not Assigned(f) or (f._isExternal) then Exit; // external functions does not have a body
|
||||
|
||||
if not Assigned(f._ResultType) then begin
|
||||
isptr := false;
|
||||
fntype := 'int';
|
||||
end else if (f._ResultType is TTypeDef) then begin
|
||||
isptr := TTypeDef(f._ResultType)._IsPointer;
|
||||
fntype := TTypeDef(f._ResultType)._Name;
|
||||
end else begin
|
||||
isptr := false;
|
||||
fntype := '{todo: not implemented... see .h file for type}';
|
||||
end;
|
||||
|
||||
restype := ObjCToDelphiType(fntype, isptr);
|
||||
s:= GetProcFuncHead(f._Name, '', CParamsListToPascalStr(f._ParamsList), restype) + ' ';
|
||||
if f._isInline then s := s + 'inline; '
|
||||
else s:=s+ConvertSettings.GetCallConv(true);
|
||||
st.Add(s);
|
||||
st.Add('begin ');
|
||||
if not Assigned(f._Body) then
|
||||
st.Add(' //body is missing... Probably declared somethere in .c (.cpp, .cxx) file? or the parser bug?')
|
||||
else begin
|
||||
txt := TFunctionBody(f._Body)._RawText;
|
||||
idx := 1;
|
||||
st.Add(' // Sorry, but the parser cannot convert the function''s body. ');
|
||||
while idx <= length(txt) do begin
|
||||
line := ScanTo(txt, idx, EoLnChars);
|
||||
idx := SkipEndOfLineChars(txt, idx);
|
||||
st.Add(' //'+Line);
|
||||
end;
|
||||
end;
|
||||
st.Add('end;');
|
||||
st.Add('');
|
||||
end;
|
||||
|
||||
procedure WriteOutImplementationSection(hdr: TObjCHeader; st: TStrings; consts: TStringList);
|
||||
var
|
||||
i : Integer;
|
||||
i : Integer;
|
||||
subs : TStringList;
|
||||
begin
|
||||
subs := TStringList.Create;
|
||||
@ -1687,7 +1704,10 @@ begin
|
||||
for i := 0 to hdr.Items.Count - 1 do
|
||||
if Assigned(hdr.Items[i]) then
|
||||
if (TObject(hdr.Items[i]) is TClassDef) then
|
||||
WriteOutClassToImplementation(TClassDef(hdr.Items[i]), subs);
|
||||
WriteOutClassToImplementation(TClassDef(hdr.Items[i]), subs)
|
||||
else if (TObject(hdr.Items[i]) is TFunctionDef) then begin
|
||||
WriteOutFuncitionToImplemenation(TFunctionDef(hdr.Items[i]), subs);
|
||||
end;
|
||||
|
||||
if subs.Count = 0 then Exit;
|
||||
|
||||
@ -1993,7 +2013,8 @@ end;
|
||||
|
||||
constructor TConvertSettings.Create;
|
||||
begin
|
||||
IgnoreTokens := TStringList.Create;
|
||||
TokenReplace := TReplaceList.Create;
|
||||
//IgnoreTokens := TStringList.Create;
|
||||
IgnoreIncludes := TStringList.Create;
|
||||
IgnoreIncludes.CaseSensitive := false;
|
||||
DefineReplace := TReplaceList.Create;
|
||||
@ -2020,11 +2041,12 @@ end;
|
||||
|
||||
destructor TConvertSettings.Destroy;
|
||||
begin
|
||||
TokenReplace.Free;
|
||||
FloatTypes.Free;
|
||||
StructTypes.Free;
|
||||
ObjCClassTypes.Free;
|
||||
|
||||
IgnoreTokens.Free;
|
||||
//IgnoreTokens.Free;
|
||||
IgnoreIncludes.Free;
|
||||
TypeDefReplace.Free;
|
||||
PtrTypeReplace.Free;
|
||||
@ -2169,6 +2191,20 @@ begin
|
||||
else Result := TReplaceItem(fItems.Objects[i]).ReplaceStr;
|
||||
end;
|
||||
|
||||
procedure TReplaceList.GetReplaces(strings: TStrings);
|
||||
var
|
||||
i : Integer;
|
||||
s : AnsiString;
|
||||
const
|
||||
EmptyString = ' ';
|
||||
begin
|
||||
for i := 0 to fItems.Count - 1 do begin
|
||||
s := TReplaceItem(fItems.Objects[i]).ReplaceStr;
|
||||
if s = '' then s := EmptyString; // otherwise it's lost
|
||||
strings.Values[ fitems[i]] := s;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TReplaceList.SetReplace(const ARepl, AValue: AnsiString);
|
||||
var
|
||||
i : integer;
|
||||
|
@ -12,12 +12,20 @@ interface
|
||||
{$ifdef fpc}{$mode delphi}{$h+}{$endif}
|
||||
|
||||
uses
|
||||
ObjCParserTypes;
|
||||
SysUtils, ObjCParserTypes;
|
||||
|
||||
const
|
||||
ObjCDefaultParamDelim = '_';
|
||||
|
||||
|
||||
type
|
||||
TCProcessor = class(TObject)
|
||||
public
|
||||
procedure ProcessTree(Root: TEntity); virtual; abstract;
|
||||
end;
|
||||
|
||||
function ObjCToPasMethodName(mtd: TClassMethodDef; CutLastDelims: Boolean = false; ParamDelim: AnsiChar = ObjCDefaultParamDelim): AnsiString;
|
||||
function IsPascalReserved(const s: AnsiString): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
@ -43,6 +51,43 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// 'result' is considered reserved word!
|
||||
function IsPascalReserved(const s: AnsiString): Boolean;
|
||||
var
|
||||
ls : AnsiString;
|
||||
begin
|
||||
//todo: a hash table should be used!
|
||||
Result := false;
|
||||
if s = '' then Exit;
|
||||
ls := AnsiLowerCase(s);
|
||||
case ls[1] of
|
||||
'a': Result := (ls = 'absolute') or (ls = 'abstract') or (ls = 'and') or (ls = 'array') or (ls = 'as') or (ls= 'asm') or (ls = 'assembler');
|
||||
'b': Result := (ls = 'begin') or (ls = 'break');
|
||||
'c': Result := (ls = 'cdecl') or (ls = 'class') or (ls = 'const') or (ls = 'constructor') or (ls = 'continue') or (ls = 'cppclass');
|
||||
'd': Result := (ls = 'deprecated') or (ls = 'destructor') or (ls = 'div') or (ls = 'do') or (ls = 'downto');
|
||||
'e': Result := (ls = 'else') or (ls = 'end') or (ls = 'except') or (ls = 'exit') or (ls = 'export') or (ls = 'exports') or (ls = 'external');
|
||||
'f': Result := (ls = 'fail') or (ls = 'false') or (ls = 'far') or (ls = 'file') or (ls = 'finally') or (ls = 'for') or (ls = 'forward') or (ls = 'function');
|
||||
'g': Result := (ls = 'goto');
|
||||
'i':
|
||||
Result := (ls = 'if') or (ls = 'implementation') or (ls = 'in') or (ls = 'index') or (ls = 'inherited') or (ls = 'initialization') or (ls = 'inline')
|
||||
or (ls = 'interface') or (ls = 'interrupt') or (ls = 'is');
|
||||
'l': Result := (ls = 'label') or (ls = 'library');
|
||||
'm': Result := (ls = 'mod');
|
||||
'n': Result := {(ls = 'name') or} (ls = 'near') or (ls = 'nil') or (ls = 'not');
|
||||
'o': Result := (ls = 'object') or (ls = 'of') or (ls = 'on') or (ls = 'operator') or (ls = 'or') or (ls = 'otherwise');
|
||||
'p':
|
||||
Result := (ls = 'packed') or (ls = 'popstack') or (ls = 'private') or (ls = 'procedure') or (ls = 'program') or (ls = 'property')
|
||||
or (ls = 'protected') or (ls = 'public');
|
||||
'r': Result := (ls = 'raise') or (ls = 'record') or (ls = 'reintroduce') or (ls = 'repeat') or (ls = 'result');
|
||||
's': Result := (ls = 'self') or (ls = 'set') or (ls = 'shl') or (ls = 'shr') or (ls = 'stdcall') or (ls = 'string');
|
||||
't': Result := (ls = 'then') or (ls = 'to') or (ls = 'true') or (ls = 'try') or (ls = 'type');
|
||||
'u': Result := (ls = 'unimplemented') or (ls = 'unit') or (ls = 'until') or (ls = 'uses');
|
||||
'v': Result := (ls = 'var') or (ls = 'virtual');
|
||||
'w': Result := (ls = 'while') or (ls = 'with');
|
||||
'x': Result := (ls = 'xor');
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
</Flags>
|
||||
<MainUnit Value="0"/>
|
||||
<TargetFileExt Value=""/>
|
||||
<ActiveEditorIndexAtStart Value="0"/>
|
||||
<ActiveEditorIndexAtStart Value="2"/>
|
||||
</General>
|
||||
<VersionInfo>
|
||||
<ProjectVersion Value=""/>
|
||||
@ -45,8 +45,8 @@
|
||||
<Unit1>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<UnitName Value="ObjCParserUtils"/>
|
||||
<CursorPos X="5" Y="9"/>
|
||||
<TopLine Value="1"/>
|
||||
<CursorPos X="37" Y="888"/>
|
||||
<TopLine Value="880"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<UsageCount Value="13"/>
|
||||
<Loaded Value="True"/>
|
||||
@ -70,79 +70,127 @@
|
||||
<Loaded Value="True"/>
|
||||
</Unit3>
|
||||
</Units>
|
||||
<JumpHistory Count="18" HistoryIndex="17">
|
||||
<JumpHistory Count="30" HistoryIndex="29">
|
||||
<Position1>
|
||||
<Filename Value="objcparser.pas"/>
|
||||
<Caret Line="342" Column="61" TopLine="325"/>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1834" Column="30" TopLine="1824"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1834" Column="30" TopLine="1824"/>
|
||||
<Caret Line="7" Column="1" TopLine="1"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="7" Column="1" TopLine="1"/>
|
||||
<Caret Line="1171" Column="8" TopLine="1139"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1171" Column="8" TopLine="1139"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
<Caret Line="144" Column="138" TopLine="128"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="144" Column="138" TopLine="128"/>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="293" Column="14" TopLine="283"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="293" Column="14" TopLine="283"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
<Caret Line="284" Column="9" TopLine="274"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="284" Column="9" TopLine="274"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
<Caret Line="284" Column="9" TopLine="274"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="284" Column="9" TopLine="274"/>
|
||||
<Caret Line="285" Column="9" TopLine="274"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="285" Column="9" TopLine="274"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="objcparser.pas"/>
|
||||
<Caret Line="17" Column="18" TopLine="1"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1754" Column="3" TopLine="1751"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="422" Column="12" TopLine="412"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="422" Column="12" TopLine="412"/>
|
||||
<Caret Line="5" Column="18" TopLine="1"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="5" Column="18" TopLine="1"/>
|
||||
<Caret Line="16" Column="1" TopLine="11"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="16" Column="1" TopLine="11"/>
|
||||
<Caret Line="117" Column="29" TopLine="107"/>
|
||||
</Position17>
|
||||
<Position18>
|
||||
<Filename Value="ObjCParserTypes.pas"/>
|
||||
<Caret Line="117" Column="29" TopLine="107"/>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="54" Column="34" TopLine="46"/>
|
||||
</Position18>
|
||||
<Position19>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="124" Column="5" TopLine="93"/>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="159" Column="143" TopLine="143"/>
|
||||
</Position21>
|
||||
<Position22>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="838" Column="36" TopLine="822"/>
|
||||
</Position22>
|
||||
<Position23>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="880" Column="51" TopLine="872"/>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position24>
|
||||
<Position25>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="151" Column="1" TopLine="143"/>
|
||||
</Position25>
|
||||
<Position26>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="159" Column="143" TopLine="143"/>
|
||||
</Position26>
|
||||
<Position27>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="838" Column="36" TopLine="822"/>
|
||||
</Position27>
|
||||
<Position28>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="888" Column="26" TopLine="872"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position29>
|
||||
<Position30>
|
||||
<Filename Value="ObjCParserUtils.pas"/>
|
||||
<Caret Line="159" Column="143" TopLine="143"/>
|
||||
</Position30>
|
||||
</JumpHistory>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@ -148,6 +148,8 @@ var
|
||||
s : AnsiString;
|
||||
i, cnt : integer;
|
||||
upini : TIniFile;
|
||||
|
||||
repl : TStringList;
|
||||
begin
|
||||
Result :=false;
|
||||
if not FileExists(FileName) then begin
|
||||
@ -158,15 +160,25 @@ begin
|
||||
s := StrFromFile(FileName);
|
||||
hdr := TObjCHeader.Create;
|
||||
prec := TPrecompileHandler.Create(hdr);
|
||||
parser := CreateCParser(s);
|
||||
parser := CreateCParser(s, true);
|
||||
try
|
||||
repl := TStringList.Create;
|
||||
ConvertSettings.TokenReplace.GetReplaces(repl);
|
||||
for i := 0 to repl.Count - 1 do begin
|
||||
TCMacroHandler(parser.MacroHandler).AddSimpleMacro(repl.Names[i], repl.ValueFromIndex[i]);
|
||||
end;
|
||||
parser.Buf := s;
|
||||
try
|
||||
parser.UsePrecompileEntities := false;
|
||||
parser.UseCommentEntities := false;
|
||||
parser.OnPrecompile := prec.OnPrecompile;
|
||||
parser.OnComment := prec.OnComment;
|
||||
parser.IgnoreTokens.AddStrings(ConvertSettings.IgnoreTokens);
|
||||
|
||||
{for i := 0 to repl.Count - 1 do begin
|
||||
TCMacroHandler(parser.MacroHandler).AddSimpleMacro(
|
||||
ConvertSettings.IgnoreTokens[i], '');
|
||||
//parser.IgnoreTokens.AddStrings(ConvertSettings.IgnoreTokens);
|
||||
end;}
|
||||
|
||||
hdr._FileName := ExtractFileName(FileName);
|
||||
Result := hdr.Parse(parser);
|
||||
@ -332,6 +344,7 @@ begin
|
||||
Settings.TypeDefReplace[a] := b;
|
||||
end;}
|
||||
|
||||
//[Common]
|
||||
values.Clear;
|
||||
a := ini.ReadString(CommonSec, 'mainunit', '');
|
||||
if a <> '' then begin
|
||||
@ -359,16 +372,19 @@ begin
|
||||
ConvertSettings.IgnoreIncludes.AddStrings(values);
|
||||
end;}
|
||||
|
||||
//ini.ReadSectionValues('ReplaceToken', values);
|
||||
// [TokenReplace]
|
||||
Values.Clear;
|
||||
ini.ReadSection(TokenReplaceSec, values);
|
||||
|
||||
for i := 0 to values.Count - 1 do begin
|
||||
a := Values[i];
|
||||
b := ini.ReadString(TokenReplaceSec, a, '');
|
||||
if b ='' then
|
||||
Settings.IgnoreTokens.Add(a);
|
||||
{if b ='' then
|
||||
Settings.IgnoreTokens.Add(a)
|
||||
else}
|
||||
Settings.TokenReplace[a] := b;
|
||||
end;
|
||||
|
||||
// [TypeReplace]
|
||||
values.Clear;
|
||||
ini.ReadSection(TypeDefsSec, values);
|
||||
for i := 0 to values.Count - 1 do begin
|
||||
@ -390,7 +406,7 @@ begin
|
||||
if isNameofPointer(a) then
|
||||
Settings.PtrTypeReplace[ Copy(a, 1, length(a) - 1)] := b
|
||||
else
|
||||
Settings.TypeDefReplace[a] := b
|
||||
Settings.TypeDefReplace[a] := b;
|
||||
end;
|
||||
|
||||
finally
|
||||
@ -563,7 +579,6 @@ begin
|
||||
// TestTemplate;
|
||||
// Exit;
|
||||
|
||||
|
||||
doOutput := true;
|
||||
try
|
||||
GetConvertSettings(ConvertSettings, inpf);
|
||||
@ -593,3 +608,4 @@ begin
|
||||
end;
|
||||
end.
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user