Merge branch 'gir2pas' into 'main'

gir2pas: Enabled generating Pascal sets to C bitfield enums by CLO.

See merge request freepascal.org/lazarus/lazarus!196
This commit is contained in:
Maxim Ganetsky 2023-06-04 10:16:08 +00:00
commit da2f33c174
5 changed files with 65 additions and 67 deletions

View File

@ -1 +1 @@
/gir2pascal /gir2pas

View File

@ -1,9 +1,28 @@
SOURCES := $(wildcard *.pas) SOURCES=$(wildcard *.pas)
OPTIONS := -O2 TARGET_CPU=$(shell fpc -iTP)
OBJ := *.o *.or *.ppu *.rsj TARGET_OS=$(shell fpc -iTO)
UNITS_DIR=lib/tools/gir2pascal/${TARGET_CPU}-${TARGET_OS}
OPTIONS=\
-MObjFPC\
-Scghi\
-Cg\
-O1\
-gw2\
-godwarfsets\
-gl\
-l\
-vewnhibq\
-Fi${UNITS_DIR}\
-Fu${UNITS_DIR}\
-FU${UNITS_DIR}\
-FE.\
gir2pascal: gir2pascal.lpr $(SOURCES) OBJ=*.o *.or *.ppu *.rsj
fpc $(OPTIONS) $<
gir2pas:gir2pascal.lpr $(SOURCES)
fpc $(OPTIONS) $< -o$@
clean: clean:
rm -f gir2pascal $(OBJ) ${RM} gir2pas ${UNITS_DIR} $(OBJ)
.PHONY: clean

View File

@ -1,17 +1,15 @@
gir2pascal # gir2pas
==========
This is the [gir2pascal][] utility, a program to convert the The [gir2pas][] utility is a program to convert the
GIR metadata format (= XML files) used by [GObject introspection][] into usable GIR metadata format (= XML files) used by [GObject introspection][] into usable
Pascal source code, suitable for generating corresponding language bindings. Pascal source code, suitable for generating corresponding language bindings.
The original is part of the Lazarus Code and Component Repository ([lazarus-ccr][], It was originaly named [gir2pascal] maintained as part of the Lazarus Code and Component Repository ([lazarus-ccr][],
[wiki article][wiki-ccr]), see `applications/gobject-introspection/`. Later it has [wiki article][wiki-ccr]), see `applications/gobject-introspection/`. Later it has
received some maintenance by [n1tehawk][] and finally was imported from his received some maintenance by [n1tehawk][] and finally was imported from his
repository into Lazarus source tree. repository into Lazarus source tree.
License # License
-------
This project builds upon the original Lazarus CCR version and is thus intended This project builds upon the original Lazarus CCR version and is thus intended
to follow the same licensing principles. For the `gobject-introspection` folder to follow the same licensing principles. For the `gobject-introspection` folder
@ -22,4 +20,4 @@ this seems to be [GPL v2](LICENSE.md), as referenced in a number of file headers
[GObject introspection]: https://gi.readthedocs.io/ [GObject introspection]: https://gi.readthedocs.io/
[lazarus-ccr]: https://sourceforge.net/projects/lazarus-ccr/ [lazarus-ccr]: https://sourceforge.net/projects/lazarus-ccr/
[wiki-ccr]: https://wiki.lazarus.freepascal.org/Lazarus-ccr_SourceForge_repository [wiki-ccr]: https://wiki.lazarus.freepascal.org/Lazarus-ccr_SourceForge_repository
[n1tehawk]: https://github.com/n1tehawk/gir2pascal [n1tehawk]: https://github.com/n1tehawk/gir2pascal

View File

@ -85,7 +85,7 @@
<CompilerOptions> <CompilerOptions>
<Version Value="11"/> <Version Value="11"/>
<Target> <Target>
<Filename Value="gir2pascal"/> <Filename Value="gir2pas"/>
</Target> </Target>
<SearchPaths> <SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/> <IncludeFiles Value="$(ProjOutDir)"/>

View File

@ -1028,6 +1028,8 @@ var
ProperUnit: TPascalUnit; ProperUnit: TPascalUnit;
IntType: String; IntType: String;
Value: String; Value: String;
UIntValue: QWord;
MSB: Integer;
begin begin
ProperUnit := FGroup.GetUnitForType(utTypes); ProperUnit := FGroup.GetUnitForType(utTypes);
if ProperUnit <> Self then begin if ProperUnit <> Self then begin
@ -1037,8 +1039,14 @@ begin
ResolveTypeTranslation(AItem); ResolveTypeTranslation(AItem);
ConstSection := WantConstSection; ConstSection := WantConstSection;
if goEnumAsSet in FOptions then begin if (goEnumAsSet in FOptions) and (AItem is TgirBitField) then begin
raise Exception.Create('Not yet supported!'); // forces forward declarations to be written
ProcessType(AItem);
TypeName := AItem.TranslatedName + 'Idx';
Section := WantEnumTypesSection;
Section.Lines.Add(IndentText(TypeName + ' = (', 2, 0));
Section.Lines.Add(IndentText(TypeName + 'MinValue = 0,', 4, 0));
AItem.Members.Sort(@CompareEnumValues)
end else if goEnumAsEnum in FOptions then begin end else if goEnumAsEnum in FOptions then begin
// forces forward declarations to be written // forces forward declarations to be written
ProcessType(AItem); ProcessType(AItem);
@ -1091,7 +1099,13 @@ begin
if CName = 'ATK_HYPERLINK_IS_INLINE' then if CName = 'ATK_HYPERLINK_IS_INLINE' then
CName :='ATK_HYPERLINK_IS_INLINE_'; CName :='ATK_HYPERLINK_IS_INLINE_';
Value := AItem.Members.Member[i]^.Value; Value := AItem.Members.Member[i]^.Value;
if goEnumAsSet in FOptions then begin if (goEnumAsSet in FOptions) and (AItem is TgirBitField) then begin
UIntValue := UInt64(StrToInt(Value));
MSB := BsrQWord(UIntValue);
if UIntValue > 1 shl MSB then
Continue;
Value := IntToStr(MSB);
Entry := IndentText(CName + ' = ' + Value + ',', 4, 0);;
end else if goEnumAsEnum in FOptions then begin end else if goEnumAsEnum in FOptions then begin
Entry := IndentText(CName + ' = ' + Value + ',', 4, 0); Entry := IndentText(CName + ' = ' + Value + ',', 4, 0);
end else if goEnumAsIntAliasConst in FOptions then begin end else if goEnumAsIntAliasConst in FOptions then begin
@ -1103,67 +1117,34 @@ begin
end; end;
Section.Lines.Add(Entry); Section.Lines.Add(Entry);
end; end;
if (goEnumAsSet in FOptions) and (AItem is TgirBitField) then begin
Value := '31';
end else begin
Value := '$7FFFFFFF';
end;
if goEnumAsEnum in FOptions then begin if goEnumAsEnum in FOptions then begin
Section.Lines.Add(IndentText(TypeName + 'MaxValue = $7FFFFFFF', 4, 0)); Section.Lines.Add(IndentText(TypeName + 'MaxValue = ' + Value, 4, 0));
Section.Lines.Add(IndentText(');', 2, 0)); Section.Lines.Add(IndentText(');', 2, 0));
end; end;
AItem.Writing:=msWritten; AItem.Writing:=msWritten;
end; end;
procedure TPascalUnit.HandleBitfield(AItem: TgirBitField); procedure TPascalUnit.HandleBitfield(AItem: TgirBitField);
{
const
TemplateLongWord =
'%s = packed object(TBitObject32)'+LineEnding+
'%s'+LineEnding+
'end';
var var
Intf: TPDeclarationType; Section: TPDeclarationWithLines;
CodeText: TPCodeText; TypeName: String;
Code: TStringList;
PName: String;
Entry: String;
i: Integer;
VarType: String;
}
begin begin
HandleEnum(AItem); if goEnumAsSet in FOptions then begin
(* Include(FOptions, goEnumAsEnum);
Intf := WantTypeSection;
CodeText := TPCodeText.Create;
ImplementationSection.Declarations.Add(CodeText);
Code := TStringList.Create;
PName:=MakePascalTypeFromCType(AItem.CType);
{case AItem.Bits of
//1..8: VarType:='Byte';
//9..16: VarType:='Word';
//0:;
//17..32: VarType:='LongWord';
//33..64: VarType:='QWord';
else
WriteLn('Bitfield <> 16bits');
Halt;
end; end;
}
HandleEnum(AItem); HandleEnum(AItem);
if goEnumAsSet in FOptions then begin
Section := WantEnumTypesSection;
TypeName := AItem.TranslatedName;
end;
Section.Lines.Add(IndentText(TypeName + ' = Set of ' + TypeName + 'Idx;', 2, 0));
Section.Lines.Add('');
VarType:='DWord';
Intf.Lines.Add(IndentText(PName+ ' = packed object(TBitObject32)',2,0));
Intf.Lines.Add(IndentText('public',2,0));
for i := 0 to AItem.Members.Count-1 do
begin
Entry := 'property '+ SanitizeName(AItem.Members.Member[i]^.Name) +': '+VarType+' index '+AItem.Members.Member[i]^.Value+' read GetBit write SetBit;';
Intf.Lines.Add(IndentText(Entry, 4,0));
end;
Intf.Lines.Add(IndentText('end;',2,0));
Intf.Lines.Add('');
CodeText.Content:=Code.Text;
Code.Free;
*)
end; end;
procedure TPascalUnit.HandleRecord(AItem: TgirRecord); procedure TPascalUnit.HandleRecord(AItem: TgirRecord);