mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-19 05:01:50 +02:00
gir2pascal: Generate C enums based pascal type selected by CLO, issue #39988.
Added a new command line option (CLO) `-e/--declare-enums-as` that selects the way how to define C enums and bit fields. Added support for 4 options and a 5th to be implemented later. 1. `IntConst`: No type, just use integer non typed constants. This was already implemented, but not easily selected at CLI. 2. `TypedIntConst`: Use non strict type aliases and typed constants. This was already implemented, selected by default in the code. 3. `IntAliasConst`: Use strict type aliases and non typed constants. This was newly added. 4. `Enum`: Use Pascal enumeration type for both C enums and bit fields. This was newly added. 5. `Set`: Use Pascal enumeration type for both C enums and Pascal sets for bit fields. This is not yet added.
This commit is contained in:
parent
1a9142c9e2
commit
d1f64050ea
@ -45,6 +45,7 @@ type
|
|||||||
FUnitPrefix: String;
|
FUnitPrefix: String;
|
||||||
FOverWriteFiles: Boolean;
|
FOverWriteFiles: Boolean;
|
||||||
FOptions: TgirOptions;
|
FOptions: TgirOptions;
|
||||||
|
FEnumImpl: TgirEnumImpl;
|
||||||
procedure AddDefaultPaths;
|
procedure AddDefaultPaths;
|
||||||
procedure AddPaths(APaths: String);
|
procedure AddPaths(APaths: String);
|
||||||
procedure VerifyOptions;
|
procedure VerifyOptions;
|
||||||
@ -256,6 +257,7 @@ begin
|
|||||||
AddOption(['P', 'unit-prefix'], True, 'Set a prefix to be added to each unitname.');
|
AddOption(['P', 'unit-prefix'], True, 'Set a prefix to be added to each unitname.');
|
||||||
AddOption(['M', 'max-version'], True, 'Do not include symbols introduced after <max-version>. Can be used multiple times. i.e "-M gtk-3.12 -M glib-2.23"');
|
AddOption(['M', 'max-version'], True, 'Do not include symbols introduced after <max-version>. Can be used multiple times. i.e "-M gtk-3.12 -M glib-2.23"');
|
||||||
AddOption(['k', 'keep-deprecated-version'], True, 'Include deprecated symbols that are >= to $version. Uses the same format as --max-version. Has no effect if --deprecated is defined');
|
AddOption(['k', 'keep-deprecated-version'], True, 'Include deprecated symbols that are >= to $version. Uses the same format as --max-version. Has no effect if --deprecated is defined');
|
||||||
|
AddOption(['e', 'declare-enums-as'], True, 'Declare C enums as either IntConst, TypedIntConst, IntAliasConst, Enum or Set');
|
||||||
end;
|
end;
|
||||||
FCmdOptions.ReadOptions;
|
FCmdOptions.ReadOptions;
|
||||||
if FCmdOptions.OptionsMalformed then
|
if FCmdOptions.OptionsMalformed then
|
||||||
@ -263,6 +265,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGirConsoleConverter.DoRun;
|
procedure TGirConsoleConverter.DoRun;
|
||||||
|
var
|
||||||
|
EnumImpl: TgirEnumImpl;
|
||||||
|
ErrorCode: Word;
|
||||||
begin
|
begin
|
||||||
// quick check parameters
|
// quick check parameters
|
||||||
CheckOptions;//('hnp:o:i:wtDCsO',['help','no-default','paths','output-directory', 'input', 'overwrite-files', 'test', 'dynamic', 'classes', 'seperate-units', 'objects']);
|
CheckOptions;//('hnp:o:i:wtDCsO',['help','no-default','paths','output-directory', 'input', 'overwrite-files', 'test', 'dynamic', 'classes', 'seperate-units', 'objects']);
|
||||||
@ -341,6 +346,15 @@ begin
|
|||||||
else
|
else
|
||||||
FUnitPrefix:='';
|
FUnitPrefix:='';
|
||||||
|
|
||||||
|
if FCmdOptions.HasOption('declare-enums-as') then begin
|
||||||
|
Val('goEnumAs' + FCmdOptions.OptionValue('declare-enums-as'), EnumImpl, ErrorCode);
|
||||||
|
if ErrorCode > 0 then begin
|
||||||
|
WriteLn('Invalid enum declaration type: "', FCmdOptions.OptionValue('declare-enums-as'), '"');
|
||||||
|
Terminate;
|
||||||
|
end;
|
||||||
|
Include(FOptions, EnumImpl);
|
||||||
|
end;
|
||||||
|
|
||||||
VerifyOptions;
|
VerifyOptions;
|
||||||
|
|
||||||
// does all the heavy lifting
|
// does all the heavy lifting
|
||||||
|
@ -8,9 +8,12 @@ uses
|
|||||||
Classes, SysUtils, girNameSpaces, girObjects, girTokens, contnrs, StrUtils;
|
Classes, SysUtils, girNameSpaces, girObjects, girTokens, contnrs, StrUtils;
|
||||||
|
|
||||||
type
|
type
|
||||||
TgirOption = (goWantTest, goLinkDynamic, goSeperateConsts, goClasses, goObjects, goIncludeDeprecated, goNoWrappers);
|
TgirOption = (goWantTest, goLinkDynamic, goSeperateConsts, goClasses, goObjects, goIncludeDeprecated, goNoWrappers,
|
||||||
|
goEnumAsIntConst, goEnumAsTypedIntConst, goEnumAsIntAliasConst, goEnumAsEnum, goEnumAsSet
|
||||||
|
);
|
||||||
TgirOptions = set of TgirOption;
|
TgirOptions = set of TgirOption;
|
||||||
TgirWriteEvent = procedure (Sender: TObject; AUnitName: AnsiString; AStream: TStringStream) of object;
|
TgirWriteEvent = procedure (Sender: TObject; AUnitName: AnsiString; AStream: TStringStream) of object;
|
||||||
|
TgirEnumImpl = goEnumAsIntConst..goEnumAsSet;
|
||||||
|
|
||||||
TPDeclaration = class
|
TPDeclaration = class
|
||||||
function AsString: String; virtual; abstract;
|
function AsString: String; virtual; abstract;
|
||||||
@ -200,7 +203,7 @@ type
|
|||||||
procedure HandleNativeType(AItem: TgirNativeTypeDef);
|
procedure HandleNativeType(AItem: TgirNativeTypeDef);
|
||||||
procedure HandleAlias(AItem: TgirAlias);
|
procedure HandleAlias(AItem: TgirAlias);
|
||||||
procedure HandleCallback(AItem: TgirCallback);
|
procedure HandleCallback(AItem: TgirCallback);
|
||||||
procedure HandleEnum(AItem: TgirEnumeration; ADeclareType: Boolean = True);
|
procedure HandleEnum(AItem: TgirEnumeration);
|
||||||
procedure HandleBitfield(AItem: TgirBitField);
|
procedure HandleBitfield(AItem: TgirBitField);
|
||||||
procedure HandleRecord(AItem: TgirRecord);
|
procedure HandleRecord(AItem: TgirRecord);
|
||||||
procedure HandleOpaqueType(AItem: TgirFuzzyType);
|
procedure HandleOpaqueType(AItem: TgirFuzzyType);
|
||||||
@ -906,7 +909,6 @@ end;
|
|||||||
procedure TPascalUnit.HandleAlias(AItem: TgirAlias);
|
procedure TPascalUnit.HandleAlias(AItem: TgirAlias);
|
||||||
var
|
var
|
||||||
ResolvedForName: String;
|
ResolvedForName: String;
|
||||||
CType: TGirBaseType = nil;
|
|
||||||
ProperUnit: TPascalUnit;
|
ProperUnit: TPascalUnit;
|
||||||
TargetType: TGirBaseType = nil;
|
TargetType: TGirBaseType = nil;
|
||||||
begin
|
begin
|
||||||
@ -970,55 +972,101 @@ begin
|
|||||||
TypeSect.Lines.Add(IndentText(CB,2,0))
|
TypeSect.Lines.Add(IndentText(CB,2,0))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPascalUnit.HandleEnum(AItem: TgirEnumeration; ADeclareType: Boolean = True);
|
function CompareEnumValues(v1, v2: Pointer): Integer;
|
||||||
|
begin
|
||||||
|
Result := StrToInt(PgirEnumMember(v1)^.Value) - StrToInt(PgirEnumMember(v2)^.Value);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPascalUnit.HandleEnum(AItem: TgirEnumeration);
|
||||||
var
|
var
|
||||||
ConstSection: TPDeclarationConst;
|
ConstSection: TPDeclarationConst;
|
||||||
|
Section: TPDeclarationWithLines;
|
||||||
Entry: String;
|
Entry: String;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
CName: String;
|
CName: String;
|
||||||
TypeName: String;
|
TypeName: String;
|
||||||
ProperUnit: TPascalUnit;
|
ProperUnit: TPascalUnit;
|
||||||
IntType: String;
|
IntType: String;
|
||||||
|
Value: String;
|
||||||
begin
|
begin
|
||||||
ProperUnit := FGroup.GetUnitForType(utTypes);
|
ProperUnit := FGroup.GetUnitForType(utTypes);
|
||||||
if ProperUnit <> Self then begin
|
if ProperUnit <> Self then begin
|
||||||
ProperUnit.HandleEnum(AItem, ADeclareType);
|
ProperUnit.HandleEnum(AItem);
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
ResolveTypeTranslation(AItem);
|
ResolveTypeTranslation(AItem);
|
||||||
|
|
||||||
ConstSection := WantConstSection;
|
ConstSection := WantConstSection;
|
||||||
ConstSection.Lines.Add('');
|
if goEnumAsSet in FOptions then begin
|
||||||
//ATK_HYPERLINK_IS_INLINE_
|
raise Exception.Create('Not yet supported!');
|
||||||
if ADeclareType then
|
end else if goEnumAsEnum in FOptions then begin
|
||||||
begin
|
// forces forward declarations to be written
|
||||||
|
ProcessType(AItem);
|
||||||
|
TypeName := AItem.TranslatedName;
|
||||||
|
Section := WantTypeSection;
|
||||||
|
Section.Lines.Add(IndentText(TypeName + ' = (', 2, 0));
|
||||||
|
Section.Lines.Add(IndentText(TypeName + 'MinValue = -$7FFFFFFF,', 4, 0));
|
||||||
|
AItem.Members.Sort(@CompareEnumValues)
|
||||||
|
end else if goEnumAsIntAliasConst in FOptions then begin
|
||||||
|
// forces forward declarations to be written
|
||||||
|
ProcessType(AItem);
|
||||||
|
TypeName := AItem.TranslatedName;
|
||||||
|
Section := WantConstSection;
|
||||||
|
Section.Lines.Add('');
|
||||||
|
Section.Lines.Add('type');
|
||||||
|
if AItem.NeedsSignedType then
|
||||||
|
IntType := 'Integer'
|
||||||
|
else
|
||||||
|
IntType := 'DWord';
|
||||||
|
// yes we cheat a little here using the const section to write type info
|
||||||
|
Section.Lines.Add(IndentText(TypeName + ' = type ' + IntType + ';', 2, 0));
|
||||||
|
Section.Lines.Add('const');
|
||||||
|
Section.Lines.Add(IndentText('{ '+ AItem.CType + ' }', 2, 0));
|
||||||
|
end else if goEnumAsTypedIntConst in FOptions then begin
|
||||||
// forces forward declarations to be written
|
// forces forward declarations to be written
|
||||||
ProcessType(AItem);
|
ProcessType(AItem);
|
||||||
|
|
||||||
TypeName := ': '+AItem.TranslatedName;
|
TypeName := AItem.TranslatedName;
|
||||||
|
|
||||||
if AItem.NeedsSignedType then
|
if AItem.NeedsSignedType then
|
||||||
IntType := 'Integer'
|
IntType := 'Integer'
|
||||||
else
|
else
|
||||||
IntType := 'DWord';
|
IntType := 'DWord';
|
||||||
|
|
||||||
// yes we cheat a little here using the const section to write type info
|
// yes we cheat a little here using the const section to write type info
|
||||||
|
ConstSection.Lines.Add('');
|
||||||
ConstSection.Lines.Add('type');
|
ConstSection.Lines.Add('type');
|
||||||
ConstSection.Lines.Add(IndentText(AItem.TranslatedName+' = '+IntType+';', 2,0));
|
ConstSection.Lines.Add(IndentText(AItem.TranslatedName+' = '+IntType+';', 2,0));
|
||||||
ConstSection.Lines.Add('const');
|
ConstSection.Lines.Add('const');
|
||||||
end
|
ConstSection.Lines.Add(IndentText('{ '+ AItem.CType + ' }', 2, 0));
|
||||||
else
|
Section := ConstSection;
|
||||||
|
end else begin
|
||||||
TypeName:='';
|
TypeName:='';
|
||||||
ConstSection.Lines.Add(IndentText('{ '+ AItem.CType + ' }',2,0));
|
ConstSection.Lines.Add(IndentText('{ '+ AItem.CType + ' }', 2, 0));
|
||||||
|
Section := ConstSection;
|
||||||
|
end;
|
||||||
|
|
||||||
for i := 0 to AItem.Members.Count-1 do
|
for i := 0 to AItem.Members.Count-1 do
|
||||||
begin
|
begin
|
||||||
CName := AItem.Members.Member[i]^.CIdentifier;
|
CName := AItem.Members.Member[i]^.CIdentifier;
|
||||||
if CName = 'ATK_HYPERLINK_IS_INLINE' then
|
if CName = 'ATK_HYPERLINK_IS_INLINE' then
|
||||||
CName :='ATK_HYPERLINK_IS_INLINE_';
|
CName :='ATK_HYPERLINK_IS_INLINE_';
|
||||||
Entry := CName + TypeName+ ' = ' + AItem.Members.Member[i]^.Value+';';
|
Value := AItem.Members.Member[i]^.Value;
|
||||||
ConstSection.Lines.Add(IndentText(Entry,2,0));
|
if goEnumAsSet in FOptions then begin
|
||||||
|
end else if goEnumAsEnum in FOptions then begin
|
||||||
|
Entry := IndentText(CName + ' = ' + Value + ',', 4, 0);
|
||||||
|
end else if goEnumAsIntAliasConst in FOptions then begin
|
||||||
|
Entry := IndentText(CName + ' = ' + TypeName + '(' + Value + ');', 2, 0);
|
||||||
|
end else if goEnumAsTypedIntConst in FOptions then begin
|
||||||
|
Entry := IndentText(CName + ': ' + TypeName + ' = ' + Value + ';', 2, 0);
|
||||||
|
end else begin
|
||||||
|
Entry := IndentText(CName + ' = ' + Value + ';', 2, 0);
|
||||||
|
end;
|
||||||
|
Section.Lines.Add(Entry);
|
||||||
end;
|
end;
|
||||||
|
if goEnumAsEnum in FOptions then begin
|
||||||
|
Section.Lines.Add(IndentText(TypeName + 'MaxValue = $7FFFFFFF', 4, 0));
|
||||||
|
Section.Lines.Add(IndentText(');', 2, 0));
|
||||||
|
end;
|
||||||
AItem.Writing:=msWritten;
|
AItem.Writing:=msWritten;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1039,7 +1087,7 @@ var
|
|||||||
VarType: String;
|
VarType: String;
|
||||||
}
|
}
|
||||||
begin
|
begin
|
||||||
HandleEnum(AItem, True);
|
HandleEnum(AItem);
|
||||||
(*
|
(*
|
||||||
Intf := WantTypeSection;
|
Intf := WantTypeSection;
|
||||||
CodeText := TPCodeText.Create;
|
CodeText := TPCodeText.Create;
|
||||||
@ -1059,7 +1107,7 @@ begin
|
|||||||
Halt;
|
Halt;
|
||||||
end;
|
end;
|
||||||
}
|
}
|
||||||
HandleEnum(AItem, False);
|
HandleEnum(AItem);
|
||||||
|
|
||||||
VarType:='DWord';
|
VarType:='DWord';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user