v0.8.7
This commit is contained in:
parent
815ccae18e
commit
b82c02b2fc
4 changed files with 387 additions and 405 deletions
14
README.adoc
14
README.adoc
|
|
@ -1,6 +1,6 @@
|
||||||
= High level GTK4 and GTK3 bindings for the Nim programming language
|
= High level GTK4 and GTK3 bindings for the Nim programming language
|
||||||
//(c) Stefan Salewski
|
//(c) Stefan Salewski
|
||||||
//Version 0.8.6
|
//Version 0.8.7
|
||||||
:experimental:
|
:experimental:
|
||||||
:imagesdir: http://ssalewski.de/tmp
|
:imagesdir: http://ssalewski.de/tmp
|
||||||
//:source-highlighter: pygments
|
//:source-highlighter: pygments
|
||||||
|
|
@ -29,8 +29,16 @@ 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 A. Rumpf, E. Bassi and other _Nim_ and _GTK/Gnome_ developers.
|
||||||
The `combinatorics` module was kindly provided by R. Behrends.
|
The `combinatorics` module was kindly provided by R. Behrends.
|
||||||
|
|
||||||
NOTE: This is version 0.8.6 of the gintro Nim GTK bindings.
|
NOTE: This is version 0.8.7 of the gintro Nim GTK bindings.
|
||||||
The package contains now all the standard gst modules, and due to a recent
|
We did a larger internal cleanup for the gen.nim generator script but tried to
|
||||||
|
generate output modules identical to v.0.8.6 still. For next release v0.8.8
|
||||||
|
there will be some changes in the generated modules then.
|
||||||
|
Also for this version 0.8.7 we do support webkit2 for GTK4, and we have
|
||||||
|
fixed the newGFileTmp() issue, see https://github.com/StefanSalewski/gintro/issues/112.
|
||||||
|
|
||||||
|
|
||||||
|
NOTE: Version 0.8.6 of the gintro Nim GTK bindings
|
||||||
|
contains now all the standard gst modules, and due to a recent
|
||||||
request also the gtklayershell.nim module. Due to issues with some gst modules
|
request also the gtklayershell.nim module. Due to issues with some gst modules
|
||||||
we do now call init() for the gst module before we use it with gobject-introspection.
|
we do now call init() for the gst module before we use it with gobject-introspection.
|
||||||
We do the same for GTK3 and GTK4 as these provide also an init() proc. According to
|
We do the same for GTK3 and GTK4 as these provide also an init() proc. According to
|
||||||
|
|
|
||||||
20
examples/gtk4/webkitgtk.nim
Normal file
20
examples/gtk4/webkitgtk.nim
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# https://wiki.gnome.org/Projects/WebKitGtk/ProgrammingGuide/Tutorial
|
||||||
|
# nim c --gc:arc webkitgtk.nim
|
||||||
|
import gintro/[gtk4, glib, gobject, gio, webkit25]
|
||||||
|
|
||||||
|
proc appActivate (app: Application) =
|
||||||
|
let window = newApplicationWindow(app)
|
||||||
|
window.title = "WebKitGtk"
|
||||||
|
window.defaultSize = (800, 600)
|
||||||
|
let view = newWebView()
|
||||||
|
view.loadUri("https://nim-lang.org/")
|
||||||
|
window.setChild(view)
|
||||||
|
window.show
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
let app = newApplication("org.gtk.example")
|
||||||
|
connect(app, "activate", appActivate)
|
||||||
|
discard app.run
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.8.6"
|
version = "0.8.7"
|
||||||
author = "Stefan Salewski"
|
author = "Stefan Salewski"
|
||||||
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
|
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
328
tests/gen.nim
328
tests/gen.nim
|
|
@ -1,6 +1,6 @@
|
||||||
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
|
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
|
||||||
# nimpretty --maxLineLen:130 gen.nim
|
# nimpretty --maxLineLen:130 gen.nim
|
||||||
# v 0.8.6 2021-JAN-28
|
# v 0.8.7 2021-FEB-16
|
||||||
# (c) S. Salewski 2018
|
# (c) S. Salewski 2018
|
||||||
|
|
||||||
# usefull for finding death code:
|
# usefull for finding death code:
|
||||||
|
|
@ -38,6 +38,9 @@
|
||||||
|
|
||||||
# NOTE: Currently we support subclassing only for constructor functions like gtk_button_new()
|
# NOTE: Currently we support subclassing only for constructor functions like gtk_button_new()
|
||||||
|
|
||||||
|
# CAUTION: some procs are advertised as constructor but do not construct new objects,
|
||||||
|
# they just return existing ones as gdk_cursor_new_from_name()
|
||||||
|
|
||||||
from os import `/`, paramCount
|
from os import `/`, paramCount
|
||||||
import gir, gobject, glib
|
import gir, gobject, glib
|
||||||
import strutils
|
import strutils
|
||||||
|
|
@ -351,8 +354,10 @@ const someEvent: HashSet[string] = """"
|
||||||
|
|
||||||
proc fixedModName(s: string): string =
|
proc fixedModName(s: string): string =
|
||||||
result = s
|
result = s
|
||||||
if not ISGTK3 and (s == "gdk" or s == "gtk" or s == "gdkX11"):
|
if not ISGTK3 and (s == "gdk" or s == "gtk" or s == "gdkx11"):
|
||||||
result &= "4"
|
result &= "4"
|
||||||
|
if not ISGTK3 and (s == "javascriptcore" or s == "webkit2" or s == "webkit2webextension"):
|
||||||
|
result &= "5"
|
||||||
if not ISGTK3 and (s == "gtksource"):
|
if not ISGTK3 and (s == "gtksource"):
|
||||||
result &= "5"
|
result &= "5"
|
||||||
|
|
||||||
|
|
@ -1337,7 +1342,11 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
# see https://discourse.gnome.org/t/what-is-wrong-with-g-enum-complete-type-info-and/4489
|
# see https://discourse.gnome.org/t/what-is-wrong-with-g-enum-complete-type-info-and/4489
|
||||||
echo "Caution: No free/unref found for ", ' ', " (", sym, ')'
|
echo "Caution: No free/unref found for ", ' ', " (", sym, ')'
|
||||||
else:
|
else:
|
||||||
if gBaseInfoGetName(info) notin ["Variant", "VariantType"]: # seems for glib.GVariant we have to guess -- or maybe just know
|
#if gBaseInfoGetName(info) notin ["Variant", "VariantType"]: # seems for glib.GVariant we have to guess -- or maybe just know
|
||||||
|
|
||||||
|
if gBaseInfoGetName(info) notin ["Variant", "VariantType"] and # looks ugly, so hide for v0.8.7, investigate later...
|
||||||
|
sym notin ["soup_xmlrpc_parse_request", "gst_audio_resampler_new", "gst_rtsp_connection_accept", "gst_rtsp_connection_create_from_socket", "gst_rtsp_connection_create", "gst_sdp_media_copy", "gst_sdp_media_new"]:
|
||||||
|
|
||||||
echo "Caution: Do guess free/unref for ", ' ', " (", sym, ')'
|
echo "Caution: Do guess free/unref for ", ' ', " (", sym, ')'
|
||||||
if boxedFreeMeName == "gBoxedFreeGVariantType": # this does not work
|
if boxedFreeMeName == "gBoxedFreeGVariantType": # this does not work
|
||||||
assert false
|
assert false
|
||||||
|
|
@ -1354,6 +1363,97 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
freeMeName = "generic_" & $g_object_info_get_unref_function(parent)
|
freeMeName = "generic_" & $g_object_info_get_unref_function(parent)
|
||||||
assert(freeMeName != "")
|
assert(freeMeName != "")
|
||||||
|
|
||||||
|
template block8(prochead: string; errorcheckadd: bool): untyped =
|
||||||
|
if isProxyCandidateret2:
|
||||||
|
assert (gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, GITransfer.EVERYTHING}) # both occur
|
||||||
|
if asym == "newFromStreamAsync" and sym.startsWith("gdk_pixbuf_animation_new"):
|
||||||
|
asym = "newAnimationFromStreamAsync"
|
||||||
|
if prochead.len == 0:
|
||||||
|
methodBuffer.writeLine("\nproc " & asym & EM & pars.plist & " =")
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(prochead)
|
||||||
|
if not isProxyCandidateret2:
|
||||||
|
methodBuffer.write(pars.tempRes)
|
||||||
|
methodBuffer.write(pars.arrLex)
|
||||||
|
methodBuffer.write(sss)
|
||||||
|
var freeMeName{.inject.}: string
|
||||||
|
var boxedFreeMeName{.inject.}: string
|
||||||
|
for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
|
||||||
|
freeMeName = ""
|
||||||
|
boxedFreeMeName = ""
|
||||||
|
let arg = gCallableInfoGetArg(minfo, j)
|
||||||
|
let t = gArgInfoGetType(arg)
|
||||||
|
var ngrt = newGenRec(t)
|
||||||
|
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0):
|
||||||
|
if gArgInfoGetDirection(arg) == GIDirection.IN and gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING and
|
||||||
|
isProxyCandidate(t) and not callerAlloc.contains(ngrt.namePlainNS):
|
||||||
|
# like gtk_widget_add_controller()
|
||||||
|
let n = mangleName(gBaseInfoGetName(arg))
|
||||||
|
if gArgInfoMayBeNull(arg): # and prochead.len != 0: # wrong to be compatible with 0.8.6
|
||||||
|
methodBuffer.writeLine(" if " & n & " != nil:")
|
||||||
|
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
||||||
|
if gArgInfoGetDirection(arg) == GIDirection.OUT and isProxyCandidate(t) and
|
||||||
|
not callerAlloc.contains(ngrt.namePlainNS) and not gArgInfoIsCallerAllocates(arg):
|
||||||
|
let tag = gTypeInfoGetTag(t)
|
||||||
|
assert(tag == GITypeTag.INTERFACE)
|
||||||
|
assert gArgInfoGetOwnershipTransfer(arg) != GITransfer.CONTAINER
|
||||||
|
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING or
|
||||||
|
gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING: # pass always the same finalizer for ARC
|
||||||
|
let iface = gTypeInfoGetInterface(t)
|
||||||
|
if gBaseInfoGetType(iface) == GIInfoType.OBJECT:
|
||||||
|
let ttt = gArgInfoGetType(arg)
|
||||||
|
freeMeName = modPrefix(ttt, sym) & "finalizeGObject" # TODO: investigate, we may need the full toggleRef stuff!
|
||||||
|
else:
|
||||||
|
let info = iface
|
||||||
|
var freeMe{.inject.}: GIFunctionInfo
|
||||||
|
findFreeProc(info, gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING)
|
||||||
|
let h2 = mangleName(gBaseInfoGetName(arg))
|
||||||
|
if gArgInfoIsOptional(arg):
|
||||||
|
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
||||||
|
if boxedFreeMeName != "":
|
||||||
|
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
||||||
|
elif freeMeName == "":
|
||||||
|
methodBuffer.writeLine(" new(" & h2 & ")")
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
||||||
|
else:
|
||||||
|
if boxedFreeMeName != "":
|
||||||
|
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
||||||
|
elif freeMeName == "":
|
||||||
|
methodBuffer.writeLine(" new(" & h2 & ")")
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
||||||
|
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING:
|
||||||
|
if gArgInfoIsOptional(arg):
|
||||||
|
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
||||||
|
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true")
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||||
|
if gCallableInfoCanThrowGerror(minfo):
|
||||||
|
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
||||||
|
if errorcheckadd:
|
||||||
|
pars.arglist.insert(", addr gerror", pars.arglist.high)
|
||||||
|
var multi = ""
|
||||||
|
for k, v in pars.replist:
|
||||||
|
if v[1].flags * {RecResFlag.namedA, cstringA} != {}:
|
||||||
|
assert v[1].flags.contains(RecResFlag.array)
|
||||||
|
methodBuffer.writeLine(" var $1x$2: array[$3, pointer]" % [StringArrayName, multi, $StringArrayEntries])
|
||||||
|
methodBuffer.writeLine(" var $1$2: cstringArray = cast[cstringArray](addr $1x$2)" % [StringArrayName, multi])
|
||||||
|
methodBuffer.writeLine(" var $1_00 = seq2$2($3, $4$5)" % [k.strip(chars = {'`'}), v[0].replace("00").capitalizeAscii, k,
|
||||||
|
StringArrayName, multi])
|
||||||
|
if multi == "":
|
||||||
|
multi = "1"
|
||||||
|
elif v[1].flags.contains(RecResFlag.unamedA):
|
||||||
|
assert v[1].flags.contains(RecResFlag.array)
|
||||||
|
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[1].name00])
|
||||||
|
else:
|
||||||
|
if v[1].optOut:
|
||||||
|
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[0], k])
|
||||||
|
else:
|
||||||
|
methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v[0], k])
|
||||||
|
|
||||||
# assert(info != nil) # why can it be nil?
|
# assert(info != nil) # why can it be nil?
|
||||||
# if Lib.len == 0: # xlib, fontconfig, freetype2 # but Lib is local to main(), so let it crash
|
# if Lib.len == 0: # xlib, fontconfig, freetype2 # but Lib is local to main(), so let it crash
|
||||||
# return
|
# return
|
||||||
|
|
@ -1436,7 +1536,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
if sym == "nice_agent_get_selected_pair": return # was very wrong, fixed manually
|
if sym == "nice_agent_get_selected_pair": return # was very wrong, fixed manually
|
||||||
if sym == "g_hash_table_destroy": return
|
if sym == "g_hash_table_destroy": return
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pars = genPars(mInfo, false, info)
|
pars = genPars(mInfo, false, info)
|
||||||
processedFunctions.incl(sym)
|
processedFunctions.incl(sym)
|
||||||
|
|
@ -1548,11 +1647,12 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
#if sym == "pango_attr_background_new": echo "sss", info != nil, asym
|
#if sym == "pango_attr_background_new": echo "sss", info != nil, asym
|
||||||
asym = fixedProcNames.getOrDefault(sym, asym)
|
asym = fixedProcNames.getOrDefault(sym, asym)
|
||||||
# BLOCKMARK8 : 3 cases: constructor, isProxyCandidate(ret2), plain else
|
# BLOCKMARK8 : 3 cases: constructor, isProxyCandidate(ret2), plain else
|
||||||
if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0:
|
let isProxyCandidateret2 = isProxyCandidate(ret2)
|
||||||
assert pars.replist.len == 0 # ok it's a fact for constructors, so we don't have to generate code for it
|
|
||||||
for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
|
#else: # BLOCKMARK8 assert gerror
|
||||||
let arg = gCallableInfoGetArg(minfo, j)
|
if not (isProxyCandidateret2 or isGObject):
|
||||||
assert gArgInfoGetDirection(arg) notin {GIDirection.OUT, INOUT} # so we can ignore this case!
|
block8("", true)
|
||||||
|
if isProxyCandidateret2 or isGObject: # BLOCKMARK8
|
||||||
for itt in 0 .. 2: # generate the new(), the new(typedesc) and the init() proc
|
for itt in 0 .. 2: # generate the new(), the new(typedesc) and the init() proc
|
||||||
var hhh = "\nproc " & asym & EM & pars.plist
|
var hhh = "\nproc " & asym & EM & pars.plist
|
||||||
if itt == 1: # new(typedesc)
|
if itt == 1: # new(typedesc)
|
||||||
|
|
@ -1568,87 +1668,17 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
# hhh = hhh.replace("new", "init")
|
# hhh = hhh.replace("new", "init")
|
||||||
hhh = hhh.replace("proc new", "proc init") # v0.8.2
|
hhh = hhh.replace("proc new", "proc init") # v0.8.2
|
||||||
hhh = hhh.replace("*(", "*[T](result: var T" & semi)
|
hhh = hhh.replace("*(", "*[T](result: var T" & semi)
|
||||||
if itt == 2:
|
if itt == 2 and ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0):
|
||||||
depStr = " {.deprecated.}"
|
depStr = " {.deprecated.}"
|
||||||
methodBuffer.writeLine(hhh & depStr & " =")
|
if itt == 2 or ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0):
|
||||||
|
hhh = hhh & depStr & " ="
|
||||||
|
else:
|
||||||
|
hhh = hhh & " ="
|
||||||
|
block8(hhh, itt == 0)
|
||||||
if not isGObject:
|
if not isGObject:
|
||||||
methodBuffer.write(pars.tempRes) # caution, gobjectTemp() may write tempRes too.
|
methodBuffer.write(pars.tempRes) # caution, gobjectTemp() may write tempRes too.
|
||||||
methodBuffer.write(pars.arrLex)
|
|
||||||
methodBuffer.write(sss)
|
|
||||||
if gCallableInfoCanThrowGerror(minfo):
|
|
||||||
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
|
||||||
if itt == 0: pars.arglist.insert(", addr gerror", pars.arglist.high)
|
|
||||||
if itt == 1 or itt == 2:
|
if itt == 1 or itt == 2:
|
||||||
methodBuffer.writeLine(" assert(result is $1)" % [manglename(gBaseInfoGetName(info))])
|
methodBuffer.writeLine(" assert(result is $1)" % [manglename(gBaseInfoGetName(info))])
|
||||||
if isGObject:
|
|
||||||
# CAUTION: some procs are advertised as constructor but do not construct new objects,
|
|
||||||
# they just return existing ones as gdk_cursor_new_from_name()
|
|
||||||
gobjectTemp()
|
|
||||||
###if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0 and
|
|
||||||
### gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING:
|
|
||||||
### methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
|
||||||
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.CONTAINER:
|
|
||||||
assert false
|
|
||||||
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING or
|
|
||||||
gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # and gBaseInfoGetName(info) == "Variant":
|
|
||||||
if false: #sym == "g_closure_new_simple":
|
|
||||||
let nMethods = gStructInfoGetNMethods(info)
|
|
||||||
for j in 0.cint ..< 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
|
|
||||||
var freeMeName: string
|
|
||||||
var boxedFreeMeName: string
|
|
||||||
findFreeProc(info, gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING)
|
|
||||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
|
||||||
methodBuffer.writeLine(" let impl0 = " & sym & pars.arglist) # fast return in case of error
|
|
||||||
checkForGerror()
|
|
||||||
if gCallableInfoMayReturnNull(minfo):
|
|
||||||
methodBuffer.writeLine(" if impl0.isNil:")
|
|
||||||
methodBuffer.writeLine(" return nil")
|
|
||||||
#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 false: #i > 0: # with ARC we have no finalizer support for user defined subclasses, so we have to leak mem!
|
|
||||||
methodBuffer.writeLine(" new(result)")
|
|
||||||
elif boxedFreeMeName != "":
|
|
||||||
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
|
||||||
elif freeMeName == "":
|
|
||||||
assert false
|
|
||||||
methodBuffer.writeLine(" new(result)")
|
|
||||||
else:
|
|
||||||
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
|
||||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
|
||||||
methodBuffer.writeLine(" result.impl = impl0")
|
|
||||||
else:
|
|
||||||
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
|
||||||
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0 and
|
|
||||||
gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING) or
|
|
||||||
((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0 and
|
|
||||||
gBaseInfoGetName(info) == "Variant"):
|
|
||||||
assert((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0)
|
|
||||||
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
|
||||||
else:
|
|
||||||
assert false
|
|
||||||
for k, v in pars.replist:
|
|
||||||
assert false
|
|
||||||
if false: #gCallableInfoCanThrowGerror(minfo):
|
|
||||||
methodBuffer.writeLine(" if gerror != nil:")
|
|
||||||
methodBuffer.writeLine(" let msg = $gerror.message")
|
|
||||||
methodBuffer.writeLine(" g_error_free(gerror[])")
|
|
||||||
methodBuffer.writeLine(" raise newException(GException, msg)")
|
|
||||||
# end of for itt in 0 .. 2:
|
|
||||||
elif isProxyCandidate(ret2): # BLOCKMARK8
|
|
||||||
assert (gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, GITransfer.EVERYTHING}) # both occur
|
|
||||||
methodBuffer.writeLine("\nproc " & asym & EM & pars.plist & " =")
|
|
||||||
methodBuffer.write(pars.arrLex)
|
|
||||||
methodBuffer.write(sss)
|
|
||||||
if gCallableInfoCanThrowGerror(minfo):
|
|
||||||
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
|
||||||
pars.arglist.insert(", addr gerror", pars.arglist.high)
|
|
||||||
for k, v in pars.replist:
|
|
||||||
methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v[0], k])
|
|
||||||
if isGObject:
|
if isGObject:
|
||||||
gobjectTemp()
|
gobjectTemp()
|
||||||
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING or
|
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING or
|
||||||
|
|
@ -1683,98 +1713,14 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
else:
|
else:
|
||||||
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
||||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # for the none gobjects
|
if gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # for the none gobjects
|
||||||
|
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0):
|
||||||
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||||
elif false: #else:
|
else: assert false
|
||||||
assert gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING
|
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0 and gBaseInfoGetName(info) == "Variant"):
|
||||||
methodBuffer.writeLine(" new(result)")
|
methodBuffer.writeLine(" result.ignoreFinalizer = true")
|
||||||
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0:
|
||||||
for k, v in pars.replist:
|
break
|
||||||
methodBuffer.writeLine(" $1 = $2($3_00)" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
elif ngrRet.res == glist:
|
||||||
else: # BLOCKMARK8
|
|
||||||
if asym == "newFromStreamAsync" and sym.startsWith("gdk_pixbuf_animation_new"):
|
|
||||||
asym = "newAnimationFromStreamAsync"
|
|
||||||
methodBuffer.writeLine("\nproc " & asym & EM & pars.plist & " =")
|
|
||||||
methodBuffer.write(pars.tempRes)
|
|
||||||
methodBuffer.write(pars.arrLex)
|
|
||||||
methodBuffer.write(sss)
|
|
||||||
var freeMeName: string
|
|
||||||
var boxedFreeMeName: string
|
|
||||||
for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
|
|
||||||
freeMeName = ""
|
|
||||||
boxedFreeMeName = ""
|
|
||||||
let arg = gCallableInfoGetArg(minfo, j)
|
|
||||||
let t = gArgInfoGetType(arg)
|
|
||||||
var ngrt = newGenRec(t)
|
|
||||||
if gArgInfoGetDirection(arg) == GIDirection.IN and gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING and
|
|
||||||
isProxyCandidate(t) and not callerAlloc.contains(ngrt.namePlainNS):
|
|
||||||
# like gtk_widget_add_controller()
|
|
||||||
let n = mangleName(gBaseInfoGetName(arg))
|
|
||||||
if gArgInfoMayBeNull(arg):
|
|
||||||
methodBuffer.writeLine(" if " & n & " != nil:")
|
|
||||||
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
|
||||||
else:
|
|
||||||
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
|
||||||
if gArgInfoGetDirection(arg) == GIDirection.OUT and isProxyCandidate(t) and
|
|
||||||
not callerAlloc.contains(ngrt.namePlainNS) and not gArgInfoIsCallerAllocates(arg):
|
|
||||||
let tag = gTypeInfoGetTag(t)
|
|
||||||
assert(tag == GITypeTag.INTERFACE)
|
|
||||||
assert gArgInfoGetOwnershipTransfer(arg) != GITransfer.CONTAINER
|
|
||||||
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING or
|
|
||||||
gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING: # pass always the same finalizer for ARC
|
|
||||||
let iface = gTypeInfoGetInterface(t)
|
|
||||||
if gBaseInfoGetType(iface) == GIInfoType.OBJECT:
|
|
||||||
let ttt = gArgInfoGetType(arg)
|
|
||||||
freeMeName = modPrefix(ttt, sym) & "finalizeGObject" # TODO: investigate, we may need the full toggleRef stuff!
|
|
||||||
else:
|
|
||||||
let info = iface
|
|
||||||
var freeMe: GIFunctionInfo
|
|
||||||
findFreeProc(info, gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING)
|
|
||||||
let h2 = mangleName(gBaseInfoGetName(arg))
|
|
||||||
if gArgInfoIsOptional(arg):
|
|
||||||
#methodBuffer.writeLine(" if cast[ptr $1]($2) != nil:" % [ngrt.namePlain, h2])
|
|
||||||
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
|
||||||
if boxedFreeMeName != "":
|
|
||||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
|
||||||
elif freeMeName == "":
|
|
||||||
methodBuffer.writeLine(" new(" & h2 & ")")
|
|
||||||
else:
|
|
||||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
|
||||||
else:
|
|
||||||
if boxedFreeMeName != "":
|
|
||||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
|
||||||
elif freeMeName == "":
|
|
||||||
methodBuffer.writeLine(" new(" & h2 & ")")
|
|
||||||
else:
|
|
||||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
|
||||||
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING:
|
|
||||||
if gArgInfoIsOptional(arg):
|
|
||||||
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
|
||||||
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true")
|
|
||||||
else:
|
|
||||||
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true") # as we have always to attach one with ARC.
|
|
||||||
if gCallableInfoCanThrowGerror(minfo):
|
|
||||||
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
|
||||||
pars.arglist.insert(", addr gerror", pars.arglist.high)
|
|
||||||
var multi = ""
|
|
||||||
for k, v in pars.replist:
|
|
||||||
if v[1].flags * {RecResFlag.namedA, cstringA} != {}:
|
|
||||||
assert v[1].flags.contains(RecResFlag.array)
|
|
||||||
#assert not (v[1].flags.contains(RecResFlag.zeroTerminated))
|
|
||||||
methodBuffer.writeLine(" var $1x$2: array[$3, pointer]" % [StringArrayName, multi, $StringArrayEntries])
|
|
||||||
methodBuffer.writeLine(" var $1$2: cstringArray = cast[cstringArray](addr $1x$2)" % [StringArrayName, multi])
|
|
||||||
methodBuffer.writeLine(" var $1_00 = seq2$2($3, $4$5)" % [k.strip(chars = {'`'}), v[0].replace("00").capitalizeAscii, k,
|
|
||||||
StringArrayName, multi])
|
|
||||||
if multi == "":
|
|
||||||
multi = "1"
|
|
||||||
elif v[1].flags.contains(RecResFlag.unamedA):
|
|
||||||
assert v[1].flags.contains(RecResFlag.array)
|
|
||||||
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[1].name00])
|
|
||||||
else:
|
|
||||||
if v[1].optOut:
|
|
||||||
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[0], k])
|
|
||||||
else:
|
|
||||||
methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v[0], k])
|
|
||||||
if ngrRet.res == glist:
|
|
||||||
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
||||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
||||||
GITransfer.NOTHING:
|
GITransfer.NOTHING:
|
||||||
|
|
@ -1786,7 +1732,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
||||||
methodBuffer.writeLine(" result = glistObjects2seq($1, resul0, $2)" % [ngrRet.childName, $elTransferFull])
|
methodBuffer.writeLine(" result = glistObjects2seq($1, resul0, $2)" % [ngrRet.childName, $elTransferFull])
|
||||||
if ngrRet.infoType == GIInfoType.STRUCT:
|
if ngrRet.infoType == GIInfoType.STRUCT:
|
||||||
|
|
||||||
if gBaseInfoGetName(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))) notin ["Atom", "Variant", "TimedValue"]: # care later
|
if gBaseInfoGetName(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))) notin ["Atom", "Variant", "TimedValue"]: # care later
|
||||||
methodBuffer.writeLine(" result = glistStructs2seq[$1](resul0, $2)" % [ngrRet.childName, $(
|
methodBuffer.writeLine(" result = glistStructs2seq[$1](resul0, $2)" % [ngrRet.childName, $(
|
||||||
gCallableInfoGetCallerOwns(minfo) != GITransfer.EVERYTHING)])
|
gCallableInfoGetCallerOwns(minfo) != GITransfer.EVERYTHING)])
|
||||||
|
|
@ -1802,7 +1747,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
else:
|
else:
|
||||||
methodBuffer.writeLine(" discard")
|
methodBuffer.writeLine(" discard")
|
||||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||||
|
|
||||||
elif ngrRet.res == gslist:
|
elif ngrRet.res == gslist:
|
||||||
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
||||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
||||||
|
|
@ -1829,7 +1773,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
else:
|
else:
|
||||||
methodBuffer.writeLine(" discard")
|
methodBuffer.writeLine(" discard")
|
||||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||||
|
|
||||||
elif ngrRet.flags.contains(RecResFlag.unamedA) and ngrRet.res == intAX:
|
elif ngrRet.flags.contains(RecResFlag.unamedA) and ngrRet.res == intAX:
|
||||||
# https://discourse.gnome.org/t/g-key-file-get-integer-list-transfer-container/4729
|
# https://discourse.gnome.org/t/g-key-file-get-integer-list-transfer-container/4729
|
||||||
# for fundamental types GITransfer.EVERYTHING and GITransfer.CONTAINER are equivalent
|
# for fundamental types GITransfer.EVERYTHING and GITransfer.CONTAINER are equivalent
|
||||||
|
|
@ -1970,7 +1913,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
if info != nil and (gBaseInfoGetType(info) == GIInfoType.UNION or gBaseInfoGetType(info) == GIInfoType.STRUCT) and
|
if info != nil and (gBaseInfoGetType(info) == GIInfoType.UNION or gBaseInfoGetType(info) == GIInfoType.STRUCT) and
|
||||||
gCallableInfoGetNArgs(minfo) == (if gCallableInfoIsMethod(minfo): 0 else: 1):
|
gCallableInfoGetNArgs(minfo) == (if gCallableInfoIsMethod(minfo): 0 else: 1):
|
||||||
#if not callerAlloc.contains(modulenamespace & '.' & $gBaseInfoGetName(info)) and (asym == "free" or asym == "unref"):
|
#if not callerAlloc.contains(modulenamespace & '.' & $gBaseInfoGetName(info)) and (asym == "free" or asym == "unref"):
|
||||||
if not callerAlloc.contains(modulenamespace & '.' & $gBaseInfoGetName(info)) and (asym == "free" or asym == "unref" or asym == "destroy"): # v0.8.6
|
if not callerAlloc.contains(modulenamespace & '.' & $gBaseInfoGetName(info)) and (asym == "free" or asym == "unref" or
|
||||||
|
asym == "destroy"): # v0.8.6
|
||||||
methodBuffer.writeLine("\nproc finalizer" & asym & EM & "(self: $1) =" % [$gBaseInfoGetName(info)])
|
methodBuffer.writeLine("\nproc finalizer" & asym & EM & "(self: $1) =" % [$gBaseInfoGetName(info)])
|
||||||
methodBuffer.writeLine(" if not self.ignoreFinalizer:")
|
methodBuffer.writeLine(" if not self.ignoreFinalizer:")
|
||||||
if gTypeInfoGetTag(ret2) != GITypeTag.VOID: # i.e. gst_sdp_media_free()
|
if gTypeInfoGetTag(ret2) != GITypeTag.VOID: # i.e. gst_sdp_media_free()
|
||||||
|
|
@ -2764,6 +2708,7 @@ proc processInfo(i: GIBaseInfo) =
|
||||||
elif gBaseInfoGetType(i) == GIInfoType.CONSTANT:
|
elif gBaseInfoGetType(i) == GIInfoType.CONSTANT:
|
||||||
writeConst(i)
|
writeConst(i)
|
||||||
elif gBaseInfoGetType(i) == GIInfoType.Boxed:
|
elif gBaseInfoGetType(i) == GIInfoType.Boxed:
|
||||||
|
if $gBaseInfoGetName(i) notin ["TreeRowData", "ByteArray", "FileList"]: # hide ugly output for v0.8.7, investgate later
|
||||||
echo "gBaseInfoGetType(i) == GIInfoType.Boxed: ", gBaseInfoGetName(i)
|
echo "gBaseInfoGetType(i) == GIInfoType.Boxed: ", gBaseInfoGetName(i)
|
||||||
# echo "++++++++ ", g_registered_type_info_get_g_type(i), g_registered_type_info_get_type_name(i)
|
# echo "++++++++ ", g_registered_type_info_get_g_type(i), g_registered_type_info_get_type_name(i)
|
||||||
# assert false executed for gtk4
|
# assert false executed for gtk4
|
||||||
|
|
@ -3245,7 +3190,6 @@ proc main(namespace: string; version: cstring = nil) =
|
||||||
if namespace == "Gtk" and version == "4.0" and gtk4Lib == nil:
|
if namespace == "Gtk" and version == "4.0" and gtk4Lib == nil:
|
||||||
gtk4Lib = tryInitGtk4()
|
gtk4Lib = tryInitGtk4()
|
||||||
|
|
||||||
|
|
||||||
let typelib = gi.gIrepositoryRequire(namespace, version, cast[GIRepositoryLoadFlags](0), error)
|
let typelib = gi.gIrepositoryRequire(namespace, version, cast[GIRepositoryLoadFlags](0), error)
|
||||||
#let typelib = gIrepositoryRequirePrivate(nil, namespace, "/usr/lib/girepository-1.0", version, cast[GIRepositoryLoadFlags](0), error)
|
#let typelib = gIrepositoryRequirePrivate(nil, namespace, "/usr/lib/girepository-1.0", version, cast[GIRepositoryLoadFlags](0), error)
|
||||||
if typelib.isNil:
|
if typelib.isNil:
|
||||||
|
|
@ -3259,7 +3203,7 @@ proc main(namespace: string; version: cstring = nil) =
|
||||||
var weImportGObject = false
|
var weImportGObject = false
|
||||||
output.writeLine("# dependencies:")
|
output.writeLine("# dependencies:")
|
||||||
var importedModules = ""
|
var importedModules = ""
|
||||||
for j in 0 .. 12:
|
for j in 0 .. 18: # stupid restriction!
|
||||||
if dep[j].isNil: break
|
if dep[j].isNil: break
|
||||||
if j == 0:
|
if j == 0:
|
||||||
importedModules = "import "
|
importedModules = "import "
|
||||||
|
|
@ -3828,6 +3772,13 @@ proc get$1*(builder: Builder; name: string): $1 =
|
||||||
suff = "4"
|
suff = "4"
|
||||||
if namespace == "GtkSource" and version == nil:
|
if namespace == "GtkSource" and version == nil:
|
||||||
suff = "5"
|
suff = "5"
|
||||||
|
|
||||||
|
if namespace in ["JavaScriptCore", "WebKit2", "WebKit2WebExtension"]:
|
||||||
|
if version == "4.0":
|
||||||
|
suff = ""
|
||||||
|
if version == "5.0":
|
||||||
|
suff = "5"
|
||||||
|
|
||||||
var o = open("nim_gi" / (namespace.toLowerAscii) & suff & ".nim", fmWrite)
|
var o = open("nim_gi" / (namespace.toLowerAscii) & suff & ".nim", fmWrite)
|
||||||
o.write(output.data)
|
o.write(output.data)
|
||||||
o.close()
|
o.close()
|
||||||
|
|
@ -3887,10 +3838,10 @@ proc launch() =
|
||||||
main("Handy")
|
main("Handy")
|
||||||
main("Nice")
|
main("Nice")
|
||||||
main("cairo")
|
main("cairo")
|
||||||
main("WebKit2")
|
main("WebKit2", "4.0")
|
||||||
main("JavaScriptCore")
|
main("JavaScriptCore", "4.0")
|
||||||
main("Soup")
|
main("Soup")
|
||||||
main("WebKit2WebExtension")
|
main("WebKit2WebExtension", "4.0")
|
||||||
main("Gst")
|
main("Gst")
|
||||||
main("GstBase")
|
main("GstBase")
|
||||||
main("GstAllocators")
|
main("GstAllocators")
|
||||||
|
|
@ -3940,6 +3891,10 @@ proc launch() =
|
||||||
# main("Handy") # not yet available for GTK4
|
# main("Handy") # not yet available for GTK4
|
||||||
main("Nice")
|
main("Nice")
|
||||||
main("cairo")
|
main("cairo")
|
||||||
|
main("WebKit2", "5.0")
|
||||||
|
main("JavaScriptCore", "5.0")
|
||||||
|
main("Soup")
|
||||||
|
main("WebKit2WebExtension", "5.0")
|
||||||
main("Gst")
|
main("Gst")
|
||||||
main("GstBase")
|
main("GstBase")
|
||||||
main("GstAllocators")
|
main("GstAllocators")
|
||||||
|
|
@ -3993,7 +3948,7 @@ launch()
|
||||||
# if not xcallerAlloc.contains(el):
|
# if not xcallerAlloc.contains(el):
|
||||||
# echo el
|
# echo el
|
||||||
|
|
||||||
# 3996 lines
|
# 3951 lines
|
||||||
# gtk_icon_view_get_tooltip_context bug Candidate
|
# gtk_icon_view_get_tooltip_context bug Candidate
|
||||||
# gtk_tree_view_get_cursor bug
|
# gtk_tree_view_get_cursor bug
|
||||||
#
|
#
|
||||||
|
|
@ -4010,4 +3965,3 @@ proc gst_structure_take(oldstrPtr: var ptr Structure00; newstr: ptr Structure00)
|
||||||
proc take*(oldstrPtr: var Structure; newstr: Structure = nil): bool =
|
proc take*(oldstrPtr: var Structure; newstr: Structure = nil): bool =
|
||||||
toBool(gst_structure_take(if oldstrPtr.isNil: nil else: cast[ptr Structure00](oldstrPtr.impl), if newstr.isNil: nil else: cast[ptr Structure00](newstr.impl)))
|
toBool(gst_structure_take(if oldstrPtr.isNil: nil else: cast[ptr Structure00](oldstrPtr.impl), if newstr.isNil: nil else: cast[ptr Structure00](newstr.impl)))
|
||||||
]#
|
]#
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue