fix for use of module name prefixes in mconnect() macro

This commit is contained in:
Stefan Salewski 2021-11-03 23:24:33 +01:00
commit e03895ceb9
5 changed files with 109 additions and 38 deletions

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017, 2018, 2019, 2020, 2021 Dr. StefanSalewski
Copyright (c) 2017, 2018, 2019, 2020, 2021, 2022 Dr. StefanSalewski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,6 +1,6 @@
= High level GTK4 and GTK3 bindings for the Nim programming language
//(c) Stefan Salewski
//Version 0.9.6
//Version 0.9.7
:experimental:
:imagesdir: http://ssalewski.de/tmp
//:source-highlighter: pygments
@ -26,10 +26,19 @@ allow to insert code from files, so I had to manually insert it, and so that cod
may not compile with latest gintro version. I plan to create a new page hosted somewhere else
with code inserted from files directly.
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by A. Rumpf, E. Bassi and other _Nim_ and _GTK/Gnome_ developers.
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by E. Bassi and other _GTK/Gnome_ developers.
The `combinatorics` module was kindly provided by R. Behrends.
NOTE: This is version 0.9.6 of the gintro Nim GTK bindings. We tried to fix a bug related to the appearance of libsoup 3.0.
NOTE: Currently we are preparing version 0.9.7 of the gintro Nim GTK bindings. In this version we try to fix an
issue resulting from use of symbols without a module prefix in the code generated by the mconnect() macro.
See https://github.com/StefanSalewski/gintro/issues/188. Unfortunately this fix may break some existing projects.
We tried hard to make changes as tiny as possible: We tried to let the content of the generated modules unchanged,
and changed only files gimplgob.nim and gen.nim and the generated gisup4.nim and gisup3.nim files.
The example programs still compile and seems to run. To install this new version you have to do
nimble install gintro@#head currently. When Mr. GavR has tested this version carefully, we may make it the
official version 0.9.7.
NOTE: In version 0.9.6 of the gintro Nim GTK bindings we tried to fix a bug related to the appearance of libsoup 3.0.
When gobject-introspection was first processing libnice, it loads old libsoup 2.4 and when then processing linsoup 3.0
name conflicts lead to error messages and the install process hung. Now we process always libsoup in version 2.4 and 3.0
before libnice, this seems to work. For libsoup 2.4 we generate a module called libsoup.nim as before, and the

View file

@ -1,6 +1,6 @@
# Package
version = "0.9.6"
version = "0.9.7"
author = "Stefan Salewski"
description = "High level GObject-Introspection based GTK4/GTK3 bindings"
license = "MIT"

View file

@ -19,7 +19,8 @@ proc findSignal(name, obj: NimNode): string =
let str = ($name).replace("-", "_") & RecSep
#echo str
if str.startsWith("notify::"):
return "notify!Object!1!(self: Object; paramSpec: ParamSpec)!(self: ptr Object00; paramSpec: ptr ParamSpec00)"
#return "notify!Object!1!(self: Object; paramSpec: ParamSpec)!(self: ptr Object00; paramSpec: ptr ParamSpec00)"
return "notify!gobject.Object!1!(self: gobject.Object; paramSpec: gobject.ParamSpec)!(self: ptr gobject.Object00; paramSpec: ptr gobject.ParamSpec00)" # v0.9.7
# "size_allocate!Widget!1!(self: Widget; allocation: gdk.Rectangle)!(self: ptr Widget00; allocation: gdk.Rectangle)"
var ipros: seq[string]
@ -37,7 +38,10 @@ proc findSignal(name, obj: NimNode): string =
var n = obj
while true:
if n.kind != nnkBracketExpr: break
var h = $getType(n)[1].toStrLit
#var h = $getType(n)[1].toStrLit
var h = n.getTypeInst.owner.strVal & '.' & $getType(n)[1].toStrLit # v0.9.7
#echo n.getTypeInst.owner.strVal
if h.endsWith(":ObjectType"):
h.setLen(h.len - 11)
if h == t:
@ -45,6 +49,8 @@ proc findSignal(name, obj: NimNode): string =
n = getType(n)[1]
n = getType(n)[1]
# for v0.9.7 we use full qualified symbols -- in mconect() and in the gisup files
# from file gisup.nim we have:
# "remove_editable!CellArea!2!(self: CellArea; renderer: CellRenderer; editable: CellEditable | SpinButton | ComboBox | ...
# so for signal remove_editable third parameter of handler proc can be CellEditable OR SpinButton OR ComboBox OR ...
@ -80,10 +86,11 @@ macro mconnect(widget: gobject.Object; signal: string; p: typed; arg: typed; ign
# let wts = getTypeInst(widget).strVal
let wts = widget.getTypeInst.owner.strVal & '.' & widget.getTypeInst.strVal # new in v0.5.5
let ats = at.toStrLit.strVal
#assert ats == $(at.toStrLit)
#assert ats == at.toStrLit.strVal
var ats: string # v0.9.7
if at.kind == nnkRefTy:
ats = at.getType[0].strVal & " " & at.getType[1].owner.strVal & '.' & at.getType[1].strVal
else:
ats = at.owner.strVal & '.' & at.toStrLit.strVal
var signalName = ($signal).replace("-", "_") # maybe we should just use plain proc names
var sigName: string # for the notify:: signals
@ -155,7 +162,9 @@ proc $1$2 {.cdecl.} =
(names[i], types[i]) = largs[i].split(": ")
let al = largs[i + 1].split(": ")[0]
var h = types[i]
h[0] = h[0].toLowerAscii
# h[0] = h[0].toLowerAscii # before v0.9.7
let xxx = h.find('.') + 1 # since v0.9.7
h[xxx] = h[xxx].toLowerAscii
h.add("2seq(" & names[i] & ", " & al & ")")
names[i] = h
types[i].setLen(0)
@ -376,6 +385,6 @@ $1($4)
""" % [$procName, ats, $procNameCdecl, $arg]
result = parseStmt(r1s & r2s)
# 376 lines
# 376 lines owner

View file

@ -1,6 +1,6 @@
# High level gobject-introspection based GTK4/GTK3 bindings for the Nim programming language
# nimpretty --maxLineLen:130 gen.nim
# v 0.9.6 2021-OCT-20
# v 0.9.7 2021-NOV-02
# (c) S. Salewski 2018, 2019, 2020, 2021
# usefull for finding death code:
@ -403,6 +403,21 @@ proc fixedModName(s: string): string =
if not ISGTK3 and (s == "libsoup"):
result &= "3"
proc gBaseInfoGetQualifiedName(info: GIBaseInfo; modPrefix: bool = false): string =
if modPrefix:
result = ($gBaseInfoGetNamespace(info)).toLowerAscii.fixedModName & "." & $(gir.gBaseInfoGetName(info))
if result == "gio.Application":
result = "gio.GApplication"
if result == "gio.File":
result = "gio.GFile"
else:
result = $(gir.gBaseInfoGetName(info))
let h = $(gir.gBaseInfoGetNamespace(info))
if h == "Gio" and result == "Application":
result = "GApplication"
if h == "Gio" and result == "File":
result = "GFile"
proc gBaseInfoGetName(info: GIBaseInfo): string =
result = $(gir.gBaseInfoGetName(info))
let h = $(gir.gBaseInfoGetNamespace(info))
@ -871,6 +886,7 @@ type
namePlain: string
namePlainNS: string
name00: string
name00NS: string
flags: RecResFlags
optOut: bool
@ -889,7 +905,7 @@ type
outgobjectargisoptional: bool
outgobjectargmaybenull: bool
proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; genArrayMark = false; tryOut2Ret: bool = false): GPars
proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; genArrayMark = false; tryOut2Ret: bool = false; modPrefix: bool = false): GPars
# recursive investigate that type -- resolve Arrays and Interfaces
proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
@ -907,14 +923,17 @@ proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
if atag == GITypeTag.INTERFACE:
let aface = gTypeInfoGetInterface(arrayType)
result[3] = gBaseInfoGetType(aface)
var child = newGenRec(arrayType, genProxy = true).namePlain # [0]
var rus = newGenRec(arrayType, genProxy = true)
var child = rus.namePlain # [0]
child = mangleType(mangleName(child))
result[0] = "ptr glib.List"
result[1] = glist
result[2] = child
result.namePlain = result[0]
result.namePlainNS = result[0]
result.namePlainNS = rus.namePlainNS # does not work
result.namePlainNS = result[0] # this is the old one, which is not really correct but works
result.name00 = result[0]
result.name00NS = rus.name00NS
return
if tag == GITypeTag.GSLIST:
@ -923,14 +942,19 @@ proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
if atag == GITypeTag.INTERFACE:
let aface = gTypeInfoGetInterface(arrayType)
result[3] = gBaseInfoGetType(aface)
var child = newGenRec(arrayType, genProxy = true).namePlain # [0]
var rus = newGenRec(arrayType, genProxy = true)
#var child = newGenRec(arrayType, genProxy = true).namePlain # [0]
var child = rus.namePlain
child = mangleType(mangleName(child))
result[0] = "ptr glib.SList"
result[1] = gslist
result[2] = child
result.namePlain = result[0]
result.namePlainNS = rus.namePlainNS # does not work
result.namePlainNS = result[0]
result.name00 = result[0]
#result.name00NS = result[0] # TODO as above!
result.name00NS = rus.name00NS
return
if tag == GITypeTag.ARRAY:
@ -942,7 +966,8 @@ proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
elif toa == GIArrayType.C:
let arrayType = gTypeInfoGetParamType(t, 0)
let arrayFixedSize = gTypeInfoGetArrayFixedSize(t)
var child = newGenRec(arrayType).name00 # [0]
var rus = newGenRec(arrayType)
var child = rus.name00 # [0]
child = mangleType(mangleName(child))
if arrayFixedSize != -1:
result[0] = "array[$1, $2]" % [$arrayFixedSize, child]
@ -951,6 +976,8 @@ proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
result.namePlain = result[0]
result.namePlainNS = result[0]
result.name00 = result[0]
result.name00NS = "ptr " & rus.name00NS # "ptr " & fixedModName(ns) & '.' &
assert result.name00NS.find('.') > 0
if gTypeInfoIsZeroTerminated(t):
result.flags.incl(RecResFlag.zeroTerminated)
result[1] = intA0
@ -982,6 +1009,7 @@ proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
if not (genProxy or callerAlloc.contains(ns & '.' & result[0])):
rawmark = "00"
result.namePlainNS = fixedModName(ns) & '.' & result[0]
result.name00NS = result.namePlainNS
if ns != moduleNamespace: #fullQualified or ns != moduleNamespace:
result[0] = fixedModName(ns) & '.' & result[0]
else:
@ -990,6 +1018,9 @@ proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
result.namePlain = result[0]
if result.namePlainNS.len == 0:
result.namePlainNS = result.namePlain
result.name00NS = result.namePlainNS
if p and newrawmark.len == 0 and not cAlloc:
result.namePlain = "ptr " & result.namePlain
result.namePlainNS = "ptr " & result.namePlainNS
@ -1000,6 +1031,12 @@ proc newGenRec(t: GITypeInfo; genProxy = false): RecRes =
result.name00 = "ptr " & result.name00
result.name00 = mangleType(result.name00)
result.name00 = result.name00 & newrawmark
if p:
result.name00NS = "ptr " & result.name00NS
result.name00NS = mangleType(result.name00NS)
result.name00NS = result.name00NS & newrawmark
if p and (not proxyResult):
result[0] = "ptr " & result[0]
result[0] = mangleType(result[0]) & rawmark
@ -1124,7 +1161,7 @@ proc fixedName2(s: string): string =
else:
return s
proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; genArrayMark = false; tryOut2Ret: bool = false): GPars =
proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; genArrayMark = false; tryOut2Ret: bool = false; modPrefix: bool = false): GPars =
proc makePList(s: seq[(string, string)]; self, r: string): string =
result = self
@ -1151,6 +1188,7 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; ge
else:
var ns = ($gBaseInfoGetNamespace(binfo)).toLowerAscii
if callerAlloc.contains(ns & '.' & manglename(gBaseInfoGetName(binfo))):
# self = "(self: " & manglename(gBaseInfoGetQualifiedName(binfo)) & "; "
self = "(self: " & manglename(gBaseInfoGetName(binfo)) & "; "
result.arglist = "(self"
else:
@ -1187,18 +1225,19 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; ge
arg0 = refFunc & "self.impl))"
else:
arg0 = "self.impl)"
result.arglist = "(cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" &
arg0 # "self.impl)" # https://discourse.gnome.org/t/g-arg-info-may-be-null-for-the-instace-itself/3284/7
result.arglist = "(cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" & arg0
#result.arglist = "(cast[ptr " & manglename(gBaseInfoGetQualifiedName(binfo)) & "00](" & arg0 # "self.impl)" # https://discourse.gnome.org/t/g-arg-info-may-be-null-for-the-instace-itself/3284/7
# arglist = "(if self.isNil: nil else: cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" & "self.impl)"
if genProxy:
var h = manglename(gBaseInfoGetName(binfo))
var h = manglename(gBaseInfoGetQualifiedName(binfo, modPrefix))
let provider = interfaceProvider.getOrDefault(h, @[])
if provider.len > 0:
for i in provider: discard mangleType(i)
h = h & " | " & provider.join(" | ")
self = "(self: " & h & "; "
else:
self = "(self: ptr " & manglename(gBaseInfoGetName(binfo)) & "00" & "; "
self = "(self: ptr " & manglename(gBaseInfoGetQualifiedName(binfo, modPrefix)) & "00" & "; "
#self = "(self: ptr " & manglename(gBaseInfoGetName(binfo)) & "00" & "; "
if m >= 0:
result.arglist.add(", ")
var num = ""
@ -1258,9 +1297,16 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; ge
var ngr = newGenRec(t, true)
var str: string
if genProxy and not gArgInfoIsCallerAllocates(arg):
str = ngr.namePlain
if modPrefix:
str = ngr.namePlainNS
else:
str = ngr.namePlain#NS
else:
str = ngr.name00
if modPrefix:
str = ngr.name00NS
else:
str = ngr.name00#NS
if genProxy and ngr.res == glist:
result.tempRes = " var tempResGL = seq2GList($1)\n" % [argname]
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING:
@ -1296,7 +1342,10 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; ge
hhh.delete(3, 3)
if callerAlloc.contains(hhh):
userAlloc = true
str = ngr.namePlain
if modPrefix:
str = ngr.namePlainNS
else:
str = ngr.namePlain
if genProxy:
let tag = gTypeInfoGetTag(t)
if tag == GITypeTag.INTERFACE:
@ -1478,9 +1527,11 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; ge
let h = gBaseInfoGetContainer(info)
if gBaseInfoGetType(h) == GIInfoType.OBJECT:
if genProxy:
resusres = ": " & mangleType(mangleName(gBaseInfoGetName(h)))
resusres = ": " & mangleType(mangleName(gBaseInfoGetQualifiedName(h, modPrefix)))
#resusres = ": " & mangleType(mangleName(gBaseInfoGetName(h)))
else:
resusres = ": ptr " & mangleType(mangleName(gBaseInfoGetName(h))) & "00"
resusres = ": ptr " & mangleType(mangleName(gBaseInfoGetQualifiedName(h, modPrefix))) & "00"
#resusres = ": ptr " & mangleType(mangleName(gBaseInfoGetName(h))) & "00"
if resusLen >= 0:
result.blex = resus[resusLen][0]
assert(resusIn)
@ -2692,24 +2743,24 @@ template writeSignal() =
memo.add(RecSep)
var plist, arglist: string
var replist: TableRef[string, (string, RecRes)]
(plist, arglist, replist) = genPars(signalInfo, true, info, genArrayMark = true)
(plist, arglist, replist) = genPars(signalInfo, true, info, genArrayMark = true, modPrefix = true)
memo.add(plist)
memo.add(RecSep)
(plist, arglist, replist) = genPars(signalInfo, false, info, genArrayMark = true)
(plist, arglist, replist) = genPars(signalInfo, false, info, genArrayMark = true, modPrefix = true)
memo.add(plist)
memo = memo.replace("\n ", " ")
memo = memo.replace("\"", "\\\"")
if moduleNamespace == "gtk" or moduleNamespace == "gdk" or moduleNamespace == "gdkX11" or moduleNamespace == "gtksource":
if ISGTK3:
supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) &
supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetQualifiedName(info, true) &
RecSep & memo & "\",")
else:
supmod4.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) &
supmod4.writeLine(" \"" & (gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetQualifiedName(info, true) &
RecSep & memo & "\",")
else:
supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep &
supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetQualifiedName(info, true) & RecSep &
memo & "\",")
supmod4.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep &
supmod4.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetQualifiedName(info, true) & RecSep &
memo & "\",")
if gCallableInfoGetNArgs(signalInfo) > 0:
h = h.replace(")", "; xdata: pointer)")
@ -3979,7 +4030,7 @@ proc cstringArrayToSeq*(s: ptr cstring): seq[string] =
let ninterfaces = info.gObjectInfoGetNInterfaces
if ninterfaces > 0:
var interf: seq[string]
let name = $gBaseInfoGetName(info)
let name = gBaseInfoGetQualifiedName(info)
for i in 0.cint ..< ninterfaces:
var ns = ($gBaseInfoGetNamespace(info.gObjectInfoGetInterface(i))).toLowerAscii
if ns != moduleNamespace:
@ -3988,7 +4039,7 @@ proc cstringArrayToSeq*(s: ptr cstring): seq[string] =
iname = fixedModName(ns) & "." & iname
let tname = fixedModName(moduleNamespace) & "." & $gBaseInfoGetName(info)
externInterfaces.add("proc " & fname & "*(x: " & tname & "): " & iname & " = cast[" & iname & "](x)")
interf.add($gBaseInfoGetName(info.gObjectInfoGetInterface(i)))
interf.add(gBaseInfoGetQualifiedName(info.gObjectInfoGetInterface(i)))
let builderinter = info.gObjectInfoGetInterface(i)
if gBaseInfoGetName(builderinter) == "Buildable":
buildableList.add($gBaseInfoGetName(info))
@ -3996,6 +4047,7 @@ proc cstringArrayToSeq*(s: ptr cstring): seq[string] =
assert false
else:
provInt[name] = interf
#echo "eeeeeeeeeee", provInt[name]
# Cross module interfaces -- maybe only a few, so we add it manually
# GSimpleActionGroup implements GActionGroup and GActionMap.
@ -4011,6 +4063,7 @@ proc cstringArrayToSeq*(s: ptr cstring): seq[string] =
for obj, ifaces in provInt:
for i in ifaces:
if not interfaceProvider.contains(i):
#echo "fff", obj
interfaceProvider[i] = @[obj]
else:
interfaceProvider[i].add(obj)
@ -4474,7 +4527,7 @@ launch()
# if not xcallerAlloc.contains(el):
# echo el
# 4477 lines
# 4477 lines gisup4 genPars memo genRec QRS XXX seq List TODO seeq ttempResGL HHHHHH echo
# gtk_icon_view_get_tooltip_context bug Candidate
# gtk_tree_view_get_cursor bug
#