diff --git a/components/codetools/ccodeparsertool.pas b/components/codetools/ccodeparsertool.pas index 9f963192cc..8b150ded21 100644 --- a/components/codetools/ccodeparsertool.pas +++ b/components/codetools/ccodeparsertool.pas @@ -22,6 +22,24 @@ Abstract: A simple C parser. + + Predefined C macros: + __LINE__ current source file line number as decimal + __FILE__ current source filename + __DATE__ current date: Apr 21 1990 or Jan 1 2008 (note the space in front of the 1) + __TIME__ current time "hh:mm:ss" + __STDC__ 1 + + Predefined gcc macros: + __attribute__((packed)) + Examples: + typedef struct { + uint8_t b[6]; + } __attribute__((packed)) bdaddr_t; + struct __attribute__((packed)) { + typeof(*(ptr)) __v; + } *__p = (void *) (ptr); + } unit CCodeParserTool; @@ -50,7 +68,7 @@ const ccnNone = 0+ccnBase; ccnRoot = 1+ccnBase; - 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, EndPos at line end ccnExtern = 3+ccnBase;// e.g. extern "C" {} ccnEnumBlock = 4+ccnBase;// e.g. enum {}; ccnEnumID = 5+ccnBase;// e.g. name = value; @@ -195,6 +213,7 @@ type function ExtractStructName(StructNode: TCodeTreeNode): string; function ExtractUnionName(UnionNode: TCodeTreeNode): string; function ExtractTypedefName(TypedefNode: TCodeTreeNode): string; + function ExtractDirectiveAction(DirectiveNode: TCodeTreeNode): string; procedure Replace(FromPos, ToPos: integer; const NewSrc: string); @@ -412,6 +431,11 @@ procedure TCCodeParserTool.ReadStruct; As variable: struct hidp_conninfo *ci; + As typecast in macros: + struct __attribute__((packed)) { + typeof(*(ptr)) __v; + } *__p = (void *) (ptr); + *) begin CreateChildNode(ccnStruct); @@ -426,6 +450,14 @@ begin ReadNextAtom; end; + // read front attributes + if AtomIs('__attribute__') then begin + ReadNextAtom; + if not AtomIsChar('(') then + RaiseExpectedButAtomFound('('); + ReadTilBracketClose(true); + ReadNextAtom; + end; if AtomIsChar('{') then begin // read block {} repeat @@ -445,7 +477,7 @@ begin else RaiseExpectedButAtomFound('identifier'); until false; - // read attributes + // read after attributes ReadNextAtom; if AtomIs('__attribute__') then begin ReadNextAtom; @@ -1582,6 +1614,15 @@ begin Result:=GetIdentifier(@Src[Node.StartPos]); end; +function TCCodeParserTool.ExtractDirectiveAction(DirectiveNode: TCodeTreeNode + ): string; +begin + if DirectiveNode.StartPos ignore + DebugLn(['TH2PasTool.ConvertStruct SKIPPING anonymous struct at ',CTool.CleanPosToStr(CNode.StartPos)]); + end else begin + // this struct has a name + // create a type + TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordType,'', + nil,ParentNode=nil); + // build recursively + BuildH2PTree(TypeH2PNode); + end; +end; + +procedure TH2PasTool.ConvertVariable(CNode: TCodeTreeNode; ParentNode: TH2PNode + ); +var + CurName: String; + TypeH2PNode: TH2PNode; + CurType: String; + SimpleType: String; + H2PNode: TH2PNode; +begin + if (CNode.FirstChild<>nil) and (CNode.FirstChild.Desc=ccnUnion) + then begin + CurName:=CTool.ExtractVariableName(CNode); + if (ParentNode<>nil) and (ParentNode.PascalDesc=ctnRecordType) + then begin + // create a pascal 'record case' + TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordCase,'', + ParentNode,false); + DebugLn(['TH2PasTool.BuildH2PTree added record case for nested union']); + // build recursively the record cases + if CNode.FirstChild.FirstChild<>nil then + BuildH2PTree(TypeH2PNode,CNode.FirstChild.FirstChild); + end else if (CurName<>'') and (ParentNode=nil) then begin + // this union has a name + // create a record type + TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordCase,'', + nil,true); + DebugLn(['TH2PasTool.BuildH2PTree added record type for union: ',TypeH2PNode.DescAsString]); + // build recursively + if CNode.FirstChild.FirstChild<>nil then + BuildH2PTree(TypeH2PNode,CNode.FirstChild.FirstChild); + // create variable + CurName:=CTool.ExtractUnionName(CNode); + H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnVarDefinition, + TypeH2PNode.PascalName, + nil,ParentNode=nil); + DebugLn(['TH2PasTool.BuildH2PTree added variable for union: ',H2PNode.DescAsString]); + end else begin + DebugLn(['TH2PasTool.BuildH2PTree SKIPPING union variable at ',CTool.CleanPosToStr(CNode.StartPos)]); + end; + end else begin + CurName:=CTool.ExtractVariableName(CNode); + CurType:=CTool.ExtractVariableType(CNode); + SimpleType:=GetSimplePascalTypeOfCVar(CNode); + 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,ParentNode=nil); + DebugLn(['TH2PasTool.BuildH2PTree added: ',H2PNode.DescAsString]); + end else begin + DebugLn(['TH2PasTool.BuildH2PTree SKIPPING Variable Name="',CurName,'" Type="',CurType,'"']); + end; + end; +end; + +procedure TH2PasTool.ConvertEnumBlock(CNode: TCodeTreeNode; + ParentNode: TH2PNode); +var + CurName: String; + TypeH2PNode: TH2PNode; + CurValue: String; + H2PNode: TH2PNode; +begin + CurName:=CTool.ExtractEnumBlockName(CNode); + 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,'', + nil,ParentNode=nil); + end else begin + // this enum block has a name + TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnEnumerationType,'', + nil,ParentNode=nil); + end; + DebugLn(['TH2PasTool.BuildH2PTree added: ',TypeH2PNode.DescAsString]); + + CNode:=CNode.FirstChild; + while CNode<>nil do begin + if CNode.Desc=ccnEnumID then begin + CurName:=CTool.ExtractEnumIDName(CNode); + CurValue:=CTool.ExtractEnumIDValue(CNode); + H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnEnumIdentifier,CurValue, + TypeH2PNode,ParentNode=nil); + DebugLn(['TH2PasTool.BuildH2PTree added: ',H2PNode.DescAsString]); + end; + CNode:=CNode.NextBrother; + end; +end; + +procedure TH2PasTool.ConvertFunction(CNode: TCodeTreeNode; ParentNode: TH2PNode + ); +var + CurName: String; + CurType: String; + SimpleType: String; + IsPointerToFunction: Boolean; + Ok: Boolean; + StatementNode: TCodeTreeNode; + TypeH2PNode: TH2PNode; + H2PNode: TH2PNode; +begin + CurName:=CTool.ExtractFunctionName(CNode); + CurType:=CTool.ExtractFunctionResultType(CNode); + SimpleType:=GetSimplePascalResultTypeOfCFunction(CNode); + IsPointerToFunction:=CTool.IsPointerToFunction(CNode); + StatementNode:=nil; + Ok:=true; + if (CNode.LastChild<>nil) and (CNode.LastChild.Desc=ccnStatementBlock) then + StatementNode:=CNode.LastChild; + DebugLn(['TH2PasTool.BuildH2PTree Function Name="',CurName,'" ResultType="',CurType,'" SimpleType=',SimpleType,' HasStatements=',StatementNode<>nil,' IsPointer=',IsPointerToFunction]); + if StatementNode<>nil then begin + // this function has a body + Ok:=false; + end; + if Ok and (SimpleType='') then begin + // this function has a complex result type + TypeH2PNode:=GetH2PNodeForComplexType(CNode); + if TypeH2PNode<>nil then begin + SimpleType:=TypeH2PNode.PascalName; + end else + Ok:=false; + end; + + if Ok then begin + H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnProcedure,SimpleType, + nil,false); + DebugLn(['TH2PasTool.BuildH2PTree function added: ',H2PNode.DescAsString]); + // build recursively + BuildH2PTree(H2PNode); + end else begin + DebugLn(['TH2PasTool.BuildH2PTree SKIPPING Function Name="',CurName,'" Type="',CurType,'" at ',CTool.CleanPosToStr(CNode.StartPos)]); + end; +end; + +procedure TH2PasTool.ConvertFuncParameter(CNode: TCodeTreeNode; + ParentNode: TH2PNode); +var + CurName: String; + CurType: String; + SimpleType: String; + TypeH2PNode: TH2PNode; + H2PNode: TH2PNode; +begin + CurName:=CTool.ExtractParameterName(CNode); + CurType:=CTool.ExtractParameterType(CNode); + SimpleType:=GetSimplePascalTypeOfCParameter(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,'" at ',CTool.CleanPosToStr(CNode.StartPos)]); + end; +end; + +procedure TH2PasTool.ConvertTypedef(CNode: TCodeTreeNode; ParentNode: TH2PNode + ); +var + CurName: String; + ChildNode: TCodeTreeNode; + CurType: String; + TypeH2PNode: TH2PNode; + IsPointerToFunction: Boolean; + SimpleType: String; + H2PNode: TH2PNode; +begin + if CNode.FirstChild=nil then begin + exit; + end; + CurName:=CTool.ExtractTypedefName(CNode); + DebugLn(['TH2PasTool.BuildH2PTree Typedef name="',CurName,'"']); + ChildNode:=CNode.FirstChild; + case ChildNode.Desc of + + ccnStruct: // typedef struct + begin + ChildNode:=CNode.FirstChild.FirstChild; + if (ChildNode<>nil) + and (ChildNode.Desc=ccnStructAlias) then begin + // this is a struct alias + CurType:=GetIdentifier(@CTool.Src[ChildNode.StartPos]); + TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode, + ctnTypeDefinition,CurType); + end else begin + // this is a new struct + TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordType,''); + DebugLn(['TH2PasTool.BuildH2PTree added record: ',TypeH2PNode.DescAsString]); + // build recursively + if ChildNode<>nil then + BuildH2PTree(TypeH2PNode,ChildNode); + end; + end; + + ccnFunction: // typedef function + begin + CurName:=CTool.ExtractFunctionName(ChildNode); + CurType:=CTool.ExtractFunctionResultType(ChildNode,false,false); + IsPointerToFunction:=CTool.IsPointerToFunction(ChildNode); + SimpleType:=GetSimplePascalResultTypeOfCFunction(ChildNode); + if IsPointerToFunction and (SimpleType='') then begin + // this function has a complex result type + TypeH2PNode:=GetH2PNodeForComplexType(ChildNode); + if TypeH2PNode<>nil then + SimpleType:=TypeH2PNode.PascalName; + end; + if IsPointerToFunction and (SimpleType<>'') then begin + H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnProcedureType,SimpleType, + nil,true); + DebugLn(['TH2PasTool.BuildH2PTree function type added: ',H2PNode.DescAsString]); + // build recursively + if ChildNode.FirstChild<>nil then + BuildH2PTree(H2PNode,ChildNode.FirstChild); + end else begin + DebugLn(['TH2PasTool.BuildH2PTree typdef function CurName=',CurName,' CurType=',CTool.ExtractFunctionResultType(ChildNode),' SimpleType=',SimpleType]); + DebugLn(['TH2PasTool.BuildH2PTree SKIPPING typedef ',CCNodeDescAsString(ChildNode.Desc),' at ',CTool.CleanPosToStr(CNode.StartPos)]); + end; + end; + + else // typedef + DebugLn(['TH2PasTool.BuildH2PTree SKIPPING typedef ',CCNodeDescAsString(CNode.FirstChild.Desc),' at ',CTool.CleanPosToStr(CNode.StartPos)]); + end; +end; + +procedure TH2PasTool.ConvertDirective(CNode: TCodeTreeNode; ParentNode: TH2PNode + ); +var + Directive: String; + PascalCode: String; + H2PNode: TH2PNode; +begin + Directive:=CTool.ExtractDirectiveAction(CNode); + if Directive='include' then begin + // #include // search independent of source position + // #include "filename" // search dependent on source position + if icspInclude in IgnoreCParts then + exit; + end else if Directive='define' then begin + // #define FMAC(a,b) a here, then b + // #define NONFMAC some text here + end else if Directive='undef' then begin + // #undef NAME + end else if Directive='if' then begin + // #if EXPRESSION + end else if Directive='ifdef' then begin + // #ifdef NAME + end else if Directive='ifndef' then begin + // #ifndef NAME + end else if Directive='elif' then begin + // #elif EXPRESSION + end else if Directive='else' then begin + // #else + H2PNode:=CreateH2PNode('#else','#else',CNode,ctnNone, + '',ParentNode,false); + DebugLn(['TH2PasTool.ConvertDirective added $else: ',H2PNode.DescAsString]); + exit; + end else if Directive='endif' then begin + // #endif + H2PNode:=CreateH2PNode('#endif','#endif',CNode,ctnNone, + '',ParentNode,false); + DebugLn(['TH2PasTool.ConvertDirective added $endif: ',H2PNode.DescAsString]); + exit; + end else if Directive='line' then begin + // #line: set the current line number -> ignore + exit; + end else if Directive='error' then begin + // #error + PascalCode:=CTool.ExtractCode(CNode.StartPos+length('#error'), + CNode.EndPos); + H2PNode:=CreateH2PNode('#error','#error',CNode,ctnNone, + PascalCode,ParentNode,false); + DebugLn(['TH2PasTool.ConvertDirective added $error: ',H2PNode.DescAsString]); + exit; + end else if Directive='pragma' then begin + // #pragma: implementation specifics + exit; + end else if Directive='' then begin + // # : null + exit; + end; + DebugLn(['TH2PasTool.ConvertDirective SKIPPING directive at ',CTool.CleanPosToStr(CNode.StartPos),' Code="',dbgstr(CTool.ExtractCode(CNode.StartPos,CNode.EndPos)),'"']); +end; + +procedure TH2PasTool.SetIgnoreCParts(const AValue: TIgnoreCSourceParts); +begin + if FIgnoreCParts=AValue then exit; + FIgnoreCParts:=AValue; +end; + function TH2PasTool.Convert(CCode, PascalCode: TCodeBuffer): boolean; begin Result:=false; @@ -278,17 +611,7 @@ procedure TH2PasTool.BuildH2PTree(ParentNode: TH2PNode; StartNode: TCodeTreeNode); var CNode: TCodeTreeNode; - CurName: String; - CurType: String; - SimpleType: String; - H2PNode: TH2PNode; NextCNode: TCodeTreeNode; - TypeH2PNode: TH2PNode; - CurValue: String; - StatementNode: TCodeTreeNode; - Ok: Boolean; - IsPointerToFunction: Boolean; - ChildNode: TCodeTreeNode; begin //DebugLn(['TH2PasTool.BuildH2PTree ParentNode=',ParentNode.DescAsString]); if ParentNode<>nil then begin @@ -307,220 +630,31 @@ begin ccnRoot, ccnExtern: NextCNode:=CNode.Next; - ccnDirective: - NextCNode:=CNode.Next; - ccnTypedef: - if CNode.FirstChild<>nil then begin - CurName:=CTool.ExtractTypedefName(CNode); - DebugLn(['TH2PasTool.BuildH2PTree Typedef name="',CurName,'"']); - ChildNode:=CNode.FirstChild; - case ChildNode.Desc of - - ccnStruct: // typedef struct - begin - ChildNode:=CNode.FirstChild.FirstChild; - if (ChildNode<>nil) - and (ChildNode.Desc=ccnStructAlias) then begin - // this is a struct alias - CurType:=GetIdentifier(@CTool.Src[ChildNode.StartPos]); - TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode, - ctnTypeDefinition,CurType); - end else begin - // this is a new struct - TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordType,''); - DebugLn(['TH2PasTool.BuildH2PTree added record: ',TypeH2PNode.DescAsString]); - // build recursively - if ChildNode<>nil then - BuildH2PTree(TypeH2PNode,ChildNode); - end; - end; - - ccnFunction: // typedef function - begin - CurName:=CTool.ExtractFunctionName(ChildNode); - CurType:=CTool.ExtractFunctionResultType(ChildNode,false,false); - IsPointerToFunction:=CTool.IsPointerToFunction(ChildNode); - SimpleType:=GetSimplePascalResultTypeOfCFunction(ChildNode); - if IsPointerToFunction and (SimpleType='') then begin - // this function has a complex result type - TypeH2PNode:=GetH2PNodeForComplexType(ChildNode); - if TypeH2PNode<>nil then - SimpleType:=TypeH2PNode.PascalName; - end; - if IsPointerToFunction and (SimpleType<>'') then begin - H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnProcedureType,SimpleType, - nil,true); - DebugLn(['TH2PasTool.BuildH2PTree function type added: ',H2PNode.DescAsString]); - // build recursively - if ChildNode.FirstChild<>nil then - BuildH2PTree(H2PNode,ChildNode.FirstChild); - end else begin - DebugLn(['TH2PasTool.BuildH2PTree typdef function CurName=',CurName,' CurType=',CTool.ExtractFunctionResultType(ChildNode),' SimpleType=',SimpleType]); - DebugLn(['TH2PasTool.BuildH2PTree SKIPPING typedef ',CCNodeDescAsString(ChildNode.Desc),' at ',CTool.CleanPosToStr(CNode.StartPos)]); - end; - end; - - else // typedef - DebugLn(['TH2PasTool.BuildH2PTree SKIPPING typedef ',CCNodeDescAsString(CNode.FirstChild.Desc),' at ',CTool.CleanPosToStr(CNode.StartPos)]); - end; - end; - + ConvertTypedef(CNode,ParentNode); + ccnVariable: - if (CNode.FirstChild<>nil) and (CNode.FirstChild.Desc=ccnUnion) - then begin - CurName:=CTool.ExtractVariableName(CNode); - if (ParentNode<>nil) and (ParentNode.PascalDesc=ctnRecordType) - then begin - // create a pascal 'record case' - TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordCase,'', - ParentNode,false); - DebugLn(['TH2PasTool.BuildH2PTree added record case for nested union']); - // build recursively the record cases - if CNode.FirstChild.FirstChild<>nil then - BuildH2PTree(TypeH2PNode,CNode.FirstChild.FirstChild); - end else if (CurName<>'') and (ParentNode=nil) then begin - // this union has a name - // create a record type - TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordCase,'', - nil,true); - DebugLn(['TH2PasTool.BuildH2PTree added record type for union: ',TypeH2PNode.DescAsString]); - // build recursively - if CNode.FirstChild.FirstChild<>nil then - BuildH2PTree(TypeH2PNode,CNode.FirstChild.FirstChild); - // create variable - CurName:=CTool.ExtractUnionName(CNode); - H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnVarDefinition, - TypeH2PNode.PascalName, - nil,ParentNode=nil); - DebugLn(['TH2PasTool.BuildH2PTree added variable for union: ',H2PNode.DescAsString]); - end else begin - DebugLn(['TH2PasTool.BuildH2PTree SKIPPING union variable at ',CTool.CleanPosToStr(CNode.StartPos)]); - end; - end else begin - CurName:=CTool.ExtractVariableName(CNode); - CurType:=CTool.ExtractVariableType(CNode); - SimpleType:=GetSimplePascalTypeOfCVar(CNode); - 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,ParentNode=nil); - DebugLn(['TH2PasTool.BuildH2PTree added: ',H2PNode.DescAsString]); - end else begin - DebugLn(['TH2PasTool.BuildH2PTree SKIPPING Variable Name="',CurName,'" Type="',CurType,'"']); - end; - end; - + ConvertVariable(CNode,ParentNode); + ccnFunction: - begin - CurName:=CTool.ExtractFunctionName(CNode); - CurType:=CTool.ExtractFunctionResultType(CNode); - SimpleType:=GetSimplePascalResultTypeOfCFunction(CNode); - IsPointerToFunction:=CTool.IsPointerToFunction(CNode); - StatementNode:=nil; - Ok:=true; - if (CNode.LastChild<>nil) and (CNode.LastChild.Desc=ccnStatementBlock) then - StatementNode:=CNode.LastChild; - DebugLn(['TH2PasTool.BuildH2PTree Function Name="',CurName,'" ResultType="',CurType,'" SimpleType=',SimpleType,' HasStatements=',StatementNode<>nil,' IsPointer=',IsPointerToFunction]); - if StatementNode<>nil then begin - // this function has a body - Ok:=false; - end; - if Ok and (SimpleType='') then begin - // this function has a complex result type - TypeH2PNode:=GetH2PNodeForComplexType(CNode); - if TypeH2PNode<>nil then begin - SimpleType:=TypeH2PNode.PascalName; - end else - Ok:=false; - end; - - if Ok then begin - H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnProcedure,SimpleType, - nil,false); - DebugLn(['TH2PasTool.BuildH2PTree function added: ',H2PNode.DescAsString]); - // build recursively - BuildH2PTree(H2PNode); - end else begin - DebugLn(['TH2PasTool.BuildH2PTree SKIPPING Function Name="',CurName,'" Type="',CurType,'" at ',CTool.CleanPosToStr(CNode.StartPos)]); - end; - end; - + ConvertFunction(CNode,ParentNode); + ccnFuncParamList: NextCNode:=CNode.FirstChild; ccnFuncParameter: - begin - CurName:=CTool.ExtractParameterName(CNode); - CurType:=CTool.ExtractParameterType(CNode); - SimpleType:=GetSimplePascalTypeOfCParameter(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,'" at ',CTool.CleanPosToStr(CNode.StartPos)]); - end; - end; - - ccnEnumBlock: - begin - CurName:=CTool.ExtractEnumBlockName(CNode); - 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,'', - nil,ParentNode=nil); - end else begin - // this enum block has a name - TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnEnumerationType,'', - nil,ParentNode=nil); - end; - DebugLn(['TH2PasTool.BuildH2PTree added: ',TypeH2PNode.DescAsString]); + ConvertFuncParameter(CNode,ParentNode); + + ccnEnumBlock: + ConvertEnumBlock(CNode,ParentNode); - CNode:=CNode.FirstChild; - while CNode<>nil do begin - if CNode.Desc=ccnEnumID then begin - CurName:=CTool.ExtractEnumIDName(CNode); - CurValue:=CTool.ExtractEnumIDValue(CNode); - H2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnEnumIdentifier,CurValue, - TypeH2PNode,ParentNode=nil); - DebugLn(['TH2PasTool.BuildH2PTree added: ',H2PNode.DescAsString]); - end; - CNode:=CNode.NextBrother; - end; - end; - ccnStruct: - begin - CurName:=CTool.ExtractStructName(CNode); - if CurName='' then begin - // this is an anonymous struct -> ignore - DebugLn(['TH2PasTool.BuildH2PTree SKIPPING anonymous struct at ',CTool.CleanPosToStr(CNode.StartPos)]); - end else begin - // this struct has a name - // create a type - TypeH2PNode:=CreateH2PNode(CurName,CurName,CNode,ctnRecordType,'', - nil,ParentNode=nil); - // build recursively - BuildH2PTree(TypeH2PNode); - end; - end; + ConvertStruct(CNode,ParentNode); ccnName: ; + ccnDirective: + ConvertDirective(CNode,ParentNode); else DebugLn(['TH2PasTool.BuildH2PTree SKIPPING ',CCNodeDescAsString(CNode.Desc),' at ',CTool.CleanPosToStr(CNode.StartPos)]); end; @@ -902,6 +1036,7 @@ begin Tree:=TH2PTree.Create; FPascalNames:=TAVLTree.Create(@CompareH2PNodePascalNames); FCNames:=TAVLTree.Create(@CompareH2PNodeCNames); + FIgnoreCParts:=[icspInclude]; end; destructor TH2PasTool.Destroy;