mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-09 14:35:56 +02:00
codetools: implemented conversion of simple c declarations
git-svn-id: trunk@14553 -
This commit is contained in:
parent
535542bc52
commit
7593e06d86
@ -53,13 +53,13 @@ const
|
|||||||
ccnDirective = 2+ccnBase;// e.g. "#define a" ,can be multiple lines, without line end
|
ccnDirective = 2+ccnBase;// e.g. "#define a" ,can be multiple lines, without line end
|
||||||
ccnExtern = 3+ccnBase;// e.g. extern "C" {}
|
ccnExtern = 3+ccnBase;// e.g. extern "C" {}
|
||||||
ccnEnumBlock = 4+ccnBase;// e.g. enum {};
|
ccnEnumBlock = 4+ccnBase;// e.g. enum {};
|
||||||
ccnEnumBlockName = 5+ccnBase;// e.g. enum {};
|
ccnEnumID = 5+ccnBase;// e.g. name = value;
|
||||||
ccnEnumID = 6+ccnBase;// e.g. name = value;
|
ccnConstant = 6+ccnBase;// e.g. 1
|
||||||
ccnConstant = 7+ccnBase;// e.g. 1
|
ccnTypedef = 7+ccnBase;// e.g. typedef int TInt;
|
||||||
ccnTypedef = 8+ccnBase;// e.g. typedef int TInt;
|
ccnStruct = 8+ccnBase;// e.g. struct{}
|
||||||
ccnStruct = 9+ccnBase;// e.g. struct{};
|
ccnUnion = 9+ccnBase;// e.g. union{}
|
||||||
ccnVariable = 10+ccnBase;// e.g. int i
|
ccnVariable = 10+ccnBase;// e.g. int i
|
||||||
ccnFunction = 11+ccnBase;// e.g. int i
|
ccnFunction = 11+ccnBase;// e.g. int i()
|
||||||
ccnName = 12+ccnBase;// e.g. i
|
ccnName = 12+ccnBase;// e.g. i
|
||||||
ccnFuncParamList = 13+ccnBase;// e.g. ()
|
ccnFuncParamList = 13+ccnBase;// e.g. ()
|
||||||
ccnStatementBlock = 14+ccnBase;// e.g. {}
|
ccnStatementBlock = 14+ccnBase;// e.g. {}
|
||||||
@ -96,11 +96,12 @@ type
|
|||||||
procedure EndChildNode;
|
procedure EndChildNode;
|
||||||
procedure CloseNodes;
|
procedure CloseNodes;
|
||||||
|
|
||||||
|
procedure ReadVariable;
|
||||||
procedure ReadEnum;
|
procedure ReadEnum;
|
||||||
procedure ReadStruct;
|
procedure ReadStruct;
|
||||||
|
procedure ReadUnion;
|
||||||
procedure ReadConstant;
|
procedure ReadConstant;
|
||||||
procedure ReadVariable;
|
|
||||||
|
|
||||||
procedure RaiseException(const AMessage: string; ReportPos: integer = 0);
|
procedure RaiseException(const AMessage: string; ReportPos: integer = 0);
|
||||||
procedure RaiseExpectedButAtomFound(const AToken: string; ReportPos: integer = 0);
|
procedure RaiseExpectedButAtomFound(const AToken: string; ReportPos: integer = 0);
|
||||||
public
|
public
|
||||||
@ -170,6 +171,7 @@ type
|
|||||||
function ExtractCode(StartPos, EndPos: integer;
|
function ExtractCode(StartPos, EndPos: integer;
|
||||||
WithDirectives: boolean = false): string;// extract code without comments
|
WithDirectives: boolean = false): string;// extract code without comments
|
||||||
|
|
||||||
|
function GetFirstNameNode(Node: TCodeTreeNode): TCodeTreeNode;
|
||||||
function ExtractVariableName(VarNode: TCodeTreeNode): string;
|
function ExtractVariableName(VarNode: TCodeTreeNode): string;
|
||||||
function ExtractVariableType(VarNode: TCodeTreeNode;
|
function ExtractVariableType(VarNode: TCodeTreeNode;
|
||||||
WithDirectives: boolean = false): string;
|
WithDirectives: boolean = false): string;
|
||||||
@ -210,11 +212,11 @@ begin
|
|||||||
ccnDirective : Result:='Directive';
|
ccnDirective : Result:='Directive';
|
||||||
ccnExtern : Result:='extern block';
|
ccnExtern : Result:='extern block';
|
||||||
ccnEnumBlock : Result:='enum block';
|
ccnEnumBlock : Result:='enum block';
|
||||||
ccnEnumBlockName : Result:='enum block name';
|
|
||||||
ccnEnumID : Result:='enum ID';
|
ccnEnumID : Result:='enum ID';
|
||||||
ccnConstant : Result:='constant';
|
ccnConstant : Result:='constant';
|
||||||
ccnTypedef : Result:='typedef';
|
ccnTypedef : Result:='typedef';
|
||||||
ccnStruct : Result:='struct';
|
ccnStruct : Result:='struct';
|
||||||
|
ccnUnion : Result:='union';
|
||||||
ccnVariable : Result:='variable';
|
ccnVariable : Result:='variable';
|
||||||
ccnFunction : Result:='function';
|
ccnFunction : Result:='function';
|
||||||
ccnName : Result:='name';
|
ccnName : Result:='name';
|
||||||
@ -339,7 +341,7 @@ begin
|
|||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
// read optional name
|
// read optional name
|
||||||
if AtomIsIdentifier then begin
|
if AtomIsIdentifier then begin
|
||||||
CreateChildNode(ccnEnumBlockName);
|
CreateChildNode(ccnName);
|
||||||
EndChildNode;
|
EndChildNode;
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
end;
|
end;
|
||||||
@ -378,7 +380,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCCodeParserTool.ReadStruct;
|
procedure TCCodeParserTool.ReadStruct;
|
||||||
(* Example for NeedIdentifier=false:
|
(* Examples:
|
||||||
|
|
||||||
As typedef:
|
As typedef:
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t b[6]; // implicit type
|
uint8_t b[6]; // implicit type
|
||||||
@ -403,6 +406,8 @@ begin
|
|||||||
// read variable name
|
// read variable name
|
||||||
if not AtomIsIdentifier then
|
if not AtomIsIdentifier then
|
||||||
RaiseExpectedButAtomFound('identifier');
|
RaiseExpectedButAtomFound('identifier');
|
||||||
|
CreateChildNode(ccnName);
|
||||||
|
EndChildNode;
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -444,6 +449,48 @@ begin
|
|||||||
EndChildNode;
|
EndChildNode;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCCodeParserTool.ReadUnion;
|
||||||
|
(* Example
|
||||||
|
union {
|
||||||
|
uint16_t uuid16;
|
||||||
|
uint32_t uuid32;
|
||||||
|
uint128_t uuid128;
|
||||||
|
} value;
|
||||||
|
|
||||||
|
*)
|
||||||
|
begin
|
||||||
|
CreateChildNode(ccnUnion);
|
||||||
|
|
||||||
|
ReadNextAtom;
|
||||||
|
|
||||||
|
if AtomIsChar('{') then begin
|
||||||
|
// read block {}
|
||||||
|
repeat
|
||||||
|
ReadNextAtom;
|
||||||
|
// read variables
|
||||||
|
if AtomIsIdentifier then begin
|
||||||
|
ReadVariable;
|
||||||
|
ReadNextAtom;
|
||||||
|
if AtomIsChar('}') then
|
||||||
|
break
|
||||||
|
else if AtomIsChar(';') then begin
|
||||||
|
// next identifier
|
||||||
|
end else
|
||||||
|
RaiseExpectedButAtomFound('}');
|
||||||
|
end else if AtomIsChar('}') then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
RaiseExpectedButAtomFound('identifier');
|
||||||
|
until false;
|
||||||
|
end else if AtomIsIdentifier then begin
|
||||||
|
// using another union
|
||||||
|
end else
|
||||||
|
RaiseExpectedButAtomFound('{');
|
||||||
|
|
||||||
|
// close node
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCCodeParserTool.TypedefToken: boolean;
|
function TCCodeParserTool.TypedefToken: boolean;
|
||||||
{ examples:
|
{ examples:
|
||||||
typedef type name;
|
typedef type name;
|
||||||
@ -607,10 +654,7 @@ begin
|
|||||||
// for example: struct structname varname
|
// for example: struct structname varname
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
end else if AtomIs('union') then begin
|
end else if AtomIs('union') then begin
|
||||||
ReadNextAtom;
|
ReadUnion;
|
||||||
if not AtomIsChar('{') then
|
|
||||||
RaiseExpectedButAtomFound('{');
|
|
||||||
ReadTilBracketClose(true);
|
|
||||||
end else if IsCCodeFunctionModifier.DoItCaseSensitive(Src,AtomStart,SrcPos-AtomStart)
|
end else if IsCCodeFunctionModifier.DoItCaseSensitive(Src,AtomStart,SrcPos-AtomStart)
|
||||||
then begin
|
then begin
|
||||||
// read function modifiers
|
// read function modifiers
|
||||||
@ -1163,12 +1207,18 @@ begin
|
|||||||
Result:=s;
|
Result:=s;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCCodeParserTool.GetFirstNameNode(Node: TCodeTreeNode): TCodeTreeNode;
|
||||||
|
begin
|
||||||
|
Result:=Node.FirstChild;
|
||||||
|
while (Result<>nil) and (Result.Desc<>ccnName) do Result:=Result.NextBrother;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCCodeParserTool.ExtractVariableName(VarNode: TCodeTreeNode): string;
|
function TCCodeParserTool.ExtractVariableName(VarNode: TCodeTreeNode): string;
|
||||||
var
|
var
|
||||||
NameNode: TCodeTreeNode;
|
NameNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
NameNode:=VarNode.FirstChild;
|
NameNode:=GetFirstNameNode(VarNode);
|
||||||
if (NameNode=nil) or (NameNode.Desc<>ccnName) then
|
if (NameNode=nil) then
|
||||||
Result:=''
|
Result:=''
|
||||||
else
|
else
|
||||||
Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos);
|
Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos);
|
||||||
@ -1180,8 +1230,8 @@ var
|
|||||||
NameNode: TCodeTreeNode;
|
NameNode: TCodeTreeNode;
|
||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
NameNode:=VarNode.FirstChild;
|
NameNode:=GetFirstNameNode(VarNode);
|
||||||
if (NameNode=nil) or (NameNode.Desc<>ccnName) then
|
if (NameNode=nil) then
|
||||||
Result:=''
|
Result:=''
|
||||||
else begin
|
else begin
|
||||||
Result:=ExtractCode(VarNode.StartPos,NameNode.StartPos,WithDirectives);
|
Result:=ExtractCode(VarNode.StartPos,NameNode.StartPos,WithDirectives);
|
||||||
@ -1204,8 +1254,8 @@ function TCCodeParserTool.ExtractFunctionName(FuncNode: TCodeTreeNode): string;
|
|||||||
var
|
var
|
||||||
NameNode: TCodeTreeNode;
|
NameNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
NameNode:=FuncNode.FirstChild;
|
NameNode:=GetFirstNameNode(FuncNode);
|
||||||
if (NameNode=nil) or (NameNode.Desc<>ccnName) then
|
if (NameNode=nil) then
|
||||||
Result:=''
|
Result:=''
|
||||||
else
|
else
|
||||||
Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos);
|
Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos);
|
||||||
@ -1216,8 +1266,8 @@ function TCCodeParserTool.ExtractFunctionType(FuncNode: TCodeTreeNode;
|
|||||||
var
|
var
|
||||||
NameNode: TCodeTreeNode;
|
NameNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
NameNode:=FuncNode.FirstChild;
|
NameNode:=GetFirstNameNode(FuncNode);
|
||||||
if (NameNode=nil) or (NameNode.Desc<>ccnName) then begin
|
if (NameNode=nil) then begin
|
||||||
Result:='';
|
Result:='';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -1239,8 +1289,8 @@ function TCCodeParserTool.ExtractFunctionResultType(FuncNode: TCodeTreeNode;
|
|||||||
var
|
var
|
||||||
NameNode: TCodeTreeNode;
|
NameNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
NameNode:=FuncNode.FirstChild;
|
NameNode:=GetFirstNameNode(FuncNode);
|
||||||
if (NameNode=nil) or (NameNode.Desc<>ccnName) then begin
|
if (NameNode=nil) then begin
|
||||||
Result:='';
|
Result:='';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -1262,7 +1312,7 @@ var
|
|||||||
NameNode: TCodeTreeNode;
|
NameNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
if (EnumBlockNode.FirstChild<>nil)
|
if (EnumBlockNode.FirstChild<>nil)
|
||||||
and (EnumBlockNode.FirstChild.Desc=ccnEnumBlockName) then begin
|
and (EnumBlockNode.FirstChild.Desc=ccnName) then begin
|
||||||
NameNode:=EnumBlockNode.FirstChild;
|
NameNode:=EnumBlockNode.FirstChild;
|
||||||
Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos);
|
Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos);
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -25,6 +25,9 @@ enum {
|
|||||||
TEST_ENUM3
|
TEST_ENUM3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum e1{dark, light};
|
||||||
|
enum e2{a=3, b=9};
|
||||||
|
|
||||||
/* Byte order conversions */
|
/* Byte order conversions */
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
#define htobs(d) (d)
|
#define htobs(d) (d)
|
||||||
@ -122,14 +125,12 @@ complex operator+(complex, complex);
|
|||||||
|
|
||||||
int y = 7;
|
int y = 7;
|
||||||
float f(int){};
|
float f(int){};
|
||||||
|
int dim2[][3];
|
||||||
bool b1 = a==b;
|
bool b1 = a==b;
|
||||||
char c = 'a';
|
char c = 'a';
|
||||||
short signed int ssi_octal = 0123;
|
short signed int ssi_octal = 0123;
|
||||||
long unsigned int lui = sizeof(char);
|
long unsigned int lui = sizeof(char);
|
||||||
|
|
||||||
enum e1{dark, light};
|
|
||||||
enum e2{a=3, b=9};
|
|
||||||
|
|
||||||
int *pi; // pointer to int
|
int *pi; // pointer to int
|
||||||
char ** ppc; // pointer to pointer to char
|
char ** ppc; // pointer to pointer to char
|
||||||
int* ap[15]; // array of 15 pointers to ints
|
int* ap[15]; // array of 15 pointers to ints
|
||||||
|
@ -103,11 +103,17 @@ type
|
|||||||
|
|
||||||
function GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string;
|
function GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string;
|
||||||
function GetSimplePascalResultTypeOfCFunction(CFuncNode: TCodeTreeNode): string;
|
function GetSimplePascalResultTypeOfCFunction(CFuncNode: TCodeTreeNode): string;
|
||||||
function ConvertSimpleCTypeToPascalType(CType: string): string;
|
function ConvertSimpleCTypeToPascalType(CType: string;
|
||||||
|
UseSingleIdentifierAsDefault: boolean): string;
|
||||||
|
|
||||||
function CreateH2PNode(const PascalName, CName: string; CNode: TCodeTreeNode;
|
function CreateH2PNode(const PascalName, CName: string; CNode: TCodeTreeNode;
|
||||||
PascalDesc: TCodeTreeNodeDesc; ParentNode: TH2PNode = nil;
|
PascalDesc: TCodeTreeNodeDesc; ParentNode: TH2PNode = nil;
|
||||||
IsGlobal: boolean = true): TH2PNode;
|
IsGlobal: boolean = true): TH2PNode;
|
||||||
|
function GetTypeForVarType(CVarNode: TCodeTreeNode;
|
||||||
|
CreateIfNotExists: boolean = true): TH2PNode;
|
||||||
|
function CreatePascalNameFromCCode(const CCode: string;
|
||||||
|
StartPos: integer = 1;
|
||||||
|
EndPos: integer = -1): string;
|
||||||
|
|
||||||
procedure WriteDebugReport;
|
procedure WriteDebugReport;
|
||||||
procedure WriteH2PNodeReport;
|
procedure WriteH2PNodeReport;
|
||||||
@ -217,6 +223,8 @@ begin
|
|||||||
Add('double*','pcdouble');
|
Add('double*','pcdouble');
|
||||||
Add('long double','clongdouble');
|
Add('long double','clongdouble');
|
||||||
Add('long double*','pclongdouble');
|
Add('long double*','pclongdouble');
|
||||||
|
// void
|
||||||
|
Add('void*','pointer');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result:=InternalPredefinedCTypes;
|
Result:=InternalPredefinedCTypes;
|
||||||
@ -258,10 +266,13 @@ var
|
|||||||
CurType: String;
|
CurType: String;
|
||||||
SimpleType: String;
|
SimpleType: String;
|
||||||
H2PNode: TH2PNode;
|
H2PNode: TH2PNode;
|
||||||
|
NextCNode: TCodeTreeNode;
|
||||||
|
TypeH2PNode: TH2PNode;
|
||||||
begin
|
begin
|
||||||
Tree.Clear;
|
Tree.Clear;
|
||||||
CNode:=CTool.Tree.Root;
|
CNode:=CTool.Tree.Root;
|
||||||
while CNode<>nil do begin
|
while CNode<>nil do begin
|
||||||
|
NextCNode:=CNode.Next;
|
||||||
case CNode.Desc of
|
case CNode.Desc of
|
||||||
ccnVariable:
|
ccnVariable:
|
||||||
begin
|
begin
|
||||||
@ -271,13 +282,16 @@ begin
|
|||||||
DebugLn(['TH2PasTool.BuildH2PTree Variable Name="',CurName,'" Type="',CurType,'" SimpleType=',SimpleType]);
|
DebugLn(['TH2PasTool.BuildH2PTree Variable Name="',CurName,'" Type="',CurType,'" SimpleType=',SimpleType]);
|
||||||
if SimpleType='' then begin
|
if SimpleType='' then begin
|
||||||
// this variable has a complex type
|
// this variable has a complex type
|
||||||
//SimpleType:=CreateTypeForVarType(CNode);
|
TypeH2PNode:=GetTypeForVarType(CNode);
|
||||||
|
if TypeH2PNode<>nil then
|
||||||
|
SimpleType:=TypeH2PNode.PascalName;
|
||||||
end;
|
end;
|
||||||
if SimpleType<>'' then begin
|
if SimpleType<>'' then begin
|
||||||
H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnVarDefinition);
|
H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnVarDefinition);
|
||||||
H2PNode.PascalCode:=SimpleType;
|
H2PNode.PascalCode:=SimpleType;
|
||||||
//DebugLn(['TH2PasTool.BuildH2PTree CNode.Desc=',CCNodeDescAsString(CNode.Desc),' ',H2PNode.DescAsString]);
|
//DebugLn(['TH2PasTool.BuildH2PTree CNode.Desc=',CCNodeDescAsString(CNode.Desc),' ',H2PNode.DescAsString]);
|
||||||
end;
|
end;
|
||||||
|
NextCNode:=CNode.NextSkipChilds;
|
||||||
end;
|
end;
|
||||||
ccnEnumBlock:
|
ccnEnumBlock:
|
||||||
begin
|
begin
|
||||||
@ -301,42 +315,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
CNode:=CNode.Next;
|
CNode:=NextCNode;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TH2PasTool.GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string;
|
function TH2PasTool.GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string;
|
||||||
var
|
|
||||||
SimpleType: String;
|
|
||||||
begin
|
begin
|
||||||
Result:=CTool.ExtractVariableType(CVarNode);
|
Result:=CTool.ExtractVariableType(CVarNode);
|
||||||
if Result='' then exit;
|
if Result='' then exit;
|
||||||
SimpleType:=ConvertSimpleCTypeToPascalType(Result);
|
Result:=ConvertSimpleCTypeToPascalType(Result,true);
|
||||||
if SimpleType<>'' then begin
|
|
||||||
Result:=SimpleType;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if not IsValidIdent(Result) then
|
|
||||||
Result:='';
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TH2PasTool.GetSimplePascalResultTypeOfCFunction(
|
function TH2PasTool.GetSimplePascalResultTypeOfCFunction(
|
||||||
CFuncNode: TCodeTreeNode): string;
|
CFuncNode: TCodeTreeNode): string;
|
||||||
var
|
|
||||||
SimpleType: String;
|
|
||||||
begin
|
begin
|
||||||
Result:=CTool.ExtractFunctionResultType(CFuncNode);
|
Result:=CTool.ExtractFunctionResultType(CFuncNode);
|
||||||
if Result='' then exit;
|
if Result='' then exit;
|
||||||
SimpleType:=ConvertSimpleCTypeToPascalType(Result);
|
Result:=ConvertSimpleCTypeToPascalType(Result,true);
|
||||||
if SimpleType<>'' then begin
|
|
||||||
Result:=SimpleType;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if not IsValidIdent(Result) then
|
|
||||||
Result:='';
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TH2PasTool.ConvertSimpleCTypeToPascalType(CType: string): string;
|
function TH2PasTool.ConvertSimpleCTypeToPascalType(CType: string;
|
||||||
|
UseSingleIdentifierAsDefault: boolean): string;
|
||||||
// the type must be normalized. That means no directives,
|
// the type must be normalized. That means no directives,
|
||||||
// no unneeded spaces, no tabs, no comments, no newlines.
|
// no unneeded spaces, no tabs, no comments, no newlines.
|
||||||
var
|
var
|
||||||
@ -375,6 +374,9 @@ begin
|
|||||||
until false;
|
until false;
|
||||||
// seach in predefined ctypes
|
// seach in predefined ctypes
|
||||||
Result:=PredefinedCTypes[CType];
|
Result:=PredefinedCTypes[CType];
|
||||||
|
|
||||||
|
if (Result='') and (UseSingleIdentifierAsDefault) and IsValidIdent(CType) then
|
||||||
|
Result:=CType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TH2PasTool.CreateH2PNode(const PascalName, CName: string;
|
function TH2PasTool.CreateH2PNode(const PascalName, CName: string;
|
||||||
@ -393,6 +395,121 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TH2PasTool.GetTypeForVarType(CVarNode: TCodeTreeNode;
|
||||||
|
CreateIfNotExists: boolean): TH2PNode;
|
||||||
|
var
|
||||||
|
CCode: String;
|
||||||
|
PascalName: String;
|
||||||
|
AtomStart: integer;
|
||||||
|
p: Integer;
|
||||||
|
CurAtom: String;
|
||||||
|
BaseCType: String;
|
||||||
|
BasePascaltype: String;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
if (CVarNode.FirstChild<>nil)
|
||||||
|
and (CVarNode.FirstChild.Desc=ccnUnion) then begin
|
||||||
|
// ToDo: union
|
||||||
|
end else begin
|
||||||
|
CCode:=CTool.ExtractVariableType(CVarNode);
|
||||||
|
{ int[][3] -> array of array[0..2] of cint
|
||||||
|
char** -> PPchar
|
||||||
|
int *[15] -> array[0..14] of pcint
|
||||||
|
|
||||||
|
}
|
||||||
|
// read identifiers
|
||||||
|
p:=1;
|
||||||
|
BaseCType:='';
|
||||||
|
repeat
|
||||||
|
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||||
|
if AtomStart>length(CCode) then break;
|
||||||
|
if IsIdentStartChar[CCode[AtomStart]] then begin
|
||||||
|
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||||
|
if BaseCType<>'' then
|
||||||
|
BaseCType:=BaseCType+' ';
|
||||||
|
BaseCType:=BaseCType+CurAtom;
|
||||||
|
end;
|
||||||
|
until false;
|
||||||
|
if BaseCType='' then begin
|
||||||
|
DebugLn(['TH2PasTool.GetTypeForVarType no base type in c declaration: CCode="',dbgstr(CCode),'"']);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
BasePascaltype:=ConvertSimpleCTypeToPascalType(BaseCType,true);
|
||||||
|
if (BasePascaltype='') then begin
|
||||||
|
DebugLn(['TH2PasTool.GetTypeForVarType unknown c type: "',BaseCType,'"']);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// read pointer
|
||||||
|
{while (AtomStart<=length(CCode)) do begin
|
||||||
|
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||||
|
if (CurAtom='*') then begin
|
||||||
|
BaseCType:=BaseCType+'*';
|
||||||
|
NewBasePascaltype:=ConvertSimpleCTypeToPascalType(BaseCType,true);
|
||||||
|
|
||||||
|
end else if (CurAtom='const') then begin
|
||||||
|
// skip 'const'
|
||||||
|
end else begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||||
|
end;}
|
||||||
|
|
||||||
|
PascalName:=CreatePascalNameFromCCode(CCode);
|
||||||
|
DebugLn(['TH2PasTool.GetTypeForVarType CCode="',dbgstr(CCode),'" PascalName="',PascalName,'"']);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TH2PasTool.CreatePascalNameFromCCode(const CCode: string;
|
||||||
|
StartPos: integer; EndPos: integer): string;
|
||||||
|
const
|
||||||
|
MaxIdentLen = 70;
|
||||||
|
|
||||||
|
function Add(var PascalName: string; const Addition: string): boolean;
|
||||||
|
begin
|
||||||
|
if Addition='' then exit(true);
|
||||||
|
if length(PascalName)+length(Addition)>MaxIdentLen then
|
||||||
|
exit(false);
|
||||||
|
PascalName:=PascalName+Addition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
p: Integer;
|
||||||
|
AtomStart: integer;
|
||||||
|
i: LongInt;
|
||||||
|
c: Char;
|
||||||
|
CurAtom: String;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
if EndPos<1 then
|
||||||
|
EndPos:=length(CCode)+1;
|
||||||
|
p:=StartPos;
|
||||||
|
if EndPos>length(CCode) then
|
||||||
|
EndPos:=length(CCode);
|
||||||
|
repeat
|
||||||
|
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||||
|
if AtomStart>EndPos then exit;
|
||||||
|
|
||||||
|
if IsIdentStartChar[CCode[AtomStart]] then begin
|
||||||
|
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||||
|
if (CurAtom<>'const')
|
||||||
|
and (CurAtom<>'struct')
|
||||||
|
and not Add(Result,CurAtom) then
|
||||||
|
exit;
|
||||||
|
end else begin
|
||||||
|
if CCode[AtomStart] in ['0'..'9'] then begin
|
||||||
|
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||||
|
for i:=AtomStart to p-1 do begin
|
||||||
|
c:=CCode[i];
|
||||||
|
if not IsIdentChar[c] then
|
||||||
|
c:='_';
|
||||||
|
if not Add(Result,c) then exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
until false;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TH2PasTool.WriteDebugReport;
|
procedure TH2PasTool.WriteDebugReport;
|
||||||
begin
|
begin
|
||||||
DebugLn(['TH2PasTool.WriteDebugReport ']);
|
DebugLn(['TH2PasTool.WriteDebugReport ']);
|
||||||
|
Loading…
Reference in New Issue
Block a user