mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 14:29:25 +01:00 
			
		
		
		
	codetools: h2p: implemented function list parameters
git-svn-id: trunk@14571 -
This commit is contained in:
		
							parent
							
								
									229b2913b9
								
							
						
					
					
						commit
						b8caa1a665
					
				@ -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;
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user