You've already forked lazarus-ccr
Added some code to create c and pascal files to test type sizes.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1994 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -23,6 +23,7 @@
|
|||||||
</BuildModes>
|
</BuildModes>
|
||||||
<PublishOptions>
|
<PublishOptions>
|
||||||
<Version Value="2"/>
|
<Version Value="2"/>
|
||||||
|
<DestinationDirectory Value="/tmp/publishedproject/"/>
|
||||||
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||||
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
|
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
|
||||||
</PublishOptions>
|
</PublishOptions>
|
||||||
@ -30,7 +31,7 @@
|
|||||||
<local>
|
<local>
|
||||||
<FormatVersion Value="1"/>
|
<FormatVersion Value="1"/>
|
||||||
<CommandLineParams Value="-i /usr/share/gir-1.0/Gtk-3.0.gir -o /tmp/gir-out -w"/>
|
<CommandLineParams Value="-i /usr/share/gir-1.0/Gtk-3.0.gir -o /tmp/gir-out -w"/>
|
||||||
<LaunchingApplication Use="True" PathPlusParams="/usr/bin/gnome-terminal -t 'Lazarus Run Output' -e '$(LazarusDir)/tools/runwait.sh $(TargetCmdLine)'"/>
|
<LaunchingApplication PathPlusParams="/usr/bin/gnome-terminal -t 'Lazarus Run Output' -e '$(LazarusDir)/tools/runwait.sh $(TargetCmdLine)'"/>
|
||||||
</local>
|
</local>
|
||||||
</RunParams>
|
</RunParams>
|
||||||
<Units Count="8">
|
<Units Count="8">
|
||||||
|
@ -38,6 +38,7 @@ type
|
|||||||
FOutPutDirectory : String;
|
FOutPutDirectory : String;
|
||||||
FFileToConvert: String;
|
FFileToConvert: String;
|
||||||
FOverWriteFiles: Boolean;
|
FOverWriteFiles: Boolean;
|
||||||
|
FWantTest: Boolean;
|
||||||
procedure AddDefaultPaths;
|
procedure AddDefaultPaths;
|
||||||
procedure AddPaths(APaths: String);
|
procedure AddPaths(APaths: String);
|
||||||
procedure VerifyOptions;
|
procedure VerifyOptions;
|
||||||
@ -45,7 +46,8 @@ type
|
|||||||
|
|
||||||
//callbacks
|
//callbacks
|
||||||
function NeedGirFile(AGirFile: TObject; NamespaceName: String) : TXMLDocument;
|
function NeedGirFile(AGirFile: TObject; NamespaceName: String) : TXMLDocument;
|
||||||
procedure WritePascalFile(Sender: TObject; AUnitName: String; AStream: TStringStream);
|
// AName is the whole name unit.pas or file.c
|
||||||
|
procedure WriteFile(Sender: TObject; AName: String; AStream: TStringStream);
|
||||||
protected
|
protected
|
||||||
procedure DoRun; override;
|
procedure DoRun; override;
|
||||||
public
|
public
|
||||||
@ -110,14 +112,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGirConsoleConverter.WritePascalFile(Sender: TObject;
|
procedure TGirConsoleConverter.WriteFile(Sender: TObject; AName: String; AStream: TStringStream);
|
||||||
AUnitName: String; AStream: TStringStream);
|
|
||||||
var
|
var
|
||||||
SStream: TFileStream;
|
SStream: TFileStream;
|
||||||
OutFileName: String;
|
OutFileName: String;
|
||||||
begin
|
begin
|
||||||
Inc(FWriteCount);
|
Inc(FWriteCount);
|
||||||
OutFileName:=FOutPutDirectory+LowerCase(AUnitName)+'.pas';
|
OutFileName:=FOutPutDirectory+LowerCase(AName);
|
||||||
if not FileExists(OutFileName)
|
if not FileExists(OutFileName)
|
||||||
or (FileExists(OutFileName) and FOverWriteFiles) then
|
or (FileExists(OutFileName) and FOverWriteFiles) then
|
||||||
begin
|
begin
|
||||||
@ -152,8 +153,8 @@ begin
|
|||||||
girFile.ParseXMLDocument(Doc);
|
girFile.ParseXMLDocument(Doc);
|
||||||
Doc.Free;
|
Doc.Free;
|
||||||
|
|
||||||
Writer := TgirPascalWriter.Create(girFile.NameSpaces);
|
Writer := TgirPascalWriter.Create(girFile.NameSpaces, FWantTest);
|
||||||
Writer.OnUnitWriteEvent:= @WritePascalFile;
|
Writer.OnUnitWriteEvent:= @WriteFile;
|
||||||
Writer.GenerateUnits;
|
Writer.GenerateUnits;
|
||||||
|
|
||||||
Writer.Free;
|
Writer.Free;
|
||||||
@ -168,7 +169,7 @@ var
|
|||||||
ErrorMsg: String;
|
ErrorMsg: String;
|
||||||
begin
|
begin
|
||||||
// quick check parameters
|
// quick check parameters
|
||||||
ErrorMsg:=CheckOptions('hnp:o:i:w',['help','no-default','paths','output-directory', 'input', 'overwrite-files']);
|
ErrorMsg:=CheckOptions('hnp:o:i:wt',['help','no-default','paths','output-directory', 'input', 'overwrite-files', 'test']);
|
||||||
if ErrorMsg<>'' then begin
|
if ErrorMsg<>'' then begin
|
||||||
ShowException(Exception.Create(ErrorMsg));
|
ShowException(Exception.Create(ErrorMsg));
|
||||||
Terminate;
|
Terminate;
|
||||||
@ -198,6 +199,8 @@ begin
|
|||||||
if HasOption('w', 'overwrite-files') then
|
if HasOption('w', 'overwrite-files') then
|
||||||
FOverWriteFiles:=True;
|
FOverWriteFiles:=True;
|
||||||
|
|
||||||
|
FWantTest := HasOption('t', 'test');
|
||||||
|
|
||||||
VerifyOptions;
|
VerifyOptions;
|
||||||
|
|
||||||
// does all the heavy lifting
|
// does all the heavy lifting
|
||||||
@ -232,6 +235,7 @@ begin
|
|||||||
Writeln(' -n --no-default /usr/share/gir-1.0 is not added as a search location for ');
|
Writeln(' -n --no-default /usr/share/gir-1.0 is not added as a search location for ');
|
||||||
Writeln(' needed .gir files.');
|
Writeln(' needed .gir files.');
|
||||||
Writeln(' -p --paths= List of paths seperated by ":" to search for needed .gir files.');
|
Writeln(' -p --paths= List of paths seperated by ":" to search for needed .gir files.');
|
||||||
|
Writeln(' -t --test Creates a test program and a test c file per unit to verify struct sizes.');
|
||||||
Writeln('');
|
Writeln('');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -59,32 +59,33 @@ uses girErrors, girTokens;
|
|||||||
|
|
||||||
procedure TgirFile.ParseNode(ANode: TDomNode);
|
procedure TgirFile.ParseNode(ANode: TDomNode);
|
||||||
var
|
var
|
||||||
|
Node: TDomNode;
|
||||||
NS: TgirNamespace;
|
NS: TgirNamespace;
|
||||||
Includes: TList;
|
Includes: TList;
|
||||||
begin
|
begin
|
||||||
if ANode.NodeName <> 'repository' then
|
if ANode.NodeName <> 'repository' then
|
||||||
girError(geError, 'Not a Valid Document Type!');
|
girError(geError, 'Not a Valid Document Type!');
|
||||||
|
|
||||||
ANode := Anode.FirstChild;
|
Node := Anode.FirstChild;
|
||||||
Ns := nil;
|
Ns := nil;
|
||||||
Includes := TList.Create;
|
Includes := TList.Create;
|
||||||
|
|
||||||
while ANode <> nil do begin
|
while Node <> nil do begin
|
||||||
case GirTokenNameToToken(ANode.NodeName) of
|
case GirTokenNameToToken(Node.NodeName) of
|
||||||
gtInclude: ParseIncludeNode(ANode, Includes);
|
gtInclude: ParseIncludeNode(Node, Includes);
|
||||||
gtNameSpace:
|
gtNameSpace:
|
||||||
begin
|
begin
|
||||||
NS := TgirNamespace.CreateFromNamespaceNode(NameSpaces, ANode, Includes);
|
NS := TgirNamespace.CreateFromRepositoryNode(NameSpaces, ANode, Includes);
|
||||||
girError(geDebug, 'Adding Namespace '+NS.NameSpace+' to NameSpaces');
|
girError(geDebug, 'Adding Namespace '+NS.NameSpace+' to NameSpaces');
|
||||||
FNameSpaces.Add(NS);
|
FNameSpaces.Add(NS);
|
||||||
girError(geDebug, 'Added Namespace '+NS.NameSpace);
|
girError(geDebug, 'Added Namespace '+NS.NameSpace);
|
||||||
NS.ParseNode(ANode);
|
NS.ParseNode(Node);
|
||||||
end;
|
end;
|
||||||
gtPackage, gtCInclude: ;// ignore for now
|
gtPackage, gtCInclude: ;// ignore for now
|
||||||
else
|
else
|
||||||
girError(geDebug, 'Unknown Node Type for Reposiotory: '+ Anode.NodeName);
|
girError(geDebug, 'Unknown Node Type for Reposiotory: '+ node.NodeName);
|
||||||
end;
|
end;
|
||||||
ANode := ANode.NextSibling;
|
Node := Node.NextSibling;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,9 @@ type
|
|||||||
|
|
||||||
TgirNamespace = class(IgirParser)
|
TgirNamespace = class(IgirParser)
|
||||||
private
|
private
|
||||||
|
FCIncludeName: String;
|
||||||
FConstants: TList;
|
FConstants: TList;
|
||||||
|
FCPackageName: String;
|
||||||
FFunctions: TList;
|
FFunctions: TList;
|
||||||
FNameSpace: String;
|
FNameSpace: String;
|
||||||
FOnlyImplied: Boolean;
|
FOnlyImplied: Boolean;
|
||||||
@ -75,9 +77,11 @@ type
|
|||||||
procedure ParseNode(ANode: TDomNode);
|
procedure ParseNode(ANode: TDomNode);
|
||||||
procedure ParseSubNode(ANode: TDomNode); // generally do not use outside of TgirNameSpace
|
procedure ParseSubNode(ANode: TDomNode); // generally do not use outside of TgirNameSpace
|
||||||
constructor Create(AOwner:TObject; AImpliedNamespace: String);
|
constructor Create(AOwner:TObject; AImpliedNamespace: String);
|
||||||
constructor CreateFromNamespaceNode(AOwner:TObject; ANode: TDOMNode; AIncludes: TList);
|
constructor CreateFromRepositoryNode(AOwner:TObject; ANode: TDOMNode; AIncludes: TList);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
property NameSpace: String read FNameSpace;
|
property NameSpace: String read FNameSpace;
|
||||||
|
property CIncludeName: String read FCIncludeName;
|
||||||
|
property CPackageName: String read FCPackageName;
|
||||||
property RequiredNameSpaces: TList Read FRequiredNameSpaces;
|
property RequiredNameSpaces: TList Read FRequiredNameSpaces;
|
||||||
property SharedLibrary: String read FSharedLibrary;
|
property SharedLibrary: String read FSharedLibrary;
|
||||||
property Version: String read FVersion;
|
property Version: String read FVersion;
|
||||||
@ -499,19 +503,39 @@ begin
|
|||||||
girError(geDebug, 'Creating Stub for namespace: '+ AImpliedNamespace);
|
girError(geDebug, 'Creating Stub for namespace: '+ AImpliedNamespace);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TgirNamespace.CreateFromNamespaceNode(AOwner:TObject; ANode: TDOMNode; AIncludes: TList);
|
constructor TgirNamespace.CreateFromRepositoryNode(AOwner:TObject; ANode: TDOMNode; AIncludes: TList);
|
||||||
|
procedure SetCInclude;
|
||||||
|
var
|
||||||
|
Child: TDomElement;
|
||||||
|
begin
|
||||||
|
Child := TDOMElement(ANode.FindNode('c:include name'));
|
||||||
|
if (Child <> nil) and Child.InheritsFrom(TDOMElement) then
|
||||||
|
FCIncludeName:= Child.GetAttribute('name');
|
||||||
|
end;
|
||||||
|
procedure SetPackage;
|
||||||
|
var
|
||||||
|
Child: TDOMElement;
|
||||||
|
begin
|
||||||
|
Child := TDOMElement(ANode.FindNode('package'));
|
||||||
|
if (Child <> nil) and Child.InheritsFrom(TDOMElement) then
|
||||||
|
FCPackageName:=Child.GetAttribute('name');
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
Node: TDOMElement absolute ANode;
|
Node: TDOMElement;
|
||||||
begin
|
begin
|
||||||
FOwner := AOwner;
|
FOwner := AOwner;
|
||||||
if ANode = nil then
|
if ANode = nil then
|
||||||
girError(geError, 'expected namespace got nil');
|
girError(geError, 'expected namespace got nil');
|
||||||
if ANode.NodeName <> 'namespace' then
|
if ANode.NodeName <> 'repository' then
|
||||||
girError(geError, 'expected namespace got '+ANode.NodeName);
|
girError(geError, 'expected "repository" got '+ANode.NodeName);
|
||||||
|
Node := TDOMElement( ANode.FindNode('namespace') );
|
||||||
FNameSpace:=Node.GetAttribute('name');
|
FNameSpace:=Node.GetAttribute('name');
|
||||||
FRequiredNameSpaces := AIncludes;
|
FRequiredNameSpaces := AIncludes;
|
||||||
FSharedLibrary:=Node.GetAttribute('shared-library');
|
FSharedLibrary:=Node.GetAttribute('shared-library');
|
||||||
FVersion:=Node.GetAttribute('version');
|
FVersion:=Node.GetAttribute('version');
|
||||||
|
SetCInclude;
|
||||||
|
SetPackage;
|
||||||
girError(geDebug, Format('Creating namespace=%s Version=%s LibName=%s',[FNameSpace, FVersion, FSharedLibrary]));
|
girError(geDebug, Format('Creating namespace=%s Version=%s LibName=%s',[FNameSpace, FVersion, FSharedLibrary]));
|
||||||
|
|
||||||
FConstants := TList.Create;
|
FConstants := TList.Create;
|
||||||
|
@ -43,6 +43,7 @@ type
|
|||||||
FCType: String;
|
FCType: String;
|
||||||
FDoc: String;
|
FDoc: String;
|
||||||
FForwardDefinitionWritten: Boolean;
|
FForwardDefinitionWritten: Boolean;
|
||||||
|
FHasFields: Boolean;
|
||||||
FImpliedPointerLevel: Integer;
|
FImpliedPointerLevel: Integer;
|
||||||
FName: String;
|
FName: String;
|
||||||
FObjectType: TGirObjectType;
|
FObjectType: TGirObjectType;
|
||||||
@ -265,9 +266,11 @@ type
|
|||||||
|
|
||||||
{ TgirFieldsList }
|
{ TgirFieldsList }
|
||||||
|
|
||||||
TgirFieldsList = class(TFPList)
|
TgirFieldsList = class(TList)
|
||||||
private
|
private
|
||||||
|
FHasFields: Boolean;
|
||||||
function GetField(AIndex: Integer): TGirBaseType;
|
function GetField(AIndex: Integer): TGirBaseType;
|
||||||
|
procedure Notify(Ptr: Pointer; Action: TListNotification); override;
|
||||||
public
|
public
|
||||||
property Field[AIndex: Integer]: TGirBaseType read GetField;
|
property Field[AIndex: Integer]: TGirBaseType read GetField;
|
||||||
end;
|
end;
|
||||||
@ -277,6 +280,7 @@ type
|
|||||||
TgirRecord = class(TGirBaseType)
|
TgirRecord = class(TGirBaseType)
|
||||||
private
|
private
|
||||||
FFields: TgirFieldsList;
|
FFields: TgirFieldsList;
|
||||||
|
function GetHasFields: Boolean;
|
||||||
protected
|
protected
|
||||||
procedure HandleUnion(ANode: TDomNode);
|
procedure HandleUnion(ANode: TDomNode);
|
||||||
procedure HandleField(ANode: TDomNode);
|
procedure HandleField(ANode: TDomNode);
|
||||||
@ -285,6 +289,7 @@ type
|
|||||||
constructor Create(AOwner: TObject; ANode: TDomNode); override;
|
constructor Create(AOwner: TObject; ANode: TDomNode); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
property Fields: TgirFieldsList read FFields;
|
property Fields: TgirFieldsList read FFields;
|
||||||
|
property HasFields: Boolean read GetHasFields;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TgirUnion }
|
{ TgirUnion }
|
||||||
@ -413,6 +418,7 @@ constructor TgirBitField.Create(AOwner: TObject; ANode: TDomNode);
|
|||||||
begin
|
begin
|
||||||
inherited Create(AOwner, ANode);
|
inherited Create(AOwner, ANode);
|
||||||
FObjectType:=otBitfield;
|
FObjectType:=otBitfield;
|
||||||
|
FHasFields:=True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TgirFieldsList }
|
{ TgirFieldsList }
|
||||||
@ -422,6 +428,15 @@ begin
|
|||||||
Result := TGirBaseType(Items[AIndex]);
|
Result := TGirBaseType(Items[AIndex]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TgirFieldsList.Notify(Ptr: Pointer; Action: TListNotification);
|
||||||
|
var
|
||||||
|
gir: TGirBaseType absolute Ptr;
|
||||||
|
begin
|
||||||
|
if FHasFields then
|
||||||
|
Exit;
|
||||||
|
FHasFields:= gir.ObjectType in [otTypeParam, otCallback, otArray];
|
||||||
|
end;
|
||||||
|
|
||||||
{ TgirParamList }
|
{ TgirParamList }
|
||||||
|
|
||||||
function TgirParamList.GetParam(AIndex: Integer): TGirFunctionParam;
|
function TgirParamList.GetParam(AIndex: Integer): TGirFunctionParam;
|
||||||
@ -625,6 +640,10 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function TgirRecord.GetHasFields: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Fields.FHasFields;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TgirRecord.HandleUnion(ANode: TDomNode);
|
procedure TgirRecord.HandleUnion(ANode: TDomNode);
|
||||||
var
|
var
|
||||||
|
@ -26,19 +26,22 @@ uses
|
|||||||
Classes, SysUtils, girNameSpaces, girObjects, girTokens, contnrs;
|
Classes, SysUtils, girNameSpaces, girObjects, girTokens, contnrs;
|
||||||
|
|
||||||
type
|
type
|
||||||
TUnitWriteEvent = procedure (Sender: TObject; AUnitName: AnsiString; AStream: TStringStream) of object;
|
TgirWriteEvent = procedure (Sender: TObject; AUnitName: AnsiString; AStream: TStringStream) of object;
|
||||||
|
|
||||||
{ TgirPascalWriter }
|
{ TgirPascalWriter }
|
||||||
|
|
||||||
TgirPascalWriter = class
|
TgirPascalWriter = class
|
||||||
private
|
private
|
||||||
FOnUnitWriteEvent: TUnitWriteEvent;
|
FDefaultUnitExtension: String;
|
||||||
|
FOnUnitWriteEvent: TgirWriteEvent;
|
||||||
FNameSpaces: TgirNamespaces;
|
FNameSpaces: TgirNamespaces;
|
||||||
FUnits: TList;
|
FUnits: TList;
|
||||||
|
FWantTest: Boolean;
|
||||||
public
|
public
|
||||||
constructor Create(ANameSpaces: TgirNamespaces);
|
constructor Create(ANameSpaces: TgirNamespaces; AWantTest: Boolean);
|
||||||
procedure GenerateUnits;
|
procedure GenerateUnits;
|
||||||
property OnUnitWriteEvent: TUnitWriteEvent read FOnUnitWriteEvent write FOnUnitWriteEvent;
|
property OnUnitWriteEvent: TgirWriteEvent read FOnUnitWriteEvent write FOnUnitWriteEvent;
|
||||||
|
property DefaultUnitExtension: String read FDefaultUnitExtension write FDefaultUnitExtension; // is .pas by default
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -180,7 +183,11 @@ type
|
|||||||
FInterfaceSection: TPInterface;
|
FInterfaceSection: TPInterface;
|
||||||
FLibName: String;
|
FLibName: String;
|
||||||
FNameSpace: TgirNamespace;
|
FNameSpace: TgirNamespace;
|
||||||
|
FWantTest: Boolean;
|
||||||
ProcessLevel: Integer; //used to know if to write forward definitions
|
ProcessLevel: Integer; //used to know if to write forward definitions
|
||||||
|
FTestCFile: TStringStream;
|
||||||
|
FTestPascalFile: TStringStream;
|
||||||
|
FTestPascalBody: TStringList;
|
||||||
function GetUnitName: String;
|
function GetUnitName: String;
|
||||||
|
|
||||||
// functions to ensure the type is being written in the correct declaration
|
// functions to ensure the type is being written in the correct declaration
|
||||||
@ -230,13 +237,16 @@ type
|
|||||||
|
|
||||||
procedure ProcessType(AType: TGirBaseType; AForceWrite: Boolean = False);
|
procedure ProcessType(AType: TGirBaseType; AForceWrite: Boolean = False);
|
||||||
procedure ResolveFuzzyTypes;
|
procedure ResolveFuzzyTypes;
|
||||||
|
procedure AddTestType(APascalName: String; ACName: String);
|
||||||
public
|
public
|
||||||
constructor Create(ANameSpace: TgirNamespace; ALinkDynamic: Boolean);
|
constructor Create(ANameSpace: TgirNamespace; ALinkDynamic: Boolean; AWantTest: Boolean);
|
||||||
|
destructor Destroy; override;
|
||||||
procedure ProcessConsts(AList:TList); // of TgirBaseType descandants
|
procedure ProcessConsts(AList:TList); // of TgirBaseType descandants
|
||||||
procedure ProcessTypes(AList:TFPHashObjectList); // of TgirBaseType descandants
|
procedure ProcessTypes(AList:TFPHashObjectList); // of TgirBaseType descandants
|
||||||
procedure ProcessFunctions(AList:TList);// of TgirFunction
|
procedure ProcessFunctions(AList:TList);// of TgirFunction
|
||||||
procedure GenerateUnit;
|
procedure GenerateUnit;
|
||||||
function AsStream: TStringStream;
|
function AsStream: TStringStream;
|
||||||
|
procedure Finish;
|
||||||
|
|
||||||
property InterfaceSection: TPInterface read FInterfaceSection;
|
property InterfaceSection: TPInterface read FInterfaceSection;
|
||||||
property ImplementationSection: TPImplementation read FImplementationSection;
|
property ImplementationSection: TPImplementation read FImplementationSection;
|
||||||
@ -614,6 +624,8 @@ begin
|
|||||||
WriteLn('Unknown Type: ', AType.ClassName);
|
WriteLn('Unknown Type: ', AType.ClassName);
|
||||||
Halt;
|
Halt;
|
||||||
end; // case
|
end; // case
|
||||||
|
if (AType.InheritsFrom(TgirRecord)) and (TgirRecord(AType).HasFields) then
|
||||||
|
AddTestType(AType.TranslatedName, AType.CType);
|
||||||
|
|
||||||
AType.Writing:=msWritten;
|
AType.Writing:=msWritten;
|
||||||
Dec(ProcessLevel);
|
Dec(ProcessLevel);
|
||||||
@ -643,6 +655,43 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPascalUnit.AddTestType(APascalName: String; ACName: String);
|
||||||
|
const
|
||||||
|
CFunction = 'int GetSizeOf_%s(void)'+
|
||||||
|
'{ return sizeof(%s); };'+LineEnding;
|
||||||
|
PImport = 'function GetSizeOf_%s: LongInt; cdecl; external;'+LineEnding;
|
||||||
|
PTest = 'procedure Test_%s;' +LineEnding+
|
||||||
|
'var' +LineEnding+
|
||||||
|
' PSize: Integer;' +LineEnding+
|
||||||
|
' CSize: Integer;' +LineEnding+
|
||||||
|
'begin' +LineEnding+
|
||||||
|
' PSize := SizeOf(%s);' +LineEnding+
|
||||||
|
' CSize := GetSizeOf_%s;' +LineEnding+
|
||||||
|
' if CSize = PSize then' +LineEnding+
|
||||||
|
' WriteLn(''%s Matches C Size: '',CSize)' +LineEnding+
|
||||||
|
' else' +LineEnding+
|
||||||
|
' WriteLn(''%s size ('',PSize,'') does NOT match %s size ('',CSize,'')'');' +LineEnding+
|
||||||
|
'end;' +LineEnding;
|
||||||
|
var
|
||||||
|
CF: String;
|
||||||
|
PI: String;
|
||||||
|
PT: String;
|
||||||
|
begin
|
||||||
|
if not FWantTest then
|
||||||
|
Exit;
|
||||||
|
if (ACName = '') or (ACName[1] = '_') then // we skip private types
|
||||||
|
Exit;
|
||||||
|
|
||||||
|
CF := Format(CFunction,[ACName, ACName]);
|
||||||
|
PI := Format(PImport, [ACName]);
|
||||||
|
PT := Format(PTest, [ACName, APascalName, ACName, APascalName, APascalName, ACName]);
|
||||||
|
|
||||||
|
FTestCFile.WriteString(CF); // c sizeof wrapper
|
||||||
|
FTestPascalFile.WriteString(PI); // c import
|
||||||
|
FTestPascalFile.WriteString(PT); // pascal testproc
|
||||||
|
FTestPascalBody.Add(Format('Test_%s;',[ACName])); //call pascal testproc
|
||||||
|
end;
|
||||||
|
|
||||||
function TPascalUnit.WantTypeSection: TPDeclarationType;
|
function TPascalUnit.WantTypeSection: TPDeclarationType;
|
||||||
begin
|
begin
|
||||||
if (InterfaceSection.Declarations.Count = 0)
|
if (InterfaceSection.Declarations.Count = 0)
|
||||||
@ -961,6 +1010,7 @@ var
|
|||||||
TypeFuncs: TStrings;
|
TypeFuncs: TStrings;
|
||||||
ParentType: String ='';
|
ParentType: String ='';
|
||||||
UsedNames: TStringList;
|
UsedNames: TStringList;
|
||||||
|
WrittenFields: Integer;
|
||||||
|
|
||||||
function GetTypeForProperty(AProperty: TgirProperty; out SetFound: Boolean): String;
|
function GetTypeForProperty(AProperty: TgirProperty; out SetFound: Boolean): String;
|
||||||
var
|
var
|
||||||
@ -1040,10 +1090,12 @@ var
|
|||||||
Param: String;
|
Param: String;
|
||||||
begin
|
begin
|
||||||
ResolveTypeTranslation(AParam.VarType);
|
ResolveTypeTranslation(AParam.VarType);
|
||||||
if (ParentType <> '') and (ParenParams(AParam.VarType.TranslatedName) = ParentType) then
|
Inc(WrittenFields);
|
||||||
|
if (WrittenFields = 1) and (AObjectType = gtClass) and (TgirClass(AItem).ParentClass <> nil) then
|
||||||
begin
|
begin
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Param := WriteParamAsString(AParam,i, nil, UsedNames);
|
Param := WriteParamAsString(AParam,i, nil, UsedNames);
|
||||||
//if Pos('destroy_:', Param) > 0 then
|
//if Pos('destroy_:', Param) > 0 then
|
||||||
// Param := StringReplace(Param, 'destroy_', 'destroy_f', [rfReplaceAll]);
|
// Param := StringReplace(Param, 'destroy_', 'destroy_f', [rfReplaceAll]);
|
||||||
@ -1063,7 +1115,7 @@ var
|
|||||||
otCallback,
|
otCallback,
|
||||||
otArray,
|
otArray,
|
||||||
otTypeParam,
|
otTypeParam,
|
||||||
otUnion: ; // these will be done on the second pass. this is to make the field names different if they are the same as some function or property. giving the function priority of the original name
|
otUnion: Exit; // these will be done on the second pass. this is to avoid duplicate names if they are the same as some function or property. giving the function priority of the original name
|
||||||
|
|
||||||
|
|
||||||
otGlibSignal : if AObjectType <> gtClass then TypeDecl.Add(IndentText(WriteCallBack(TgirCallback(Field),True, UsedNames),4,0)); // classes do not have signals They are in the class *struct*
|
otGlibSignal : if AObjectType <> gtClass then TypeDecl.Add(IndentText(WriteCallBack(TgirCallback(Field),True, UsedNames),4,0)); // classes do not have signals They are in the class *struct*
|
||||||
@ -1166,11 +1218,17 @@ begin
|
|||||||
AddGetTypeProc(TgirGType(AItem));
|
AddGetTypeProc(TgirGType(AItem));
|
||||||
end;
|
end;
|
||||||
TypeDecl.Add(IndentText(AItem.TranslatedName +' = object'+ParentType,2,0));
|
TypeDecl.Add(IndentText(AItem.TranslatedName +' = object'+ParentType,2,0));
|
||||||
// two passes to process the fields last for naming reasons
|
|
||||||
|
// two passes to process the fields last for naming reasons first for methods/properties second for fields
|
||||||
for i := 0 to Aitem.Fields.Count-1 do
|
for i := 0 to Aitem.Fields.Count-1 do
|
||||||
HandleFieldType(AItem.Fields.Field[i], True);
|
HandleFieldType(AItem.Fields.Field[i], True);
|
||||||
for i := 0 to Aitem.Fields.Count-1 do
|
if AItem.CType <> 'GInitiallyUnowned' then // empty type GInitiallyUnowned is empty and aliased to GObject which causes object introspection to add the types again since it's empty...how many places does that happen...
|
||||||
HandleFieldType(AItem.Fields.Field[i], False);
|
begin
|
||||||
|
WrittenFields:=0;
|
||||||
|
for i := 0 to Aitem.Fields.Count-1 do
|
||||||
|
HandleFieldType(AItem.Fields.Field[i], False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if TypeFuncs.Count > 0 then
|
if TypeFuncs.Count > 0 then
|
||||||
@ -1595,19 +1653,50 @@ begin
|
|||||||
ABaseType.TranslatedName:=MakePascalTypeFromCType(ABaseType.CType, 0);
|
ABaseType.TranslatedName:=MakePascalTypeFromCType(ABaseType.CType, 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TPascalUnit.Create(ANameSpace: TgirNamespace; ALinkDynamic: Boolean);
|
constructor TPascalUnit.Create(ANameSpace: TgirNamespace; ALinkDynamic: Boolean; AWantTest: Boolean);
|
||||||
|
const
|
||||||
|
CBasic = '#include <%s>'+LineEnding;
|
||||||
|
PBasic = 'program %s_test;'+LineEnding+
|
||||||
|
'{$LINK %s_c_test}'+LineEnding+
|
||||||
|
'uses %s;'+LineEnding;
|
||||||
begin
|
begin
|
||||||
ProcessLevel:=0;
|
ProcessLevel:=0;
|
||||||
|
FWantTest:=AWantTest;
|
||||||
FLinkDynamic := ALinkDynamic;
|
FLinkDynamic := ALinkDynamic;
|
||||||
FFinalizeSection := TPFinialization.Create(Self);
|
FFinalizeSection := TPFinialization.Create(Self);
|
||||||
FImplementationSection := TPImplementation.Create(Self);
|
FImplementationSection := TPImplementation.Create(Self);
|
||||||
FInitializeSection := TPInitialize.Create(Self);
|
FInitializeSection := TPInitialize.Create(Self);
|
||||||
FInterfaceSection := TPInterface.Create(Self, TPUses.Create);
|
FInterfaceSection := TPInterface.Create(Self, TPUses.Create);
|
||||||
FNameSpace := ANameSpace;
|
FNameSpace := ANameSpace;
|
||||||
|
if FWantTest then
|
||||||
|
begin
|
||||||
|
FTestCFile := TStringStream.Create('');
|
||||||
|
FTestCFile.WriteString(Format(CBasic, [FNameSpace.CIncludeName]));
|
||||||
|
FTestPascalFile := TStringStream.Create('');
|
||||||
|
FTestPascalFile.WriteString(Format(PBasic,[UnitName, UnitName, UnitName]));
|
||||||
|
FTestPascalBody := TStringList.Create;
|
||||||
|
FTestPascalBody.Add('begin');
|
||||||
|
end;
|
||||||
ResolveFuzzyTypes;
|
ResolveFuzzyTypes;
|
||||||
GenerateUnit;
|
GenerateUnit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TPascalUnit.Destroy;
|
||||||
|
begin
|
||||||
|
if FWantTest then
|
||||||
|
begin
|
||||||
|
FTestPascalFile.Free;
|
||||||
|
FTestCFile.Free;
|
||||||
|
FTestPascalBody.Free;
|
||||||
|
end;
|
||||||
|
FFinalizeSection.Free;
|
||||||
|
FImplementationSection.Free;
|
||||||
|
FInitializeSection.Free;
|
||||||
|
FInterfaceSection.Free;
|
||||||
|
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPascalUnit.ProcessConsts(AList: TList);
|
procedure TPascalUnit.ProcessConsts(AList: TList);
|
||||||
function WriteConst(AConst: TgirConstant; Suffix: String = ''): String;
|
function WriteConst(AConst: TgirConstant; Suffix: String = ''): String;
|
||||||
begin
|
begin
|
||||||
@ -1744,6 +1833,17 @@ begin
|
|||||||
Result.Position:=0;
|
Result.Position:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPascalUnit.Finish;
|
||||||
|
begin
|
||||||
|
if FWantTest then
|
||||||
|
begin
|
||||||
|
FTestPascalFile.WriteString(FTestPascalBody.Text);
|
||||||
|
FTestPascalFile.WriteString('end.');
|
||||||
|
FTestCFile.Position:=0;
|
||||||
|
FTestPascalFile.Position:=0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPDeclarationList }
|
{ TPDeclarationList }
|
||||||
|
|
||||||
function TPDeclarationList.GetDeclarations(AIndex: Integer): TPDeclaration;
|
function TPDeclarationList.GetDeclarations(AIndex: Integer): TPDeclaration;
|
||||||
@ -1763,10 +1863,12 @@ end;
|
|||||||
|
|
||||||
{ TgirPascalWriter }
|
{ TgirPascalWriter }
|
||||||
|
|
||||||
constructor TgirPascalWriter.Create(ANameSpaces: TgirNamespaces);
|
constructor TgirPascalWriter.Create(ANameSpaces: TgirNamespaces; AWantTest: Boolean);
|
||||||
begin
|
begin
|
||||||
FNameSpaces := ANameSpaces;
|
FNameSpaces := ANameSpaces;
|
||||||
FUnits := TList.Create;
|
FUnits := TList.Create;
|
||||||
|
FDefaultUnitExtension:='.pas';
|
||||||
|
FWantTest:=AWantTest;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TgirPascalWriter.GenerateUnits;
|
procedure TgirPascalWriter.GenerateUnits;
|
||||||
@ -1774,16 +1876,23 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
FUnit: TPascalUnit;
|
FUnit: TPascalUnit;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
for i := 0 to FNameSpaces.Count-1 do
|
for i := 0 to FNameSpaces.Count-1 do
|
||||||
begin
|
begin
|
||||||
WriteLn(Format('Converting %s', [FNameSpaces.NameSpace[i].NameSpace]));
|
WriteLn(Format('Converting %s', [FNameSpaces.NameSpace[i].NameSpace]));
|
||||||
FUnit := TPascalUnit.Create(FNameSpaces.NameSpace[i], False);
|
FUnit := TPascalUnit.Create(FNameSpaces.NameSpace[i], False, FWantTest);
|
||||||
FUnit.ProcessConsts(FNameSpaces.NameSpace[i].Constants);
|
FUnit.ProcessConsts(FNameSpaces.NameSpace[i].Constants);
|
||||||
FUnit.ProcessTypes(FNameSpaces.NameSpace[i].Types);
|
FUnit.ProcessTypes(FNameSpaces.NameSpace[i].Types);
|
||||||
FUnit.ProcessFunctions(FNameSpaces.NameSpace[i].Functions);
|
FUnit.ProcessFunctions(FNameSpaces.NameSpace[i].Functions);
|
||||||
|
FUnit.Finish;
|
||||||
FUnits.Add(FUnit);
|
FUnits.Add(FUnit);
|
||||||
FOnUnitWriteEvent(Self, FUnit.UnitName, FUnit.AsStream);
|
FOnUnitWriteEvent(Self, FUnit.UnitName+FDefaultUnitExtension, FUnit.AsStream);
|
||||||
|
if FWantTest then
|
||||||
|
begin
|
||||||
|
FOnUnitWriteEvent(Self, FUnit.UnitName+'_test'+FDefaultUnitExtension, FUnit.FTestPascalFile);
|
||||||
|
FOnUnitWriteEvent(Self, FUnit.UnitName+'_c_test.c', FUnit.FTestCFile);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user