codetools: h2p: implemented function list parameters

git-svn-id: trunk@14571 -
This commit is contained in:
mattias 2008-03-18 14:57:47 +00:00
parent 229b2913b9
commit b8caa1a665
3 changed files with 103 additions and 30 deletions

View File

@ -183,6 +183,9 @@ type
function ExtractFunctionResultType(FuncNode: TCodeTreeNode;
WithDirectives: boolean = false): string;
function IsPointerToFunction(FuncNode: TCodeTreeNode): boolean;
function ExtractParameterName(ParamNode: TCodeTreeNode): string;
function ExtractParameterType(ParamNode: TCodeTreeNode;
WithDirectives: boolean = false): string;
function ExtractEnumBlockName(EnumBlockNode: TCodeTreeNode): string;
function ExtractEnumIDName(EnumIDNode: TCodeTreeNode): string;
function ExtractEnumIDValue(EnumIDNode: TCodeTreeNode;
@ -605,8 +608,9 @@ begin
end;
procedure TCCodeParserTool.ReadConstant;
// ends on last atom of constant
begin
if AtomIsChar(',') or AtomIsChar(';') then
if AtomIsChar(',') or AtomIsChar(';') or AtomIsChar(')') then
RaiseExpectedButAtomFound('identifier');
CreateChildNode(ccnConstant);
repeat
@ -820,8 +824,8 @@ begin
SrcPos:=AtomStart+1;
RaiseException('closing bracket not found');
end;
if AtomIs(')') then break;
if AtomIs(',') then
if AtomIsChar(')') then break;
if AtomIsChar(',') then
RaiseExpectedButAtomFound('parameter type');
// read parameter
CreateChildNode(ccnFuncParameter);
@ -833,12 +837,12 @@ begin
NamePos:=0;
repeat
if AtomStart>SrcLen then break;
if AtomIs(')') then begin
if AtomIsChar(')') then begin
// end of parameter list
break;
end else if AtomIs('[') then
ReadTilBracketClose(true)
else if AtomIs(',') then
else if AtomIsChar(',') then
break
else if IsIdentStartChar[Src[AtomStart]] then begin
if NamePos>0 then
@ -869,12 +873,17 @@ begin
EndChildNode;
end;
end;
end else if AtomIsChar('=') then begin
if TypePos<1 then
RaiseExpectedButAtomFound('type');
ReadNextAtom;
ReadConstant;
end;
CurNode.EndPos:=SrcPos;
ReadNextAtom;
until false;
EndChildNode;
until AtomIs(')');
until AtomIsChar(')');
CurNode.EndPos:=SrcPos;
EndChildNode;
end;
@ -1320,7 +1329,7 @@ begin
// a variable with an initial value
// omit the constant
s:=ExtractCode(NameNode.EndPos,NameNode.NextBrother.StartPos,
WithDirectives);
WithDirectives);
s:=copy(s,1,length(s)-1);
Result:=Result+s;
end else begin
@ -1420,6 +1429,57 @@ begin
Result:=false;
end;
function TCCodeParserTool.ExtractParameterName(ParamNode: TCodeTreeNode
): string;
var
NameNode: TCodeTreeNode;
begin
NameNode:=GetFirstNameNode(ParamNode);
if (NameNode=nil) then
Result:=''
else
Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos);
end;
function TCCodeParserTool.ExtractParameterType(ParamNode: TCodeTreeNode;
WithDirectives: boolean): string;
var
NameNode: TCodeTreeNode;
s: String;
ConstantNode: TCodeTreeNode;
begin
NameNode:=GetFirstNameNode(ParamNode);
if (ParamNode.LastChild<>nil)
and (ParamNode.LastChild.Desc=ccnConstant) then
ConstantNode:=ParamNode.LastChild
else
ConstantNode:=nil;
if (NameNode=nil) then begin
if ConstantNode<>nil then begin
// a parameter with an initial value
// omit the constant
Result:=ExtractCode(ParamNode.StartPos,ConstantNode.StartPos,WithDirectives);
Result:=copy(Result,1,length(Result)-1);
end else begin
Result:=ExtractCode(ParamNode.StartPos,ParamNode.EndPos,WithDirectives);
end;
end else begin
Result:=ExtractCode(ParamNode.StartPos,NameNode.StartPos,WithDirectives);
if (NameNode.NextBrother<>nil)
and (NameNode.NextBrother.Desc=ccnConstant) then begin
// a parameter with an initial value
// omit the constant
s:=ExtractCode(NameNode.EndPos,NameNode.NextBrother.StartPos,
WithDirectives);
s:=copy(s,1,length(s)-1);
Result:=Result+s;
end else begin
Result:=Result+ExtractCode(NameNode.EndPos,ParamNode.EndPos,
WithDirectives);
end;
end;
end;
function TCCodeParserTool.ExtractEnumBlockName(EnumBlockNode: TCodeTreeNode
): string;
var

View File

@ -141,6 +141,7 @@ char ** ppc; // pointer to pointer to char
int* ap[15]; // array of 15 pointers to ints
int (*fp)(char*); // pointer to function taking a char* argument; returns an int
int * f(char*); // function taking a char* argument; returns a pointer to int
int func2(int=3); // function taking an int argument or no argument; returns an int
unsigned short unsigned_short;
unsigned long long unsigned_long_long;

View File

@ -345,28 +345,38 @@ begin
Ok:=false;
end;
NextCNode:=CNode.NextSkipChilds;
if Ok then begin
H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnProcedure,SimpleType,
ParentNode,ParentNode=nil);
DebugLn(['TH2PasTool.BuildH2PTree added: ',H2PNode.DescAsString]);
CNode:=CNode.FirstChild;
while (CNode<>nil) and (CNode.Desc<>ccnFuncParamList) do
CNode:=CNode.NextBrother;
if CNode<>nil then begin
CNode:=CNode.FirstChild;
while CNode<>nil do begin
if CNode.Desc=ccnFuncParameter then begin
CurType:=CTool.ExtractCode(CNode.StartPos,CNode.EndPos);
DebugLn(['TH2PasTool.BuildH2PTree Parameter="',CurType,'"']);
end;
CNode:=CNode.NextBrother;
end;
end;
DebugLn(['TH2PasTool.BuildH2PTree function added: ',H2PNode.DescAsString]);
// build recursively
BuildH2PTree(H2PNode);
end else begin
DebugLn(['TH2PasTool.BuildH2PTree SKIPPING Function Name="',CurName,'" Type="',CurType,'"']);
end;
end;
ccnFuncParamList:
NextCNode:=CNode.FirstChild;
ccnFuncParameter:
begin
CurName:=CTool.ExtractParameterName(CNode);
CurType:=CTool.ExtractParameterType(CNode);
SimpleType:=GetSimplePascalTypeOfCVar(CNode);
DebugLn(['TH2PasTool.BuildH2PTree Parameter: Name="',CurName,'" Type="',CurType,'" SimpleType="',SimpleType,'"']);
if SimpleType='' then begin
// this variable has a complex type
TypeH2PNode:=GetH2PNodeForComplexType(CNode);
if TypeH2PNode<>nil then
SimpleType:=TypeH2PNode.PascalName;
end;
if SimpleType<>'' then begin
H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnVarDefinition,SimpleType,
ParentNode,false);
DebugLn(['TH2PasTool.BuildH2PTree added: ',H2PNode.DescAsString]);
end else begin
DebugLn(['TH2PasTool.BuildH2PTree SKIPPING parameter Name="',CurName,'" Type="',CurType,'"']);
end;
end;
ccnEnumBlock:
begin
CurName:=CTool.ExtractEnumBlockName(CNode);
@ -381,7 +391,7 @@ begin
ParentNode,ParentNode=nil);
end;
DebugLn(['TH2PasTool.BuildH2PTree added: ',TypeH2PNode.DescAsString]);
NextCNode:=CNode.NextSkipChilds;
CNode:=CNode.FirstChild;
while CNode<>nil do begin
if CNode.Desc=ccnEnumID then begin
@ -560,10 +570,12 @@ begin
CCode:=CTool.ExtractVariableType(CNode)
else if CNode.Desc=ccnFunction then
CCode:=CTool.ExtractFunctionResultType(CNode)
else if CNode.Desc=ccnFuncParameter then
CCode:=CTool.ExtractParameterType(CNode)
else
exit;
DebugLn(['TH2PasTool.GetTypeForVarType CCode="',CCode,'"']);
DebugLn(['TH2PasTool.GetH2PNodeForComplexType CCode="',CCode,'"']);
{ int[][3] -> array of array[0..2] of cint
char** -> PPchar
int *[15] -> array[0..14] of pcint
@ -584,15 +596,15 @@ begin
break;
until false;
if BaseCType='' then begin
DebugLn(['TH2PasTool.GetTypeForVarType no base type in c declaration: CCode="',dbgstr(CCode),'"']);
DebugLn(['TH2PasTool.GetH2PNodeForComplexType 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,'"']);
DebugLn(['TH2PasTool.GetH2PNodeForComplexType unknown c type: "',BaseCType,'"']);
exit;
end;
DebugLn(['TH2PasTool.GetTypeForVarType BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
DebugLn(['TH2PasTool.GetH2PNodeForComplexType BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
// read pointer(s)
while (AtomStart<=length(CCode)) do begin
@ -607,11 +619,11 @@ begin
NewBasePascalType:='P'+BasePascalType;
SubH2PNode:=CreateAutoGeneratedH2PNode(NewBasePascalType,nil,
ctnTypeDefinition,'^'+BasePascalType);
DebugLn(['TH2PasTool.GetTypeForVarType added new pointer type: ',SubH2PNode.DescAsString]);
DebugLn(['TH2PasTool.GetH2PNodeForComplexType added new pointer type: ',SubH2PNode.DescAsString]);
NewBasePascalType:=SubH2PNode.PascalName;
end;
BasePascalType:=NewBasePascalType;
DebugLn(['TH2PasTool.GetTypeForVarType using pointer type: BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
DebugLn(['TH2PasTool.GetH2PNodeForComplexType using pointer type: BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
end else if (CurAtom='const') then begin
// skip 'const'
end else begin
@ -632,7 +644,7 @@ begin
BracketOpenPos:=AtomStart;
ReadRawNextCAtom(CCode,p,AtomStart);
if AtomStart>length(CCode) then begin
DebugLn(['TH2PasTool.GetTypeForVarType untranslatable (missing ]): CCode="',dbgstr(CCode),'"']);
DebugLn(['TH2PasTool.GetH2PNodeForComplexType untranslatable (missing ]): CCode="',dbgstr(CCode),'"']);
exit;
end;
CurAtom:=copy(CCode,AtomStart,p-AtomStart);