some bug fixes
This commit is contained in:
parent
b0c8857651
commit
8b0f82455e
1 changed files with 162 additions and 11 deletions
173
tests/gen.nim
173
tests/gen.nim
|
|
@ -1,5 +1,5 @@
|
||||||
# High level gobject-introspection based GTK3 bindings for the Nim programming language
|
# High level gobject-introspection based GTK3 bindings for the Nim programming language
|
||||||
# v 0.2 2017-SEP-08
|
# v 0.2 2017-SEP-13
|
||||||
# (c) S. Salewski 2017
|
# (c) S. Salewski 2017
|
||||||
|
|
||||||
# https://wiki.gnome.org/Projects/GObjectIntrospection
|
# https://wiki.gnome.org/Projects/GObjectIntrospection
|
||||||
|
|
@ -200,6 +200,7 @@ gtk.TextIter
|
||||||
pango.Weight
|
pango.Weight
|
||||||
gdk.Rectangle
|
gdk.Rectangle
|
||||||
gtk.AccelKey
|
gtk.AccelKey
|
||||||
|
gtksource.RegionIter
|
||||||
gtk.TextAttributes
|
gtk.TextAttributes
|
||||||
gobject.Value
|
gobject.Value
|
||||||
gobject.SignalQuery
|
gobject.SignalQuery
|
||||||
|
|
@ -289,7 +290,6 @@ proc genRec(t: GITypeInfo; genProxy = false; fullQualified: bool = false): strin
|
||||||
result = mangleType(result)
|
result = mangleType(result)
|
||||||
if p and (not proxyResult):# or callerAlloc.contains(result)):
|
if p and (not proxyResult):# or callerAlloc.contains(result)):
|
||||||
result = "ptr " & result
|
result = "ptr " & result
|
||||||
var xxx = result
|
|
||||||
result = mangleType(result) & rawmark
|
result = mangleType(result) & rawmark
|
||||||
|
|
||||||
proc isProxyCandidate(t: GITypeInfo): bool =
|
proc isProxyCandidate(t: GITypeInfo): bool =
|
||||||
|
|
@ -368,6 +368,10 @@ proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (str
|
||||||
if gArgInfoIsCallerAllocates(arg):
|
if gArgInfoIsCallerAllocates(arg):
|
||||||
callerAllocCollector.incl(genRec(t, true, true))
|
callerAllocCollector.incl(genRec(t, true, true))
|
||||||
var str = genRec(t, genProxy and not gArgInfoIsCallerAllocates(arg))
|
var str = genRec(t, genProxy and not gArgInfoIsCallerAllocates(arg))
|
||||||
|
|
||||||
|
if (sym.startsWith("gtk_widget_set_events") or sym.startsWith("gtk_widget_add_events")) and str == "int32":
|
||||||
|
str = "gdk.EventMask"
|
||||||
|
|
||||||
if isSignalInfo(info) and isProxyCandidate(t) and not genProxy:
|
if isSignalInfo(info) and isProxyCandidate(t) and not genProxy:
|
||||||
str.insert("ptr ")
|
str.insert("ptr ")
|
||||||
var userAlloc: bool
|
var userAlloc: bool
|
||||||
|
|
@ -567,6 +571,35 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) =
|
||||||
methodBuffer.writeLine(" g_object_unref(result.impl)")
|
methodBuffer.writeLine(" g_object_unref(result.impl)")
|
||||||
methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)")
|
methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)")
|
||||||
methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))")
|
methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))")
|
||||||
|
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||||
|
if sym == "g_closure_new_simple":
|
||||||
|
let nMethods = gStructInfoGetNMethods(info)
|
||||||
|
for j in 0 .. <nMethods:
|
||||||
|
echo "yes there is unref method! ", $gBaseInfoGetName(gStructInfoGetMethod(info, j))
|
||||||
|
#assert(gStructInfoFindMethod(info, "unref") != nil) # TODO GI bug?
|
||||||
|
assert info != nil
|
||||||
|
var freeMe: GIFunctionInfo
|
||||||
|
if gBaseInfoGetType(info) == GIInfoType.UNION:
|
||||||
|
freeMe = gUnionInfoFindMethod(info, "free")
|
||||||
|
if freeMe.isNil:
|
||||||
|
freeMe = gUnionInfoFindMethod(info, "unref")
|
||||||
|
else:
|
||||||
|
assert gBaseInfoGetType(info) == GIInfoType.STRUCT
|
||||||
|
freeMe = gStructInfoFindMethod(info, "free")
|
||||||
|
if freeMe.isNil:
|
||||||
|
freeMe = gStructInfoFindMethod(info, "unref")
|
||||||
|
var freeMeName: string
|
||||||
|
if freeMe == nil:
|
||||||
|
echo "Caution: No free/unref found for ", ' ', " (", sym, ')' # Mostly missing cairo functions...
|
||||||
|
else:
|
||||||
|
freeMeName = $gBaseInfoGetName(freeMe)
|
||||||
|
if sym == "g_closure_new_simple" or sym == "g_closure_new_object": freeMeName = "unref" # TODO GI bug?
|
||||||
|
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
|
||||||
|
if freeMeName.isNil:
|
||||||
|
methodBuffer.writeLine(" new(result)")
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(" new(result, $1)" % freeMeName)
|
||||||
|
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
||||||
else:
|
else:
|
||||||
methodBuffer.writeLine(" new(result)")
|
methodBuffer.writeLine(" new(result)")
|
||||||
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
||||||
|
|
@ -576,7 +609,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) =
|
||||||
elif isProxyCandidate(ret2):
|
elif isProxyCandidate(ret2):
|
||||||
if info != nil:
|
if info != nil:
|
||||||
asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info)))
|
asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info)))
|
||||||
#asym = asym.replace("get", "get" & manglename(gBaseInfoGetName(info)))
|
|
||||||
if fixedProcNames.contains(sym):
|
if fixedProcNames.contains(sym):
|
||||||
asym = fixedProcNames[sym]
|
asym = fixedProcNames[sym]
|
||||||
methodBuffer.writeLine("\nproc " & asym & EM & plist & " =")
|
methodBuffer.writeLine("\nproc " & asym & EM & plist & " =")
|
||||||
|
|
@ -603,6 +635,33 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) =
|
||||||
methodBuffer.writeLine(" g_object_unref(result.impl)")
|
methodBuffer.writeLine(" g_object_unref(result.impl)")
|
||||||
methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)")
|
methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)")
|
||||||
methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))")
|
methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))")
|
||||||
|
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||||
|
let tag = gTypeInfoGetTag(ret2)
|
||||||
|
assert tag == GITypeTag.INTERFACE
|
||||||
|
var iface = gTypeInfoGetInterface(ret2)
|
||||||
|
if gBaseInfoGetType(iface) == GIInfoType.INTERFACE:
|
||||||
|
iface = gInterfaceInfoGetIfaceStruct(iface)
|
||||||
|
methodBuffer.writeLine(" new(result, gobject.genericGObjectUnref)")
|
||||||
|
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
||||||
|
else:
|
||||||
|
#if gBaseInfoGetType(iface) == GIInfoType.Struct:
|
||||||
|
let nMethods = gStructInfoGetNMethods(iface)
|
||||||
|
var freeMeName: string
|
||||||
|
for j in 0 .. <nMethods:
|
||||||
|
let h = $gBaseInfoGetName(gStructInfoGetMethod(iface, j))
|
||||||
|
if h.endsWith("free"):
|
||||||
|
freeMeName = "free"
|
||||||
|
break
|
||||||
|
elif h.endsWith("unref"):
|
||||||
|
freeMeName = "unref"
|
||||||
|
break
|
||||||
|
if freeMeName.isNil:
|
||||||
|
# assert false # TODO we have to fix this case manually
|
||||||
|
echo "Caution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')'
|
||||||
|
methodBuffer.writeLine(" new(result)")
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(" new(result, $1)" % freeMeName)
|
||||||
|
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
||||||
else:
|
else:
|
||||||
methodBuffer.writeLine(" new(result)")
|
methodBuffer.writeLine(" new(result)")
|
||||||
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
methodBuffer.writeLine(" result.impl = " & sym & arglist)
|
||||||
|
|
@ -652,6 +711,11 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) =
|
||||||
if sym == "gtk_window_set_default_size":
|
if sym == "gtk_window_set_default_size":
|
||||||
methodBuffer.writeLine("\nproc `defaultSize=`*(self: Window; dim: tuple[width: int; height: int]) =")
|
methodBuffer.writeLine("\nproc `defaultSize=`*(self: Window; dim: tuple[width: int; height: int]) =")
|
||||||
methodBuffer.writeLine(" gtk_window_set_default_size(cast[ptr Window00](self.impl), int32(dim[0]), int32(dim[1]))")
|
methodBuffer.writeLine(" gtk_window_set_default_size(cast[ptr Window00](self.impl), int32(dim[0]), int32(dim[1]))")
|
||||||
|
|
||||||
|
if sym == "g_object_unref":
|
||||||
|
methodBuffer.writeLine("\nproc genericGObjectUnref*[T](self: T) =")
|
||||||
|
methodBuffer.writeLine(" g_object_unref(cast[ptr Object00](self.impl))")
|
||||||
|
|
||||||
except UndefEx:
|
except UndefEx:
|
||||||
echo "delay ", sym#, delayedMethods.len
|
echo "delay ", sym#, delayedMethods.len
|
||||||
processedFunctions.excl(sym)
|
processedFunctions.excl(sym)
|
||||||
|
|
@ -676,15 +740,27 @@ proc writeUnion(info: GIUnionInfo) =
|
||||||
output.writeLine(" SomeEvent* = Event | EventButton | EventMotion | EventTouch | EventScroll | EventCrossing | EventTouchpadSwipe | EventTouchpadPinch")
|
output.writeLine(" SomeEvent* = Event | EventButton | EventMotion | EventTouch | EventScroll | EventCrossing | EventTouchpadSwipe | EventTouchpadPinch")
|
||||||
|
|
||||||
let nMethods = gUnionInfoGetNMethods(info)
|
let nMethods = gUnionInfoGetNMethods(info)
|
||||||
|
#for j in 0 .. <nMethods:
|
||||||
|
# let mInfo = gUnionInfoGetMethod(info, j)
|
||||||
|
# writeMethod(info, minfo)
|
||||||
|
|
||||||
|
var mseq = newSeq[GIFunctionInfo]()
|
||||||
|
var freePos = -1
|
||||||
for j in 0 .. <nMethods:
|
for j in 0 .. <nMethods:
|
||||||
let mInfo = gUnionInfoGetMethod(info, j)
|
mseq.add(gUnionInfoGetMethod(info, j))
|
||||||
|
if freePos < 0 and gBaseInfoGetName(gUnionInfoGetMethod(info, j)) == "free":
|
||||||
|
freePos = j
|
||||||
|
if freePos < 0 and gBaseInfoGetName(gUnionInfoGetMethod(info, j)) == "unref":
|
||||||
|
freePos = j
|
||||||
|
if freePos > 0: swap(mseq[0], mseq[freePos])
|
||||||
|
for mInfo in mseq:
|
||||||
writeMethod(info, minfo)
|
writeMethod(info, minfo)
|
||||||
|
|
||||||
proc writeStruct(info: GIStructInfo) =
|
proc writeStruct(info: GIStructInfo) =
|
||||||
if not suppressType:
|
if not suppressType:
|
||||||
output.writeLine("type")
|
output.writeLine("type")
|
||||||
if callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
if callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
||||||
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " {.pure, byCopy.} = object")
|
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " {.pure, byRef.} = object")
|
||||||
else:
|
else:
|
||||||
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object")
|
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object")
|
||||||
let n = info.gStructInfoGetNFields()
|
let n = info.gStructInfoGetNFields()
|
||||||
|
|
@ -702,22 +778,93 @@ proc writeStruct(info: GIStructInfo) =
|
||||||
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object")
|
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object")
|
||||||
output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00")
|
output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00")
|
||||||
let nMethods = gStructInfoGetNMethods(info)
|
let nMethods = gStructInfoGetNMethods(info)
|
||||||
|
var mseq = newSeq[GIFunctionInfo]()
|
||||||
|
var freePos = -1
|
||||||
for j in 0 .. <nMethods:
|
for j in 0 .. <nMethods:
|
||||||
let mInfo = gStructInfoGetMethod(info, j)
|
mseq.add(gStructInfoGetMethod(info, j))
|
||||||
|
if freePos < 0 and gBaseInfoGetName(gStructInfoGetMethod(info, j)) == "free":
|
||||||
|
freePos = j
|
||||||
|
if freePos < 0 and gBaseInfoGetName(gStructInfoGetMethod(info, j)) == "unref":
|
||||||
|
freePos = j
|
||||||
|
if freePos > 0: swap(mseq[0], mseq[freePos])
|
||||||
|
for mInfo in mseq:
|
||||||
writeMethod(info, minfo)
|
writeMethod(info, minfo)
|
||||||
|
|
||||||
proc writeInterface(info: GIInterfaceInfo) =
|
proc writeInterface(info: GIInterfaceInfo) =
|
||||||
if not suppressType:
|
if not suppressType:
|
||||||
output.writeLine("type")
|
output.writeLine("type")
|
||||||
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object")
|
# we made interfaces a gobject now...
|
||||||
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object")
|
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " = object of gobject.Object00")
|
||||||
output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00")
|
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of gobject.Object")
|
||||||
|
#output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object")
|
||||||
|
#output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object")
|
||||||
|
#output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00")
|
||||||
let nMethods = gInterfaceInfoGetNMethods(info)
|
let nMethods = gInterfaceInfoGetNMethods(info)
|
||||||
for j in 0 .. <nMethods:
|
for j in 0 .. <nMethods:
|
||||||
let mInfo = gInterfaceInfoGetMethod(info, j)
|
let mInfo = gInterfaceInfoGetMethod(info, j)
|
||||||
writeMethod(info, minfo)
|
writeMethod(info, minfo)
|
||||||
|
|
||||||
|
# the EventMask enum is very special, so we use a separate proc for it
|
||||||
|
proc writeEventMask(info: GIEnumInfo) =
|
||||||
|
type T = tuple[v: int64; n: string]
|
||||||
|
var s = newSeq[T]()
|
||||||
|
var alias = newSeq[string]()
|
||||||
|
var flags = ($gBaseInfoGetName(info)).endsWith("Mask")
|
||||||
|
output.writeLine("type")
|
||||||
|
let n = info.gEnumInfoGetNValues()
|
||||||
|
for j in 0 .. <n:
|
||||||
|
let value = info.gEnumInfoGetValue(j)
|
||||||
|
let name = ($mangleName(gBaseInfoGetName(value)))[0 .. ^5]
|
||||||
|
let v = gValueInfoGetValue(value)
|
||||||
|
if bitops.popCount(v) == 1:
|
||||||
|
s.add((v, name))
|
||||||
|
s.sort do (x, y: T) -> int:
|
||||||
|
result = cmp(x.v, y.v)
|
||||||
|
if result == 0:
|
||||||
|
result = cmp(x.n, y.n)
|
||||||
|
for j in 0 .. s.high:
|
||||||
|
if s[j].v < 0: flags = false
|
||||||
|
if j == 0 and s[j].v == 0: continue
|
||||||
|
#if bitops.popCount(s[j].v) != 1: flags = false
|
||||||
|
if s.len <= 1: flags = false
|
||||||
|
var tname = mangleName(gBaseInfoGetName(info))
|
||||||
|
if flags: tname = tname[0 .. ^5]
|
||||||
|
if flags:
|
||||||
|
#output.writeLine(" ", tname & "Flag" & EM, " {.size: sizeof(cint), pure.} = enum")
|
||||||
|
output.writeLine(" ", tname & "Flag" & EM, " {.size: sizeof(cint), pure.} = enum")
|
||||||
|
if s[0].v != 1 and s[1].v != 1:
|
||||||
|
output.writeLine(" ignoreThisDummyValue = 0")
|
||||||
|
else:
|
||||||
|
output.writeLine(" ", tname & EM, " {.size: sizeof(cint), pure.} = enum")
|
||||||
|
var k: T
|
||||||
|
for j in 0 .. s.high:
|
||||||
|
let i = s[j]
|
||||||
|
var val = i.v
|
||||||
|
if flags and j == 0 and val == 0: continue
|
||||||
|
if j > 0 and i.v == k.v:
|
||||||
|
if i.n != k.n:
|
||||||
|
alias.add(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & '.' & k.n)
|
||||||
|
continue
|
||||||
|
if flags: val = countTrailingZeroBits(val) # firstSetBit(val)
|
||||||
|
output.writeLine(" ", i.n, " = ", val)
|
||||||
|
k = i
|
||||||
|
if alias.len > 0:
|
||||||
|
output.writeLine("\nconst")
|
||||||
|
for i in alias:
|
||||||
|
output.writeLine(i)
|
||||||
|
if flags:
|
||||||
|
output.writeLine("\n ", tname & "Mask" & EM, " {.size: sizeof(cint).} = set[$1Flag]" % [tname])
|
||||||
|
let nMethods = gEnumInfoGetNMethods(info)
|
||||||
|
###assert(nMethods <= 0)
|
||||||
|
assert(flags)
|
||||||
|
for j in 0 .. <nMethods:
|
||||||
|
let mInfo = gEnumInfoGetMethod(info, j)
|
||||||
|
writeMethod(info, minfo)
|
||||||
|
|
||||||
proc writeEnum(info: GIEnumInfo) =
|
proc writeEnum(info: GIEnumInfo) =
|
||||||
|
if mangleName(gBaseInfoGetName(info)) == "EventMask":
|
||||||
|
writeEventMask(info)
|
||||||
|
return
|
||||||
type T = tuple[v: int64; n: string]
|
type T = tuple[v: int64; n: string]
|
||||||
var s = newSeq[T]()
|
var s = newSeq[T]()
|
||||||
var alias = newSeq[string]()
|
var alias = newSeq[string]()
|
||||||
|
|
@ -752,6 +899,8 @@ proc writeEnum(info: GIEnumInfo) =
|
||||||
if flags: tname = tname[0 .. ^6]
|
if flags: tname = tname[0 .. ^6]
|
||||||
if flags:
|
if flags:
|
||||||
output.writeLine(" ", tname & "Flag" & EM, " {.size: sizeof(cint), pure.} = enum")
|
output.writeLine(" ", tname & "Flag" & EM, " {.size: sizeof(cint), pure.} = enum")
|
||||||
|
if s[0].v != 1 and s[1].v != 1:
|
||||||
|
output.writeLine(" ignoreThisDummyValue = 0")
|
||||||
else:
|
else:
|
||||||
output.writeLine(" ", tname & EM, " {.size: sizeof(cint), pure.} = enum")
|
output.writeLine(" ", tname & EM, " {.size: sizeof(cint), pure.} = enum")
|
||||||
var k: T
|
var k: T
|
||||||
|
|
@ -763,7 +912,8 @@ proc writeEnum(info: GIEnumInfo) =
|
||||||
if i.n != k.n:
|
if i.n != k.n:
|
||||||
alias.add(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & '.' & k.n)
|
alias.add(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & '.' & k.n)
|
||||||
continue
|
continue
|
||||||
if flags: val = firstSetBit(val)
|
if flags:
|
||||||
|
val = countTrailingZeroBits(val) # firstSetBit(val)
|
||||||
output.writeLine(" ", i.n, " = ", val)
|
output.writeLine(" ", i.n, " = ", val)
|
||||||
k = i
|
k = i
|
||||||
if alias.len > 0:
|
if alias.len > 0:
|
||||||
|
|
@ -1368,7 +1518,7 @@ main("xlib")
|
||||||
main("Gio")
|
main("Gio")
|
||||||
main("Atk")
|
main("Atk")
|
||||||
main("Pango")
|
main("Pango")
|
||||||
# main("cairo") # that file is now hand crafted
|
## main("cairo") # that file is now hand crafted
|
||||||
main("GdkPixbuf")
|
main("GdkPixbuf")
|
||||||
main("Rsvg")
|
main("Rsvg")
|
||||||
main("Gdk")
|
main("Gdk")
|
||||||
|
|
@ -1383,3 +1533,4 @@ o.close()
|
||||||
supmod.close
|
supmod.close
|
||||||
|
|
||||||
#for i in callerAllocCollector: echo i
|
#for i in callerAllocCollector: echo i
|
||||||
|
# 1530 lines
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue