codetools: h2p: added trees for pascal and c names

git-svn-id: trunk@14551 -
This commit is contained in:
mattias 2008-03-17 10:58:20 +00:00
parent d2aed0e2c3
commit db1b64812b
3 changed files with 88 additions and 24 deletions

View File

@ -138,7 +138,7 @@ function CompareSubStrings(const Find, Txt: string;
FindStartPos, TxtStartPos, Len: integer; CaseSensitive: boolean): integer; FindStartPos, TxtStartPos, Len: integer; CaseSensitive: boolean): integer;
function CompareIdentifiers(Identifier1, Identifier2: PChar): integer; function CompareIdentifiers(Identifier1, Identifier2: PChar): integer;
function CompareIdentifiersCaseSensitive(Identifier1, Identifier2: PChar): integer; function CompareIdentifiersCaseSensitive(Identifier1, Identifier2: PChar): integer;
function CompareIdentifierPtrs(Identifier1, Identifier2: Pointer): integer; function CompareIdentifierPtrs(Identifier1, Identifier2: Pointer): integer; {$IFDEF HasInline}inline;{$ENDIF}
function ComparePrefixIdent(PrefixIdent, Identifier: PChar): boolean; function ComparePrefixIdent(PrefixIdent, Identifier: PChar): boolean;
function TextBeginsWith(Txt: PChar; TxtLen: integer; StartTxt: PChar; function TextBeginsWith(Txt: PChar; TxtLen: integer; StartTxt: PChar;
StartTxtLen: integer; CaseSensitive: boolean): boolean; StartTxtLen: integer; CaseSensitive: boolean): boolean;

View File

@ -604,6 +604,7 @@ begin
MainNode:=CurNode; MainNode:=CurNode;
IsFunction:=false; IsFunction:=false;
if AtomIs('struct') then begin if AtomIs('struct') then begin
// for example: struct structname varname
ReadNextAtom; ReadNextAtom;
end else if AtomIs('union') then begin end else if AtomIs('union') then begin
ReadNextAtom; ReadNextAtom;

View File

@ -40,9 +40,9 @@ unit H2PasTool;
interface interface
uses uses
Classes, SysUtils, contnrs, Classes, SysUtils, contnrs, AVL_Tree,
FileProcs, BasicCodeTools, CCodeParserTool, NonPascalCodeTools, FileProcs, BasicCodeTools, CCodeParserTool, NonPascalCodeTools,
CodeCache, CodeTree, CodeAtom; KeywordFuncLists, CodeCache, CodeTree, CodeAtom;
type type
@ -50,11 +50,12 @@ type
TH2PNode = class TH2PNode = class
public public
Name: string; PascalName: string;
CName: string;
CNode: TCodeTreeNode; CNode: TCodeTreeNode;
PascalDesc: TCodeTreeNodeDesc; PascalDesc: TCodeTreeNodeDesc;
Code: string; PascalCode: string;
NormalizedCode: string; NormalizedPascalCode: string;
Parent, FirstChild, LastChild, NextBrother, PriorBrother: TH2PNode; Parent, FirstChild, LastChild, NextBrother, PriorBrother: TH2PNode;
function Next: TH2PNode; function Next: TH2PNode;
function NextSkipChilds: TH2PNode; function NextSkipChilds: TH2PNode;
@ -74,6 +75,7 @@ type
FNodeCount: integer; FNodeCount: integer;
public public
Root: TH2PNode; Root: TH2PNode;
LastRoot: TH2PNode;
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
procedure Clear; procedure Clear;
@ -91,6 +93,8 @@ type
TH2PasTool = class TH2PasTool = class
private private
FPredefinedCTypes: TFPStringHashTable; FPredefinedCTypes: TFPStringHashTable;
FPascalNames: TAVLTree;// tree of TH2PNode sorted for PascalName
FCNames: TAVLTree;// tree of TH2PNode sorted for CName
public public
Tree: TH2PTree; Tree: TH2PTree;
CTool: TCCodeParserTool; CTool: TCCodeParserTool;
@ -101,6 +105,10 @@ type
function GetSimplePascalResultTypeOfCFunction(CFuncNode: TCodeTreeNode): string; function GetSimplePascalResultTypeOfCFunction(CFuncNode: TCodeTreeNode): string;
function ConvertSimpleCTypeToPascalType(CType: string): string; function ConvertSimpleCTypeToPascalType(CType: string): string;
function CreateH2PNode(const PascalName: string; CNode: TCodeTreeNode;
PascalDesc: TCodeTreeNodeDesc; ParentNode: TH2PNode = nil;
IsGlobal: boolean = true): TH2PNode;
procedure WriteDebugReport; procedure WriteDebugReport;
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
@ -111,6 +119,9 @@ type
function DefaultPredefinedCTypes: TFPStringHashTable;// types in unit ctypes function DefaultPredefinedCTypes: TFPStringHashTable;// types in unit ctypes
function CompareH2PNodePascalNames(Data1, Data2: Pointer): integer;
function CompareH2PNodeCNames(Data1, Data2: Pointer): integer;
implementation implementation
var var
@ -210,6 +221,18 @@ begin
Result:=InternalPredefinedCTypes; Result:=InternalPredefinedCTypes;
end; end;
function CompareH2PNodePascalNames(Data1, Data2: Pointer): integer;
begin
Result:=CompareIdentifierPtrs(Pointer(TH2PNode(Data1).PascalName),
Pointer(TH2PNode(Data2).PascalName));
end;
function CompareH2PNodeCNames(Data1, Data2: Pointer): integer;
begin
Result:=CompareIdentifiersCaseSensitive(PChar(Pointer(TH2PNode(Data1).CName)),
PChar(Pointer(TH2PNode(Data2).CName)));
end;
{ TH2PasTool } { TH2PasTool }
function TH2PasTool.Convert(CCode, PascalCode: TCodeBuffer): boolean; function TH2PasTool.Convert(CCode, PascalCode: TCodeBuffer): boolean;
@ -249,6 +272,9 @@ begin
DebugLn(['TH2PasTool.BuildH2PTree Variable Name="',CurName,'" Type="',CurType,'" SimpleType=',SimpleType]); DebugLn(['TH2PasTool.BuildH2PTree Variable Name="',CurName,'" Type="',CurType,'" SimpleType=',SimpleType]);
if SimpleType='' then begin if SimpleType='' then begin
// this variable has a complex type // this variable has a complex type
//SimpleType:=CreateTypeForVarType(CNode);
end;
if SimpleType<>'' then begin
end; end;
end; end;
@ -315,28 +341,56 @@ function TH2PasTool.ConvertSimpleCTypeToPascalType(CType: string): string;
var var
p: Integer; p: Integer;
CurAtomStart: integer; CurAtomStart: integer;
function TestIsAtomAndRemove(const s: shortstring): boolean;
begin
if (p-CurAtomStart<>length(s))
or (not CompareMem(@s[1],@CType[CurAtomStart],length(s))) then
exit(false);
Result:=true;
// remove token
if IsIdentStartChar[s[1]] then begin
// token is a word => remove one space too
if (CurAtomStart>1) and (CType[CurAtomStart-1]=' ') then
dec(CurAtomStart)
else if (p<=length(CType)) and (CType[p]=' ') then
inc(p);
end;
// remove token
CType:=copy(CType,1,CurAtomStart-1)+copy(CType,p,length(CType));
p:=CurAtomStart;
//DebugLn(['TH2PasTool.ConvertSimpleCTypeToPascalType CType="',CType,'"']);
end;
begin begin
// remove 'const' // remove 'const' and 'struct'
p:=1; p:=1;
repeat repeat
ReadRawNextCAtom(CType,p,CurAtomStart); ReadRawNextCAtom(CType,p,CurAtomStart);
if CurAtomStart>length(CType) then break; if CurAtomStart>length(CType) then break;
//DebugLn(['TH2PasTool.ConvertSimpleCTypeToPascalType Atom=',copy(CType,CurAtomStart,p-CurAtomStart)]); //DebugLn(['TH2PasTool.ConvertSimpleCTypeToPascalType Atom=',copy(CType,CurAtomStart,p-CurAtomStart)]);
if (p-CurAtomStart=5) if (not TestIsAtomAndRemove('const'))
and CompareMem(PChar('const'),@CType[CurAtomStart],5) then begin and (not TestIsAtomAndRemove('struct')) then ;
// remove 'const' and one space
if (CurAtomStart>1) and (CType[CurAtomStart-1]=' ') 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;
//DebugLn(['TH2PasTool.ConvertSimpleCTypeToPascalType CType="',CType,'"']);
end;
until false; until false;
// seach in predefined ctypes
Result:=PredefinedCTypes[CType]; Result:=PredefinedCTypes[CType];
end; end;
function TH2PasTool.CreateH2PNode(const PascalName: string;
CNode: TCodeTreeNode; PascalDesc: TCodeTreeNodeDesc; ParentNode: TH2PNode;
IsGlobal: boolean): TH2PNode;
begin
Result:=TH2PNode.Create;
Result.PascalName:=PascalName;
Result.CNode:=CNode;
Result.PascalDesc:=PascalDesc;
Tree.AddNodeAsLastChild(ParentNode,Result);
if IsGlobal then begin
FPascalNames.Add(Result);
FCNames.Add(Result);
end;
end;
procedure TH2PasTool.WriteDebugReport; procedure TH2PasTool.WriteDebugReport;
begin begin
DebugLn(['TH2PasTool.WriteDebugReport ']); DebugLn(['TH2PasTool.WriteDebugReport ']);
@ -348,6 +402,8 @@ constructor TH2PasTool.Create;
begin begin
FPredefinedCTypes:=DefaultPredefinedCTypes; FPredefinedCTypes:=DefaultPredefinedCTypes;
Tree:=TH2PTree.Create; Tree:=TH2PTree.Create;
FPascalNames:=TAVLTree.Create(@CompareH2PNodePascalNames);
FCNames:=TAVLTree.Create(@CompareH2PNodeCNames);
end; end;
destructor TH2PasTool.Destroy; destructor TH2PasTool.Destroy;
@ -355,11 +411,15 @@ begin
FPredefinedCTypes:=nil; FPredefinedCTypes:=nil;
Clear; Clear;
FreeAndNil(Tree); FreeAndNil(Tree);
FreeAndNil(FPascalNames);
FreeAndNil(FCNames);
inherited Destroy; inherited Destroy;
end; end;
procedure TH2PasTool.Clear; procedure TH2PasTool.Clear;
begin begin
FPascalNames.Clear;
FCNames.Clear;
Tree.Clear; Tree.Clear;
end; end;
@ -430,7 +490,7 @@ end;
function TH2PNode.DescAsString: string; function TH2PNode.DescAsString: string;
begin begin
Result:='Name="'+Name+'"'; Result:='PascalName="'+PascalName+'"';
Result:=Result+' PascalDesc='+NodeDescriptionAsString(PascalDesc); Result:=Result+' PascalDesc='+NodeDescriptionAsString(PascalDesc);
if CNode<>nil then begin if CNode<>nil then begin
Result:=Result+' CNode='+CNode.DescAsString; Result:=Result+' CNode='+CNode.DescAsString;
@ -518,13 +578,15 @@ begin
end; end;
procedure TH2PTree.AddNodeAsLastChild(ParentNode, ANode: TH2PNode); procedure TH2PTree.AddNodeAsLastChild(ParentNode, ANode: TH2PNode);
var TopNode: TH2PNode;
begin begin
ANode.Parent:=ParentNode; ANode.Parent:=ParentNode;
if Root=nil then begin if Root=nil then begin
// set as root // set as root
Root:=ANode; Root:=ANode;
while Root.Parent<>nil do Root:=Root.Parent; while Root.Parent<>nil do Root:=Root.Parent;
LastRoot:=Root;
while LastRoot.NextBrother<>nil do
LastRoot:=LastRoot.NextBrother;
end else if ParentNode<>nil then begin end else if ParentNode<>nil then begin
if ParentNode.FirstChild=nil then begin if ParentNode.FirstChild=nil then begin
// add as first child // add as first child
@ -538,10 +600,11 @@ begin
end; end;
end else begin end else begin
// add as last brother of top nodes // add as last brother of top nodes
TopNode:=Root; while (LastRoot.NextBrother<>nil) do LastRoot:=LastRoot.NextBrother;
while (TopNode.NextBrother<>nil) do TopNode:=TopNode.NextBrother; ANode.PriorBrother:=LastRoot;
ANode.PriorBrother:=TopNode;
ANode.PriorBrother.NextBrother:=ANode; ANode.PriorBrother.NextBrother:=ANode;
LastRoot:=ANode;
while (LastRoot.NextBrother<>nil) do LastRoot:=LastRoot.NextBrother;
end; end;
inc(FNodeCount); inc(FNodeCount);
end; end;