detached 9aaf3ff

GIR: Add property getters and setters generation support for `[]string`

Signed-off-by: Felicitas Pojtinger <felicitas@pojtinger.com>
commit
9aaf3ff274df5078e3a65b5e27aed50df35d439a
author
Felicitas Pojtinger · · 2025-10-31 05:13 UTC
committer
Jeroen Wijenbergh · · 2025-12-01 16:10 UTC
parent
db73800
signature
unsigned
2 files · +82 -6
M internal/gir/types/types.go +2 -0
@@ -769,6 +769,8 @@ func mapGoTypeToGValue(goType string) (gvalueType, setMethod, getMethod string)
769769 return "TypeDoubleVal", "SetDouble", "GetDouble"
770770 case "string":
771771 return "TypeStringVal", "SetString", "GetString"
772+ case "[]string":
773+ return "BoxedStrv", "SetBoxed", "GetBoxed"
772774 default:
773775 return "", "", ""
774776 }
@@ -769,6 +769,8 @@ func mapGoTypeToGValue(goType string) (gvalueType, setMethod, getMethod string)
769 return "TypeDoubleVal", "SetDouble", "GetDouble"769 return "TypeDoubleVal", "SetDouble", "GetDouble"
770 case "string":770 case "string":
771 return "TypeStringVal", "SetString", "GetString"771 return "TypeStringVal", "SetString", "GetString"
772+ case "[]string":
773+ return "BoxedStrv", "SetBoxed", "GetBoxed"
772 default:774 default:
773 return "", "", ""775 return "", "", ""
774 }776 }
M templates/go +80 -6
@@ -172,8 +172,20 @@ func (x *{{$outer.Name}}Base) {{.Name}}({{conv .Args.API.Full}}) {{.Ret.Return}}
172172 obj := {{if $NotGObject}}gobject.{{end}}Object{}
173173 obj.Ptr = x.GoPointer()
174174 var v {{if $NotGObject}}gobject.{{end}}Value
175- v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})
176- v.{{.SetMethod}}(value)
175+ {{if eq .GValueType "BoxedStrv"}}v.Init({{if $NotGLib}}glib.{{end}}StrvGetType())
176+
177+ cStrBytes := make([][]byte, len(value))
178+ cStrings := make([]uintptr, len(value)+1)
179+ for i, s := range value {
180+ cStrBytes[i] = make([]byte, len(s)+1)
181+ copy(cStrBytes[i], s)
182+ cStrBytes[i][len(s)] = 0
183+ cStrings[i] = uintptr(unsafe.Pointer(&cStrBytes[i][0]))
184+ }
185+ cStrings[len(value)] = 0
186+
187+ v.SetBoxed(uintptr(unsafe.Pointer(&cStrings[0]))){{else}}v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})
188+ v.{{.SetMethod}}(value){{end}}
177189 obj.SetProperty("{{.CName}}", &v)
178190 }
179191 {{end}}
@@ -186,7 +198,32 @@ func (x *{{$outer.Name}}Base) {{.Name}}({{conv .Args.API.Full}}) {{.Ret.Return}}
186198 obj.Ptr = x.GoPointer()
187199 var v {{if $NotGObject}}gobject.{{end}}Value
188200 obj.GetProperty("{{.CName}}", &v)
189- return v.{{.GetMethod}}()
201+ {{if eq .GValueType "BoxedStrv"}}cStrvPtr := v.GetBoxed()
202+ if cStrvPtr == 0 {
203+ return nil
204+ }
205+
206+ var result []string
207+ ptr := cStrvPtr
208+ for {
209+ strPtr := *(*uintptr)(unsafe.Pointer(ptr))
210+ if strPtr == 0 {
211+ break
212+ }
213+
214+ var length int
215+ for i := 0; ; i++ {
216+ if *(*byte)(unsafe.Pointer(strPtr + uintptr(i))) == 0 {
217+ length = i
218+ break
219+ }
220+ }
221+
222+ bytes := unsafe.Slice((*byte)(unsafe.Pointer(strPtr)), length)
223+ result = append(result, string(bytes))
224+ ptr += unsafe.Sizeof(uintptr(0))
225+ }
226+ return result{{else}}return v.{{.GetMethod}}(){{end}}
190227 }
191228 {{end}}
192229 {{end}}
@@ -309,8 +346,20 @@ func (c *{{.Name}}) SetGoPointer(ptr uintptr) {
309346 {{if .Doc}}{{.Doc}}
310347 {{end}}func (x *{{$outer.Name}}) SetProperty{{.Name}}(value {{.GoType}}) {
311348 var v {{if $NotGObject}}gobject.{{end}}Value
312- v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})
313- v.{{.SetMethod}}(value)
349+ {{if eq .GValueType "BoxedStrv"}}v.Init({{if $NotGLib}}glib.{{end}}StrvGetType())
350+
351+ cStrBytes := make([][]byte, len(value))
352+ cStrings := make([]uintptr, len(value)+1)
353+ for i, s := range value {
354+ cStrBytes[i] = make([]byte, len(s)+1)
355+ copy(cStrBytes[i], s)
356+ cStrBytes[i][len(s)] = 0
357+ cStrings[i] = uintptr(unsafe.Pointer(&cStrBytes[i][0]))
358+ }
359+ cStrings[len(value)] = 0
360+
361+ v.SetBoxed(uintptr(unsafe.Pointer(&cStrings[0]))){{else}}v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})
362+ v.{{.SetMethod}}(value){{end}}
314363 x.SetProperty("{{.CName}}", &v)
315364 }
316365 {{end}}
@@ -321,7 +370,32 @@ func (c *{{.Name}}) SetGoPointer(ptr uintptr) {
321370 {{end}}func (x *{{$outer.Name}}) GetProperty{{.Name}}() {{.GoType}} {
322371 var v {{if $NotGObject}}gobject.{{end}}Value
323372 x.GetProperty("{{.CName}}", &v)
324- return v.{{.GetMethod}}()
373+ {{if eq .GValueType "BoxedStrv"}}cStrvPtr := v.GetBoxed()
374+ if cStrvPtr == 0 {
375+ return nil
376+ }
377+
378+ var result []string
379+ ptr := cStrvPtr
380+ for {
381+ strPtr := *(*uintptr)(unsafe.Pointer(ptr))
382+ if strPtr == 0 {
383+ break
384+ }
385+
386+ var length int
387+ for i := 0; ; i++ {
388+ if *(*byte)(unsafe.Pointer(strPtr + uintptr(i))) == 0 {
389+ length = i
390+ break
391+ }
392+ }
393+
394+ bytes := unsafe.Slice((*byte)(unsafe.Pointer(strPtr)), length)
395+ result = append(result, string(bytes))
396+ ptr += unsafe.Sizeof(uintptr(0))
397+ }
398+ return result{{else}}return v.{{.GetMethod}}(){{end}}
325399 }
326400 {{end}}
327401 {{end}}
@@ -172,8 +172,20 @@ func (x *{{$outer.Name}}Base) {{.Name}}({{conv .Args.API.Full}}) {{.Ret.Return}}
172 obj := {{if $NotGObject}}gobject.{{end}}Object{}172 obj := {{if $NotGObject}}gobject.{{end}}Object{}
173 obj.Ptr = x.GoPointer()173 obj.Ptr = x.GoPointer()
174 var v {{if $NotGObject}}gobject.{{end}}Value174 var v {{if $NotGObject}}gobject.{{end}}Value
175- v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})175+ {{if eq .GValueType "BoxedStrv"}}v.Init({{if $NotGLib}}glib.{{end}}StrvGetType())
176- v.{{.SetMethod}}(value)176+
177+ cStrBytes := make([][]byte, len(value))
178+ cStrings := make([]uintptr, len(value)+1)
179+ for i, s := range value {
180+ cStrBytes[i] = make([]byte, len(s)+1)
181+ copy(cStrBytes[i], s)
182+ cStrBytes[i][len(s)] = 0
183+ cStrings[i] = uintptr(unsafe.Pointer(&cStrBytes[i][0]))
184+ }
185+ cStrings[len(value)] = 0
186+
187+ v.SetBoxed(uintptr(unsafe.Pointer(&cStrings[0]))){{else}}v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})
188+ v.{{.SetMethod}}(value){{end}}
177 obj.SetProperty("{{.CName}}", &v)189 obj.SetProperty("{{.CName}}", &v)
178 }190 }
179 {{end}}191 {{end}}
@@ -186,7 +198,32 @@ func (x *{{$outer.Name}}Base) {{.Name}}({{conv .Args.API.Full}}) {{.Ret.Return}}
186 obj.Ptr = x.GoPointer()198 obj.Ptr = x.GoPointer()
187 var v {{if $NotGObject}}gobject.{{end}}Value199 var v {{if $NotGObject}}gobject.{{end}}Value
188 obj.GetProperty("{{.CName}}", &v)200 obj.GetProperty("{{.CName}}", &v)
189- return v.{{.GetMethod}}()201+ {{if eq .GValueType "BoxedStrv"}}cStrvPtr := v.GetBoxed()
202+ if cStrvPtr == 0 {
203+ return nil
204+ }
205+
206+ var result []string
207+ ptr := cStrvPtr
208+ for {
209+ strPtr := *(*uintptr)(unsafe.Pointer(ptr))
210+ if strPtr == 0 {
211+ break
212+ }
213+
214+ var length int
215+ for i := 0; ; i++ {
216+ if *(*byte)(unsafe.Pointer(strPtr + uintptr(i))) == 0 {
217+ length = i
218+ break
219+ }
220+ }
221+
222+ bytes := unsafe.Slice((*byte)(unsafe.Pointer(strPtr)), length)
223+ result = append(result, string(bytes))
224+ ptr += unsafe.Sizeof(uintptr(0))
225+ }
226+ return result{{else}}return v.{{.GetMethod}}(){{end}}
190 }227 }
191 {{end}}228 {{end}}
192 {{end}}229 {{end}}
@@ -309,8 +346,20 @@ func (c *{{.Name}}) SetGoPointer(ptr uintptr) {
309 {{if .Doc}}{{.Doc}}346 {{if .Doc}}{{.Doc}}
310 {{end}}func (x *{{$outer.Name}}) SetProperty{{.Name}}(value {{.GoType}}) {347 {{end}}func (x *{{$outer.Name}}) SetProperty{{.Name}}(value {{.GoType}}) {
311 var v {{if $NotGObject}}gobject.{{end}}Value348 var v {{if $NotGObject}}gobject.{{end}}Value
312- v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})349+ {{if eq .GValueType "BoxedStrv"}}v.Init({{if $NotGLib}}glib.{{end}}StrvGetType())
313- v.{{.SetMethod}}(value)350+
351+ cStrBytes := make([][]byte, len(value))
352+ cStrings := make([]uintptr, len(value)+1)
353+ for i, s := range value {
354+ cStrBytes[i] = make([]byte, len(s)+1)
355+ copy(cStrBytes[i], s)
356+ cStrBytes[i][len(s)] = 0
357+ cStrings[i] = uintptr(unsafe.Pointer(&cStrBytes[i][0]))
358+ }
359+ cStrings[len(value)] = 0
360+
361+ v.SetBoxed(uintptr(unsafe.Pointer(&cStrings[0]))){{else}}v.Init({{if $NotGObject}}gobject.{{end}}{{.GValueType}})
362+ v.{{.SetMethod}}(value){{end}}
314 x.SetProperty("{{.CName}}", &v)363 x.SetProperty("{{.CName}}", &v)
315 }364 }
316 {{end}}365 {{end}}
@@ -321,7 +370,32 @@ func (c *{{.Name}}) SetGoPointer(ptr uintptr) {
321 {{end}}func (x *{{$outer.Name}}) GetProperty{{.Name}}() {{.GoType}} {370 {{end}}func (x *{{$outer.Name}}) GetProperty{{.Name}}() {{.GoType}} {
322 var v {{if $NotGObject}}gobject.{{end}}Value371 var v {{if $NotGObject}}gobject.{{end}}Value
323 x.GetProperty("{{.CName}}", &v)372 x.GetProperty("{{.CName}}", &v)
324- return v.{{.GetMethod}}()373+ {{if eq .GValueType "BoxedStrv"}}cStrvPtr := v.GetBoxed()
374+ if cStrvPtr == 0 {
375+ return nil
376+ }
377+
378+ var result []string
379+ ptr := cStrvPtr
380+ for {
381+ strPtr := *(*uintptr)(unsafe.Pointer(ptr))
382+ if strPtr == 0 {
383+ break
384+ }
385+
386+ var length int
387+ for i := 0; ; i++ {
388+ if *(*byte)(unsafe.Pointer(strPtr + uintptr(i))) == 0 {
389+ length = i
390+ break
391+ }
392+ }
393+
394+ bytes := unsafe.Slice((*byte)(unsafe.Pointer(strPtr)), length)
395+ result = append(result, string(bytes))
396+ ptr += unsafe.Sizeof(uintptr(0))
397+ }
398+ return result{{else}}return v.{{.GetMethod}}(){{end}}
325 }399 }
326 {{end}}400 {{end}}
327 {{end}}401 {{end}}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close