From 40018b422161035b67db0fba0351e80558412b8b Mon Sep 17 00:00:00 2001 From: mattias Date: Sat, 15 Mar 2008 13:07:47 +0000 Subject: [PATCH] codetools: added table of ctypes git-svn-id: trunk@14529 - --- components/codetools/ccodeparsertool.pas | 11 +- components/codetools/h2pastool.pas | 125 ++++++++++++++++++++--- 2 files changed, 120 insertions(+), 16 deletions(-) diff --git a/components/codetools/ccodeparsertool.pas b/components/codetools/ccodeparsertool.pas index c3ed75d502..39f2f08a88 100644 --- a/components/codetools/ccodeparsertool.pas +++ b/components/codetools/ccodeparsertool.pas @@ -169,7 +169,8 @@ type WithDirectives: boolean = false): string;// extract code without comments function ExtractVariableName(Node: TCodeTreeNode): string; - function ExtractVariableType(Node: TCodeTreeNode): string; + function ExtractVariableType(Node: TCodeTreeNode; + WithDirectives: boolean = false): string; procedure Replace(FromPos, ToPos: integer; const NewSrc: string); @@ -1149,7 +1150,8 @@ begin Result:=copy(Src,NameNode.StartPos,NameNode.EndPos-NameNode.StartPos); end; -function TCCodeParserTool.ExtractVariableType(Node: TCodeTreeNode): string; +function TCCodeParserTool.ExtractVariableType(Node: TCodeTreeNode; + WithDirectives: boolean): string; var NameNode: TCodeTreeNode; begin @@ -1157,12 +1159,13 @@ begin if (NameNode=nil) or (NameNode.Desc<>ccnVariableName) then Result:='' else begin - Result:=ExtractCode(Node.StartPos,NameNode.StartPos,true); + Result:=ExtractCode(Node.StartPos,NameNode.StartPos,WithDirectives); if (NameNode.NextBrother<>nil) and (NameNode.NextBrother.Desc=ccnFuncParamList) then begin // this is a function. The name is in between. // The type is result type + parameter list - Result:=Result+ExtractCode(NameNode.EndPos,NameNode.NextBrother.EndPos,true); + Result:=Result+ExtractCode(NameNode.EndPos,NameNode.NextBrother.EndPos, + WithDirectives); end; end; end; diff --git a/components/codetools/h2pastool.pas b/components/codetools/h2pastool.pas index 3ba970ce0b..720cd38578 100644 --- a/components/codetools/h2pastool.pas +++ b/components/codetools/h2pastool.pas @@ -40,8 +40,9 @@ unit H2PasTool; interface uses - Classes, SysUtils, FileProcs, BasicCodeTools, CCodeParserTool, - NonPascalCodeTools, CodeCache, CodeTree, CodeAtom; + Classes, SysUtils, contnrs, + FileProcs, BasicCodeTools, CCodeParserTool, NonPascalCodeTools, + CodeCache, CodeTree, CodeAtom; type @@ -88,22 +89,84 @@ type { TH2PasTool } TH2PasTool = class + private + FPredefinedCTypes: TFPStringHashTable; public Tree: TH2PTree; CTool: TCCodeParserTool; function Convert(CCode, PascalCode: TCodeBuffer): boolean; procedure BuildH2PTree; - function HasCVariableSimplePascalType(CVarNode: TCodeTreeNode): boolean; - + function GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string; + function ConvertSimpleCTypeToPascalType(CType: string): string; + procedure WriteDebugReport; constructor Create; destructor Destroy; override; procedure Clear; + property PredefinedCTypes: TFPStringHashTable read FPredefinedCTypes; end; + + +function DefaultPredefinedCTypes: TFPStringHashTable;// types in unit ctypes implementation +var + InternalPredefinedCTypes: TFPStringHashTable = nil;// types in unit ctypes + +function DefaultPredefinedCTypes: TFPStringHashTable; +begin + if InternalPredefinedCTypes=nil then begin + InternalPredefinedCTypes:=TFPStringHashTable.Create; + with InternalPredefinedCTypes do begin + // int + Add('int','cint'); + Add('signed int','csint'); + Add('unsigned int','cuint'); + Add('short int','cshort'); + Add('signed short int','csshort'); + Add('unsigned short int','csshort'); + // short + Add('short','cshort'); + Add('signed short','csshort'); + Add('unsigned short','csshort'); + // int8 + Add('int8','cint8'); + Add('unsigned int8','cuint8'); + // int16 + Add('int16','cint16'); + Add('unsigned int16','cuint16'); + // int32 + Add('int32','cint32'); + Add('unsigned int32','cuint32'); + // int64 + Add('int64','cint64'); + Add('unsigned int64','cuint64'); + // long + Add('long','clong'); + Add('signed long','cslong'); + Add('unsigned long','culong'); + // long long + Add('long long','clonglong'); + Add('signed long long','cslonglong'); + Add('unsigned long long','culonglong'); + // bool + Add('bool','cbool'); + // char + Add('char','cchar'); + Add('signed char','cschar'); + Add('unsigned char','cuchar'); + // float + Add('float','cfloat'); + // double + Add('double','cdouble'); + Add('long double','clongdouble'); + end; + end; + Result:=InternalPredefinedCTypes; +end; + { TH2PasTool } function TH2PasTool.Convert(CCode, PascalCode: TCodeBuffer): boolean; @@ -129,6 +192,7 @@ var CNode: TCodeTreeNode; VarName: String; VarType: String; + SimpleType: String; begin Tree.Clear; CNode:=CTool.Tree.Root; @@ -138,7 +202,8 @@ begin begin VarName:=CTool.ExtractVariableName(CNode); VarType:=CTool.ExtractVariableType(CNode); - DebugLn(['TH2PasTool.BuildH2PTree Variable Name="',VarName,'" Type="',VarType,'"']); + SimpleType:=GetSimplePascalTypeOfCVar(CNode); + DebugLn(['TH2PasTool.BuildH2PTree Variable Name="',VarName,'" Type="',VarType,'" SimpleType=',SimpleType]); end; end; @@ -146,15 +211,45 @@ begin end; end; -function TH2PasTool.HasCVariableSimplePascalType( - CVarNode: TCodeTreeNode): boolean; +function TH2PasTool.GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string; var - VarType: String; + SimpleType: String; begin - VarType:=CTool.ExtractVariableType(CVarNode); - if VarType='' then - exit(false); - Result:=IsValidIdent(VarType); + Result:=CTool.ExtractVariableType(CVarNode); + if Result='' then exit; + SimpleType:=ConvertSimpleCTypeToPascalType(Result); + if SimpleType<>'' then begin + Result:=SimpleType; + exit; + end; + if not IsValidIdent(Result) then + Result:=''; +end; + +function TH2PasTool.ConvertSimpleCTypeToPascalType(CType: string): string; +// the type must be normalized. That means no directives, +// no unneeded spaces, no tabs, no comments, no newlines. +var + p: Integer; + CurAtomStart: integer; +begin + // remove 'const' + p:=1; + repeat + ReadRawNextCAtom(CType,p,CurAtomStart); + if CurAtomStart>length(CType) then break; + if (p-CurAtomStart=5) + and CompareMem(PChar('const'),@CType[CurAtomStart],5) then begin + // remove 'const' and one space + if (CurAtomStart>1) and (CType[CurAtomStart]=' ') then + dec(CurAtomStart) + else if (p<=length(CType)) and (CType[p]=' ') then + inc(p); + CType:=copy(CType,1,CurAtomStart-1)+copy(CType,p,length(CType)); + p:=CurAtomStart; + end; + until false; + Result:=PredefinedCTypes[CType]; end; procedure TH2PasTool.WriteDebugReport; @@ -166,12 +261,15 @@ end; constructor TH2PasTool.Create; begin + FPredefinedCTypes:=DefaultPredefinedCTypes; Tree:=TH2PTree.Create; end; destructor TH2PasTool.Destroy; begin + FPredefinedCTypes:=nil; Clear; + FreeAndNil(Tree); inherited Destroy; end; @@ -413,5 +511,8 @@ begin ConsistencyCheck; end; +finalization + FreeAndNil(InternalPredefinedCTypes); + end.