From bb05d66329f94a18a936cbf7fbf2adab8c3dc33c Mon Sep 17 00:00:00 2001 From: Abou Al Montacir Date: Tue, 9 May 2023 20:45:48 +0200 Subject: [PATCH 1/2] Renamed executable from gir2pascal to gir2pas. --- tools/gir2pascal/.gitignore | 2 +- tools/gir2pascal/Makefile | 31 +++++++++++++++++++++++++------ tools/gir2pascal/README.md | 12 +++++------- tools/gir2pascal/gir2pascal.lpi | 2 +- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/tools/gir2pascal/.gitignore b/tools/gir2pascal/.gitignore index d422b6f1c2..f1256ad73d 100644 --- a/tools/gir2pascal/.gitignore +++ b/tools/gir2pascal/.gitignore @@ -1 +1 @@ -/gir2pascal +/gir2pas diff --git a/tools/gir2pascal/Makefile b/tools/gir2pascal/Makefile index bc86bfe82d..385fbd1a51 100644 --- a/tools/gir2pascal/Makefile +++ b/tools/gir2pascal/Makefile @@ -1,9 +1,28 @@ -SOURCES := $(wildcard *.pas) -OPTIONS := -O2 -OBJ := *.o *.or *.ppu *.rsj +SOURCES=$(wildcard *.pas) +TARGET_CPU=$(shell fpc -iTP) +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) - fpc $(OPTIONS) $< +OBJ=*.o *.or *.ppu *.rsj + +gir2pas:gir2pascal.lpr $(SOURCES) + fpc $(OPTIONS) $< -o$@ clean: - rm -f gir2pascal $(OBJ) + ${RM} gir2pas ${UNITS_DIR} $(OBJ) + +.PHONY: clean diff --git a/tools/gir2pascal/README.md b/tools/gir2pascal/README.md index 642ee01e97..beae07e98f 100644 --- a/tools/gir2pascal/README.md +++ b/tools/gir2pascal/README.md @@ -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 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 received some maintenance by [n1tehawk][] and finally was imported from his repository into Lazarus source tree. -License -------- +# License This project builds upon the original Lazarus CCR version and is thus intended 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/ [lazarus-ccr]: https://sourceforge.net/projects/lazarus-ccr/ [wiki-ccr]: https://wiki.lazarus.freepascal.org/Lazarus-ccr_SourceForge_repository -[n1tehawk]: https://github.com/n1tehawk/gir2pascal \ No newline at end of file +[n1tehawk]: https://github.com/n1tehawk/gir2pascal diff --git a/tools/gir2pascal/gir2pascal.lpi b/tools/gir2pascal/gir2pascal.lpi index 9da34d667a..30f4f0ccd5 100644 --- a/tools/gir2pascal/gir2pascal.lpi +++ b/tools/gir2pascal/gir2pascal.lpi @@ -85,7 +85,7 @@ - + From cd0756f17ba80d710a283288e98ddfda41d55323 Mon Sep 17 00:00:00 2001 From: Abou Al Montacir Date: Sat, 3 Jun 2023 23:46:46 +0200 Subject: [PATCH 2/2] gir2pas: Enabled generating Pascal sets to C bitfield enums by CLO. Based on command line option (CLO) `-e/--declare-enums-as` that selects the way how to define C enums and bit fields. Added support for 5th options in addition 4 already implemented. 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 now implemented. --- tools/gir2pascal/girpascalwritertypes.pas | 85 +++++++++-------------- 1 file changed, 33 insertions(+), 52 deletions(-) diff --git a/tools/gir2pascal/girpascalwritertypes.pas b/tools/gir2pascal/girpascalwritertypes.pas index 73da5888f0..24c0d3862d 100644 --- a/tools/gir2pascal/girpascalwritertypes.pas +++ b/tools/gir2pascal/girpascalwritertypes.pas @@ -1028,6 +1028,8 @@ var ProperUnit: TPascalUnit; IntType: String; Value: String; + UIntValue: QWord; + MSB: Integer; begin ProperUnit := FGroup.GetUnitForType(utTypes); if ProperUnit <> Self then begin @@ -1037,8 +1039,14 @@ begin ResolveTypeTranslation(AItem); ConstSection := WantConstSection; - if goEnumAsSet in FOptions then begin - raise Exception.Create('Not yet supported!'); + if (goEnumAsSet in FOptions) and (AItem is TgirBitField) then begin + // 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 // forces forward declarations to be written ProcessType(AItem); @@ -1091,7 +1099,13 @@ begin if CName = 'ATK_HYPERLINK_IS_INLINE' then CName :='ATK_HYPERLINK_IS_INLINE_'; 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 Entry := IndentText(CName + ' = ' + Value + ',', 4, 0); end else if goEnumAsIntAliasConst in FOptions then begin @@ -1103,67 +1117,34 @@ begin end; Section.Lines.Add(Entry); 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 - Section.Lines.Add(IndentText(TypeName + 'MaxValue = $7FFFFFFF', 4, 0)); + Section.Lines.Add(IndentText(TypeName + 'MaxValue = ' + Value, 4, 0)); Section.Lines.Add(IndentText(');', 2, 0)); end; AItem.Writing:=msWritten; end; procedure TPascalUnit.HandleBitfield(AItem: TgirBitField); -{ -const - TemplateLongWord = - '%s = packed object(TBitObject32)'+LineEnding+ - '%s'+LineEnding+ - 'end'; var - Intf: TPDeclarationType; - CodeText: TPCodeText; - Code: TStringList; - PName: String; - Entry: String; - i: Integer; - VarType: String; - } + Section: TPDeclarationWithLines; + TypeName: String; begin - HandleEnum(AItem); -(* - 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; + if goEnumAsSet in FOptions then begin + Include(FOptions, goEnumAsEnum); end; - } 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; procedure TPascalUnit.HandleRecord(AItem: TgirRecord);