mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-22 12:59:26 +02:00
codetools: h2pas: convert anonymous enum
git-svn-id: trunk@31304 -
This commit is contained in:
parent
3abbb28e51
commit
357f42936c
@ -2022,24 +2022,28 @@ function TCCodeParserTool.ExtractDefinitionType(VarNode: TCodeTreeNode;
|
||||
var
|
||||
NameNode: TCodeTreeNode;
|
||||
s: String;
|
||||
AfterNameNode: TCodeTreeNode;
|
||||
StartPos: Integer;
|
||||
begin
|
||||
Result:='';
|
||||
NameNode:=GetFirstNameNode(VarNode);
|
||||
if (NameNode=nil) then
|
||||
Result:=''
|
||||
else begin
|
||||
if (NameNode<>nil) then begin
|
||||
Result:=ExtractCode(VarNode.StartPos,NameNode.StartPos,WithDirectives);
|
||||
if (NameNode.NextBrother<>nil)
|
||||
and (NameNode.NextBrother.Desc=ccnConstant) then begin
|
||||
// a variable 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,VarNode.EndPos,
|
||||
WithDirectives);
|
||||
end;
|
||||
AfterNameNode:=NameNode.NextBrother;
|
||||
StartPos:=NameNode.EndPos;
|
||||
end else begin
|
||||
AfterNameNode:=VarNode.FirstChild;
|
||||
StartPos:=VarNode.StartPos;
|
||||
end;
|
||||
if (AfterNameNode<>nil)
|
||||
and (AfterNameNode.Desc=ccnConstant) then begin
|
||||
// omit constant
|
||||
s:=ExtractCode(StartPos,AfterNameNode.StartPos,WithDirectives);
|
||||
if (s<>'') and (s[length(s)]='=') then
|
||||
s:=Trim(copy(s,1,length(s)-1));
|
||||
Result:=Result+s;
|
||||
end else begin
|
||||
Result:=Result+ExtractCode(StartPos,VarNode.EndPos,WithDirectives);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2544,7 +2548,7 @@ begin
|
||||
if Tree<>nil then begin
|
||||
Node:=Tree.Root;
|
||||
while Node<>nil do begin
|
||||
DebugLn([GetNodeIndent(CurNode)+NodeAsString(Node)]);
|
||||
DebugLn([GetNodeIndent(Node)+NodeAsString(Node)]);
|
||||
Node:=Node.Next;
|
||||
end;
|
||||
end;
|
||||
|
@ -194,7 +194,7 @@ type
|
||||
// converting C nodes to H2P nodes
|
||||
procedure ConvertStruct(CNode: TCodeTreeNode; ParentNode: TH2PNode);
|
||||
procedure ConvertVariable(CNode: TCodeTreeNode; ParentNode: TH2PNode);
|
||||
procedure ConvertEnumBlock(CNode: TCodeTreeNode; ParentNode: TH2PNode);
|
||||
function ConvertEnumBlock(CNode: TCodeTreeNode; ParentNode: TH2PNode): TH2PNode;
|
||||
procedure ConvertFunction(CNode: TCodeTreeNode; ParentNode: TH2PNode);
|
||||
procedure ConvertFuncParameter(CNode: TCodeTreeNode; ParentNode: TH2PNode);
|
||||
procedure ConvertTypedef(CNode: TCodeTreeNode; ParentNode: TH2PNode);
|
||||
@ -268,7 +268,7 @@ type
|
||||
PascalDesc: TCodeTreeNodeDesc; const PascalCode: string;
|
||||
ParentNode: TH2PNode; IsGlobal: boolean;
|
||||
InsertAsPreLast: boolean): TH2PNode;
|
||||
function GetH2PNodeForComplexType(CNode: TCodeTreeNode;
|
||||
function CreateH2PNodeForComplexType(CNode: TCodeTreeNode;
|
||||
CreateIfNotExists: boolean;
|
||||
InsertAsPreLast: boolean): TH2PNode;
|
||||
function CreatePascalNameFromCCode(const CCode: string;
|
||||
@ -580,31 +580,32 @@ begin
|
||||
end;
|
||||
end else begin
|
||||
CurName:=CTool.ExtractDefinitionName(CNode);
|
||||
CurType:=CTool.ExtractDefinitionType(CNode);
|
||||
SimpleType:=GetSimplePascalTypeOfCVar(CNode);
|
||||
if SimpleType='' then begin
|
||||
// this variable has a complex type
|
||||
TypeH2PNode:=GetH2PNodeForComplexType(CNode,true,ParentNode<>nil);
|
||||
TypeH2PNode:=CreateH2PNodeForComplexType(CNode,true,ParentNode<>nil);
|
||||
if TypeH2PNode<>nil then
|
||||
SimpleType:=TypeH2PNode.PascalName;
|
||||
end;
|
||||
if SimpleType<>'' then begin
|
||||
CurCName:=CurName;
|
||||
H2PNode:=CreateH2PNode(CurName,CurCName,CNode,ctnVarDefinition,SimpleType,
|
||||
ParentNode,ParentNode=nil);
|
||||
DebugLn(['TH2PasTool.ConvertVariable CurName=',CurName,' ',H2PNode.PascalName]);
|
||||
DebugLn(['TH2PasTool.ConvertVariable added: ',H2PNode.DescAsString(CTool)]);
|
||||
end else begin
|
||||
DebugLn(['TH2PasTool.ConvertVariable SKIPPING Variable Name="',CurName,'" Type="',CurType,'"']);
|
||||
if CurName<>'' then begin
|
||||
if SimpleType<>'' then begin
|
||||
CurCName:=CurName;
|
||||
H2PNode:=CreateH2PNode(CurName,CurCName,CNode,ctnVarDefinition,SimpleType,
|
||||
ParentNode,ParentNode=nil);
|
||||
DebugLn(['TH2PasTool.ConvertVariable CurName=',CurName,' ',H2PNode.PascalName]);
|
||||
DebugLn(['TH2PasTool.ConvertVariable added: ',H2PNode.DescAsString(CTool)]);
|
||||
end else begin
|
||||
CurType:=CTool.ExtractDefinitionType(CNode);
|
||||
DebugLn(['TH2PasTool.ConvertVariable SKIPPING Variable Name="',CurName,'" Type="',CurType,'"']);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TH2PasTool.ConvertEnumBlock(CNode: TCodeTreeNode;
|
||||
ParentNode: TH2PNode);
|
||||
function TH2PasTool.ConvertEnumBlock(CNode: TCodeTreeNode; ParentNode: TH2PNode
|
||||
): TH2PNode;
|
||||
var
|
||||
CurName: String;
|
||||
TypeH2PNode: TH2PNode;
|
||||
CurValue: String;
|
||||
H2PNode: TH2PNode;
|
||||
CurCName: String;
|
||||
@ -613,15 +614,15 @@ begin
|
||||
if CurName='' then begin
|
||||
// this is an anonymous enum block => auto generate a name
|
||||
CurName:=CreatePascalNameFromCCode(CTool.Src,CNode.StartPos,CNode.EndPos);
|
||||
TypeH2PNode:=CreateAutoGeneratedH2PNode(CurName,CNode,ctnEnumerationType,'',
|
||||
Result:=CreateAutoGeneratedH2PNode(CurName,CNode,ctnEnumerationType,'',
|
||||
nil,true,ParentNode<>nil);
|
||||
end else begin
|
||||
// this enum block has a name
|
||||
CurCName:=CurName;
|
||||
TypeH2PNode:=CreateH2PNode(CurName,CurCName,CNode,ctnEnumerationType,'',
|
||||
Result:=CreateH2PNode(CurName,CurCName,CNode,ctnEnumerationType,'',
|
||||
nil,true);
|
||||
end;
|
||||
DebugLn(['TH2PasTool.ConvertEnumBlock added: ',TypeH2PNode.DescAsString(CTool)]);
|
||||
DebugLn(['TH2PasTool.ConvertEnumBlock added: ',Result.DescAsString(CTool)]);
|
||||
|
||||
CNode:=CNode.FirstChild;
|
||||
while CNode<>nil do begin
|
||||
@ -630,7 +631,7 @@ begin
|
||||
CurValue:=CTool.ExtractEnumIDValue(CNode);
|
||||
CurCName:=CurName;
|
||||
H2PNode:=CreateH2PNode(CurName,CurCName,CNode,ctnEnumIdentifier,CurValue,
|
||||
TypeH2PNode,true);
|
||||
Result,true);
|
||||
DebugLn(['TH2PasTool.ConvertEnumBlock added: ',H2PNode.DescAsString(CTool)]);
|
||||
end;
|
||||
CNode:=CNode.NextBrother;
|
||||
@ -666,7 +667,7 @@ begin
|
||||
end;
|
||||
if Ok and (SimpleType='') then begin
|
||||
// this function has a complex result type
|
||||
TypeH2PNode:=GetH2PNodeForComplexType(CNode,true,ParentNode<>nil);
|
||||
TypeH2PNode:=CreateH2PNodeForComplexType(CNode,true,ParentNode<>nil);
|
||||
if TypeH2PNode<>nil then begin
|
||||
SimpleType:=TypeH2PNode.PascalName;
|
||||
end else
|
||||
@ -724,7 +725,7 @@ begin
|
||||
DebugLn(['TH2PasTool.ConvertFuncParameter Parameter: Name="',CurName,'" Type="',CurType,'" SimpleType="',SimpleType,'"']);
|
||||
if SimpleType='' then begin
|
||||
// this variable has a complex type
|
||||
TypeH2PNode:=GetH2PNodeForComplexType(CNode,true,true);
|
||||
TypeH2PNode:=CreateH2PNodeForComplexType(CNode,true,true);
|
||||
if TypeH2PNode<>nil then
|
||||
SimpleType:=TypeH2PNode.PascalName;
|
||||
end;
|
||||
@ -768,7 +769,7 @@ begin
|
||||
SimpleType:=GetSimplePascalTypeOfCVar(ChildNode);
|
||||
if SimpleType='' then begin
|
||||
// this variable has a complex type
|
||||
TypeH2PNode:=GetH2PNodeForComplexType(ChildNode,true,ParentNode<>nil);
|
||||
TypeH2PNode:=CreateH2PNodeForComplexType(ChildNode,true,ParentNode<>nil);
|
||||
if TypeH2PNode<>nil then
|
||||
SimpleType:=TypeH2PNode.PascalName;
|
||||
end;
|
||||
@ -838,7 +839,7 @@ begin
|
||||
SimpleType:=GetSimplePascalResultTypeOfCFunction(ChildNode);
|
||||
if IsPointerToFunction and (SimpleType='') then begin
|
||||
// this function has a complex result type
|
||||
TypeH2PNode:=GetH2PNodeForComplexType(ChildNode,true,ParentNode<>nil);
|
||||
TypeH2PNode:=CreateH2PNodeForComplexType(ChildNode,true,ParentNode<>nil);
|
||||
if TypeH2PNode<>nil then
|
||||
SimpleType:=TypeH2PNode.PascalName;
|
||||
end;
|
||||
@ -2395,7 +2396,7 @@ begin
|
||||
inc(i);
|
||||
end;
|
||||
|
||||
function TH2PasTool.GetH2PNodeForComplexType(CNode: TCodeTreeNode;
|
||||
function TH2PasTool.CreateH2PNodeForComplexType(CNode: TCodeTreeNode;
|
||||
CreateIfNotExists: boolean; InsertAsPreLast: boolean): TH2PNode;
|
||||
var
|
||||
CCode: String;
|
||||
@ -2414,144 +2415,156 @@ var
|
||||
ConstantNumber: int64;
|
||||
BracketOpenPos: LongInt;
|
||||
NeedH2PNode: Boolean;
|
||||
SubCNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (CNode.Desc=ccnDefinition)
|
||||
and (CNode.FirstChild<>nil)
|
||||
and (CNode.FirstChild.Desc=ccnUnion) then begin
|
||||
// ToDo: union
|
||||
end else begin
|
||||
SubH2PNode:=nil;
|
||||
if CNode.Desc=ccnDefinition then
|
||||
CCode:=CTool.ExtractDefinitionType(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.GetH2PNodeForComplexType CCode="',CCode,'"']);
|
||||
{ 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 else
|
||||
break;
|
||||
until false;
|
||||
if BaseCType='' then begin
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType no base type in c declaration: CCode="',dbgstr(CCode),'"']);
|
||||
exit;
|
||||
end;
|
||||
BasePascalType:=ConvertSimpleCTypeToPascalType(BaseCType,true);
|
||||
if (BasePascalType='') then begin
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType unknown c type: "',BaseCType,'"']);
|
||||
exit;
|
||||
end;
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
|
||||
|
||||
// read pointer(s)
|
||||
while (AtomStart<=length(CCode)) do begin
|
||||
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||
if (CurAtom='*') then begin
|
||||
BaseCType:=BaseCType+'*';
|
||||
NewBasePascalType:=ConvertSimpleCTypeToPascalType(BaseCType,true);
|
||||
if NewBasePascalType<>'' then begin
|
||||
// for this pointer type exists already a predefined simple type
|
||||
end else begin
|
||||
// a new pointer type is needed
|
||||
NewBasePascalType:='P'+BasePascalType;
|
||||
SubH2PNode:=CreateAutoGeneratedH2PNode(NewBasePascalType,nil,
|
||||
ctnTypeDefinition,'^'+BasePascalType,
|
||||
nil,true,InsertAsPreLast);
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType added new pointer type: ',SubH2PNode.DescAsString(CTool)]);
|
||||
NewBasePascalType:=SubH2PNode.PascalName;
|
||||
end;
|
||||
BasePascalType:=NewBasePascalType;
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType using pointer type: BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
|
||||
end else if (CurAtom='const') then begin
|
||||
// skip 'const'
|
||||
end else begin
|
||||
break;
|
||||
if (CNode.Desc=ccnDefinition) and (CNode.FirstChild<>nil) then begin
|
||||
SubCNode:=CNode.FirstChild;
|
||||
if SubCNode.Desc=ccnName then
|
||||
SubCNode:=SubCNode.NextBrother;
|
||||
if (SubCNode<>nil) then begin
|
||||
if (SubCNode.Desc=ccnEnumBlock) then begin
|
||||
Result:=ConvertEnumBlock(SubCNode,nil);
|
||||
exit;
|
||||
end;
|
||||
if SubCNode.Desc<>ccnConstant then begin
|
||||
debugln(['TH2PasTool.GetH2PNodeForComplexType TODO: ',CCNodeDescAsString(CNode.Desc),' of ',CCNodeDescAsString(SubCNode.Desc)]);
|
||||
exit;
|
||||
end;
|
||||
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||
end;
|
||||
|
||||
PascalName:=BasePascalType;
|
||||
PascalCode:=PascalName;
|
||||
|
||||
// read arrays
|
||||
NeedH2PNode:=false;
|
||||
while (AtomStart<=length(CCode)) do begin
|
||||
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||
if CurAtom='[' then begin
|
||||
NeedH2PNode:=true;
|
||||
BracketOpenPos:=AtomStart;
|
||||
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||
if AtomStart>length(CCode) then begin
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType untranslatable (missing ]): CCode="',dbgstr(CCode),'"']);
|
||||
exit;
|
||||
end;
|
||||
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||
if CurAtom=']' then begin
|
||||
// [] -> open array
|
||||
PascalCode:='array of '+PascalCode;
|
||||
PascalName:='ArrayOf'+PascalName;
|
||||
//DebugLn(['TH2PasTool.GetTypeForVarType open array: ',PascalCode]);
|
||||
end else begin
|
||||
// [constant] -> array[0..constant-1]
|
||||
ConstantStartPos:=AtomStart;
|
||||
p:=BracketOpenPos;
|
||||
ReadTilCBracketClose(CCode,p);
|
||||
ConstantEndPos:=p-1;
|
||||
ConstantCode:=copy(CCode,ConstantStartPos,ConstantEndPos-ConstantStartPos);
|
||||
//DebugLn(['TH2PasTool.GetTypeForVarType ConstantCode="',ConstantCode,'"']);
|
||||
if CConstantToInt64(ConstantCode,ConstantNumber) then begin
|
||||
if ConstantNumber>0 then
|
||||
dec(ConstantNumber)
|
||||
else
|
||||
ConstantNumber:=0;
|
||||
ConstantCode:=IntToStr(ConstantNumber);
|
||||
end else begin
|
||||
ConstantCode:=ConstantCode+'-1';
|
||||
end;
|
||||
PascalCode:='array[0..'+ConstantCode+'] of '+PascalCode;
|
||||
PascalName:='Array0to'+CreatePascalNameFromCCode(ConstantCode)+'Of'+PascalName;
|
||||
//DebugLn(['TH2PasTool.GetTypeForVarType fixed array: ',PascalCode]);
|
||||
end;
|
||||
end else
|
||||
break;
|
||||
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||
end;
|
||||
if NeedH2PNode then begin
|
||||
PascalName:='T'+PascalName;
|
||||
PascalName:=copy(PascalName,1,DefaultMaxPascalIdentLen);
|
||||
SubH2PNode:=CreateAutoGeneratedH2PNode(PascalName,nil,ctnTypeDefinition,
|
||||
PascalCode,nil,true,InsertAsPreLast);
|
||||
end;
|
||||
|
||||
// check if the whole declaration was translated
|
||||
if AtomStart<=length(CCode) then begin
|
||||
// unknown C type
|
||||
DebugLn(['TH2PasTool.GetTypeForVarType untranslatable: CCode="',dbgstr(CCode),'"']);
|
||||
exit;
|
||||
end;
|
||||
|
||||
DebugLn(['TH2PasTool.GetTypeForVarType CCode="',dbgstr(CCode),'" PascalName="',PascalName,'"']);
|
||||
Result:=SubH2PNode;
|
||||
end;
|
||||
|
||||
SubH2PNode:=nil;
|
||||
debugln(['TH2PasTool.GetH2PNodeForComplexType CNode=',CCNodeDescAsString(CNode.Desc)]);
|
||||
if CNode.Desc=ccnDefinition then
|
||||
CCode:=CTool.ExtractDefinitionType(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.GetH2PNodeForComplexType CCode="',CCode,'"']);
|
||||
{ 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 else
|
||||
break;
|
||||
until false;
|
||||
if BaseCType='' then begin
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType no base type in c declaration: CCode="',dbgstr(CCode),'"']);
|
||||
exit;
|
||||
end;
|
||||
BasePascalType:=ConvertSimpleCTypeToPascalType(BaseCType,true);
|
||||
if (BasePascalType='') then begin
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType unknown c type: "',BaseCType,'"']);
|
||||
exit;
|
||||
end;
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
|
||||
|
||||
// read pointer(s)
|
||||
while (AtomStart<=length(CCode)) do begin
|
||||
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||
if (CurAtom='*') then begin
|
||||
BaseCType:=BaseCType+'*';
|
||||
NewBasePascalType:=ConvertSimpleCTypeToPascalType(BaseCType,true);
|
||||
if NewBasePascalType<>'' then begin
|
||||
// for this pointer type exists already a predefined simple type
|
||||
end else begin
|
||||
// a new pointer type is needed
|
||||
NewBasePascalType:='P'+BasePascalType;
|
||||
SubH2PNode:=CreateAutoGeneratedH2PNode(NewBasePascalType,nil,
|
||||
ctnTypeDefinition,'^'+BasePascalType,
|
||||
nil,true,InsertAsPreLast);
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType added new pointer type: ',SubH2PNode.DescAsString(CTool)]);
|
||||
NewBasePascalType:=SubH2PNode.PascalName;
|
||||
end;
|
||||
BasePascalType:=NewBasePascalType;
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType using pointer type: BasePascalType="',BasePascalType,'" BaseCType="',BaseCType,'"']);
|
||||
end else if (CurAtom='const') then begin
|
||||
// skip 'const'
|
||||
end else begin
|
||||
break;
|
||||
end;
|
||||
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||
end;
|
||||
|
||||
PascalName:=BasePascalType;
|
||||
PascalCode:=PascalName;
|
||||
|
||||
// read arrays
|
||||
NeedH2PNode:=false;
|
||||
while (AtomStart<=length(CCode)) do begin
|
||||
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||
if CurAtom='[' then begin
|
||||
NeedH2PNode:=true;
|
||||
BracketOpenPos:=AtomStart;
|
||||
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||
if AtomStart>length(CCode) then begin
|
||||
DebugLn(['TH2PasTool.GetH2PNodeForComplexType untranslatable (missing ]): CCode="',dbgstr(CCode),'"']);
|
||||
exit;
|
||||
end;
|
||||
CurAtom:=copy(CCode,AtomStart,p-AtomStart);
|
||||
if CurAtom=']' then begin
|
||||
// [] -> open array
|
||||
PascalCode:='array of '+PascalCode;
|
||||
PascalName:='ArrayOf'+PascalName;
|
||||
//DebugLn(['TH2PasTool.GetTypeForVarType open array: ',PascalCode]);
|
||||
end else begin
|
||||
// [constant] -> array[0..constant-1]
|
||||
ConstantStartPos:=AtomStart;
|
||||
p:=BracketOpenPos;
|
||||
ReadTilCBracketClose(CCode,p);
|
||||
ConstantEndPos:=p-1;
|
||||
ConstantCode:=copy(CCode,ConstantStartPos,ConstantEndPos-ConstantStartPos);
|
||||
//DebugLn(['TH2PasTool.GetTypeForVarType ConstantCode="',ConstantCode,'"']);
|
||||
if CConstantToInt64(ConstantCode,ConstantNumber) then begin
|
||||
if ConstantNumber>0 then
|
||||
dec(ConstantNumber)
|
||||
else
|
||||
ConstantNumber:=0;
|
||||
ConstantCode:=IntToStr(ConstantNumber);
|
||||
end else begin
|
||||
ConstantCode:=ConstantCode+'-1';
|
||||
end;
|
||||
PascalCode:='array[0..'+ConstantCode+'] of '+PascalCode;
|
||||
PascalName:='Array0to'+CreatePascalNameFromCCode(ConstantCode)+'Of'+PascalName;
|
||||
//DebugLn(['TH2PasTool.GetTypeForVarType fixed array: ',PascalCode]);
|
||||
end;
|
||||
end else
|
||||
break;
|
||||
ReadRawNextCAtom(CCode,p,AtomStart);
|
||||
end;
|
||||
if NeedH2PNode then begin
|
||||
PascalName:='T'+PascalName;
|
||||
PascalName:=copy(PascalName,1,DefaultMaxPascalIdentLen);
|
||||
SubH2PNode:=CreateAutoGeneratedH2PNode(PascalName,nil,ctnTypeDefinition,
|
||||
PascalCode,nil,true,InsertAsPreLast);
|
||||
end;
|
||||
|
||||
// check if the whole declaration was translated
|
||||
if AtomStart<=length(CCode) then begin
|
||||
// unknown C type
|
||||
DebugLn(['TH2PasTool.GetTypeForVarType untranslatable: CCode="',dbgstr(CCode),'"']);
|
||||
exit;
|
||||
end;
|
||||
|
||||
DebugLn(['TH2PasTool.GetTypeForVarType CCode="',dbgstr(CCode),'" PascalName="',PascalName,'"']);
|
||||
Result:=SubH2PNode;
|
||||
end;
|
||||
|
||||
function TH2PasTool.CreatePascalNameFromCCode(const CCode: string;
|
||||
@ -2670,6 +2683,7 @@ begin
|
||||
end else if (Tree.Root=nil) then begin
|
||||
DebugLn(['TH2PasTool.WriteH2PNodeReport Tree.Root=nil']);
|
||||
end else begin
|
||||
//debugln(['TH2PasTool.WriteH2PNodeReport ']);
|
||||
Node:=Tree.Root;
|
||||
while Node<>nil do begin
|
||||
DebugLn([GetIndentStr(Node.GetLevel*2),Node.DescAsString(CTool)]);
|
||||
|
@ -4,6 +4,7 @@
|
||||
./runtests --format=plain --suite=TestCTH2PMergeHeaderFiles
|
||||
./runtests --format=plain --suite=TestCTH2PReplaceMacros
|
||||
./runtests --format=plain --suite=TestCTH2PConvertSimpleTypes
|
||||
./runtests --format=plain --suite=TestCTH2PConvertEnumsTypes
|
||||
}
|
||||
unit TestCTH2Pas;
|
||||
|
||||
@ -23,16 +24,50 @@ type
|
||||
|
||||
TTestCodetoolsH2Pas = class(TTestCase)
|
||||
protected
|
||||
procedure Test(Title, CHeaderSrc, ExpectedPasSrc: string);
|
||||
published
|
||||
procedure TestCTH2PMergeHeaderFiles;
|
||||
procedure TestCTH2PReplaceMacros;
|
||||
procedure TestCTH2PConvertSimpleTypes;
|
||||
procedure TestCTH2PConvertEnumsTypes;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TTestCodetoolsH2Pas }
|
||||
|
||||
procedure TTestCodetoolsH2Pas.Test(Title, CHeaderSrc, ExpectedPasSrc: string);
|
||||
var
|
||||
Tool: TH2PasTool;
|
||||
Header1: TCodeBuffer;
|
||||
PasCode: TCodeBuffer;
|
||||
begin
|
||||
Tool:=TH2PasTool.Create;
|
||||
Header1:=nil;
|
||||
PasCode:=nil;
|
||||
try
|
||||
Header1:=CodeToolBoss.CreateFile('header1.h');
|
||||
PasCode:=CodeToolBoss.CreateFile('header1.pas');
|
||||
Header1.Source:=CHeaderSrc;
|
||||
Tool.Convert(Header1,PasCode);
|
||||
if CompareTextIgnoringSpace(ExpectedPasSrc,PasCode.Source,true)<>0 then begin
|
||||
// failed
|
||||
debugln(['TTestCodetoolsH2Pas.Test C Source="',CHeaderSrc,'"']);
|
||||
debugln(['TTestCodetoolsH2Pas.Test Expected pas="',ExpectedPasSrc,'"']);
|
||||
debugln(['TTestCodetoolsH2Pas.Test Found pas="',PasCode.Source,'"']);
|
||||
Tool.WriteH2PNodeReport;
|
||||
Tool.WriteH2PDirectivesNodeReport;
|
||||
AssertEquals(Title,ExpectedPasSrc,PasCode.Source);
|
||||
end else begin
|
||||
AssertEquals(Title,true,true);
|
||||
end;
|
||||
finally
|
||||
if Header1<>nil then Header1.IsDeleted:=true;
|
||||
if PasCode<>nil then PasCode.IsDeleted:=true;
|
||||
Tool.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestCodetoolsH2Pas.TestCTH2PMergeHeaderFiles;
|
||||
var
|
||||
Header1, Header2: TCodeBuffer;
|
||||
@ -116,41 +151,26 @@ end;
|
||||
|
||||
procedure TTestCodetoolsH2Pas.TestCTH2PConvertSimpleTypes;
|
||||
var
|
||||
Tool: TH2PasTool;
|
||||
Header1: TCodeBuffer;
|
||||
PasCode: TCodeBuffer;
|
||||
ExpectedSrc: String;
|
||||
UsesCTypes: String;
|
||||
EmpytImplementation: String;
|
||||
begin
|
||||
Tool:=TH2PasTool.Create;
|
||||
Header1:=nil;
|
||||
PasCode:=nil;
|
||||
try
|
||||
Header1:=CodeToolBoss.CreateFile('header1.h');
|
||||
PasCode:=CodeToolBoss.CreateFile('header1.pas');
|
||||
Header1.Source:='int i;';
|
||||
Tool.Convert(Header1,PasCode);
|
||||
ExpectedSrc:=
|
||||
'uses ctypes;'+LineEnding
|
||||
+'var'+LineEnding
|
||||
+' i: cint; cvar; external;'+LineEnding
|
||||
+'implementation'+LineEnding
|
||||
+'end.';
|
||||
if CompareTextIgnoringSpace(ExpectedSrc,PasCode.Source,true)<>0 then begin
|
||||
AssertEquals('convert int i;',ExpectedSrc,PasCode.Source);
|
||||
end else begin
|
||||
AssertEquals('convert int i;',true,true);
|
||||
end;
|
||||
UsesCTypes:='uses ctypes;'+LineEnding;
|
||||
EmpytImplementation:=LineEnding+'implementation'+LineEnding+'end.';
|
||||
Test('convert int i;',
|
||||
'int i;',
|
||||
UsesCTypes+'var i: cint; cvar; external;'+EmpytImplementation);
|
||||
end;
|
||||
|
||||
{Tool.WriteH2PNodeReport;
|
||||
Tool.WriteH2PDirectivesNodeReport;
|
||||
writeln;
|
||||
writeln('=============================================');
|
||||
writeln(PasCode.Source);}
|
||||
finally
|
||||
if Header1<>nil then Header1.IsDeleted:=true;
|
||||
if PasCode<>nil then PasCode.IsDeleted:=true;
|
||||
Tool.Free;
|
||||
end;
|
||||
procedure TTestCodetoolsH2Pas.TestCTH2PConvertEnumsTypes;
|
||||
var
|
||||
UsesCTypes: String;
|
||||
EmpytImplementation: String;
|
||||
begin
|
||||
UsesCTypes:='uses ctypes;'+LineEnding;
|
||||
EmpytImplementation:=LineEnding+'implementation'+LineEnding+'end.';
|
||||
Test('convert anonymous enum{ENUM1};',
|
||||
'enum{ENUM1};',
|
||||
UsesCTypes+'type enumENUM1 = (ENUM1);'+EmpytImplementation);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
Loading…
Reference in New Issue
Block a user