codetools: h2p: clean up

git-svn-id: trunk@14645 -
This commit is contained in:
mattias 2008-03-26 09:33:43 +00:00
parent d59f3d0a5e
commit e159c54b13
2 changed files with 416 additions and 303 deletions

View File

@ -1,3 +1,7 @@
// The macro __TEST_H is an example for a common trick in c header files
// Undefine it. The h2p simplifier will remove it.
#undef __TEST_H
/* /*
Comment Comment
*/ */
@ -22,7 +26,7 @@ extern "C" {
#define MPI_FILE_DEFINED #define MPI_FILE_DEFINED
// null pointer // null pointer
#define MPI_BOTTOM (void *)0 #define MPI_BOTTOM (void *)0
/* An anonymous enum */ /* An anonymous enum */
enum { enum {
TEST_ENUM1 = 1, /* Enum starts at 1 */ TEST_ENUM1 = 1, /* Enum starts at 1 */
@ -155,7 +159,6 @@ static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
return memcmp(ba1, ba2, sizeof(bdaddr_t)); return memcmp(ba1, ba2, sizeof(bdaddr_t));
} }
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -160,16 +160,19 @@ type
TH2PasTool = class TH2PasTool = class
private private
FCNames: TAVLTree;// tree of TH2PNode sorted for CName
FCurDirectiveNode: TH2PDirectiveNode;
FCurIndentStr: string;
FCurPasSection: TCodeTreeNodeDesc;
FCurPasStream: TStream;
FDefines: TStringToStringTree; FDefines: TStringToStringTree;
FDisableUnusedDefines: boolean; FDisableUnusedDefines: boolean;
FIgnoreCParts: TIgnoreCSourceParts; FIgnoreCParts: TIgnoreCSourceParts;
FPredefinedCTypes: TStringToStringTree;
FPascalNames: TAVLTree;// tree of TH2PNode sorted for PascalName FPascalNames: TAVLTree;// tree of TH2PNode sorted for PascalName
FCNames: TAVLTree;// tree of TH2PNode sorted for CName FPredefinedCTypes: TStringToStringTree;
FRemoveDisabledDirectives: boolean; FRemoveDisabledDirectives: boolean;
FSimplifyExpressions: boolean; FSimplifyExpressions: boolean;
FSourceName: string; FSourceName: string;
FCurDirectiveNode: TH2PDirectiveNode;
FUndefines: TStringToStringTree; FUndefines: TStringToStringTree;
procedure ConvertStruct(CNode: TCodeTreeNode; ParentNode: TH2PNode); procedure ConvertStruct(CNode: TCodeTreeNode; ParentNode: TH2PNode);
procedure ConvertVariable(CNode: TCodeTreeNode; ParentNode: TH2PNode); procedure ConvertVariable(CNode: TCodeTreeNode; ParentNode: TH2PNode);
@ -182,9 +185,23 @@ type
StartPos, EndPos: integer; out PasExpr: string; StartPos, EndPos: integer; out PasExpr: string;
out ErrorPos: integer; out ErrorMsg: string): boolean; out ErrorPos: integer; out ErrorMsg: string): boolean;
procedure WriteStr(const Line: string; s: TStream); procedure WriteStr(const Line: string);
procedure WriteLnStr(const Line: string; s: TStream); procedure WriteLnStr(const Line: string);
procedure W(const aStr: string);// write indent + aStr + lineend
procedure IncIndent;
procedure DecIndent;
procedure SetPasSection(NewSection: TCodeTreeNodeDesc);
procedure WriteGlobalVarNode(H2PNode: TH2PNode);
procedure WriteGlobalTypeNode(H2PNode: TH2PNode);
procedure WriteGlobalProcedureNode(H2PNode: TH2PNode);
procedure WriteGlobalEnumerationTypeNode(H2PNode: TH2PNode);
procedure WriteGlobalRecordTypeNode(H2PNode: TH2PNode);
procedure WriteDirectiveNode(DirNode: TH2PDirectiveNode);
procedure SimplifyUndefineDirective(Node: TH2PDirectiveNode;
var NextNode: TH2PDirectiveNode);
procedure SimplifyDefineDirective(Node: TH2PDirectiveNode;
var NextNode: TH2PDirectiveNode);
procedure SimplifyIfDirective(Node: TH2PDirectiveNode; const Expression: string; procedure SimplifyIfDirective(Node: TH2PDirectiveNode; const Expression: string;
var NextNode: TH2PDirectiveNode); var NextNode: TH2PDirectiveNode);
public public
@ -239,6 +256,7 @@ type
write FRemoveDisabledDirectives; write FRemoveDisabledDirectives;
property Defines: TStringToStringTree read FDefines; property Defines: TStringToStringTree read FDefines;
property Undefines: TStringToStringTree read FUndefines;// undefines take precedence over defines property Undefines: TStringToStringTree read FUndefines;// undefines take precedence over defines
procedure AddCommonCDefines;
// macros - temporary values - use Defines and Undefines // macros - temporary values - use Defines and Undefines
procedure ResetMacros; procedure ResetMacros;
@ -965,15 +983,352 @@ begin
until false; until false;
end; end;
procedure TH2PasTool.WriteStr(const Line: string; s: TStream); procedure TH2PasTool.WriteStr(const Line: string);
begin begin
if Line='' then exit; if Line='' then exit;
s.Write(Line[1],length(Line)); FCurPasStream.Write(Line[1],length(Line));
end; end;
procedure TH2PasTool.WriteLnStr(const Line: string; s: TStream); procedure TH2PasTool.WriteLnStr(const Line: string);
begin begin
WriteStr(Line+LineEnding,s); WriteStr(Line+LineEnding);
end;
procedure TH2PasTool.W(const aStr: string);
begin
WriteLnStr(FCurIndentStr+aStr);
end;
procedure TH2PasTool.IncIndent;
begin
FCurIndentStr:=FCurIndentStr+' ';
end;
procedure TH2PasTool.DecIndent;
begin
FCurIndentStr:=copy(FCurIndentStr,1,length(FCurIndentStr)-2);
end;
procedure TH2PasTool.SetPasSection(NewSection: TCodeTreeNodeDesc);
begin
if NewSection=FCurPasSection then exit;
// close old section
case FCurPasSection of
ctnVarSection,ctnTypeSection,ctnConstSection:
begin
DecIndent;
end;
end;
FCurPasSection:=NewSection;
// start new section
W('');
case FCurPasSection of
ctnVarSection,ctnTypeSection,ctnConstSection:
begin
case FCurPasSection of
ctnVarSection: W('var');
ctnTypeSection: W('type');
ctnConstSection: W('const');
end;
IncIndent;
end;
end;
end;
procedure TH2PasTool.WriteGlobalVarNode(H2PNode: TH2PNode);
var
PascalCode: String;
begin
// global variable
SetPasSection(ctnVarSection);
PascalCode:=H2PNode.PascalCode+';';
if H2PNode.CName<>'' then begin
PascalCode:=PascalCode+' cvar; public';
if H2PNode.PascalName<>H2PNode.CName then begin
PascalCode:=PascalCode+' name '''+H2PNode.CName+'''';
end;
PascalCode:=PascalCode+';';
end;
W(H2PNode.PascalName+': '+PascalCode);
end;
procedure TH2PasTool.WriteGlobalTypeNode(H2PNode: TH2PNode);
begin
// global type
SetPasSection(ctnTypeSection);
if H2PNode.FirstChild=nil then begin
W(H2PNode.PascalName+' = '+H2PNode.PascalCode+';');
end else begin
DebugLn(['TH2PasTool.WriteGlobalTypeNode SKIPPING ',H2PNode.DescAsString(CTool)]);
end;
end;
procedure TH2PasTool.WriteGlobalProcedureNode(H2PNode: TH2PNode);
var
PascalCode: String;
ChildNode: TH2PNode;
NoNameCount: Integer;
CurName: String;
begin
// global procedure or procedure type
if H2PNode.PascalDesc=ctnProcedure then
SetPasSection(ctnNone)
else
SetPasSection(ctnTypeSection);
// create param list
PascalCode:='';
ChildNode:=TH2PNode(H2PNode.FirstChild);
NoNameCount:=0;
while ChildNode<>nil do begin
if ChildNode.PascalDesc=ctnVarDefinition then begin
if PascalCode<>'' then
PascalCode:=PascalCode+'; ';
CurName:=ChildNode.PascalName;
if CurName='' then begin
inc(NoNameCount);
CurName:='param'+IntToStr(NoNameCount)
+CreatePascalNameFromCCode(ChildNode.PascalCode);
end;
PascalCode:=PascalCode+CurName+': '+ChildNode.PascalCode;
end else begin
DebugLn(['TH2PasTool.WriteGlobalProcedureNode SKIPPING ',ChildNode.DescAsString(CTool)]);
end;
ChildNode:=TH2PNode(ChildNode.NextBrother);
end;
if PascalCode<>'' then
PascalCode:='('+PascalCode+')';
if H2PNode.PascalDesc=ctnProcedure then begin
PascalCode:=H2PNode.PascalName+PascalCode;
if H2PNode.PascalCode='void' then
PascalCode:='procedure '+PascalCode
else
PascalCode:='function '+PascalCode+': '+H2PNode.PascalCode;
PascalCode:=PascalCode+'; cdecl;';
if H2PNode.CName<>'' then begin
if H2PNode.CName<>H2PNode.PascalName then
PascalCode:=PascalCode+' external name '''+H2PNode.CName+''';'
else
PascalCode:=PascalCode+' external;';
end;
end else begin
if H2PNode.PascalCode='void' then
PascalCode:='procedure'+PascalCode
else
PascalCode:='function'+PascalCode+': '+H2PNode.PascalCode;
PascalCode:=PascalCode+'; cdecl;';
PascalCode:=H2PNode.PascalName+' = '+PascalCode;
end;
W(PascalCode);
end;
procedure TH2PasTool.WriteGlobalEnumerationTypeNode(H2PNode: TH2PNode);
var
PascalCode: String;
ChildNode: TH2PNode;
begin
{ for example:
e2 = (
a = 3,
b = 9
);
}
SetPasSection(ctnTypeSection);
// write start
PascalCode:=H2PNode.PascalName+' = (';
W(PascalCode);
// write enums
IncIndent;
ChildNode:=TH2PNode(H2PNode.FirstChild);
while ChildNode<>nil do begin
PascalCode:=ChildNode.PascalName;
if ChildNode.PascalCode<>'' then
PascalCode:=PascalCode+' = '+ChildNode.PascalCode;
if ChildNode.NextBrother<>nil then
PascalCode:=PascalCode+',';
W(PascalCode);
ChildNode:=TH2PNode(ChildNode.NextBrother);
end;
DecIndent;
// write end
W(');');
end;
procedure TH2PasTool.WriteGlobalRecordTypeNode(H2PNode: TH2PNode);
var
PascalCode: String;
ChildNode: TH2PNode;
NoNameCount: Integer;
SubChildNode: TH2PNode;
begin
{ examples:
TRecord = record
end;
}
SetPasSection(ctnTypeSection);
// write header
PascalCode:=H2PNode.PascalName+' = record';
W(PascalCode);
// write sub variables
IncIndent;
ChildNode:=TH2PNode(H2PNode.FirstChild);
while ChildNode<>nil do begin
if ChildNode.PascalDesc=ctnVarDefinition then begin
PascalCode:=ChildNode.PascalName+': '+ChildNode.PascalCode+';';
W(PascalCode);
end else if ChildNode.PascalDesc=ctnRecordCase then begin
{ record
case longint of
0: ( a: b );
2: ( c: d );
end;
}
// write header
PascalCode:=ChildNode.PascalName+': record';
W(PascalCode);
IncIndent;
// write childs
W('case longint of');
IncIndent;
NoNameCount:=0;
SubChildNode:=TH2PNode(ChildNode.FirstChild);
while SubChildNode<>nil do begin
PascalCode:=IntToStr(NoNameCount)+': ('
+SubChildNode.PascalName+': '+SubChildNode.PascalCode+' );';
W(PascalCode);
SubChildNode:=TH2PNode(SubChildNode.NextBrother);
inc(NoNameCount);
end;
DecIndent;
// write footer
W('end;');
DecIndent;
end else
DebugLn(['TH2PasTool.WriteGlobalRecordTypeNode SKIPPING record sub ',ChildNode.DescAsString(CTool)]);
ChildNode:=TH2PNode(ChildNode.NextBrother);
end;
DecIndent;
// write end
W('end;');
end;
procedure TH2PasTool.WriteDirectiveNode(DirNode: TH2PDirectiveNode);
begin
case DirNode.Desc of
h2pdnIfDef:
begin
SetPasSection(ctnNone);
W('{$IfDef '+DirNode.MacroName+'}');
IncIndent;
end;
h2pdnIfNDef:
begin
SetPasSection(ctnNone);
W('{$IfNDef '+DirNode.MacroName+'}');
IncIndent;
end;
h2pdnIf:
begin
SetPasSection(ctnNone);
W('{$If '+DirNode.Expression+'}');
IncIndent;
end;
h2pdnElseIf:
begin
SetPasSection(ctnNone);
DecIndent;
W('{$ElseIf '+DirNode.Expression+'}');
IncIndent;
end;
h2pdnElse:
begin
SetPasSection(ctnNone);
DecIndent;
W('{$Else}');
IncIndent;
end;
h2pdnEndIf:
begin
SetPasSection(ctnNone);
DecIndent;
W('{$EndIf}');
end;
h2pdnError:
begin
SetPasSection(ctnNone);
W('{$Error '+dbgstr(DirNode.Expression)+'}');
end;
h2pdnUndefine:
begin
SetPasSection(ctnNone);
W('{$UnDef '+DirNode.MacroName+'}');
end;
h2pdnDefine:
if (DirNode.MacroParams='') then begin
SetPasSection(ctnNone);
if DirNode.Expression='' then begin
W('{$Define '+DirNode.MacroName+'}');
end else begin
W('{$Define '+DirNode.MacroName+':='+dbgstr(DirNode.Expression)+'}');
end;
end else begin
DebugLn(['TH2PasTool.WriteDirectiveNode SKIPPING ',DirNode.DescAsString(CTool)]);
end;
else
DebugLn(['TH2PasTool.WriteDirectiveNode SKIPPING ',DirNode.DescAsString(CTool)]);
end;
end;
procedure TH2PasTool.SimplifyUndefineDirective(Node: TH2PDirectiveNode;
var NextNode: TH2PDirectiveNode);
begin
UndefineMacro(Node.MacroName);
end;
procedure TH2PasTool.SimplifyDefineDirective(Node: TH2PDirectiveNode;
var NextNode: TH2PDirectiveNode);
{ Examples:
Macro flag:
#define MPI_FILE_DEFINED
=> $Define MPI_FILE_DEFINED
Simple constant:
#define SOME_FLAG1 31
=> const SOME_FLAG1 = 31;
null pointer
#define MPI_BOTTOM (void *)0
=> const MPI_BOTTOM = nil;
Alias:
#define SOME_FLAG2 SOME_FLAG1
=> const SOME_FLAG2 = SOME_FLAG1;
OR type SOME_FLAG2 = SOME_FLAG1;
Dummy function:
#define htobs(d) (d)
=> comment
Function alias:
#define htobs(d) bswap_16(d)
=> comment
Function without parameters:
#define HIDPCONNADD _IOW('H', 200, int)
=> comment
}
begin
if Node.MacroParams='' then begin
// a macro without parameters
if Node.Expression='' then begin
// example: #define MPI_FILE_DEFINED
DefineMacro(Node.MacroName,'');
end else begin
end;
end else begin
end;
end; end;
procedure TH2PasTool.SimplifyIfDirective(Node: TH2PDirectiveNode; procedure TH2PasTool.SimplifyIfDirective(Node: TH2PDirectiveNode;
@ -1085,25 +1440,29 @@ procedure TH2PasTool.SimplifyDirectives;
var var
Node: TH2PDirectiveNode; Node: TH2PDirectiveNode;
NextNode: TH2PDirectiveNode; NextNode: TH2PDirectiveNode;
Changed: Boolean;
begin begin
InitMacros; repeat
Node:=TH2PDirectiveNode(DirectivesTree.Root); Changed:=false;
while Node<>nil do begin InitMacros;
NextNode:=TH2PDirectiveNode(Node.Next); Node:=TH2PDirectiveNode(DirectivesTree.Root);
case Node.Desc of while Node<>nil do begin
h2pdnDefine: NextNode:=TH2PDirectiveNode(Node.Next);
begin case Node.Desc of
DefineMacro(Node.MacroName,Node.Expression); h2pdnUndefine:
SimplifyUndefineDirective(Node,NextNode);
h2pdnDefine:
SimplifyDefineDirective(Node,NextNode);
h2pdnIfDef:
SimplifyIfDirective(Node,'defined('+Node.MacroName+')',NextNode);
h2pdnIfNDef:
SimplifyIfDirective(Node,'not defined('+Node.MacroName+')',NextNode);
h2pdnIf:
SimplifyIfDirective(Node,Node.Expression,NextNode);
end; end;
h2pdnIfDef: Node:=NextNode;
SimplifyIfDirective(Node,'defined('+Node.MacroName+')',NextNode);
h2pdnIfNDef:
SimplifyIfDirective(Node,'not defined('+Node.MacroName+')',NextNode);
h2pdnIf:
SimplifyIfDirective(Node,Node.Expression,NextNode);
end; end;
Node:=NextNode; until not Changed;
end;
end; end;
procedure TH2PasTool.WritePascal(PascalCode: TCodeBuffer); procedure TH2PasTool.WritePascal(PascalCode: TCodeBuffer);
@ -1127,63 +1486,14 @@ begin
end; end;
procedure TH2PasTool.WritePascalToStream(s: TStream); procedure TH2PasTool.WritePascalToStream(s: TStream);
var
IndentStr: string;
CurSection: TCodeTreeNodeDesc;
procedure W(const aStr: string);
begin
WriteLnStr(IndentStr+aStr,s);
end;
procedure IncIndent;
begin
IndentStr:=IndentStr+' ';
end;
procedure DecIndent;
begin
IndentStr:=copy(IndentStr,1,length(IndentStr)-2);
end;
procedure SetSection(NewSection: TCodeTreeNodeDesc);
begin
if NewSection=CurSection then exit;
// close old section
case CurSection of
ctnVarSection,ctnTypeSection,ctnConstSection:
begin
DecIndent;
end;
end;
CurSection:=NewSection;
// start new section
W('');
case CurSection of
ctnVarSection,ctnTypeSection,ctnConstSection:
begin
case CurSection of
ctnVarSection: W('var');
ctnTypeSection: W('type');
ctnConstSection: W('const');
end;
IncIndent;
end;
end;
end;
var var
H2PNode: TH2PNode; H2PNode: TH2PNode;
UsesClause: String; UsesClause: String;
PascalCode: String;
ChildNode: TH2PNode;
CurName: String;
NoNameCount: Integer;
SubChildNode: TH2PNode;
DirNode: TH2PDirectiveNode;
begin begin
IndentStr:=''; FCurIndentStr:='';
FCurPasSection:=ctnNone;
FCurPasStream:=s;
// write header // write header
if SourceName<>'' then begin if SourceName<>'' then begin
W('unit '+SourceName+';'); W('unit '+SourceName+';');
@ -1205,238 +1515,28 @@ begin
end; end;
// write interface nodes // write interface nodes
CurSection:=ctnNone;
H2PNode:=TH2PNode(Tree.Root); H2PNode:=TH2PNode(Tree.Root);
while H2PNode<>nil do begin while H2PNode<>nil do begin
case H2PNode.PascalDesc of case H2PNode.PascalDesc of
ctnVarDefinition: ctnVarDefinition:
begin WriteGlobalVarNode(H2PNode);
// global variable
SetSection(ctnVarSection);
PascalCode:=H2PNode.PascalCode+';';
if H2PNode.CName<>'' then begin
PascalCode:=PascalCode+' cvar; public';
if H2PNode.PascalName<>H2PNode.CName then begin
PascalCode:=PascalCode+' name '''+H2PNode.CName+'''';
end;
PascalCode:=PascalCode+';';
end;
W(H2PNode.PascalName+': '+PascalCode);
end;
ctnTypeDefinition: ctnTypeDefinition:
begin WriteGlobalTypeNode(H2PNode);
// global variable
SetSection(ctnTypeSection);
if H2PNode.FirstChild=nil then begin
PascalCode:=H2PNode.PascalCode+';';
W(H2PNode.PascalName+' = '+PascalCode);
end else
DebugLn(['TH2PasTool.WritePascalToStream SKIPPING ',H2PNode.DescAsString(CTool)]);
end;
ctnProcedure, ctnProcedureType: ctnProcedure, ctnProcedureType:
begin WriteGlobalProcedureNode(H2PNode);
// global procedure or procedure type
if H2PNode.PascalDesc=ctnProcedure then
SetSection(ctnNone)
else
SetSection(ctnTypeSection);
// create param list
PascalCode:='';
ChildNode:=TH2PNode(H2PNode.FirstChild);
NoNameCount:=0;
while ChildNode<>nil do begin
if ChildNode.PascalDesc=ctnVarDefinition then begin
if PascalCode<>'' then
PascalCode:=PascalCode+'; ';
CurName:=ChildNode.PascalName;
if CurName='' then begin
inc(NoNameCount);
CurName:='param'+IntToStr(NoNameCount)
+CreatePascalNameFromCCode(ChildNode.PascalCode);
end;
PascalCode:=PascalCode+CurName+': '+ChildNode.PascalCode;
end else begin
DebugLn(['TH2PasTool.WritePascalToStream SKIPPING ',ChildNode.DescAsString(CTool)]);
end;
ChildNode:=TH2PNode(ChildNode.NextBrother);
end;
if PascalCode<>'' then
PascalCode:='('+PascalCode+')';
if H2PNode.PascalDesc=ctnProcedure then begin
PascalCode:=H2PNode.PascalName+PascalCode;
if H2PNode.PascalCode='void' then
PascalCode:='procedure '+PascalCode
else
PascalCode:='function '+PascalCode+': '+H2PNode.PascalCode;
PascalCode:=PascalCode+'; cdecl;';
if H2PNode.CName<>'' then begin
if H2PNode.CName<>H2PNode.PascalName then
PascalCode:=PascalCode+' external name '''+H2PNode.CName+''';'
else
PascalCode:=PascalCode+' external;';
end;
end else begin
if H2PNode.PascalCode='void' then
PascalCode:='procedure'+PascalCode
else
PascalCode:='function'+PascalCode+': '+H2PNode.PascalCode;
PascalCode:=PascalCode+'; cdecl;';
PascalCode:=H2PNode.PascalName+' = '+PascalCode;
end;
W(PascalCode);
end;
ctnEnumerationType: ctnEnumerationType:
begin WriteGlobalEnumerationTypeNode(H2PNode);
{ for example:
e2 = (
a = 3,
b = 9
);
}
SetSection(ctnTypeSection);
// write start
PascalCode:=H2PNode.PascalName+' = (';
W(PascalCode);
// write enums
IncIndent;
ChildNode:=TH2PNode(H2PNode.FirstChild);
while ChildNode<>nil do begin
PascalCode:=ChildNode.PascalName;
if ChildNode.PascalCode<>'' then
PascalCode:=PascalCode+' = '+ChildNode.PascalCode;
if ChildNode.NextBrother<>nil then
PascalCode:=PascalCode+',';
W(PascalCode);
ChildNode:=TH2PNode(ChildNode.NextBrother);
end;
DecIndent;
// write end
W(');');
end;
ctnRecordType: ctnRecordType:
begin WriteGlobalRecordTypeNode(H2PNode);
{ examples:
TRecord = record
end;
}
SetSection(ctnTypeSection);
// write header
PascalCode:=H2PNode.PascalName+' = record';
W(PascalCode);
// write sub variables
IncIndent;
ChildNode:=TH2PNode(H2PNode.FirstChild);
while ChildNode<>nil do begin
if ChildNode.PascalDesc=ctnVarDefinition then begin
PascalCode:=ChildNode.PascalName+': '+ChildNode.PascalCode+';';
W(PascalCode);
end else if ChildNode.PascalDesc=ctnRecordCase then begin
{ record
case longint of
0: ( a: b );
2: ( c: d );
end;
}
// write header
PascalCode:=ChildNode.PascalName+': record';
W(PascalCode);
IncIndent;
// write childs
W('case longint of');
IncIndent;
NoNameCount:=0;
SubChildNode:=TH2PNode(ChildNode.FirstChild);
while SubChildNode<>nil do begin
PascalCode:=IntToStr(NoNameCount)+': ('
+SubChildNode.PascalName+': '+SubChildNode.PascalCode+' );';
W(PascalCode);
SubChildNode:=TH2PNode(SubChildNode.NextBrother);
inc(NoNameCount);
end;
DecIndent;
// write footer
W('end;');
DecIndent;
end else
DebugLn(['TH2PasTool.WritePascalToStream SKIPPING record sub ',ChildNode.DescAsString(CTool)]);
ChildNode:=TH2PNode(ChildNode.NextBrother);
end;
DecIndent;
// write end
W('end;');
end;
ctnNone: ctnNone:
if H2PNode.Directive<>nil then begin if H2PNode.Directive<>nil then begin
DirNode:=H2PNode.Directive; WriteDirectiveNode(H2PNode.Directive);
case DirNode.Desc of
h2pdnIfDef:
begin
SetSection(ctnNone);
W('{$IfDef '+DirNode.MacroName+'}');
IncIndent;
end;
h2pdnIfNDef:
begin
SetSection(ctnNone);
W('{$IfNDef '+DirNode.MacroName+'}');
IncIndent;
end;
h2pdnIf:
begin
SetSection(ctnNone);
W('{$If '+DirNode.Expression+'}');
IncIndent;
end;
h2pdnElseIf:
begin
SetSection(ctnNone);
DecIndent;
W('{$ElseIf '+DirNode.Expression+'}');
IncIndent;
end;
h2pdnElse:
begin
SetSection(ctnNone);
DecIndent;
W('{$Else}');
IncIndent;
end;
h2pdnEndIf:
begin
SetSection(ctnNone);
DecIndent;
W('{$EndIf}');
end;
h2pdnError:
begin
SetSection(ctnNone);
W('{$Error '+dbgstr(DirNode.Expression)+'}');
end;
h2pdnUndefine:
begin
SetSection(ctnNone);
W('{$UnDef '+DirNode.MacroName+'}');
end;
h2pdnDefine:
if (DirNode.MacroParams='') then begin
SetSection(ctnNone);
if DirNode.Expression='' then begin
W('{$Define '+DirNode.MacroName+'}');
end else begin
W('{$Define '+DirNode.MacroName+':='+dbgstr(DirNode.Expression)+'}');
end;
end else begin
DebugLn(['TH2PasTool.WritePascalToStream SKIPPING ',DirNode.DescAsString(CTool)]);
end;
else
DebugLn(['TH2PasTool.WritePascalToStream SKIPPING ',DirNode.DescAsString(CTool)]);
end;
end else end else
DebugLn(['TH2PasTool.WritePascalToStream SKIPPING ',H2PNode.DescAsString(CTool)]); DebugLn(['TH2PasTool.WritePascalToStream SKIPPING ',H2PNode.DescAsString(CTool)]);
@ -1447,12 +1547,15 @@ begin
end; end;
// write implementation // write implementation
SetSection(ctnNone); SetPasSection(ctnNone);
W('implementation'); W('implementation');
W(''); W('');
// write end. // write end.
W('end.'); W('end.');
FCurPasStream:=nil;
FCurIndentStr:='';
end; end;
function TH2PasTool.GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string; function TH2PasTool.GetSimplePascalTypeOfCVar(CVarNode: TCodeTreeNode): string;
@ -1858,6 +1961,7 @@ begin
FIgnoreCParts:=[icspInclude]; FIgnoreCParts:=[icspInclude];
FDefines:=TStringToStringTree.Create(true); FDefines:=TStringToStringTree.Create(true);
FUndefines:=TStringToStringTree.Create(true); FUndefines:=TStringToStringTree.Create(true);
AddCommonCDefines;
end; end;
destructor TH2PasTool.Destroy; destructor TH2PasTool.Destroy;
@ -1883,6 +1987,12 @@ begin
ClearMacros; ClearMacros;
FDefines.Clear; FDefines.Clear;
FUndefines.Clear; FUndefines.Clear;
AddCommonCDefines;
end;
procedure TH2PasTool.AddCommonCDefines;
begin
Undefines['__cplusplus']:='1';
end; end;
procedure TH2PasTool.ResetMacros; procedure TH2PasTool.ResetMacros;