unit HeaderGenerator; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DOM, fgl, variants; type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// THeaderGenerator = class(TObject) private type TvkObjectType = ( otUnknown, otType, otHandle, otFuncPtr, otStruct, otEnum, otCommand); TvkObjectTypes = set of TvkObjectType; TvkObject = class; TvkObjectList = class(specialize TFPGObjectList) public function FindObj(const aName: DOMstring; const aTypes: TvkObjectTypes; out aObject): Boolean; procedure MarkObj(const aName: DOMstring; const aTypes: TvkObjectTypes; const aMark: Integer); end; //////////////////////////////////////////////////////////////////////////////////////////// TvkObject = class(TObject) private fType: TvkObjectType; fMark: Integer; fName: DOMString; fComment: DOMString; fList: TvkObjectList; private procedure SetMark(aValue: Integer); protected procedure DoMark(const aMark: Integer); virtual; public property Mark: Integer read fMark write SetMark; property Name: DOMString read fName write fName; property Comment: DOMString read fComment write fComment; property VkType: TvkObjectType read fType; property List: TvkObjectList read fList write fList; procedure AddCommentFromXml(xml: TDOMNode); constructor Create(const aType: TvkObjectType); public class function CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkObject; end; //////////////////////////////////////////////////////////////////////////////////////////// TvkTypeSimple = class(TvkObject) private fParent: DOMString; protected procedure DoMark(const aMark: Integer); override; public property Parent: DOMString read fParent write fParent; public class function CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeSimple; end; //////////////////////////////////////////////////////////////////////////////////////////// TvkTypeHandle = class(TvkTypeSimple) private fNonDispatchable: Boolean; public property NonDispatchable: Boolean read fNonDispatchable write fNonDispatchable; public class function CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeHandle; end; //////////////////////////////////////////////////////////////////////////////////////////// TvkTypeFunction = class(TvkObject) private type TArgument = class(TObject) Typ: DOMString; Name: DOMString; IsPointer: Boolean; IsConst: Boolean; end; TArgumentList = specialize TFPGObjectList; private fReturnValue: TArgument; fArguments: TArgumentList; protected procedure DoMark(const aMark: Integer); override; public property ReturnValue: TArgument read fReturnValue; property Arguments: TArgumentList read fArguments; constructor Create(const aType: TvkObjectType); destructor Destroy; override; end; //////////////////////////////////////////////////////////////////////////////////////////// TvkTypeFunctionPtr = class(TvkTypeFunction) public class function CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeFunctionPtr; end; //////////////////////////////////////////////////////////////////////////////////////////// TvkCommand = class(TvkTypeFunction) public class function CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkCommand; end; //////////////////////////////////////////////////////////////////////////////////////////// TvkTypeStruct = class(TvkObject) private type TMember = class(TObject) Typ: DOMString; Name: DOMString; ArrSize: Integer; IsPointer: Boolean; IsConst: Boolean; end; TMemberList = specialize TFPGObjectList; private fIsUnion: Boolean; fMember: TMemberList; protected procedure DoMark(const aMark: Integer); override; public property Member: TMemberList read fMember; property IsUnion: Boolean read fIsUnion write fIsUnion; constructor Create(const aType: TvkObjectType); destructor Destroy; override; public class function CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeStruct; end; //////////////////////////////////////////////////////////////////////////////////////////// TvkTypeEnum = class(TvkObject) private type TValue = class(TObject) Name: DOMString; Value: Variant; IsBit: Boolean; end; TValueList = specialize TFPGObjectList; private fValues: TValueList; public property Values: TValueList read fValues; constructor Create(const aType: TvkObjectType); destructor Destroy; override; public class function CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeEnum; end; private const VK_OBJECT_TYPES: TvkObjectTypes = [ otType, otHandle, otFuncPtr, otStruct, otEnum ]; private fDocument: TXMLDocument; fComment: DOMString; fObjects: TvkObjectList; public procedure ReadFile(const aFilename: String); procedure ReadFile(const aStream: TStream); procedure Clear; constructor Create; destructor Destroy; override; end; implementation uses XMLRead, RegExpr; type XmlException = class(Exception) public xml: TDOMNode; constructor Create(const aMsg: WideString; const aXml: TDOMNode); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function FormatType(const aType: THeaderGenerator.TvkObjectType): WideString; begin case aType of otType: result := 'TYPE'; otHandle: result := 'HANDLE'; otFuncPtr: result := 'FUNCPTR'; otStruct: result := 'STRUCT'; otEnum: result := 'ENUM'; otCommand: result := 'COMMAND'; else result := ''; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure WriteResolveWarning(const aName: DOMString); begin WriteLn('WARNING! unable to resolve identifier: ' + aName); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function GetNodeValue(xml: TDOMNode; const aName: WideString): DOMString; var x: TDOMNode; begin x := xml.FindNode(aName); if not Assigned(x) then raise XmlException.Create(xml.NodeName + ' witout child ''' + aName + '''', xml); result := x.TextContent; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function GetNodeValue(xml: TDOMNode; const aName: WideString; const aDefault: DOMString): DOMString; var x: TDOMNode; begin x := xml.FindNode(aName); if not Assigned(x) then result := aDefault else result := x.TextContent; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function GetNodeAttrib(xml: TDOMNode; const aName: WideString): DOMString; var x: TDOMNode; begin if xml.HasAttributes then begin x := xml.Attributes.GetNamedItem(aName); if Assigned(x) then begin result := x.TextContent; exit; end; end; raise XmlException.Create(xml.NodeName + ' without ''' + aName + ''' attribute', xml); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function GetNodeAttrib(xml: TDOMNode; const aName: WideString; const aDefault: DOMString): DOMString; var x: TDOMNode; begin result := aDefault; if xml.HasAttributes then begin x := xml.Attributes.GetNamedItem(aName); if Assigned(x) then result := x.TextContent; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //XmlException////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor XmlException.Create(const aMsg: WideString; const aXml: TDOMNode); begin inherited Create(String(aMsg + ': ' + aXml.TextContent)); xml := aXml; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkObjectList//////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function THeaderGenerator.TvkObjectList.FindObj(const aName: DOMstring; const aTypes: TvkObjectTypes; out aObject): Boolean; var o: TvkObject; begin if (aName = '') then raise Exception.Create('empty name'); result := true; TvkObject(aObject) := nil; for o in self do begin if (o.VkType in aTypes) and (o.Name = aName) then begin TvkObject(aObject) := o; exit; end; end; result := false; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.TvkObjectList.MarkObj(const aName: DOMstring; const aTypes: TvkObjectTypes; const aMark: Integer); var o: TvkObject; begin if FindObj(aName, aTypes, o) then o.Mark := aMark else WriteResolveWarning(aName); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkObject//////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.TvkObject.SetMark(aValue: Integer); begin if (fMark <> 0) then exit; fMark := aValue; DoMark(fMark); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.TvkObject.DoMark(const aMark: Integer); begin WriteLn(Format(' %-10s%-50s marked for generation', [FormatType(fType), fName])); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.TvkObject.AddCommentFromXml(xml: TDOMNode); begin xml := xml.FindNode('comment'); if Assigned(xml) then fComment := xml.TextContent; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor THeaderGenerator.TvkObject.Create(const aType: TvkObjectType); begin inherited Create; fType := aType; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function THeaderGenerator.TvkObject.CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkObject; var s: DOMString; x: TDOMNode; begin result := nil; if (xml.NodeName = 'type') and xml.HasAttributes then begin x := xml.Attributes.GetNamedItem('category'); if not Assigned(x) then exit; s := x.TextContent; if (s = 'basetype') or (s = 'bitmask') then result := TvkTypeSimple.CreateFromXml(xml) else if (s = 'handle') then result := TvkTypeHandle.CreateFromXml(xml) else if (s = 'funcpointer') then result := TvkTypeFunctionPtr.CreateFromXml(xml) else if (s = 'struct') or (s = 'union') then result := TvkTypeStruct.CreateFromXml(xml); end else if (xml.NodeName = 'command') then result := TvkCommand.CreateFromXml(xml); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkTypeSimple//////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.TvkTypeSimple.DoMark(const aMark: Integer); begin inherited DoMark(aMark); if (fParent <> '') and Assigned(fList) then fList.MarkObj(fParent, VK_OBJECT_TYPES, aMark); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function THeaderGenerator.TvkTypeSimple.CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeSimple; begin result := TvkTypeSimple.Create(otType); try result.Name := GetNodeValue(xml, 'name'); result.Parent := GetNodeValue(xml, 'type'); except FreeAndNil(result); raise; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkTypeHandle//////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function THeaderGenerator.TvkTypeHandle.CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeHandle; begin result := TvkTypeHandle.Create(otHandle); try result.Name := GetNodeValue(xml, 'name'); result.Parent := GetNodeValue(xml, 'parent', 'VkHandle'); result.NonDispatchable := (GetNodeValue(xml, 'type', '') = 'VK_DEFINE_NON_DISPATCHABLE_HANDLE'); except FreeAndNil(result); raise; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.TvkTypeFunction.DoMark(const aMark: Integer); var a: TArgument; begin inherited DoMark(aMark); if Assigned(fList) then begin fList.MarkObj(fReturnValue.Typ, VK_OBJECT_TYPES, aMark); for a in fArguments do fList.MarkObj(a.Typ, VK_OBJECT_TYPES, aMark); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkTypeFunction/////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor THeaderGenerator.TvkTypeFunction.Create(const aType: TvkObjectType); begin inherited Create(aType); fReturnValue := TArgument.Create; fArguments := TArgumentList.Create; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor THeaderGenerator.TvkTypeFunction.Destroy; begin FreeAndNil(fReturnValue); FreeAndNil(fArguments); inherited Destroy; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkTypeFunctionPtr/////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function THeaderGenerator.TvkTypeFunctionPtr.CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeFunctionPtr; var x, p: TDOMNode; a: TArgument; rx: TRegExpr; begin result := TvkTypeFunctionPtr.Create(otFuncPtr); try x := xml.FindNode('name'); if not Assigned(x) then raise XmlException.Create(xml.NodeName + ' witout child ''name''', xml); result.Name := x.TextContent; p := x.PreviousSibling; if not Assigned(p) then raise XmlException.Create(xml.NodeName + ' witout return type', xml); rx := TRegExpr.Create('typedef\s+((const)?)\s*([-_A-Za-z0-9\s]+?)\s*(\*?)\s*\('); try if not rx.Exec(String(p.TextContent)) then raise XmlException.Create('unable to parse return type of function pointer', xml); result.ReturnValue.IsConst := (Trim(rx.Match[1]) = 'const'); result.ReturnValue.Typ := WideString(Trim(rx.Match[3])); result.ReturnValue.IsPointer := (Trim(rx.Match[4]) = '*'); x := xml.FirstChild; while Assigned(x) do begin if (x.NodeName = 'type') then begin a := TArgument.Create; try p := x.PreviousSibling; if not Assigned(p) then raise XmlException.Create('unable to parse function pointer arguments', xml); rx.Expression := '[A-Za-z]*'; a.IsConst := rx.Exec(String(p.TextContent)) and (rx.Match[0] = 'const'); a.Typ := x.TextContent; p := x.NextSibling; if not Assigned(p) then raise XmlException.Create('unable to parse function pointer arguments', xml); rx.Expression := '(\*?)\s*([-_A-Za-z0-9]+)'; if not rx.Exec(String(p.TextContent)) then raise XmlException.Create('unable to parse function pointer arguments', xml); a.IsPointer := (rx.Match[1] = '*'); a.Name := WideString(Trim(rx.Match[2])); result.Arguments.Add(a); except FreeAndNil(a) end; end; x := x.NextSibling; end; finally FreeAndNil(rx); end; except FreeAndNil(result); raise; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkCommand/////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function THeaderGenerator.TvkCommand.CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkCommand; procedure ParseProto(const x: TDOMNode); begin result.Name := GetNodeValue(x, 'name'); result.ReturnValue.Typ := GetNodeValue(x, 'type'); end; procedure ParseParam(const x: TDOMNode); var p: TDOMNode; a: TArgument; begin a := TArgument.Create; try p := x.FindNode('name'); if not Assigned(p) then raise XmlException.Create('unable to parse command; param without name', xml); a.Name := p.TextContent; p := x.FindNode('type'); if not Assigned(p) then raise XmlException.Create('unable to parse command; param without type', xml); a.Typ := p.TextContent; a.IsConst := Assigned(p.PreviousSibling) and (Trim(p.PreviousSibling.TextContent) = 'const'); a.IsPointer := Assigned(p.NextSibling) and (Trim(p.NextSibling.TextContent) = '*'); result.Arguments.Add(a); except FreeAndNil(a); raise; end; end; var x: TDOMNode; begin result := TvkCommand.Create(otCommand); try x := xml.FirstChild; while Assigned(x) do begin if (x.NodeName = 'proto') then ParseProto(x) else if (x.NodeName = 'param') then ParseParam(x); x := x.NextSibling; end; except FreeAndNil(result); raise; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.TvkTypeStruct.DoMark(const aMark: Integer); var m: TMember; begin inherited DoMark(aMark); if Assigned(fList) then begin for m in fMember do fList.MarkObj(m.Typ, VK_OBJECT_TYPES, aMark); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkTypeStruct//////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor THeaderGenerator.TvkTypeStruct.Create(const aType: TvkObjectType); begin inherited Create(aType); fMember := TMemberList.Create; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor THeaderGenerator.TvkTypeStruct.Destroy; begin FreeAndNil(fMember); inherited Destroy; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function THeaderGenerator.TvkTypeStruct.CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeStruct; var x, p: TDOMNode; m: TMember; rx: TRegExpr; begin result := TvkTypeStruct.Create(otStruct); try result.Name := GetNodeAttrib(xml, 'name'); result.IsUnion := (GetNodeAttrib(xml, 'category') = 'union'); x := xml.FirstChild; while Assigned(x) do begin if (x.NodeName = 'member') then begin m := TMember.Create; try // read name p := x.FindNode('name'); if not Assigned(p) then raise XmlException.Create('struct member without name', xml); m.Name := p.TextContent; if Assigned(p.NextSibling) then m.Name := m.Name + p.NextSibling.TextContent; m.Name := Trim(m.Name); rx := TRegExpr.Create('([-_A-Za-z0-9]+)\s*\[\s*([0-9]+)\s*\]'); try if rx.Exec(String(m.Name)) then begin m.Name := WideString(rx.Match[1]); m.ArrSize := StrToInt(rx.Match[2]); end; finally FreeAndNil(rx); end; // read type p := x.FindNode('type'); if not Assigned(p) then raise XmlException.Create('struct member without type', xml); m.Typ := p.TextContent; m.IsConst := Assigned(p.PreviousSibling) and (Trim(p.PreviousSibling.TextContent) = 'const'); m.IsPointer := Assigned(p.NextSibling) and (Trim(p.NextSibling.TextContent) = '*'); result.Member.Add(m); except FreeAndNil(m); end; end; x := x.NextSibling; end; except FreeAndNil(result); raise; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator.TvkTypeEnum////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor THeaderGenerator.TvkTypeEnum.Create(const aType: TvkObjectType); begin inherited Create(aType); fValues := TValueList.Create; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor THeaderGenerator.TvkTypeEnum.Destroy; begin FreeAndNil(fValues); inherited Destroy; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function THeaderGenerator.TvkTypeEnum.CreateFromXml(const xml: TDOMNode): THeaderGenerator.TvkTypeEnum; var x, p: TDOMNode; v: TValue; function StrToValue(s: String): Variant; var f: TFormatSettings; rx: TRegExpr; begin f.DecimalSeparator := '.'; rx := TRegExpr.Create; try result := Unassigned; rx.Expression := '^-?(0x)?([0-9A-Fa-f]+)$'; if rx.Exec(s) then result := StrToInt(rx.Match[1] + rx.Match[2]); rx.Expression := '^([0-9\.]+)(f|d)?$'; if rx.Exec(s) then begin result := StrToFloat(rx.Match[1], f); if (rx.Match[2] = 'd') then result := Double(result); end; rx.Expression := '^\(~0U([L]*)\)$'; if rx.Exec(s) then begin if (rx.Match[2] = '') then result := High(Cardinal) else result := High(UInt64); end; if (result = Unassigned) then raise XmlException.Create(WideString('invalid enum value (' + s + ')'), xml); finally FreeAndNil(rx); end; end; begin result := TvkTypeEnum.Create(otEnum); try result.Name := GetNodeAttrib(xml, 'name'); x := xml.FirstChild; while Assigned(x) do begin if (x.NodeName = 'enum') then begin v := TValue.Create; try v.Name := GetNodeAttrib(x, 'name'); p := x.Attributes.GetNamedItem('value'); if Assigned(p) then begin v.IsBit := false; v.Value := StrToValue(String(p.TextContent)); end else begin p := x.Attributes.GetNamedItem('bitpos'); if not Assigned(p) then raise XmlException.Create('enum without value or bitpos', xml); v.IsBit := false; v.Value := StrToValue(String(p.TextContent)); end; result.Values.Add(v); except FreeAndNil(v); raise; end; end; x := x.NextSibling; end; except FreeAndNil(result); raise; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //THeaderGenerator////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.ReadFile(const aFilename: String); var fs: TFileStream; begin if not FileExists(aFilename) then raise Exception.Create('file does not exist: ' + aFilename); fs := TFileStream.Create(aFilename, fmOpenRead); try ReadFile(fs); finally FreeAndNil(fs); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.ReadFile(const aStream: TStream); var xml: TDOMNode; CurrentMark: Integer; procedure AddObject(const aObj: TvkObject); begin if Assigned(aObj) then begin fObjects.Add(aObj); aObj.List := fObjects; WriteLn(Format(' %-10s%s', [FormatType(aObj.VkType), aObj.Name])); end; end; procedure ParseTypes(const xml: TDOMNode); var x: TDOMNode; begin x := xml.FirstChild; while Assigned(x) do begin AddObject(TvkObject.CreateFromXml(x)); x := x.NextSibling; end; end; procedure EnableFeature(const xml: TDOMNode); var x: TDOMNode; begin x := xml.FirstChild; while Assigned(x) do begin if (x.NodeName = 'require') then EnableFeature(x) else if (x.NodeName = 'type') then fObjects.MarkObj(GetNodeAttrib(x, 'name'), VK_OBJECT_TYPES, CurrentMark) else if (x.NodeName = 'command') then fObjects.MarkObj(GetNodeAttrib(x, 'name'), [ otCommand ], CurrentMark); x := x.NextSibling; end; end; begin Clear; ReadXMLFile(fDocument, aStream); CurrentMark := 1; WriteLn('read xml data'); xml := fDocument.DocumentElement.FirstChild; while Assigned(xml) do begin if (xml.NodeName = 'types') or (xml.NodeName = 'commands') then ParseTypes(xml) else if (xml.NodeName = 'enums') then AddObject(TvkTypeEnum.CreateFromXml(xml)) else if (xml.NodeName = 'comment') then fComment := xml.TextContent else if (xml.NodeName = 'feature') then EnableFeature(xml); xml := xml.NextSibling; end; WriteLn('generate header'); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure THeaderGenerator.Clear; procedure CreateBaseType(const aName: DOMString); var o: TvkObject; begin o := TvkTypeSimple.Create(otType); try o.Name := aName; o.List := fObjects; fObjects.Add(o); except FreeAndNil(o); raise; end; end; begin fComment := ''; fObjects.Clear; CreateBaseType('void'); CreateBaseType('uint16_t'); CreateBaseType('uint32_t'); CreateBaseType('uint64_t'); CreateBaseType('int16_t'); CreateBaseType('int32_t'); CreateBaseType('int64_t'); CreateBaseType('float'); CreateBaseType('double'); CreateBaseType('char'); CreateBaseType('uint8_t'); CreateBaseType('size_t'); CreateBaseType('VkHandle'); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor THeaderGenerator.Create; begin inherited Create; fObjects := TvkObjectList.Create; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor THeaderGenerator.Destroy; begin FreeAndNil(fObjects); FreeAndNil(fDocument); inherited Destroy; end; end.