mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
codegen/: Backport pygtk 2.6.2 codegen
Original commit message from CVS: * codegen/argtypes.py: * codegen/codegen.py: * codegen/definitions.py: * codegen/defsparser.py: * codegen/h2def.py: * codegen/mergedefs.py: * codegen/reversewrapper.py: Backport pygtk 2.6.2 codegen * gst/gst-types.defs: Added fields for Buffer, Event, Message and Query Added pre-roll for enum ElementStateReturn * gst/gst.defs: Added (define-method for gst_structure_nth_field_name() * gst/gstelement.override: Added override for gst_element_get_state * gst/gstcaps.override: re-enabled structure functions
This commit is contained in:
parent
febd74992d
commit
685c434a03
12 changed files with 1489 additions and 162 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
2005-06-26 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
|
* codegen/argtypes.py:
|
||||||
|
* codegen/codegen.py:
|
||||||
|
* codegen/definitions.py:
|
||||||
|
* codegen/defsparser.py:
|
||||||
|
* codegen/h2def.py:
|
||||||
|
* codegen/mergedefs.py:
|
||||||
|
* codegen/reversewrapper.py:
|
||||||
|
Backport pygtk 2.6.2 codegen
|
||||||
|
|
||||||
|
* gst/gst-types.defs:
|
||||||
|
Added fields for Buffer, Event, Message and Query
|
||||||
|
Added pre-roll for enum ElementStateReturn
|
||||||
|
|
||||||
|
* gst/gst.defs:
|
||||||
|
Added (define-method for gst_structure_nth_field_name()
|
||||||
|
|
||||||
|
* gst/gstelement.override:
|
||||||
|
Added override for gst_element_get_state
|
||||||
|
|
||||||
|
* gst/gstcaps.override:
|
||||||
|
re-enabled structure functions
|
||||||
|
|
||||||
2005-06-26 Edward Hervey <edward@fluendo.com>
|
2005-06-26 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
* codegen/argtypes.py:
|
* codegen/argtypes.py:
|
||||||
|
|
|
@ -3,6 +3,7 @@ import sys
|
||||||
import string
|
import string
|
||||||
import traceback
|
import traceback
|
||||||
import keyword
|
import keyword
|
||||||
|
import struct
|
||||||
|
|
||||||
class VarList:
|
class VarList:
|
||||||
"""Nicely format a C variable list"""
|
"""Nicely format a C variable list"""
|
||||||
|
@ -188,13 +189,82 @@ class IntArg(ArgType):
|
||||||
info.varlist.add('int', 'ret')
|
info.varlist.add('int', 'ret')
|
||||||
info.codeafter.append(' return PyInt_FromLong(ret);')
|
info.codeafter.append(' return PyInt_FromLong(ret);')
|
||||||
|
|
||||||
|
class UIntArg(ArgType):
|
||||||
|
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||||
|
if pdflt:
|
||||||
|
info.varlist.add(ptype, pname + ' = ' + pdflt)
|
||||||
|
else:
|
||||||
|
info.varlist.add(ptype, pname)
|
||||||
|
info.arglist.append(pname)
|
||||||
|
info.add_parselist('I', ['&' + pname], [pname])
|
||||||
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
|
info.varlist.add(ptype, 'ret')
|
||||||
|
info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n')
|
||||||
|
|
||||||
|
class SizeArg(ArgType):
|
||||||
|
|
||||||
|
if struct.calcsize('P') <= struct.calcsize('l'):
|
||||||
|
llp64 = True
|
||||||
|
else:
|
||||||
|
llp64 = False
|
||||||
|
|
||||||
|
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||||
|
if pdflt:
|
||||||
|
info.varlist.add(ptype, pname + ' = ' + pdflt)
|
||||||
|
else:
|
||||||
|
info.varlist.add(ptype, pname)
|
||||||
|
info.arglist.append(pname)
|
||||||
|
if self.llp64:
|
||||||
|
info.add_parselist('k', ['&' + pname], [pname])
|
||||||
|
else:
|
||||||
|
info.add_parselist('K', ['&' + pname], [pname])
|
||||||
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
|
info.varlist.add(ptype, 'ret')
|
||||||
|
if self.llp64:
|
||||||
|
info.codeafter.append(' return PyLong_FromUnsignedLongLong(ret);\n')
|
||||||
|
else:
|
||||||
|
info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n')
|
||||||
|
|
||||||
|
class SSizeArg(ArgType):
|
||||||
|
|
||||||
|
if struct.calcsize('P') <= struct.calcsize('l'):
|
||||||
|
llp64 = True
|
||||||
|
else:
|
||||||
|
llp64 = False
|
||||||
|
|
||||||
|
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||||
|
if pdflt:
|
||||||
|
info.varlist.add(ptype, pname + ' = ' + pdflt)
|
||||||
|
else:
|
||||||
|
info.varlist.add(ptype, pname)
|
||||||
|
info.arglist.append(pname)
|
||||||
|
if self.llp64:
|
||||||
|
info.add_parselist('l', ['&' + pname], [pname])
|
||||||
|
else:
|
||||||
|
info.add_parselist('L', ['&' + pname], [pname])
|
||||||
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
|
info.varlist.add(ptype, 'ret')
|
||||||
|
if self.llp64:
|
||||||
|
info.codeafter.append(' return PyLong_FromLongLong(ret);\n')
|
||||||
|
else:
|
||||||
|
info.codeafter.append(' return PyLong_FromLong(ret);\n')
|
||||||
|
|
||||||
|
class LongArg(ArgType):
|
||||||
|
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||||
|
if pdflt:
|
||||||
|
info.varlist.add(ptype, pname + ' = ' + pdflt)
|
||||||
|
else:
|
||||||
|
info.varlist.add(ptype, pname)
|
||||||
|
info.arglist.append(pname)
|
||||||
|
info.add_parselist('l', ['&' + pname], [pname])
|
||||||
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
|
info.varlist.add(ptype, 'ret')
|
||||||
|
info.codeafter.append(' return PyInt_FromLong(ret);\n')
|
||||||
|
|
||||||
class BoolArg(IntArg):
|
class BoolArg(IntArg):
|
||||||
def write_return(self, ptype, ownsreturn, info):
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
info.varlist.add('int', 'ret')
|
info.varlist.add('int', 'ret')
|
||||||
info.varlist.add('PyObject', '*py_ret')
|
info.codeafter.append(' return PyBool_FromLong(ret);\n')
|
||||||
info.codeafter.append(' py_ret = ret ? Py_True : Py_False;\n'
|
|
||||||
' Py_INCREF(py_ret);\n'
|
|
||||||
' return py_ret;')
|
|
||||||
|
|
||||||
class TimeTArg(ArgType):
|
class TimeTArg(ArgType):
|
||||||
def write_param(self, ptype, pname, pdflt, pnull, info):
|
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||||
|
@ -333,7 +403,7 @@ class EnumArg(ArgType):
|
||||||
info.add_parselist('O', ['&py_' + pname], [pname]);
|
info.add_parselist('O', ['&py_' + pname], [pname]);
|
||||||
def write_return(self, ptype, ownsreturn, info):
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
info.varlist.add('gint', 'ret')
|
info.varlist.add('gint', 'ret')
|
||||||
info.codeafter.append(' return PyInt_FromLong(ret);')
|
info.codeafter.append(' return pyg_enum_from_gtype(%s, ret);' % self.typecode)
|
||||||
|
|
||||||
class FlagsArg(ArgType):
|
class FlagsArg(ArgType):
|
||||||
flag = (' if (%(default)spyg_flags_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
|
flag = (' if (%(default)spyg_flags_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
|
||||||
|
@ -356,7 +426,7 @@ class FlagsArg(ArgType):
|
||||||
info.add_parselist('O', ['&py_' + pname], [pname])
|
info.add_parselist('O', ['&py_' + pname], [pname])
|
||||||
def write_return(self, ptype, ownsreturn, info):
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
info.varlist.add('guint', 'ret')
|
info.varlist.add('guint', 'ret')
|
||||||
info.codeafter.append(' return PyInt_FromLong(ret);')
|
info.codeafter.append(' return pyg_flags_from_gtype(%s, ret);' % self.typecode)
|
||||||
|
|
||||||
class ObjectArg(ArgType):
|
class ObjectArg(ArgType):
|
||||||
# should change these checks to more typesafe versions that check
|
# should change these checks to more typesafe versions that check
|
||||||
|
@ -404,7 +474,7 @@ class ObjectArg(ArgType):
|
||||||
info.codebefore.append(self.dflt % {'name':pname,
|
info.codebefore.append(self.dflt % {'name':pname,
|
||||||
'cast':self.cast})
|
'cast':self.cast})
|
||||||
info.arglist.append(pname)
|
info.arglist.append(pname)
|
||||||
info.add_parselist('O', ['&Py%s_Type' % self.objname,
|
info.add_parselist('O!', ['&Py%s_Type' % self.objname,
|
||||||
'&py_' + pname], [pname])
|
'&py_' + pname], [pname])
|
||||||
else:
|
else:
|
||||||
info.varlist.add('PyGObject', '*' + pname)
|
info.varlist.add('PyGObject', '*' + pname)
|
||||||
|
@ -417,7 +487,8 @@ class ObjectArg(ArgType):
|
||||||
if ownsreturn:
|
if ownsreturn:
|
||||||
info.varlist.add('PyObject', '*py_ret')
|
info.varlist.add('PyObject', '*py_ret')
|
||||||
info.codeafter.append(' py_ret = pygobject_new((GObject *)ret);\n'
|
info.codeafter.append(' py_ret = pygobject_new((GObject *)ret);\n'
|
||||||
' g_object_unref(ret);\n'
|
' if (ret != NULL)\n'
|
||||||
|
' g_object_unref(ret);\n'
|
||||||
' return py_ret;')
|
' return py_ret;')
|
||||||
else:
|
else:
|
||||||
info.codeafter.append(' /* pygobject_new handles NULL checking */\n' +
|
info.codeafter.append(' /* pygobject_new handles NULL checking */\n' +
|
||||||
|
@ -620,18 +691,28 @@ class PointerArg(ArgType):
|
||||||
' return pyg_pointer_new(' + self.typecode + ', &ret);')
|
' return pyg_pointer_new(' + self.typecode + ', &ret);')
|
||||||
|
|
||||||
class AtomArg(IntArg):
|
class AtomArg(IntArg):
|
||||||
|
dflt = ' if (py_%(name)s) {\n' \
|
||||||
|
' %(name)s = pygdk_atom_from_pyobject(py_%(name)s);\n' \
|
||||||
|
' if (PyErr_Occurred())\n' \
|
||||||
|
' return NULL;\n' \
|
||||||
|
' }\n'
|
||||||
atom = (' %(name)s = pygdk_atom_from_pyobject(py_%(name)s);\n'
|
atom = (' %(name)s = pygdk_atom_from_pyobject(py_%(name)s);\n'
|
||||||
' if (PyErr_Occurred())\n'
|
' if (PyErr_Occurred())\n'
|
||||||
' return NULL;\n')
|
' return NULL;\n')
|
||||||
def write_param(self, ptype, pname, pdflt, pnull, info):
|
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||||
info.varlist.add('GdkAtom', pname)
|
if pdflt:
|
||||||
info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
|
info.varlist.add('GdkAtom', pname + ' = ' + pdflt)
|
||||||
info.codebefore.append(self.atom % {'name': pname})
|
info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
|
||||||
info.arglist.append(pname)
|
info.codebefore.append(self.dflt % {'name': pname})
|
||||||
|
else:
|
||||||
|
info.varlist.add('GdkAtom', pname)
|
||||||
|
info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
|
||||||
|
info.codebefore.append(self.atom % {'name': pname})
|
||||||
|
info.arglist.append(pname)
|
||||||
info.add_parselist('O', ['&py_' + pname], [pname])
|
info.add_parselist('O', ['&py_' + pname], [pname])
|
||||||
def write_return(self, ptype, ownsreturn, info):
|
def write_return(self, ptype, ownsreturn, info):
|
||||||
info.varlist.add('GdkAtom', 'ret')
|
info.varlist.add('GdkAtom', 'ret')
|
||||||
info.codeafter.append(' return PyGdkAtom_New(ret);')
|
info.codeafter.append(' return PyString_FromString(gdk_atom_name(ret));')
|
||||||
|
|
||||||
class GTypeArg(ArgType):
|
class GTypeArg(ArgType):
|
||||||
gtype = (' if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n'
|
gtype = (' if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n'
|
||||||
|
@ -669,12 +750,6 @@ class GtkTreePathArg(ArgType):
|
||||||
' return NULL;\n'
|
' return NULL;\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
' }\n')
|
' }\n')
|
||||||
null = (' if (PyTuple_Check(py_%(name)s))\n'
|
|
||||||
' %(name)s = pygtk_tree_path_from_pyobject(py_%(name)s);\n'
|
|
||||||
' else if (py_%(name)s != Py_None) {\n'
|
|
||||||
' PyErr_SetString(PyExc_TypeError, "%(name)s should be a GtkTreePath or None");\n'
|
|
||||||
' return NULL;\n'
|
|
||||||
' }\n')
|
|
||||||
freepath = (' if (%(name)s)\n'
|
freepath = (' if (%(name)s)\n'
|
||||||
' gtk_tree_path_free(%(name)s);\n')
|
' gtk_tree_path_free(%(name)s);\n')
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -761,9 +836,16 @@ class PyObjectArg(ArgType):
|
||||||
class ArgMatcher:
|
class ArgMatcher:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.argtypes = {}
|
self.argtypes = {}
|
||||||
|
self.reverse_argtypes = {}
|
||||||
|
self.reverse_rettypes = {}
|
||||||
|
|
||||||
def register(self, ptype, handler):
|
def register(self, ptype, handler):
|
||||||
self.argtypes[ptype] = handler
|
self.argtypes[ptype] = handler
|
||||||
|
def register_reverse(self, ptype, handler):
|
||||||
|
self.reverse_argtypes[ptype] = handler
|
||||||
|
def register_reverse_ret(self, ptype, handler):
|
||||||
|
self.reverse_rettypes[ptype] = handler
|
||||||
|
|
||||||
def register_enum(self, ptype, typecode):
|
def register_enum(self, ptype, typecode):
|
||||||
if typecode is None:
|
if typecode is None:
|
||||||
typecode = "G_TYPE_NONE"
|
typecode = "G_TYPE_NONE"
|
||||||
|
@ -806,6 +888,39 @@ class ArgMatcher:
|
||||||
if ptype[:8] == 'GdkEvent' and ptype[-1] == '*':
|
if ptype[:8] == 'GdkEvent' and ptype[-1] == '*':
|
||||||
return self.argtypes['GdkEvent*']
|
return self.argtypes['GdkEvent*']
|
||||||
raise
|
raise
|
||||||
|
def _get_reverse_common(self, ptype, registry):
|
||||||
|
props = dict(c_type=ptype)
|
||||||
|
try:
|
||||||
|
return registry[ptype], props
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
handler = self.argtypes[ptype]
|
||||||
|
except KeyError:
|
||||||
|
if ptype.startswith('GdkEvent') and ptype.endswith('*'):
|
||||||
|
handler = self.argtypes['GdkEvent*']
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
if isinstance(handler, ObjectArg):
|
||||||
|
return registry['GObject*'], props
|
||||||
|
elif isinstance(handler, EnumArg):
|
||||||
|
props['typecode'] = handler.typecode
|
||||||
|
props['enumname'] = handler.enumname
|
||||||
|
return registry['GEnum'], props
|
||||||
|
elif isinstance(handler, FlagsArg):
|
||||||
|
props['typecode'] = handler.typecode
|
||||||
|
props['flagname'] = handler.flagname
|
||||||
|
return registry['GFlags'], props
|
||||||
|
elif isinstance(handler, BoxedArg):
|
||||||
|
props['typecode'] = handler.typecode
|
||||||
|
props['typename'] = handler.typename
|
||||||
|
return registry['GBoxed'], props
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
def get_reverse(self, ptype):
|
||||||
|
return self._get_reverse_common(ptype, self.reverse_argtypes)
|
||||||
|
def get_reverse_ret(self, ptype):
|
||||||
|
return self._get_reverse_common(ptype, self.reverse_rettypes)
|
||||||
|
|
||||||
def object_is_a(self, otype, parent):
|
def object_is_a(self, otype, parent):
|
||||||
if otype == None: return 0
|
if otype == None: return 0
|
||||||
if otype == parent: return 1
|
if otype == parent: return 1
|
||||||
|
@ -844,19 +959,24 @@ matcher.register('gunichar', arg)
|
||||||
arg = IntArg()
|
arg = IntArg()
|
||||||
matcher.register('int', arg)
|
matcher.register('int', arg)
|
||||||
matcher.register('gint', arg)
|
matcher.register('gint', arg)
|
||||||
matcher.register('guint', arg)
|
|
||||||
matcher.register('short', arg)
|
matcher.register('short', arg)
|
||||||
matcher.register('gshort', arg)
|
matcher.register('gshort', arg)
|
||||||
matcher.register('gushort', arg)
|
matcher.register('gushort', arg)
|
||||||
matcher.register('long', arg)
|
matcher.register('gsize', SizeArg())
|
||||||
matcher.register('glong', arg)
|
matcher.register('gssize', SSizeArg())
|
||||||
matcher.register('gsize', arg)
|
|
||||||
matcher.register('gssize', arg)
|
|
||||||
matcher.register('guint8', arg)
|
matcher.register('guint8', arg)
|
||||||
matcher.register('gint8', arg)
|
matcher.register('gint8', arg)
|
||||||
matcher.register('guint16', arg)
|
matcher.register('guint16', arg)
|
||||||
matcher.register('gint16', arg)
|
matcher.register('gint16', arg)
|
||||||
matcher.register('gint32', arg)
|
matcher.register('gint32', arg)
|
||||||
|
matcher.register('GTime', arg)
|
||||||
|
|
||||||
|
arg = LongArg()
|
||||||
|
matcher.register('long', arg)
|
||||||
|
matcher.register('glong', arg)
|
||||||
|
|
||||||
|
arg = UIntArg()
|
||||||
|
matcher.register('guint', arg)
|
||||||
|
|
||||||
arg = BoolArg()
|
arg = BoolArg()
|
||||||
matcher.register('gboolean', arg)
|
matcher.register('gboolean', arg)
|
||||||
|
|
|
@ -1,6 +1,32 @@
|
||||||
import sys, os, string
|
import sys, os, string
|
||||||
import getopt, traceback, keyword
|
import getopt, traceback, keyword
|
||||||
import defsparser, argtypes, override
|
import defsparser, argtypes, override
|
||||||
|
import definitions
|
||||||
|
import reversewrapper
|
||||||
|
|
||||||
|
class Coverage(object):
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
self.wrapped = 0
|
||||||
|
self.not_wrapped = 0
|
||||||
|
def declare_wrapped(self):
|
||||||
|
self.wrapped += 1
|
||||||
|
def declare_not_wrapped(self):
|
||||||
|
self.not_wrapped += 1
|
||||||
|
def printstats(self):
|
||||||
|
total = (self.wrapped + self.not_wrapped)
|
||||||
|
if total:
|
||||||
|
print >> sys.stderr, "***INFO*** The coverage of %s is %.2f%% (%i/%i)" %\
|
||||||
|
(self.name, float(self.wrapped*100)/total, self.wrapped, total)
|
||||||
|
else:
|
||||||
|
print >> sys.stderr, "***INFO*** There are no declared %s." %\
|
||||||
|
(self.name, )
|
||||||
|
|
||||||
|
functions_coverage = Coverage("global functions")
|
||||||
|
methods_coverage = Coverage("methods")
|
||||||
|
vproxies_coverage = Coverage("virtual proxies")
|
||||||
|
vaccessors_coverage = Coverage("virtual accessors")
|
||||||
|
iproxies_coverage = Coverage("interface proxies")
|
||||||
|
|
||||||
def exc_info():
|
def exc_info():
|
||||||
#traceback.print_exc()
|
#traceback.print_exc()
|
||||||
|
@ -60,7 +86,7 @@ class Wrapper:
|
||||||
' sizeof(%(tp_basicsize)s), /* tp_basicsize */\n' \
|
' sizeof(%(tp_basicsize)s), /* tp_basicsize */\n' \
|
||||||
' 0, /* tp_itemsize */\n' \
|
' 0, /* tp_itemsize */\n' \
|
||||||
' /* methods */\n' \
|
' /* methods */\n' \
|
||||||
' (destructor)0, /* tp_dealloc */\n' \
|
' (destructor)%(tp_dealloc)s, /* tp_dealloc */\n' \
|
||||||
' (printfunc)0, /* tp_print */\n' \
|
' (printfunc)0, /* tp_print */\n' \
|
||||||
' (getattrfunc)%(tp_getattr)s, /* tp_getattr */\n' \
|
' (getattrfunc)%(tp_getattr)s, /* tp_getattr */\n' \
|
||||||
' (setattrfunc)%(tp_setattr)s, /* tp_setattr */\n' \
|
' (setattrfunc)%(tp_setattr)s, /* tp_setattr */\n' \
|
||||||
|
@ -72,13 +98,13 @@ class Wrapper:
|
||||||
' (hashfunc)%(tp_hash)s, /* tp_hash */\n' \
|
' (hashfunc)%(tp_hash)s, /* tp_hash */\n' \
|
||||||
' (ternaryfunc)%(tp_call)s, /* tp_call */\n' \
|
' (ternaryfunc)%(tp_call)s, /* tp_call */\n' \
|
||||||
' (reprfunc)%(tp_str)s, /* tp_str */\n' \
|
' (reprfunc)%(tp_str)s, /* tp_str */\n' \
|
||||||
' (getattrofunc)0, /* tp_getattro */\n' \
|
' (getattrofunc)%(tp_getattro)s, /* tp_getattro */\n' \
|
||||||
' (setattrofunc)0, /* tp_setattro */\n' \
|
' (setattrofunc)%(tp_setattro)s, /* tp_setattro */\n' \
|
||||||
' (PyBufferProcs*)%(tp_as_buffer)s, /* tp_as_buffer */\n' \
|
' (PyBufferProcs*)%(tp_as_buffer)s, /* tp_as_buffer */\n' \
|
||||||
' Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */\n' \
|
' %(tp_flags)s, /* tp_flags */\n' \
|
||||||
' NULL, /* Documentation string */\n' \
|
' NULL, /* Documentation string */\n' \
|
||||||
' (traverseproc)0, /* tp_traverse */\n' \
|
' (traverseproc)%(tp_traverse)s, /* tp_traverse */\n' \
|
||||||
' (inquiry)0, /* tp_clear */\n' \
|
' (inquiry)%(tp_clear)s, /* tp_clear */\n' \
|
||||||
' (richcmpfunc)%(tp_richcompare)s, /* tp_richcompare */\n' \
|
' (richcmpfunc)%(tp_richcompare)s, /* tp_richcompare */\n' \
|
||||||
' %(tp_weaklistoffset)s, /* tp_weaklistoffset */\n' \
|
' %(tp_weaklistoffset)s, /* tp_weaklistoffset */\n' \
|
||||||
' (getiterfunc)%(tp_iter)s, /* tp_iter */\n' \
|
' (getiterfunc)%(tp_iter)s, /* tp_iter */\n' \
|
||||||
|
@ -98,11 +124,13 @@ class Wrapper:
|
||||||
' (inquiry)%(tp_is_gc)s /* tp_is_gc */\n' \
|
' (inquiry)%(tp_is_gc)s /* tp_is_gc */\n' \
|
||||||
'};\n\n'
|
'};\n\n'
|
||||||
|
|
||||||
slots_list = ['tp_getattr', 'tp_setattr', 'tp_compare', 'tp_repr',
|
slots_list = ['tp_getattr', 'tp_setattr', 'tp_getattro', 'tp_setattro',
|
||||||
|
'tp_compare', 'tp_repr',
|
||||||
'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash',
|
'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash',
|
||||||
'tp_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
|
'tp_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
|
||||||
'tp_iternext', 'tp_descr_get', 'tp_descr_set', 'tp_init',
|
'tp_iternext', 'tp_descr_get', 'tp_descr_set', 'tp_init',
|
||||||
'tp_alloc', 'tp_new', 'tp_free', 'tp_is_gc']
|
'tp_alloc', 'tp_new', 'tp_free', 'tp_is_gc',
|
||||||
|
'tp_traverse', 'tp_clear', 'tp_dealloc', 'tp_flags']
|
||||||
|
|
||||||
getter_tmpl = \
|
getter_tmpl = \
|
||||||
'static PyObject *\n' \
|
'static PyObject *\n' \
|
||||||
|
@ -145,6 +173,27 @@ class Wrapper:
|
||||||
'%(codeafter)s\n' \
|
'%(codeafter)s\n' \
|
||||||
'}\n\n'
|
'}\n\n'
|
||||||
|
|
||||||
|
virtual_accessor_tmpl = \
|
||||||
|
'static PyObject *\n' \
|
||||||
|
'_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n' \
|
||||||
|
'{\n' \
|
||||||
|
' gpointer klass;\n' \
|
||||||
|
'%(varlist)s' \
|
||||||
|
'%(parseargs)s' \
|
||||||
|
'%(codebefore)s' \
|
||||||
|
' klass = g_type_class_ref(pyg_type_from_object(cls));\n' \
|
||||||
|
' if (%(class_cast_macro)s(klass)->%(virtual)s)\n' \
|
||||||
|
' %(setreturn)s%(class_cast_macro)s(klass)->%(virtual)s(%(arglist)s);\n' \
|
||||||
|
' else {\n' \
|
||||||
|
' PyErr_SetString(PyExc_NotImplementedError, ' \
|
||||||
|
'"virtual method %(name)s not implemented");\n' \
|
||||||
|
' g_type_class_unref(klass);\n' \
|
||||||
|
' return NULL;\n' \
|
||||||
|
' }\n' \
|
||||||
|
' g_type_class_unref(klass);\n' \
|
||||||
|
'%(codeafter)s\n' \
|
||||||
|
'}\n\n'
|
||||||
|
|
||||||
# template for method calls
|
# template for method calls
|
||||||
constructor_tmpl = None
|
constructor_tmpl = None
|
||||||
method_tmpl = None
|
method_tmpl = None
|
||||||
|
@ -173,6 +222,8 @@ class Wrapper:
|
||||||
def write_class(self):
|
def write_class(self):
|
||||||
self.fp.write('\n/* ----------- ' + self.objinfo.c_name + ' ----------- */\n\n')
|
self.fp.write('\n/* ----------- ' + self.objinfo.c_name + ' ----------- */\n\n')
|
||||||
substdict = self.get_initial_class_substdict()
|
substdict = self.get_initial_class_substdict()
|
||||||
|
if not substdict.has_key('tp_flags'):
|
||||||
|
substdict['tp_flags'] = 'Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE'
|
||||||
substdict['typename'] = self.objinfo.c_name
|
substdict['typename'] = self.objinfo.c_name
|
||||||
if self.overrides.modulename:
|
if self.overrides.modulename:
|
||||||
substdict['classname'] = '%s.%s' % (self.overrides.modulename,
|
substdict['classname'] = '%s.%s' % (self.overrides.modulename,
|
||||||
|
@ -189,8 +240,6 @@ class Wrapper:
|
||||||
|
|
||||||
# handle slots ...
|
# handle slots ...
|
||||||
for slot in self.slots_list:
|
for slot in self.slots_list:
|
||||||
if substdict.has_key(slot) and substdict[slot] != '0':
|
|
||||||
continue
|
|
||||||
|
|
||||||
slotname = '%s.%s' % (self.objinfo.c_name, slot)
|
slotname = '%s.%s' % (self.objinfo.c_name, slot)
|
||||||
slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
|
slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
|
||||||
|
@ -201,10 +250,13 @@ class Wrapper:
|
||||||
self.write_function(slotname, data)
|
self.write_function(slotname, data)
|
||||||
substdict[slot] = slotfunc
|
substdict[slot] = slotfunc
|
||||||
else:
|
else:
|
||||||
substdict[slot] = '0'
|
if not substdict.has_key(slot):
|
||||||
|
substdict[slot] = '0'
|
||||||
|
|
||||||
self.fp.write(self.type_tmpl % substdict)
|
self.fp.write(self.type_tmpl % substdict)
|
||||||
|
|
||||||
|
self.write_virtuals()
|
||||||
|
|
||||||
def write_function_wrapper(self, function_obj, template,
|
def write_function_wrapper(self, function_obj, template,
|
||||||
handle_return=0, is_method=0, kwargs_needed=0,
|
handle_return=0, is_method=0, kwargs_needed=0,
|
||||||
substdict=None):
|
substdict=None):
|
||||||
|
@ -223,11 +275,12 @@ class Wrapper:
|
||||||
if function_obj.varargs:
|
if function_obj.varargs:
|
||||||
raise ValueError, "varargs functions not supported"
|
raise ValueError, "varargs functions not supported"
|
||||||
|
|
||||||
for ptype, pname, pdflt, pnull in function_obj.params:
|
for param in function_obj.params:
|
||||||
if pdflt and '|' not in info.parsestr:
|
if param.pdflt and '|' not in info.parsestr:
|
||||||
info.add_parselist('|', [], [])
|
info.add_parselist('|', [], [])
|
||||||
handler = argtypes.matcher.get(ptype)
|
handler = argtypes.matcher.get(param.ptype)
|
||||||
handler.write_param(ptype, pname, pdflt, pnull, info)
|
handler.write_param(param.ptype, param.pname, param.pdflt,
|
||||||
|
param.pnull, info)
|
||||||
|
|
||||||
substdict['setreturn'] = ''
|
substdict['setreturn'] = ''
|
||||||
if handle_return:
|
if handle_return:
|
||||||
|
@ -249,7 +302,7 @@ class Wrapper:
|
||||||
|
|
||||||
if self.objinfo:
|
if self.objinfo:
|
||||||
substdict['typename'] = self.objinfo.c_name
|
substdict['typename'] = self.objinfo.c_name
|
||||||
substdict['cname'] = function_obj.c_name
|
substdict.setdefault('cname', function_obj.c_name)
|
||||||
substdict['varlist'] = info.get_varlist()
|
substdict['varlist'] = info.get_varlist()
|
||||||
substdict['typecodes'] = info.parsestr
|
substdict['typecodes'] = info.parsestr
|
||||||
substdict['parselist'] = info.get_parselist()
|
substdict['parselist'] = info.get_parselist()
|
||||||
|
@ -284,6 +337,16 @@ class Wrapper:
|
||||||
data = self.overrides.override(funcname)
|
data = self.overrides.override(funcname)
|
||||||
self.write_function(funcname, data)
|
self.write_function(funcname, data)
|
||||||
else:
|
else:
|
||||||
|
# ok, a hack to determine if we should use new-style constructores :P
|
||||||
|
if getattr(self, 'write_property_based_constructor', None) is not None:
|
||||||
|
if (len(constructor.params) == 0 or
|
||||||
|
isinstance(constructor.params[0], definitions.Property)):
|
||||||
|
# write_property_based_constructor is only
|
||||||
|
# implemented in GObjectWrapper
|
||||||
|
return self.write_property_based_constructor(constructor)
|
||||||
|
else:
|
||||||
|
print >> sys.stderr, "Warning: generating old-style constructor for",\
|
||||||
|
constructor.c_name
|
||||||
# write constructor from template ...
|
# write constructor from template ...
|
||||||
code = self.write_function_wrapper(constructor,
|
code = self.write_function_wrapper(constructor,
|
||||||
self.constructor_tmpl,
|
self.constructor_tmpl,
|
||||||
|
@ -294,19 +357,22 @@ class Wrapper:
|
||||||
except:
|
except:
|
||||||
sys.stderr.write('Could not write constructor for %s: %s\n'
|
sys.stderr.write('Could not write constructor for %s: %s\n'
|
||||||
% (self.objinfo.c_name, exc_info()))
|
% (self.objinfo.c_name, exc_info()))
|
||||||
# this is a hack ...
|
initfunc = self.write_noconstructor()
|
||||||
if not hasattr(self.overrides, 'no_constructor_written'):
|
|
||||||
self.fp.write(self.noconstructor)
|
|
||||||
self.overrides.no_constructor_written = 1
|
|
||||||
initfunc = 'pygobject_no_constructor'
|
|
||||||
else:
|
else:
|
||||||
# this is a hack ...
|
initfunc = self.write_default_constructor()
|
||||||
if not hasattr(self.overrides, 'no_constructor_written'):
|
|
||||||
self.fp.write(self.noconstructor)
|
|
||||||
self.overrides.no_constructor_written = 1
|
|
||||||
initfunc = 'pygobject_no_constructor'
|
|
||||||
return initfunc
|
return initfunc
|
||||||
|
|
||||||
|
def write_noconstructor(self):
|
||||||
|
# this is a hack ...
|
||||||
|
if not hasattr(self.overrides, 'no_constructor_written'):
|
||||||
|
self.fp.write(self.noconstructor)
|
||||||
|
self.overrides.no_constructor_written = 1
|
||||||
|
initfunc = 'pygobject_no_constructor'
|
||||||
|
return initfunc
|
||||||
|
|
||||||
|
def write_default_constructor(self):
|
||||||
|
return self.write_noconstructor()
|
||||||
|
|
||||||
def get_methflags(self, funcname):
|
def get_methflags(self, funcname):
|
||||||
if self.overrides.wants_kwargs(funcname):
|
if self.overrides.wants_kwargs(funcname):
|
||||||
return 'METH_VARARGS|METH_KEYWORDS'
|
return 'METH_VARARGS|METH_KEYWORDS'
|
||||||
|
@ -321,7 +387,16 @@ class Wrapper:
|
||||||
self.fp.write(data)
|
self.fp.write(data)
|
||||||
self.fp.resetline()
|
self.fp.resetline()
|
||||||
self.fp.write('\n\n')
|
self.fp.write('\n\n')
|
||||||
|
|
||||||
|
def _get_class_virtual_substdict(self, meth, cname, parent):
|
||||||
|
substdict = self.get_initial_method_substdict(meth)
|
||||||
|
substdict['virtual'] = substdict['name'].split('.')[1]
|
||||||
|
substdict['cname'] = cname
|
||||||
|
substdict['class_cast_macro'] = parent.typecode.replace('_TYPE_', '_', 1) + "_CLASS"
|
||||||
|
substdict['typecode'] = self.objinfo.typecode
|
||||||
|
substdict['cast'] = string.replace(parent.typecode, '_TYPE_', '_', 1)
|
||||||
|
return substdict
|
||||||
|
|
||||||
def write_methods(self):
|
def write_methods(self):
|
||||||
methods = []
|
methods = []
|
||||||
klass = self.objinfo.c_name
|
klass = self.objinfo.c_name
|
||||||
|
@ -347,7 +422,9 @@ class Wrapper:
|
||||||
{ 'name': fixname(meth.name),
|
{ 'name': fixname(meth.name),
|
||||||
'cname': '_wrap_' + method_name,
|
'cname': '_wrap_' + method_name,
|
||||||
'flags': methflags})
|
'flags': methflags})
|
||||||
|
methods_coverage.declare_wrapped()
|
||||||
except:
|
except:
|
||||||
|
methods_coverage.declare_not_wrapped()
|
||||||
sys.stderr.write('Could not write method %s.%s: %s\n'
|
sys.stderr.write('Could not write method %s.%s: %s\n'
|
||||||
% (klass, meth.name, exc_info()))
|
% (klass, meth.name, exc_info()))
|
||||||
|
|
||||||
|
@ -360,15 +437,21 @@ class Wrapper:
|
||||||
try:
|
try:
|
||||||
data = self.overrides.define(klass, method_name)
|
data = self.overrides.define(klass, method_name)
|
||||||
self.write_function(method_name, data)
|
self.write_function(method_name, data)
|
||||||
self.get_methflags(method_name)
|
methflags = self.get_methflags(method_name)
|
||||||
|
|
||||||
methods.append(self.methdef_tmpl %
|
methods.append(self.methdef_tmpl %
|
||||||
{ 'name': method_name,
|
{ 'name': method_name,
|
||||||
'cname': '_wrap_' + c_name,
|
'cname': '_wrap_' + c_name,
|
||||||
'flags': methflags})
|
'flags': methflags})
|
||||||
|
methods_coverage.declare_wrapped()
|
||||||
except:
|
except:
|
||||||
|
methods_coverage.declare_not_wrapped()
|
||||||
sys.stderr.write('Could not write method %s.%s: %s\n'
|
sys.stderr.write('Could not write method %s.%s: %s\n'
|
||||||
% (klass, meth.name, exc_info()))
|
% (klass, meth.name, exc_info()))
|
||||||
|
|
||||||
|
# Add GObject virtual method accessors, for chaining to parent
|
||||||
|
# virtuals from subclasses
|
||||||
|
methods += self.write_virtual_accessors()
|
||||||
|
|
||||||
if methods:
|
if methods:
|
||||||
methoddefs = '_Py%s_methods' % self.objinfo.c_name
|
methoddefs = '_Py%s_methods' % self.objinfo.c_name
|
||||||
|
@ -380,6 +463,112 @@ class Wrapper:
|
||||||
else:
|
else:
|
||||||
methoddefs = 'NULL'
|
methoddefs = 'NULL'
|
||||||
return methoddefs
|
return methoddefs
|
||||||
|
|
||||||
|
def write_virtual_accessors(self):
|
||||||
|
klass = self.objinfo.c_name
|
||||||
|
methods = []
|
||||||
|
for meth in self.parser.find_virtuals(self.objinfo):
|
||||||
|
method_name = self.objinfo.c_name + "__do_" + meth.name
|
||||||
|
if self.overrides.is_ignored(method_name):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
if self.overrides.is_overriden(method_name):
|
||||||
|
if not self.overrides.is_already_included(method_name):
|
||||||
|
data = self.overrides.override(method_name)
|
||||||
|
self.write_function(method_name, data)
|
||||||
|
methflags = self.get_methflags(method_name)
|
||||||
|
else:
|
||||||
|
# temporarily add a 'self' parameter as first argument
|
||||||
|
meth.params.insert(0, definitions.Parameter(
|
||||||
|
ptype=(self.objinfo.c_name + '*'),
|
||||||
|
pname='self', pdflt=None, pnull=None))
|
||||||
|
try:
|
||||||
|
# write method from template ...
|
||||||
|
code, methflags = self.write_function_wrapper(meth,
|
||||||
|
self.virtual_accessor_tmpl, handle_return=True, is_method=False,
|
||||||
|
substdict=self._get_class_virtual_substdict(meth, method_name, self.objinfo))
|
||||||
|
self.fp.write(code)
|
||||||
|
finally:
|
||||||
|
del meth.params[0]
|
||||||
|
methods.append(self.methdef_tmpl %
|
||||||
|
{ 'name': "do_" + fixname(meth.name),
|
||||||
|
'cname': '_wrap_' + method_name,
|
||||||
|
'flags': methflags + '|METH_CLASS'})
|
||||||
|
vaccessors_coverage.declare_wrapped()
|
||||||
|
except:
|
||||||
|
vaccessors_coverage.declare_not_wrapped()
|
||||||
|
sys.stderr.write('Could not write virtual accessor method %s.%s: %s\n'
|
||||||
|
% (klass, meth.name, exc_info()))
|
||||||
|
return methods
|
||||||
|
|
||||||
|
def write_virtuals(self):
|
||||||
|
'''Write _wrap_FooBar__proxy_do_zbr() reverse wrapers for GObject virtuals'''
|
||||||
|
klass = self.objinfo.c_name
|
||||||
|
virtuals = []
|
||||||
|
for meth in self.parser.find_virtuals(self.objinfo):
|
||||||
|
method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
|
||||||
|
if self.overrides.is_ignored(method_name):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
if self.overrides.is_overriden(method_name):
|
||||||
|
if not self.overrides.is_already_included(method_name):
|
||||||
|
data = self.overrides.override(method_name)
|
||||||
|
self.write_function(method_name, data)
|
||||||
|
else:
|
||||||
|
# write virtual proxy ...
|
||||||
|
ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
|
||||||
|
wrapper = reversewrapper.ReverseWrapper(
|
||||||
|
'_wrap_' + method_name, is_static=True)
|
||||||
|
wrapper.set_return_type(ret(wrapper, **props))
|
||||||
|
wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
|
||||||
|
wrapper, "self", method_name="do_" + meth.name,
|
||||||
|
c_type=(klass + ' *')))
|
||||||
|
for param in meth.params:
|
||||||
|
handler, props = argtypes.matcher.get_reverse(param.ptype)
|
||||||
|
wrapper.add_parameter(handler(wrapper, param.pname, **props))
|
||||||
|
buf = reversewrapper.MemoryCodeSink()
|
||||||
|
wrapper.generate(buf)
|
||||||
|
self.fp.write(buf.flush())
|
||||||
|
virtuals.append((fixname(meth.name), '_wrap_' + method_name))
|
||||||
|
vproxies_coverage.declare_wrapped()
|
||||||
|
except KeyError:
|
||||||
|
vproxies_coverage.declare_not_wrapped()
|
||||||
|
virtuals.append((fixname(meth.name), None))
|
||||||
|
sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
|
||||||
|
% (klass, meth.name, exc_info()))
|
||||||
|
if virtuals:
|
||||||
|
# Write a 'pygtk class init' function for this object,
|
||||||
|
# except when the object type is explicitly ignored (like
|
||||||
|
# GtkPlug and GtkSocket on win32).
|
||||||
|
if self.overrides.is_ignored(self.objinfo.typecode):
|
||||||
|
return
|
||||||
|
class_cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1) + "_CLASS"
|
||||||
|
cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1)
|
||||||
|
funcname = "__%s_class_init" % klass
|
||||||
|
self.objinfo.class_init_func = funcname
|
||||||
|
have_implemented_virtuals = not not [True for name, cname in virtuals
|
||||||
|
if cname is not None]
|
||||||
|
self.fp.write(('\nstatic int\n'
|
||||||
|
'%(funcname)s(gpointer gclass, PyTypeObject *pyclass)\n'
|
||||||
|
'{\n') % vars())
|
||||||
|
|
||||||
|
if have_implemented_virtuals:
|
||||||
|
self.fp.write(' PyObject *o;\n')
|
||||||
|
self.fp.write(
|
||||||
|
' %(klass)sClass *klass = %(class_cast_macro)s(gclass);\n'
|
||||||
|
% vars())
|
||||||
|
|
||||||
|
for name, cname in virtuals:
|
||||||
|
do_name = 'do_' + name
|
||||||
|
if cname is None:
|
||||||
|
self.fp.write('\n /* overriding %(do_name)s '
|
||||||
|
'is currently not supported */\n' % vars())
|
||||||
|
else:
|
||||||
|
self.fp.write('''
|
||||||
|
if ((o = PyDict_GetItemString(pyclass->tp_dict, "%(do_name)s"))
|
||||||
|
&& !PyObject_TypeCheck(o, &PyCFunction_Type))
|
||||||
|
klass->%(name)s = %(cname)s;\n''' % vars())
|
||||||
|
self.fp.write(' return 0;\n}\n')
|
||||||
|
|
||||||
def write_getsets(self):
|
def write_getsets(self):
|
||||||
lower_name = self.get_lower_name()
|
lower_name = self.get_lower_name()
|
||||||
|
@ -456,7 +645,9 @@ class Wrapper:
|
||||||
{ 'name': func.name,
|
{ 'name': func.name,
|
||||||
'cname': '_wrap_' + funcname,
|
'cname': '_wrap_' + funcname,
|
||||||
'flags': methflags })
|
'flags': methflags })
|
||||||
|
functions_coverage.declare_wrapped()
|
||||||
except:
|
except:
|
||||||
|
functions_coverage.declare_not_wrapped()
|
||||||
sys.stderr.write('Could not write function %s: %s\n'
|
sys.stderr.write('Could not write function %s: %s\n'
|
||||||
% (func.name, exc_info()))
|
% (func.name, exc_info()))
|
||||||
|
|
||||||
|
@ -470,7 +661,9 @@ class Wrapper:
|
||||||
{ 'name': funcname,
|
{ 'name': funcname,
|
||||||
'cname': '_wrap_' + funcname,
|
'cname': '_wrap_' + funcname,
|
||||||
'flags': methflags })
|
'flags': methflags })
|
||||||
|
functions_coverage.declare_wrapped()
|
||||||
except:
|
except:
|
||||||
|
functions_coverage.declare_not_wrapped()
|
||||||
sys.stderr.write('Could not write function %s: %s\n'
|
sys.stderr.write('Could not write function %s: %s\n'
|
||||||
% (funcname, exc_info()))
|
% (funcname, exc_info()))
|
||||||
|
|
||||||
|
@ -527,21 +720,101 @@ class GObjectWrapper(Wrapper):
|
||||||
|
|
||||||
def get_initial_constructor_substdict(self, constructor):
|
def get_initial_constructor_substdict(self, constructor):
|
||||||
substdict = Wrapper.get_initial_constructor_substdict(self, constructor)
|
substdict = Wrapper.get_initial_constructor_substdict(self, constructor)
|
||||||
if argtypes.matcher.object_is_a(self.objinfo.c_name, 'GtkWindow'):
|
if not constructor.caller_owns_return:
|
||||||
substdict['aftercreate'] = " g_object_ref(self->obj); /* we don't own the first reference of windows */\n"
|
substdict['aftercreate'] = " g_object_ref(self->obj);\n"
|
||||||
elif argtypes.matcher.object_is_a(self.objinfo.c_name, 'GtkInvisible'):
|
else:
|
||||||
substdict['aftercreate'] = " g_object_ref(self->obj); /* we don't own the first reference of invisibles */\n"
|
substdict['aftercreate'] = ''
|
||||||
else:
|
|
||||||
if not constructor.caller_owns_return:
|
|
||||||
substdict['aftercreate'] = " g_object_ref(self->obj);\n"
|
|
||||||
else:
|
|
||||||
substdict['aftercreate'] = ''
|
|
||||||
return substdict
|
return substdict
|
||||||
|
|
||||||
def get_initial_method_substdict(self, method):
|
def get_initial_method_substdict(self, method):
|
||||||
substdict = Wrapper.get_initial_method_substdict(self, method)
|
substdict = Wrapper.get_initial_method_substdict(self, method)
|
||||||
substdict['cast'] = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
|
substdict['cast'] = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
|
||||||
return substdict
|
return substdict
|
||||||
|
def write_default_constructor(self):
|
||||||
|
return '0'
|
||||||
|
|
||||||
|
def write_property_based_constructor(self, constructor):
|
||||||
|
out = self.fp
|
||||||
|
print >> out, "static int"
|
||||||
|
print >> out, '_wrap_%s(PyGObject *self, PyObject *args,'\
|
||||||
|
' PyObject *kwargs)\n{' % constructor.c_name
|
||||||
|
print >> out, " GType obj_type = pyg_type_from_object((PyObject *) self);"
|
||||||
|
|
||||||
|
def py_str_list_to_c(arg):
|
||||||
|
if arg:
|
||||||
|
return "{" + ", ".join(map(lambda s: '"' + s + '"', arg)) + ", NULL }"
|
||||||
|
else:
|
||||||
|
return "{ NULL }"
|
||||||
|
|
||||||
|
classname = '%s.%s' % (self.overrides.modulename, self.objinfo.name)
|
||||||
|
|
||||||
|
if constructor.params:
|
||||||
|
mandatory_arguments = [param for param in constructor.params if not param.optional]
|
||||||
|
optional_arguments = [param for param in constructor.params if param.optional]
|
||||||
|
arg_names = py_str_list_to_c([param.argname for param in
|
||||||
|
mandatory_arguments + optional_arguments])
|
||||||
|
prop_names = py_str_list_to_c([param.pname for param in
|
||||||
|
mandatory_arguments + optional_arguments])
|
||||||
|
|
||||||
|
print >> out, " GParameter params[%i];" % len(constructor.params)
|
||||||
|
print >> out, " PyObject *parsed_args[%i] = {NULL, };" % len(constructor.params)
|
||||||
|
print >> out, " char *arg_names[] = %s;" % arg_names
|
||||||
|
print >> out, " char *prop_names[] = %s;" % prop_names
|
||||||
|
print >> out, " guint nparams, i;"
|
||||||
|
print >> out
|
||||||
|
if constructor.deprecated is not None:
|
||||||
|
print >> out, ' if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)' %\
|
||||||
|
constructor.deprecated
|
||||||
|
print >> out, ' return -1;'
|
||||||
|
print >> out
|
||||||
|
print >> out, " if (!PyArg_ParseTupleAndKeywords(args, kwargs, ",
|
||||||
|
template = '"'
|
||||||
|
if mandatory_arguments:
|
||||||
|
template += "O"*len(mandatory_arguments)
|
||||||
|
if optional_arguments:
|
||||||
|
template += "|" + "O"*len(optional_arguments)
|
||||||
|
template += ':%s.__init__"' % classname
|
||||||
|
print >> out, template, ", arg_names",
|
||||||
|
for i in range(len(constructor.params)):
|
||||||
|
print >> out, ", &parsed_args[%i]" % i,
|
||||||
|
print >> out, "))"
|
||||||
|
print >> out, " return -1;"
|
||||||
|
print >> out
|
||||||
|
print >> out, " memset(params, 0, sizeof(GParameter)*%i);" % len(constructor.params)
|
||||||
|
print >> out, " if (!pyg_parse_constructor_args(obj_type, arg_names, prop_names,"
|
||||||
|
print >> out, " params, &nparams, parsed_args))"
|
||||||
|
print >> out, " return -1;"
|
||||||
|
print >> out, " self->obj = g_object_newv(obj_type, nparams, params);"
|
||||||
|
print >> out, " for (i = 0; i < nparams; ++i)"
|
||||||
|
print >> out, " g_value_unset(¶ms[i].value);"
|
||||||
|
else:
|
||||||
|
print >> out, " static char* kwlist[] = { NULL };";
|
||||||
|
print >> out
|
||||||
|
if constructor.deprecated is not None:
|
||||||
|
print >> out, ' if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)' %\
|
||||||
|
constructor.deprecated
|
||||||
|
print >> out, ' return -1;'
|
||||||
|
print >> out
|
||||||
|
print >> out, ' if (!PyArg_ParseTupleAndKeywords(args, kwargs, ":%s.__init__", kwlist))' % classname
|
||||||
|
print >> out, " return -1;"
|
||||||
|
print >> out
|
||||||
|
print >> out, " self->obj = g_object_newv(obj_type, 0, NULL);"
|
||||||
|
|
||||||
|
print >> out, \
|
||||||
|
' if (!self->obj) {\n' \
|
||||||
|
' PyErr_SetString(PyExc_RuntimeError, "could not create %(typename)s object");\n' \
|
||||||
|
' return -1;\n' \
|
||||||
|
' }\n'
|
||||||
|
|
||||||
|
if not constructor.caller_owns_return:
|
||||||
|
print >> out, " g_object_ref(self->obj);\n"
|
||||||
|
|
||||||
|
print >> out, \
|
||||||
|
' pygobject_register_wrapper((PyObject *)self);\n' \
|
||||||
|
' return 0;\n' \
|
||||||
|
'}\n\n' % { 'typename': classname }
|
||||||
|
return "_wrap_%s" % constructor.c_name
|
||||||
|
|
||||||
|
|
||||||
## TODO : Add GstMiniObjectWrapper(Wrapper)
|
## TODO : Add GstMiniObjectWrapper(Wrapper)
|
||||||
class GstMiniObjectWrapper(Wrapper):
|
class GstMiniObjectWrapper(Wrapper):
|
||||||
|
@ -615,6 +888,70 @@ class GInterfaceWrapper(GObjectWrapper):
|
||||||
# interfaces have no fields ...
|
# interfaces have no fields ...
|
||||||
return '0'
|
return '0'
|
||||||
|
|
||||||
|
def write_virtual_accessors(self):
|
||||||
|
## we don't want the 'chaining' functions for interfaces
|
||||||
|
return []
|
||||||
|
|
||||||
|
def write_virtuals(self):
|
||||||
|
## Now write reverse method wrappers, which let python code
|
||||||
|
## implement interface methods.
|
||||||
|
# First, get methods from the defs files
|
||||||
|
klass = self.objinfo.c_name
|
||||||
|
proxies = []
|
||||||
|
for meth in self.parser.find_virtuals(self.objinfo):
|
||||||
|
method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
|
||||||
|
if self.overrides.is_ignored(method_name):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
if self.overrides.is_overriden(method_name):
|
||||||
|
if not self.overrides.is_already_included(method_name):
|
||||||
|
data = self.overrides.override(method_name)
|
||||||
|
self.write_function(method_name, data)
|
||||||
|
else:
|
||||||
|
# write proxy ...
|
||||||
|
ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
|
||||||
|
wrapper = reversewrapper.ReverseWrapper(
|
||||||
|
'_wrap_' + method_name, is_static=True)
|
||||||
|
wrapper.set_return_type(ret(wrapper, **props))
|
||||||
|
wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
|
||||||
|
wrapper, "self", method_name="do_" + meth.name,
|
||||||
|
c_type=(klass + ' *')))
|
||||||
|
for param in meth.params:
|
||||||
|
handler, props = argtypes.matcher.get_reverse(param.ptype)
|
||||||
|
wrapper.add_parameter(handler(wrapper, param.pname, **props))
|
||||||
|
buf = reversewrapper.MemoryCodeSink()
|
||||||
|
wrapper.generate(buf)
|
||||||
|
self.fp.write(buf.flush())
|
||||||
|
proxies.append((fixname(meth.name), '_wrap_' + method_name))
|
||||||
|
iproxies_coverage.declare_wrapped()
|
||||||
|
except KeyError:
|
||||||
|
iproxies_coverage.declare_not_wrapped()
|
||||||
|
proxies.append((fixname(meth.name), None))
|
||||||
|
sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
|
||||||
|
% (klass, meth.name, exc_info()))
|
||||||
|
if proxies:
|
||||||
|
## Write an interface init function for this object
|
||||||
|
funcname = "__%s__interface_init" % klass
|
||||||
|
vtable = self.objinfo.vtable
|
||||||
|
self.fp.write(('\nstatic void\n'
|
||||||
|
'%(funcname)s(%(vtable)s *iface)\n'
|
||||||
|
'{\n') % vars())
|
||||||
|
for name, cname in proxies:
|
||||||
|
do_name = 'do_' + name
|
||||||
|
if cname is not None:
|
||||||
|
self.fp.write(' iface->%s = %s;\n' % (name, cname))
|
||||||
|
self.fp.write('}\n\n')
|
||||||
|
interface_info = "__%s__iinfo" % klass
|
||||||
|
self.fp.write('''
|
||||||
|
static const GInterfaceInfo %s = {
|
||||||
|
(GInterfaceInitFunc) %s,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
''' % (interface_info, funcname))
|
||||||
|
self.objinfo.interface_info = interface_info
|
||||||
|
|
||||||
|
|
||||||
class GBoxedWrapper(Wrapper):
|
class GBoxedWrapper(Wrapper):
|
||||||
constructor_tmpl = \
|
constructor_tmpl = \
|
||||||
'static int\n' \
|
'static int\n' \
|
||||||
|
@ -702,7 +1039,7 @@ class GPointerWrapper(GBoxedWrapper):
|
||||||
return substdict
|
return substdict
|
||||||
|
|
||||||
def write_headers(data, fp):
|
def write_headers(data, fp):
|
||||||
fp.write('/* -- THIS FILE IS GENERATE - DO NOT EDIT */')
|
fp.write('/* -- THIS FILE IS GENERATED - DO NOT EDIT */')
|
||||||
fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
|
fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
|
||||||
fp.write('#include <Python.h>\n\n\n')
|
fp.write('#include <Python.h>\n\n\n')
|
||||||
fp.write(data)
|
fp.write(data)
|
||||||
|
@ -751,15 +1088,17 @@ def write_enums(parser, prefix, fp=sys.stdout):
|
||||||
% (value, value))
|
% (value, value))
|
||||||
else:
|
else:
|
||||||
if enum.deftype == 'enum':
|
if enum.deftype == 'enum':
|
||||||
fp.write(' pyg_enum_add_constants(module, %s, strip_prefix);\n'
|
fp.write(' pyg_enum_add(module, "%s", strip_prefix, %s);\n' % (enum.name, enum.typecode))
|
||||||
% (enum.typecode,))
|
|
||||||
else:
|
else:
|
||||||
fp.write(' pyg_flags_add_constants(module, %s, strip_prefix);\n'
|
fp.write(' pyg_flags_add(module, "%s", strip_prefix, %s);\n' % (enum.name, enum.typecode))
|
||||||
% (enum.typecode,))
|
|
||||||
|
fp.write('\n')
|
||||||
|
fp.write(' if (PyErr_Occurred())\n')
|
||||||
|
fp.write(' PyErr_Print();\n')
|
||||||
fp.write('}\n\n')
|
fp.write('}\n\n')
|
||||||
|
|
||||||
def write_extension_init(overrides, prefix, fp):
|
def write_extension_init(overrides, prefix, fp):
|
||||||
fp.write('/* intialise stuff extension classes */\n')
|
fp.write('/* initialise stuff extension classes */\n')
|
||||||
fp.write('void\n' + prefix + '_register_classes(PyObject *d)\n{\n')
|
fp.write('void\n' + prefix + '_register_classes(PyObject *d)\n{\n')
|
||||||
imports = overrides.get_imports()[:]
|
imports = overrides.get_imports()[:]
|
||||||
if imports:
|
if imports:
|
||||||
|
@ -798,6 +1137,9 @@ def write_registers(parser, fp):
|
||||||
fp.write(' pyg_register_interface(d, "' + interface.name +
|
fp.write(' pyg_register_interface(d, "' + interface.name +
|
||||||
'", '+ interface.typecode + ', &Py' + interface.c_name +
|
'", '+ interface.typecode + ', &Py' + interface.c_name +
|
||||||
'_Type);\n')
|
'_Type);\n')
|
||||||
|
if interface.interface_info is not None:
|
||||||
|
fp.write(' pyg_register_interface_info(%s, &%s);\n' %
|
||||||
|
(interface.typecode, interface.interface_info))
|
||||||
|
|
||||||
objects = parser.objects[:]
|
objects = parser.objects[:]
|
||||||
pos = 0
|
pos = 0
|
||||||
|
@ -825,6 +1167,9 @@ def write_registers(parser, fp):
|
||||||
fp.write(' pygobject_register_class(d, "' + obj.c_name +
|
fp.write(' pygobject_register_class(d, "' + obj.c_name +
|
||||||
'", ' + obj.typecode + ', &Py' + obj.c_name +
|
'", ' + obj.typecode + ', &Py' + obj.c_name +
|
||||||
'_Type, NULL);\n')
|
'_Type, NULL);\n')
|
||||||
|
if obj.class_init_func is not None:
|
||||||
|
fp.write(' pyg_register_class_init(%s, %s);\n' %
|
||||||
|
(obj.typecode, obj.class_init_func))
|
||||||
#TODO: register mini-objects
|
#TODO: register mini-objects
|
||||||
miniobjects = parser.miniobjects[:]
|
miniobjects = parser.miniobjects[:]
|
||||||
for obj in miniobjects:
|
for obj in miniobjects:
|
||||||
|
@ -917,9 +1262,17 @@ def main(argv):
|
||||||
p = defsparser.DefsParser(args[0], defines)
|
p = defsparser.DefsParser(args[0], defines)
|
||||||
if not outfilename:
|
if not outfilename:
|
||||||
outfilename = os.path.splitext(args[0])[0] + '.c'
|
outfilename = os.path.splitext(args[0])[0] + '.c'
|
||||||
|
|
||||||
p.startParsing()
|
p.startParsing()
|
||||||
|
|
||||||
register_types(p)
|
register_types(p)
|
||||||
write_source(p, o, prefix, FileOutput(sys.stdout, outfilename))
|
write_source(p, o, prefix, FileOutput(sys.stdout, outfilename))
|
||||||
|
|
||||||
|
functions_coverage.printstats()
|
||||||
|
methods_coverage.printstats()
|
||||||
|
vproxies_coverage.printstats()
|
||||||
|
vaccessors_coverage.printstats()
|
||||||
|
iproxies_coverage.printstats()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main(sys.argv))
|
sys.exit(main(sys.argv))
|
||||||
|
|
|
@ -1,5 +1,41 @@
|
||||||
# -*- Mode: Python; py-indent-offset: 4 -*-
|
# -*- Mode: Python; py-indent-offset: 4 -*-
|
||||||
import sys
|
import sys
|
||||||
|
from copy import *
|
||||||
|
|
||||||
|
def get_valid_scheme_definitions(defs):
|
||||||
|
return [x for x in defs if isinstance(x, tuple) and len(x) >= 2]
|
||||||
|
|
||||||
|
# New Parameter class, wich emulates a tuple for compatibility reasons
|
||||||
|
class Parameter(object):
|
||||||
|
def __init__(self, ptype, pname, pdflt, pnull, prop=None):
|
||||||
|
self.ptype = ptype
|
||||||
|
self.pname = pname
|
||||||
|
self.pdflt = pdflt
|
||||||
|
self.pnull = pnull
|
||||||
|
|
||||||
|
def __len__(self): return 4
|
||||||
|
def __getitem__(self, i):
|
||||||
|
return (self.ptype, self.pname, self.pdflt, self.pnull)[i]
|
||||||
|
|
||||||
|
def merge(self, old):
|
||||||
|
if old.pdflt is not None:
|
||||||
|
self.pdflt = old.pdflt
|
||||||
|
if old.pnull is not None:
|
||||||
|
self.pnull = old.pnull
|
||||||
|
|
||||||
|
# Parameter for property based constructors
|
||||||
|
class Property(object):
|
||||||
|
def __init__(self, pname, optional, argname):
|
||||||
|
self.pname = pname
|
||||||
|
self.optional = optional
|
||||||
|
self.argname = argname
|
||||||
|
|
||||||
|
def merge(self, old):
|
||||||
|
if old.optional is not None:
|
||||||
|
self.optional = old.optional
|
||||||
|
if old.argname is not None:
|
||||||
|
self.argname = old.argname
|
||||||
|
|
||||||
|
|
||||||
class Definition:
|
class Definition:
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
|
@ -13,6 +49,16 @@ class Definition:
|
||||||
"""write out this definition in defs file format"""
|
"""write out this definition in defs file format"""
|
||||||
raise RuntimeError, "this is an abstract class"
|
raise RuntimeError, "this is an abstract class"
|
||||||
|
|
||||||
|
def guess_return_value_ownership(self):
|
||||||
|
"return 1 if caller owns return value"
|
||||||
|
if getattr(self, 'is_constructor_of', False):
|
||||||
|
self.caller_owns_return = True
|
||||||
|
elif self.ret in ('char*', 'gchar*', 'string'):
|
||||||
|
self.caller_owns_return = True
|
||||||
|
else:
|
||||||
|
self.caller_owns_return = False
|
||||||
|
|
||||||
|
|
||||||
class ObjectDef(Definition):
|
class ObjectDef(Definition):
|
||||||
def __init__(self, name, *args):
|
def __init__(self, name, *args):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -22,9 +68,8 @@ class ObjectDef(Definition):
|
||||||
self.typecode = None
|
self.typecode = None
|
||||||
self.fields = []
|
self.fields = []
|
||||||
self.implements = []
|
self.implements = []
|
||||||
for arg in args:
|
self.class_init_func = None
|
||||||
if type(arg) != type(()) or len(arg) < 2:
|
for arg in get_valid_scheme_definitions(args):
|
||||||
continue
|
|
||||||
if arg[0] == 'in-module':
|
if arg[0] == 'in-module':
|
||||||
self.module = arg[1]
|
self.module = arg[1]
|
||||||
elif arg[0] == 'parent':
|
elif arg[0] == 'parent':
|
||||||
|
@ -120,16 +165,20 @@ class InterfaceDef(Definition):
|
||||||
self.module = None
|
self.module = None
|
||||||
self.c_name = None
|
self.c_name = None
|
||||||
self.typecode = None
|
self.typecode = None
|
||||||
|
self.vtable = None
|
||||||
self.fields = []
|
self.fields = []
|
||||||
for arg in args:
|
self.interface_info = None
|
||||||
if type(arg) != type(()) or len(arg) < 2:
|
for arg in get_valid_scheme_definitions(args):
|
||||||
continue
|
|
||||||
if arg[0] == 'in-module':
|
if arg[0] == 'in-module':
|
||||||
self.module = arg[1]
|
self.module = arg[1]
|
||||||
elif arg[0] == 'c-name':
|
elif arg[0] == 'c-name':
|
||||||
self.c_name = arg[1]
|
self.c_name = arg[1]
|
||||||
elif arg[0] == 'gtype-id':
|
elif arg[0] == 'gtype-id':
|
||||||
self.typecode = arg[1]
|
self.typecode = arg[1]
|
||||||
|
elif arg[0] == 'vtable':
|
||||||
|
self.vtable = arg[1]
|
||||||
|
if self.vtable is None:
|
||||||
|
self.vtable = self.c_name + "Iface"
|
||||||
def write_defs(self, fp=sys.stdout):
|
def write_defs(self, fp=sys.stdout):
|
||||||
fp.write('(define-interface ' + self.name + '\n')
|
fp.write('(define-interface ' + self.name + '\n')
|
||||||
if self.module:
|
if self.module:
|
||||||
|
@ -148,9 +197,7 @@ class EnumDef(Definition):
|
||||||
self.c_name = None
|
self.c_name = None
|
||||||
self.typecode = None
|
self.typecode = None
|
||||||
self.values = []
|
self.values = []
|
||||||
for arg in args:
|
for arg in get_valid_scheme_definitions(args):
|
||||||
if type(arg) != type(()) or len(arg) < 2:
|
|
||||||
continue
|
|
||||||
if arg[0] == 'in-module':
|
if arg[0] == 'in-module':
|
||||||
self.in_module = arg[1]
|
self.in_module = arg[1]
|
||||||
elif arg[0] == 'c-name':
|
elif arg[0] == 'c-name':
|
||||||
|
@ -189,9 +236,7 @@ class BoxedDef(Definition):
|
||||||
self.copy = None
|
self.copy = None
|
||||||
self.release = None
|
self.release = None
|
||||||
self.fields = []
|
self.fields = []
|
||||||
for arg in args:
|
for arg in get_valid_scheme_definitions(args):
|
||||||
if type(arg) != type(()) or len(arg) < 2:
|
|
||||||
continue
|
|
||||||
if arg[0] == 'in-module':
|
if arg[0] == 'in-module':
|
||||||
self.module = arg[1]
|
self.module = arg[1]
|
||||||
elif arg[0] == 'c-name':
|
elif arg[0] == 'c-name':
|
||||||
|
@ -236,9 +281,7 @@ class PointerDef(Definition):
|
||||||
self.c_name = None
|
self.c_name = None
|
||||||
self.typecode = None
|
self.typecode = None
|
||||||
self.fields = []
|
self.fields = []
|
||||||
for arg in args:
|
for arg in get_valid_scheme_definitions(args):
|
||||||
if type(arg) != type(()) or len(arg) < 2:
|
|
||||||
continue
|
|
||||||
if arg[0] == 'in-module':
|
if arg[0] == 'in-module':
|
||||||
self.module = arg[1]
|
self.module = arg[1]
|
||||||
elif arg[0] == 'c-name':
|
elif arg[0] == 'c-name':
|
||||||
|
@ -268,7 +311,7 @@ class PointerDef(Definition):
|
||||||
fp.write(' )\n')
|
fp.write(' )\n')
|
||||||
fp.write(')\n\n')
|
fp.write(')\n\n')
|
||||||
|
|
||||||
class MethodDef(Definition):
|
class MethodDefBase(Definition):
|
||||||
def __init__(self, name, *args):
|
def __init__(self, name, *args):
|
||||||
dump = 0
|
dump = 0
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -280,9 +323,7 @@ class MethodDef(Definition):
|
||||||
self.params = [] # of form (type, name, default, nullok)
|
self.params = [] # of form (type, name, default, nullok)
|
||||||
self.varargs = 0
|
self.varargs = 0
|
||||||
self.deprecated = None
|
self.deprecated = None
|
||||||
for arg in args:
|
for arg in get_valid_scheme_definitions(args):
|
||||||
if type(arg) != type(()) or len(arg) < 2:
|
|
||||||
continue
|
|
||||||
if arg[0] == 'of-object':
|
if arg[0] == 'of-object':
|
||||||
self.of_object = arg[1]
|
self.of_object = arg[1]
|
||||||
elif arg[0] == 'c-name':
|
elif arg[0] == 'c-name':
|
||||||
|
@ -300,11 +341,12 @@ class MethodDef(Definition):
|
||||||
pdflt = None
|
pdflt = None
|
||||||
pnull = 0
|
pnull = 0
|
||||||
for farg in parg[2:]:
|
for farg in parg[2:]:
|
||||||
|
assert isinstance(farg, tuple)
|
||||||
if farg[0] == 'default':
|
if farg[0] == 'default':
|
||||||
pdflt = farg[1]
|
pdflt = farg[1]
|
||||||
elif farg[0] == 'null-ok':
|
elif farg[0] == 'null-ok':
|
||||||
pnull = 1
|
pnull = 1
|
||||||
self.params.append((ptype, pname, pdflt, pnull))
|
self.params.append(Parameter(ptype, pname, pdflt, pnull))
|
||||||
elif arg[0] == 'varargs':
|
elif arg[0] == 'varargs':
|
||||||
self.varargs = arg[1] in ('t', '#t')
|
self.varargs = arg[1] in ('t', '#t')
|
||||||
elif arg[0] == 'deprecated':
|
elif arg[0] == 'deprecated':
|
||||||
|
@ -317,33 +359,30 @@ class MethodDef(Definition):
|
||||||
self.write_defs(sys.stderr)
|
self.write_defs(sys.stderr)
|
||||||
|
|
||||||
if self.caller_owns_return is None and self.ret is not None:
|
if self.caller_owns_return is None and self.ret is not None:
|
||||||
if self.ret[:6] == 'const-':
|
self.guess_return_value_ownership()
|
||||||
self.caller_owns_return = 0
|
|
||||||
elif self.ret in ('char*', 'gchar*', 'string'):
|
|
||||||
self.caller_owns_return = 1
|
|
||||||
else:
|
|
||||||
self.caller_owns_return = 0
|
|
||||||
for item in ('c_name', 'of_object'):
|
|
||||||
if self.__dict__[item] == None:
|
|
||||||
self.write_defs(sys.stderr)
|
|
||||||
raise RuntimeError, "definition missing required %s" % (item,)
|
|
||||||
|
|
||||||
def merge(self, old):
|
def merge(self, old, parmerge):
|
||||||
|
self.caller_owns_return = old.caller_owns_return
|
||||||
|
self.varargs = old.varargs
|
||||||
# here we merge extra parameter flags accross to the new object.
|
# here we merge extra parameter flags accross to the new object.
|
||||||
|
if not parmerge:
|
||||||
|
self.params = deepcopy(old.params)
|
||||||
|
return
|
||||||
for i in range(len(self.params)):
|
for i in range(len(self.params)):
|
||||||
ptype, pname, pdflt, pnull = self.params[i]
|
ptype, pname, pdflt, pnull = self.params[i]
|
||||||
for p2 in old.params:
|
for p2 in old.params:
|
||||||
if p2[1] == pname:
|
if p2[1] == pname:
|
||||||
self.params[i] = (ptype, pname, p2[2], p2[3])
|
self.params[i] = (ptype, pname, p2[2], p2[3])
|
||||||
break
|
break
|
||||||
def write_defs(self, fp=sys.stdout):
|
def _write_defs(self, fp=sys.stdout):
|
||||||
fp.write('(define-method ' + self.name + '\n')
|
|
||||||
if self.of_object != (None, None):
|
if self.of_object != (None, None):
|
||||||
fp.write(' (of-object "' + self.of_object + '")\n')
|
fp.write(' (of-object "' + self.of_object + '")\n')
|
||||||
if self.c_name:
|
if self.c_name:
|
||||||
fp.write(' (c-name "' + self.c_name + '")\n')
|
fp.write(' (c-name "' + self.c_name + '")\n')
|
||||||
if self.typecode:
|
if self.typecode:
|
||||||
fp.write(' (gtype-id "' + self.typecode + '")\n')
|
fp.write(' (gtype-id "' + self.typecode + '")\n')
|
||||||
|
if self.caller_owns_return:
|
||||||
|
fp.write(' (caller-owns-return #t)\n')
|
||||||
if self.ret:
|
if self.ret:
|
||||||
fp.write(' (return-type "' + self.ret + '")\n')
|
fp.write(' (return-type "' + self.ret + '")\n')
|
||||||
if self.deprecated:
|
if self.deprecated:
|
||||||
|
@ -356,8 +395,27 @@ class MethodDef(Definition):
|
||||||
if pnull: fp.write(' (null-ok)')
|
if pnull: fp.write(' (null-ok)')
|
||||||
fp.write(')\n')
|
fp.write(')\n')
|
||||||
fp.write(' )\n')
|
fp.write(' )\n')
|
||||||
|
if self.varargs:
|
||||||
|
fp.write(' (varargs #t)\n')
|
||||||
fp.write(')\n\n')
|
fp.write(')\n\n')
|
||||||
|
|
||||||
|
class MethodDef(MethodDefBase):
|
||||||
|
def __init__(self, name, *args):
|
||||||
|
MethodDefBase.__init__(self, name, *args)
|
||||||
|
for item in ('c_name', 'of_object'):
|
||||||
|
if self.__dict__[item] == None:
|
||||||
|
self.write_defs(sys.stderr)
|
||||||
|
raise RuntimeError, "definition missing required %s" % (item,)
|
||||||
|
|
||||||
|
def write_defs(self, fp=sys.stdout):
|
||||||
|
fp.write('(define-method ' + self.name + '\n')
|
||||||
|
self._write_defs(fp)
|
||||||
|
|
||||||
|
class VirtualDef(MethodDefBase):
|
||||||
|
def write_defs(self, fp=sys.stdout):
|
||||||
|
fp.write('(define-virtual ' + self.name + '\n')
|
||||||
|
self._write_defs(fp)
|
||||||
|
|
||||||
class FunctionDef(Definition):
|
class FunctionDef(Definition):
|
||||||
def __init__(self, name, *args):
|
def __init__(self, name, *args):
|
||||||
dump = 0
|
dump = 0
|
||||||
|
@ -371,9 +429,7 @@ class FunctionDef(Definition):
|
||||||
self.params = [] # of form (type, name, default, nullok)
|
self.params = [] # of form (type, name, default, nullok)
|
||||||
self.varargs = 0
|
self.varargs = 0
|
||||||
self.deprecated = None
|
self.deprecated = None
|
||||||
for arg in args:
|
for arg in get_valid_scheme_definitions(args):
|
||||||
if type(arg) != type(()) or len(arg) < 2:
|
|
||||||
continue
|
|
||||||
if arg[0] == 'in-module':
|
if arg[0] == 'in-module':
|
||||||
self.in_module = arg[1]
|
self.in_module = arg[1]
|
||||||
elif arg[0] == 'is-constructor-of':
|
elif arg[0] == 'is-constructor-of':
|
||||||
|
@ -397,7 +453,21 @@ class FunctionDef(Definition):
|
||||||
pdflt = farg[1]
|
pdflt = farg[1]
|
||||||
elif farg[0] == 'null-ok':
|
elif farg[0] == 'null-ok':
|
||||||
pnull = 1
|
pnull = 1
|
||||||
self.params.append((ptype, pname, pdflt, pnull))
|
self.params.append(Parameter(ptype, pname, pdflt, pnull))
|
||||||
|
elif arg[0] == 'properties':
|
||||||
|
if self.is_constructor_of is None:
|
||||||
|
print >> sys.stderr, "Warning: (properties ...) "\
|
||||||
|
"is only valid for constructors"
|
||||||
|
for prop in arg[1:]:
|
||||||
|
pname = prop[0]
|
||||||
|
optional = False
|
||||||
|
argname = pname
|
||||||
|
for farg in prop[1:]:
|
||||||
|
if farg[0] == 'optional':
|
||||||
|
optional = True
|
||||||
|
elif farg[0] == 'argname':
|
||||||
|
argname = farg[1]
|
||||||
|
self.params.append(Property(pname, optional, argname))
|
||||||
elif arg[0] == 'varargs':
|
elif arg[0] == 'varargs':
|
||||||
self.varargs = arg[1] in ('t', '#t')
|
self.varargs = arg[1] in ('t', '#t')
|
||||||
elif arg[0] == 'deprecated':
|
elif arg[0] == 'deprecated':
|
||||||
|
@ -410,14 +480,7 @@ class FunctionDef(Definition):
|
||||||
self.write_defs(sys.stderr)
|
self.write_defs(sys.stderr)
|
||||||
|
|
||||||
if self.caller_owns_return is None and self.ret is not None:
|
if self.caller_owns_return is None and self.ret is not None:
|
||||||
if self.ret[:6] == 'const-':
|
self.guess_return_value_ownership()
|
||||||
self.caller_owns_return = 0
|
|
||||||
elif self.is_constructor_of:
|
|
||||||
self.caller_owns_return = 1
|
|
||||||
elif self.ret in ('char*', 'gchar*', 'string'):
|
|
||||||
self.caller_owns_return = 1
|
|
||||||
else:
|
|
||||||
self.caller_owns_return = 0
|
|
||||||
for item in ('c_name',):
|
for item in ('c_name',):
|
||||||
if self.__dict__[item] == None:
|
if self.__dict__[item] == None:
|
||||||
self.write_defs(sys.stderr)
|
self.write_defs(sys.stderr)
|
||||||
|
@ -425,14 +488,33 @@ class FunctionDef(Definition):
|
||||||
|
|
||||||
_method_write_defs = MethodDef.__dict__['write_defs']
|
_method_write_defs = MethodDef.__dict__['write_defs']
|
||||||
|
|
||||||
def merge(self, old):
|
def merge(self, old, parmerge):
|
||||||
|
self.caller_owns_return = old.caller_owns_return
|
||||||
|
self.varargs = old.varargs
|
||||||
|
if not parmerge:
|
||||||
|
self.params = deepcopy(old.params)
|
||||||
|
return
|
||||||
# here we merge extra parameter flags accross to the new object.
|
# here we merge extra parameter flags accross to the new object.
|
||||||
for i in range(len(self.params)):
|
def merge_param(param):
|
||||||
ptype, pname, pdflt, pnull = self.params[i]
|
for old_param in old.params:
|
||||||
for p2 in old.params:
|
if old_param.pname == param.pname:
|
||||||
if p2[1] == pname:
|
if isinstance(old_param, Property):
|
||||||
self.params[i] = (ptype, pname, p2[2], p2[3])
|
# h2def never scans Property's, therefore if
|
||||||
break
|
# we have one it was manually written, so we
|
||||||
|
# keep it.
|
||||||
|
return deepcopy(old_param)
|
||||||
|
else:
|
||||||
|
param.merge(old_param)
|
||||||
|
return param
|
||||||
|
raise RuntimeError, "could not find %s in old_parameters %r" % (
|
||||||
|
param.pname, [p.pname for p in old.params])
|
||||||
|
try:
|
||||||
|
self.params = map(merge_param, self.params)
|
||||||
|
except RuntimeError:
|
||||||
|
# parameter names changed and we can't find a match; it's
|
||||||
|
# safer to keep the old parameter list untouched.
|
||||||
|
self.params = deepcopy(old.params)
|
||||||
|
|
||||||
if not self.is_constructor_of:
|
if not self.is_constructor_of:
|
||||||
try:
|
try:
|
||||||
self.is_constructor_of = old.is_constructor_of
|
self.is_constructor_of = old.is_constructor_of
|
||||||
|
@ -454,17 +536,31 @@ class FunctionDef(Definition):
|
||||||
fp.write(' (c-name "' + self.c_name + '")\n')
|
fp.write(' (c-name "' + self.c_name + '")\n')
|
||||||
if self.typecode:
|
if self.typecode:
|
||||||
fp.write(' (gtype-id "' + self.typecode + '")\n')
|
fp.write(' (gtype-id "' + self.typecode + '")\n')
|
||||||
|
if self.caller_owns_return:
|
||||||
|
fp.write(' (caller-owns-return #t)\n')
|
||||||
if self.ret:
|
if self.ret:
|
||||||
fp.write(' (return-type "' + self.ret + '")\n')
|
fp.write(' (return-type "' + self.ret + '")\n')
|
||||||
if self.deprecated:
|
if self.deprecated:
|
||||||
fp.write(' (deprecated "' + self.deprecated + '")\n')
|
fp.write(' (deprecated "' + self.deprecated + '")\n')
|
||||||
if self.params:
|
if self.params:
|
||||||
fp.write(' (parameters\n')
|
if isinstance(self.params[0], Parameter):
|
||||||
for ptype, pname, pdflt, pnull in self.params:
|
fp.write(' (parameters\n')
|
||||||
fp.write(' \'("' + ptype + '" "' + pname +'"')
|
for ptype, pname, pdflt, pnull in self.params:
|
||||||
if pdflt: fp.write(' (default "' + pdflt + '")')
|
fp.write(' \'("' + ptype + '" "' + pname +'"')
|
||||||
if pnull: fp.write(' (null-ok)')
|
if pdflt: fp.write(' (default "' + pdflt + '")')
|
||||||
fp.write(')\n')
|
if pnull: fp.write(' (null-ok)')
|
||||||
fp.write(' )\n')
|
fp.write(')\n')
|
||||||
fp.write(')\n\n')
|
fp.write(' )\n')
|
||||||
|
elif isinstance(self.params[0], Property):
|
||||||
|
fp.write(' (properties\n')
|
||||||
|
for prop in self.params:
|
||||||
|
fp.write(' \'("' + prop.pname +'"')
|
||||||
|
if prop.optional: fp.write(' (optional)')
|
||||||
|
fp.write(')\n')
|
||||||
|
fp.write(' )\n')
|
||||||
|
else:
|
||||||
|
assert False, "strange parameter list %r" % self.params[0]
|
||||||
|
if self.varargs:
|
||||||
|
fp.write(' (varargs #t)\n')
|
||||||
|
|
||||||
|
fp.write(')\n\n')
|
||||||
|
|
|
@ -25,6 +25,7 @@ class DefsParser(IncludeParser):
|
||||||
self.boxes = [] # boxed types
|
self.boxes = [] # boxed types
|
||||||
self.pointers = [] # pointer types
|
self.pointers = [] # pointer types
|
||||||
self.functions = [] # functions and methods
|
self.functions = [] # functions and methods
|
||||||
|
self.virtuals = [] # virtual methods
|
||||||
self.c_name = {} # hash of c names of functions
|
self.c_name = {} # hash of c names of functions
|
||||||
self.methods = {} # hash of methods of particular objects
|
self.methods = {} # hash of methods of particular objects
|
||||||
self.defines = defines # -Dfoo=bar options, as dictionary
|
self.defines = defines # -Dfoo=bar options, as dictionary
|
||||||
|
@ -66,13 +67,17 @@ class DefsParser(IncludeParser):
|
||||||
mdef = apply(MethodDef, args)
|
mdef = apply(MethodDef, args)
|
||||||
self.functions.append(mdef)
|
self.functions.append(mdef)
|
||||||
self.c_name[mdef.c_name] = mdef
|
self.c_name[mdef.c_name] = mdef
|
||||||
def merge(self, old):
|
def define_virtual(self, *args):
|
||||||
|
vdef = apply(VirtualDef, args)
|
||||||
|
self.virtuals.append(vdef)
|
||||||
|
def merge(self, old, parmerge):
|
||||||
for obj in self.objects:
|
for obj in self.objects:
|
||||||
if old.c_name.has_key(obj.c_name):
|
if old.c_name.has_key(obj.c_name):
|
||||||
obj.merge(old.c_name[obj.c_name])
|
obj.merge(old.c_name[obj.c_name])
|
||||||
for f in self.functions:
|
for f in self.functions:
|
||||||
if old.c_name.has_key(f.c_name):
|
if old.c_name.has_key(f.c_name):
|
||||||
f.merge(old.c_name[f.c_name])
|
f.merge(old.c_name[f.c_name], parmerge)
|
||||||
|
|
||||||
def printMissing(self, old):
|
def printMissing(self, old):
|
||||||
for obj in self.objects:
|
for obj in self.objects:
|
||||||
if not old.c_name.has_key(obj.c_name):
|
if not old.c_name.has_key(obj.c_name):
|
||||||
|
@ -115,6 +120,12 @@ class DefsParser(IncludeParser):
|
||||||
return filter(lambda func, on=objname: isinstance(func, MethodDef) and
|
return filter(lambda func, on=objname: isinstance(func, MethodDef) and
|
||||||
func.of_object == on, self.functions)
|
func.of_object == on, self.functions)
|
||||||
|
|
||||||
|
def find_virtuals(self, obj):
|
||||||
|
objname = obj.c_name
|
||||||
|
retval = filter(lambda func, on=objname: isinstance(func, VirtualDef) and
|
||||||
|
func.of_object == on, self.virtuals)
|
||||||
|
return retval
|
||||||
|
|
||||||
def find_functions(self):
|
def find_functions(self):
|
||||||
return filter(lambda func: isinstance(func, FunctionDef) and
|
return filter(lambda func: isinstance(func, FunctionDef) and
|
||||||
not func.is_constructor_of, self.functions)
|
not func.is_constructor_of, self.functions)
|
||||||
|
|
|
@ -53,7 +53,7 @@ def strip_comments(buf):
|
||||||
|
|
||||||
obj_name_pat = "[A-Z][a-z]*[A-Z][A-Za-z0-9]*"
|
obj_name_pat = "[A-Z][a-z]*[A-Z][A-Za-z0-9]*"
|
||||||
|
|
||||||
split_prefix_pat = re.compile('([A-Z][a-z]*)([A-Za-z0-9]+)')
|
split_prefix_pat = re.compile('([A-Z]+[a-z]*)([A-Za-z0-9]+)')
|
||||||
|
|
||||||
def find_obj_defs(buf, objdefs=[]):
|
def find_obj_defs(buf, objdefs=[]):
|
||||||
"""
|
"""
|
||||||
|
@ -312,7 +312,7 @@ proto_pat=re.compile(r"""
|
||||||
(?P<ret>(-|\w|\&|\*)+\s*) # return type
|
(?P<ret>(-|\w|\&|\*)+\s*) # return type
|
||||||
\s+ # skip whitespace
|
\s+ # skip whitespace
|
||||||
(?P<func>\w+)\s*[(] # match the function name until the opening (
|
(?P<func>\w+)\s*[(] # match the function name until the opening (
|
||||||
(?P<args>.*?)[)] # group the function arguments
|
\s*(?P<args>.*?)[)] # group the function arguments
|
||||||
""", re.IGNORECASE|re.VERBOSE)
|
""", re.IGNORECASE|re.VERBOSE)
|
||||||
#"""
|
#"""
|
||||||
arg_split_pat = re.compile("\s*,\s*")
|
arg_split_pat = re.compile("\s*,\s*")
|
||||||
|
@ -353,7 +353,7 @@ def write_func(fp, name, ret, args, prefix):
|
||||||
obj = m.group(2)
|
obj = m.group(2)
|
||||||
if munged_name[:len(obj)] == string.lower(obj):
|
if munged_name[:len(obj)] == string.lower(obj):
|
||||||
regex = string.join(map(lambda x: x+'_?',string.lower(obj)),'')
|
regex = string.join(map(lambda x: x+'_?',string.lower(obj)),'')
|
||||||
mname = re.sub(regex, '', name)
|
mname = re.sub(regex, '', name, 1)
|
||||||
if prefix:
|
if prefix:
|
||||||
l = len(prefix) + 1
|
l = len(prefix) + 1
|
||||||
if mname[:l] == prefix and mname[l+1] == '_':
|
if mname[:l] == prefix and mname[l+1] == '_':
|
||||||
|
|
|
@ -3,17 +3,23 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import defsparser
|
import defsparser
|
||||||
|
from optparse import OptionParser
|
||||||
|
|
||||||
if len(sys.argv) < 3:
|
parser = OptionParser(usage="usage: %prog [options] generated-defs old-defs")
|
||||||
sys.stderr.write("Usage: mergedefs.py generated-defs old-defs\n")
|
parser.add_option("-p", "--merge-parameters",
|
||||||
sys.exit(1)
|
help="Merge changes in function/methods parameter lists",
|
||||||
|
action="store_true", dest="parmerge", default=False)
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
newp = defsparser.DefsParser(sys.argv[1])
|
if len(args) != 2:
|
||||||
oldp = defsparser.DefsParser(sys.argv[2])
|
parser.error("wrong number of arguments")
|
||||||
|
|
||||||
|
newp = defsparser.DefsParser(args[0])
|
||||||
|
oldp = defsparser.DefsParser(args[1])
|
||||||
|
|
||||||
newp.startParsing()
|
newp.startParsing()
|
||||||
oldp.startParsing()
|
oldp.startParsing()
|
||||||
|
|
||||||
newp.merge(oldp)
|
newp.merge(oldp, options.parmerge)
|
||||||
|
|
||||||
newp.write_defs()
|
newp.write_defs()
|
||||||
|
|
667
codegen/reversewrapper.py
Normal file
667
codegen/reversewrapper.py
Normal file
|
@ -0,0 +1,667 @@
|
||||||
|
### -*- python -*-
|
||||||
|
### Code to generate "Reverse Wrappers", i.e. C->Python wrappers
|
||||||
|
### (C) 2004 Gustavo Carneiro <gjc@gnome.org>
|
||||||
|
import argtypes
|
||||||
|
|
||||||
|
def join_ctype_name(ctype, name):
|
||||||
|
'''Joins a C type and a variable name into a single string'''
|
||||||
|
if ctype[-1] != '*':
|
||||||
|
return " ".join((ctype, name))
|
||||||
|
else:
|
||||||
|
return "".join((ctype, name))
|
||||||
|
|
||||||
|
|
||||||
|
class CodeSink(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.indent_level = 0 # current indent level
|
||||||
|
self.indent_stack = [] # previous indent levels
|
||||||
|
|
||||||
|
def _format_code(self, code):
|
||||||
|
assert isinstance(code, str)
|
||||||
|
l = []
|
||||||
|
for line in code.split('\n'):
|
||||||
|
l.append(' '*self.indent_level + line)
|
||||||
|
if l[-1]:
|
||||||
|
l.append('')
|
||||||
|
return '\n'.join(l)
|
||||||
|
|
||||||
|
def writeln(self, line=''):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def indent(self, level=4):
|
||||||
|
'''Add a certain ammount of indentation to all lines written
|
||||||
|
from now on and until unindent() is called'''
|
||||||
|
self.indent_stack.append(self.indent_level)
|
||||||
|
self.indent_level += level
|
||||||
|
|
||||||
|
def unindent(self):
|
||||||
|
'''Revert indentation level to the value before last indent() call'''
|
||||||
|
self.indent_level = self.indent_stack.pop()
|
||||||
|
|
||||||
|
|
||||||
|
class FileCodeSink(CodeSink):
|
||||||
|
def __init__(self, fp):
|
||||||
|
CodeSink.__init__(self)
|
||||||
|
assert isinstance(fp, file)
|
||||||
|
self.fp = fp
|
||||||
|
|
||||||
|
def writeln(self, line=''):
|
||||||
|
self.fp.write(self._format_code(line))
|
||||||
|
|
||||||
|
class MemoryCodeSink(CodeSink):
|
||||||
|
def __init__(self):
|
||||||
|
CodeSink.__init__(self)
|
||||||
|
self.lines = []
|
||||||
|
|
||||||
|
def writeln(self, line=''):
|
||||||
|
self.lines.append(self._format_code(line))
|
||||||
|
|
||||||
|
def flush_to(self, sink):
|
||||||
|
assert isinstance(sink, CodeSink)
|
||||||
|
for line in self.lines:
|
||||||
|
sink.writeln(line.rstrip())
|
||||||
|
self.lines = []
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
l = []
|
||||||
|
for line in self.lines:
|
||||||
|
l.append(self._format_code(line))
|
||||||
|
self.lines = []
|
||||||
|
return "".join(l)
|
||||||
|
|
||||||
|
class ReverseWrapper(object):
|
||||||
|
'''Object that generates a C->Python wrapper'''
|
||||||
|
def __init__(self, cname, is_static=True):
|
||||||
|
assert isinstance(cname, str)
|
||||||
|
|
||||||
|
self.cname = cname
|
||||||
|
## function object we will call, or object whose method we will call
|
||||||
|
self.called_pyobj = None
|
||||||
|
## name of method of self.called_pyobj we will call
|
||||||
|
self.method_name = None
|
||||||
|
self.is_static = is_static
|
||||||
|
|
||||||
|
self.parameters = []
|
||||||
|
self.declarations = MemoryCodeSink()
|
||||||
|
self.body = MemoryCodeSink()
|
||||||
|
self.cleanup_actions = []
|
||||||
|
self.pyargv_items = []
|
||||||
|
self.pyargv_optional_items = []
|
||||||
|
|
||||||
|
def set_call_target(self, called_pyobj, method_name=None):
|
||||||
|
assert called_pyobj is not None
|
||||||
|
assert self.called_pyobj is None
|
||||||
|
self.called_pyobj = called_pyobj
|
||||||
|
self.method_name = method_name
|
||||||
|
|
||||||
|
def set_return_type(self, return_type):
|
||||||
|
assert isinstance(return_type, ReturnType)
|
||||||
|
self.return_type = return_type
|
||||||
|
|
||||||
|
def add_parameter(self, param):
|
||||||
|
assert isinstance(param, Parameter)
|
||||||
|
self.parameters.append(param)
|
||||||
|
|
||||||
|
def add_declaration(self, decl_code):
|
||||||
|
self.declarations.writeln(decl_code)
|
||||||
|
|
||||||
|
def add_pyargv_item(self, variable, optional=False):
|
||||||
|
if optional:
|
||||||
|
self.pyargv_optional_items.append(variable)
|
||||||
|
else:
|
||||||
|
self.pyargv_items.append(variable)
|
||||||
|
|
||||||
|
def write_code(self, code,
|
||||||
|
cleanup=None,
|
||||||
|
failure_expression=None,
|
||||||
|
failure_cleanup=None):
|
||||||
|
'''Add a chunk of code with cleanup and error handling
|
||||||
|
|
||||||
|
This method is to be used by TypeHandlers when generating code
|
||||||
|
|
||||||
|
Keywork arguments:
|
||||||
|
code -- code to add
|
||||||
|
cleanup -- code to cleanup any dynamic resources created by @code
|
||||||
|
(except in case of failure) (default None)
|
||||||
|
failure_expression -- C boolean expression to indicate
|
||||||
|
if anything failed (default None)
|
||||||
|
failure_cleanup -- code to cleanup any dynamic resources
|
||||||
|
created by @code in case of failure (default None)
|
||||||
|
'''
|
||||||
|
if code is not None:
|
||||||
|
self.body.writeln(code)
|
||||||
|
if failure_expression is not None:
|
||||||
|
self.body.writeln("if (%s) {" % failure_expression)
|
||||||
|
self.body.indent()
|
||||||
|
self.body.writeln("if (PyErr_Occurred())")
|
||||||
|
self.body.indent()
|
||||||
|
self.body.writeln("PyErr_Print();")
|
||||||
|
self.body.unindent()
|
||||||
|
if failure_cleanup is not None:
|
||||||
|
self.body.writeln(failure_cleanup)
|
||||||
|
for cleanup_action in self.cleanup_actions:
|
||||||
|
self.body.writeln(cleanup_action)
|
||||||
|
self.return_type.write_error_return()
|
||||||
|
self.body.unindent()
|
||||||
|
self.body.writeln("}")
|
||||||
|
if cleanup is not None:
|
||||||
|
self.cleanup_actions.insert(0, cleanup)
|
||||||
|
|
||||||
|
def generate(self, sink):
|
||||||
|
'''Generate the code into a CodeSink object'''
|
||||||
|
assert isinstance(sink, CodeSink)
|
||||||
|
|
||||||
|
self.add_declaration("PyGILState_STATE __py_state;")
|
||||||
|
self.write_code(code="__py_state = pyg_gil_state_ensure();",
|
||||||
|
cleanup="pyg_gil_state_release(__py_state);")
|
||||||
|
|
||||||
|
for param in self.parameters:
|
||||||
|
param.convert_c2py()
|
||||||
|
|
||||||
|
assert self.called_pyobj is not None,\
|
||||||
|
"Parameters failed to provide a target function or method."
|
||||||
|
|
||||||
|
if self.is_static:
|
||||||
|
sink.writeln('static %s' % self.return_type.get_c_type())
|
||||||
|
else:
|
||||||
|
sink.writeln(self.return_type.get_c_type())
|
||||||
|
c_proto_params = map(Parameter.format_for_c_proto, self.parameters)
|
||||||
|
sink.writeln("%s(%s)\n{" % (self.cname, ", ".join(c_proto_params)))
|
||||||
|
|
||||||
|
self.return_type.write_decl()
|
||||||
|
self.add_declaration("PyObject *py_retval;")
|
||||||
|
|
||||||
|
## Handle number of arguments
|
||||||
|
if self.pyargv_items:
|
||||||
|
self.add_declaration("PyObject *py_args;")
|
||||||
|
py_args = "py_args"
|
||||||
|
if self.pyargv_optional_items:
|
||||||
|
self.add_declaration("int argc = %i;" % len(self.pyargv_items))
|
||||||
|
argc = "argc"
|
||||||
|
for arg in self.pyargv_optional_items:
|
||||||
|
self.body.writeln("if (%s)" % arg)
|
||||||
|
self.body.indent()
|
||||||
|
self.body.writeln("++argc;")
|
||||||
|
self.body.unindent()
|
||||||
|
else:
|
||||||
|
argc = str(len(self.pyargv_items))
|
||||||
|
else:
|
||||||
|
if self.pyargv_optional_items:
|
||||||
|
self.add_declaration("PyObject *py_args;")
|
||||||
|
py_args = "py_args"
|
||||||
|
self.add_declaration("int argc = 0;")
|
||||||
|
argc = "argc"
|
||||||
|
for arg in self.pyargv_optional_items:
|
||||||
|
self.body.writeln("if (%s)" % arg)
|
||||||
|
self.body.indent()
|
||||||
|
self.body.writeln("++argc;")
|
||||||
|
self.body.unindent()
|
||||||
|
else:
|
||||||
|
py_args = "NULL"
|
||||||
|
argc = None
|
||||||
|
|
||||||
|
self.body.writeln()
|
||||||
|
|
||||||
|
if py_args != "NULL":
|
||||||
|
self.write_code("py_args = PyTuple_New(%s);" % argc,
|
||||||
|
cleanup="Py_DECREF(py_args);")
|
||||||
|
pos = 0
|
||||||
|
for arg in self.pyargv_items:
|
||||||
|
try: # try to remove the Py_DECREF cleanup action, if we can
|
||||||
|
self.cleanup_actions.remove("Py_DECREF(%s);" % arg)
|
||||||
|
except ValueError: # otherwise we have to Py_INCREF..
|
||||||
|
self.body.writeln("Py_INCREF(%s);" % arg)
|
||||||
|
self.body.writeln("PyTuple_SET_ITEM(%s, %i, %s);" % (py_args, pos, arg))
|
||||||
|
pos += 1
|
||||||
|
for arg in self.pyargv_optional_items:
|
||||||
|
self.body.writeln("if (%s) {" % arg)
|
||||||
|
self.body.indent()
|
||||||
|
try: # try to remove the Py_DECREF cleanup action, if we can
|
||||||
|
self.cleanup_actions.remove("Py_XDECREF(%s);" % arg)
|
||||||
|
except ValueError: # otherwise we have to Py_INCREF..
|
||||||
|
self.body.writeln("Py_INCREF(%s);" % arg)
|
||||||
|
self.body.writeln("PyTuple_SET_ITEM(%s, %i, %s);" % (py_args, pos, arg))
|
||||||
|
self.body.unindent()
|
||||||
|
self.body.writeln("}")
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
self.body.writeln()
|
||||||
|
|
||||||
|
# call it
|
||||||
|
if self.method_name is None:
|
||||||
|
self.write_code("py_retval = PyObject_Call(%s, %s);"
|
||||||
|
% (self.called_pyobj, py_args),
|
||||||
|
cleanup="Py_DECREF(py_retval);",
|
||||||
|
failure_expression="!py_retval")
|
||||||
|
else:
|
||||||
|
self.add_declaration("PyObject *py_method;")
|
||||||
|
self.write_code("py_method = PyObject_GetAttrString(%s, \"%s\");"
|
||||||
|
% (self.called_pyobj, self.method_name),
|
||||||
|
cleanup="Py_DECREF(py_method);",
|
||||||
|
failure_expression="!py_method")
|
||||||
|
self.write_code("py_retval = PyObject_CallObject(py_method, %s);"
|
||||||
|
% (py_args,),
|
||||||
|
cleanup="Py_DECREF(py_retval);",
|
||||||
|
failure_expression="!py_retval")
|
||||||
|
|
||||||
|
self.return_type.write_conversion()
|
||||||
|
|
||||||
|
sink.indent()
|
||||||
|
self.declarations.flush_to(sink)
|
||||||
|
sink.writeln()
|
||||||
|
self.body.flush_to(sink)
|
||||||
|
sink.writeln()
|
||||||
|
for cleanup_action in self.cleanup_actions:
|
||||||
|
sink.writeln(cleanup_action)
|
||||||
|
if self.return_type.get_c_type() != 'void':
|
||||||
|
sink.writeln()
|
||||||
|
sink.writeln("return retval;")
|
||||||
|
sink.unindent()
|
||||||
|
sink.writeln("}")
|
||||||
|
|
||||||
|
class TypeHandler(object):
|
||||||
|
def __init__(self, wrapper, **props):
|
||||||
|
assert isinstance(wrapper, ReverseWrapper)
|
||||||
|
self.wrapper = wrapper
|
||||||
|
self.props = props
|
||||||
|
|
||||||
|
class ReturnType(TypeHandler):
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def write_decl(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def write_error_return(self):
|
||||||
|
'''Write "return <value>" code in case of error'''
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def write_conversion(self):
|
||||||
|
'''Writes code to convert Python return value in 'py_retval'
|
||||||
|
into C 'retval'. Returns a string with C boolean expression
|
||||||
|
that determines if anything went wrong. '''
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
class Parameter(TypeHandler):
|
||||||
|
|
||||||
|
def __init__(self, wrapper, name, **props):
|
||||||
|
TypeHandler.__init__(self, wrapper, **props)
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def convert_c2py(self):
|
||||||
|
'''Write some code before calling the Python method.'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
def format_for_c_proto(self):
|
||||||
|
return join_ctype_name(self.get_c_type(), self.name)
|
||||||
|
|
||||||
|
|
||||||
|
###---
|
||||||
|
class StringParam(Parameter):
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'char *').replace('const-', 'const ')
|
||||||
|
|
||||||
|
def convert_c2py(self):
|
||||||
|
if self.props.get('optional', False):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s = NULL;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("if (%s)\n"
|
||||||
|
" py_%s = PyString_FromString(%s);\n"
|
||||||
|
% (self.name, self.name, self.name)),
|
||||||
|
cleanup=("Py_XDECREF(py_%s);" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name, optional=True)
|
||||||
|
else:
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("py_%s = PyString_FromString(%s);" %
|
||||||
|
(self.name, self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name),
|
||||||
|
failure_expression=("!py_%s" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
for ctype in ('char*', 'gchar*', 'const-char*', 'char-const*', 'const-gchar*',
|
||||||
|
'gchar-const*', 'string', 'static_string'):
|
||||||
|
argtypes.matcher.register_reverse(ctype, StringParam)
|
||||||
|
|
||||||
|
|
||||||
|
class StringReturn(ReturnType):
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return "char *"
|
||||||
|
|
||||||
|
def write_decl(self):
|
||||||
|
self.wrapper.add_declaration("char *retval;")
|
||||||
|
|
||||||
|
def write_error_return(self):
|
||||||
|
self.wrapper.write_code("return NULL;")
|
||||||
|
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=None,
|
||||||
|
failure_expression="!PyString_Check(py_retval)",
|
||||||
|
failure_cleanup='PyErr_SetString(PyExc_TypeError, "retval should be a string");')
|
||||||
|
self.wrapper.write_code("retval = g_strdup(PyString_AsString(py_retval));")
|
||||||
|
|
||||||
|
for ctype in ('char*', 'gchar*'):
|
||||||
|
argtypes.matcher.register_reverse(ctype, StringReturn)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class VoidReturn(ReturnType):
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return "void"
|
||||||
|
|
||||||
|
def write_decl(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def write_error_return(self):
|
||||||
|
self.wrapper.write_code("return;")
|
||||||
|
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=None,
|
||||||
|
failure_expression="py_retval != Py_None",
|
||||||
|
failure_cleanup='PyErr_SetString(PyExc_TypeError, "retval should be None");')
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse_ret('void', VoidReturn)
|
||||||
|
argtypes.matcher.register_reverse_ret('none', VoidReturn)
|
||||||
|
|
||||||
|
class GObjectParam(Parameter):
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'GObject *')
|
||||||
|
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s = NULL;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("if (%s)\n"
|
||||||
|
" py_%s = pygobject_new((GObject *) %s);\n"
|
||||||
|
"else {\n"
|
||||||
|
" Py_INCREF(Py_None);\n"
|
||||||
|
" py_%s = Py_None;\n"
|
||||||
|
"}"
|
||||||
|
% (self.name, self.name, self.name, self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse('GObject*', GObjectParam)
|
||||||
|
|
||||||
|
class GObjectReturn(ReturnType):
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'GObject *')
|
||||||
|
|
||||||
|
def write_decl(self):
|
||||||
|
self.wrapper.add_declaration("%s retval;" % self.get_c_type())
|
||||||
|
|
||||||
|
def write_error_return(self):
|
||||||
|
self.wrapper.write_code("return NULL;")
|
||||||
|
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code("retval = (%s) pygobject_get(py_retval);"
|
||||||
|
% self.get_c_type())
|
||||||
|
self.wrapper.write_code("g_object_ref((GObject *) retval);")
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse_ret('GObject*', GObjectReturn)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class IntParam(Parameter):
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'int')
|
||||||
|
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("py_%s = PyInt_FromLong(%s);" %
|
||||||
|
(self.name, self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
class IntReturn(ReturnType):
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'int')
|
||||||
|
def write_decl(self):
|
||||||
|
self.wrapper.add_declaration("%s retval;" % self.get_c_type())
|
||||||
|
def write_error_return(self):
|
||||||
|
self.wrapper.write_code("return -G_MAXINT;")
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=None,
|
||||||
|
failure_expression="!PyInt_Check(py_retval)",
|
||||||
|
failure_cleanup='PyErr_SetString(PyExc_TypeError, "retval should be an int");')
|
||||||
|
self.wrapper.write_code("retval = PyInt_AsLong(py_retval);")
|
||||||
|
|
||||||
|
for argtype in ('int', 'gint', 'guint', 'short', 'gshort', 'gushort', 'long',
|
||||||
|
'glong', 'gsize', 'gssize', 'guint8', 'gint8', 'guint16',
|
||||||
|
'gint16', 'gint32', 'GTime'):
|
||||||
|
argtypes.matcher.register_reverse(argtype, IntParam)
|
||||||
|
argtypes.matcher.register_reverse_ret(argtype, IntReturn)
|
||||||
|
|
||||||
|
|
||||||
|
class GEnumReturn(IntReturn):
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=None,
|
||||||
|
failure_expression=("pyg_enum_get_value(%s, py_retval, (gint *)&retval)" %
|
||||||
|
self.props['typecode']))
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse_ret("GEnum", GEnumReturn)
|
||||||
|
|
||||||
|
class GEnumParam(IntParam):
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("py_%s = pyg_enum_from_gtype(%s, %s);" %
|
||||||
|
(self.name, self.props['typecode'], self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name),
|
||||||
|
failure_expression=("!py_%s" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse("GEnum", GEnumParam)
|
||||||
|
|
||||||
|
class GFlagsReturn(IntReturn):
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=None,
|
||||||
|
failure_expression=("pyg_flags_get_value(%s, py_retval, (gint *)&retval)" %
|
||||||
|
self.props['typecode']))
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse_ret("GFlags", GFlagsReturn)
|
||||||
|
|
||||||
|
class GFlagsParam(IntParam):
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("py_%s = pyg_flags_from_gtype(%s, %s);" %
|
||||||
|
(self.name, self.props['typecode'], self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name),
|
||||||
|
failure_expression=("!py_%s" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse("GFlags", GFlagsParam)
|
||||||
|
|
||||||
|
|
||||||
|
class GtkTreePathParam(IntParam):
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("py_%s = pygtk_tree_path_to_pyobject(%s);" %
|
||||||
|
(self.name, self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name),
|
||||||
|
failure_expression=("!py_%s" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse("GtkTreePath*", GtkTreePathParam)
|
||||||
|
|
||||||
|
|
||||||
|
class BooleanReturn(ReturnType):
|
||||||
|
def get_c_type(self):
|
||||||
|
return "gboolean"
|
||||||
|
def write_decl(self):
|
||||||
|
self.wrapper.add_declaration("gboolean retval;")
|
||||||
|
def write_error_return(self):
|
||||||
|
self.wrapper.write_code("return FALSE;")
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code("retval = PyObject_IsTrue(py_retval)? TRUE : FALSE;")
|
||||||
|
argtypes.matcher.register_reverse_ret("gboolean", BooleanReturn)
|
||||||
|
|
||||||
|
class BooleanParam(Parameter):
|
||||||
|
def get_c_type(self):
|
||||||
|
return "gboolean"
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code("py_%s = %s? Py_True : Py_False;"
|
||||||
|
% (self.name, self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse("gboolean", BooleanParam)
|
||||||
|
|
||||||
|
|
||||||
|
class DoubleParam(Parameter):
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'gdouble')
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("py_%s = PyFloat_FromDouble(%s);" %
|
||||||
|
(self.name, self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
class DoubleReturn(ReturnType):
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'gdouble')
|
||||||
|
def write_decl(self):
|
||||||
|
self.wrapper.add_declaration("%s retval;" % self.get_c_type())
|
||||||
|
def write_error_return(self):
|
||||||
|
self.wrapper.write_code("return -G_MAXFLOAT;")
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=None,
|
||||||
|
failure_expression="!PyFloat_AsDouble(py_retval)",
|
||||||
|
failure_cleanup='PyErr_SetString(PyExc_TypeError, "retval should be a float");')
|
||||||
|
self.wrapper.write_code("retval = PyFloat_AsDouble(py_retval);")
|
||||||
|
|
||||||
|
for argtype in ('float', 'double', 'gfloat', 'gdouble'):
|
||||||
|
argtypes.matcher.register_reverse(argtype, DoubleParam)
|
||||||
|
argtypes.matcher.register_reverse_ret(argtype, DoubleReturn)
|
||||||
|
|
||||||
|
|
||||||
|
class GBoxedParam(Parameter):
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type').replace('const-', 'const ')
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
ctype = self.get_c_type()
|
||||||
|
if ctype.startswith('const '):
|
||||||
|
ctype_no_const = ctype[len('const '):]
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=('py_%s = pyg_boxed_new(%s, (%s) %s, TRUE, TRUE);' %
|
||||||
|
(self.name, self.props['typecode'],
|
||||||
|
ctype_no_const, self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name))
|
||||||
|
else:
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=('py_%s = pyg_boxed_new(%s, %s, FALSE, FALSE);' %
|
||||||
|
(self.name, self.props['typecode'], self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse("GBoxed", GBoxedParam)
|
||||||
|
|
||||||
|
class GBoxedReturn(ReturnType):
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type')
|
||||||
|
def write_decl(self):
|
||||||
|
self.wrapper.add_declaration("%s retval;" % self.get_c_type())
|
||||||
|
def write_error_return(self):
|
||||||
|
self.wrapper.write_code("return retval;")
|
||||||
|
def write_conversion(self):
|
||||||
|
self.wrapper.write_code(
|
||||||
|
failure_expression=("!pyg_boxed_check(py_retval, %s)" %
|
||||||
|
(self.props['typecode'],)),
|
||||||
|
failure_cleanup=('PyErr_SetString(PyExc_TypeError, "retval should be a %s");'
|
||||||
|
% (self.props['typename'],)))
|
||||||
|
self.wrapper.write_code('retval = pyg_boxed_get(py_retval, %s);' %
|
||||||
|
self.props['typename'])
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse_ret("GBoxed", GBoxedReturn)
|
||||||
|
|
||||||
|
|
||||||
|
class GdkRectanglePtrParam(Parameter):
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type').replace('const-', 'const ')
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(
|
||||||
|
code=('py_%(name)s = Py_BuildValue("(ffff)", %(name)s->x, %(name)s->y,\n'
|
||||||
|
' %(name)s->width, %(name)s->height);'
|
||||||
|
% dict(name=self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name))
|
||||||
|
self.wrapper.add_pyargv_item("py_%s" % self.name)
|
||||||
|
|
||||||
|
argtypes.matcher.register_reverse("GdkRectangle*", GdkRectanglePtrParam)
|
||||||
|
|
||||||
|
|
||||||
|
class PyGObjectMethodParam(Parameter):
|
||||||
|
def __init__(self, wrapper, name, method_name, **props):
|
||||||
|
Parameter.__init__(self, wrapper, name, **props)
|
||||||
|
self.method_name = method_name
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return self.props.get('c_type', 'GObject *')
|
||||||
|
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
|
||||||
|
self.wrapper.write_code(code=("py_%s = pygobject_new((GObject *) %s);" %
|
||||||
|
(self.name, self.name)),
|
||||||
|
cleanup=("Py_DECREF(py_%s);" % self.name),
|
||||||
|
failure_expression=("!py_%s" % self.name))
|
||||||
|
self.wrapper.set_call_target("py_%s" % self.name, self.method_name)
|
||||||
|
|
||||||
|
class CallbackInUserDataParam(Parameter):
|
||||||
|
def __init__(self, wrapper, name, free_it, **props):
|
||||||
|
Parameter.__init__(self, wrapper, name, **props)
|
||||||
|
self.free_it = free_it
|
||||||
|
|
||||||
|
def get_c_type(self):
|
||||||
|
return "gpointer"
|
||||||
|
|
||||||
|
def convert_c2py(self):
|
||||||
|
self.wrapper.add_declaration("PyObject **_user_data;")
|
||||||
|
cleanup = self.free_it and ("g_free(%s);" % self.name) or None
|
||||||
|
self.wrapper.write_code(code=("_real_user_data = (PyObject **) %s;"
|
||||||
|
% self.name),
|
||||||
|
cleanup=cleanup)
|
||||||
|
|
||||||
|
self.wrapper.add_declaration("PyObject *py_func;")
|
||||||
|
cleanup = self.free_it and "Py_DECREF(py_func);" or None
|
||||||
|
self.wrapper.write_code(code="py_func = _user_data[0];",
|
||||||
|
cleanup=cleanup)
|
||||||
|
self.wrapper.set_call_target("py_func")
|
||||||
|
|
||||||
|
self.wrapper.add_declaration("PyObject *py_user_data;")
|
||||||
|
cleanup = self.free_it and "Py_XDECREF(py_user_data);" or None
|
||||||
|
self.wrapper.write_code(code="py_user_data = _user_data[1];",
|
||||||
|
cleanup=cleanup)
|
||||||
|
self.wrapper.add_pyargv_item("py_user_data", optional=True)
|
||||||
|
|
||||||
|
def _test():
|
||||||
|
import sys
|
||||||
|
|
||||||
|
wrapper = ReverseWrapper("this_is_the_c_function_name", is_static=True)
|
||||||
|
wrapper.set_return_type(StringReturn(wrapper))
|
||||||
|
wrapper.add_parameter(PyGObjectMethodParam(wrapper, "self", method_name="do_xxx"))
|
||||||
|
wrapper.add_parameter(StringParam(wrapper, "param2", optional=True))
|
||||||
|
wrapper.add_parameter(GObjectParam(wrapper, "param3"))
|
||||||
|
wrapper.generate(FileCodeSink(sys.stderr))
|
||||||
|
|
||||||
|
wrapper = ReverseWrapper("this_a_callback_wrapper")
|
||||||
|
wrapper.set_return_type(VoidReturn(wrapper))
|
||||||
|
wrapper.add_parameter(StringParam(wrapper, "param1", optional=False))
|
||||||
|
wrapper.add_parameter(GObjectParam(wrapper, "param2"))
|
||||||
|
wrapper.add_parameter(CallbackInUserDataParam(wrapper, "data", free_it=True))
|
||||||
|
wrapper.generate(FileCodeSink(sys.stderr))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
_test()
|
|
@ -151,6 +151,15 @@
|
||||||
(parent "GstMiniObject")
|
(parent "GstMiniObject")
|
||||||
(c-name "GstBuffer")
|
(c-name "GstBuffer")
|
||||||
(gtype-id "GST_TYPE_BUFFER")
|
(gtype-id "GST_TYPE_BUFFER")
|
||||||
|
(fields
|
||||||
|
'("guint8*" "data")
|
||||||
|
'("guint" "size")
|
||||||
|
'("GstClockTime" "timestamp")
|
||||||
|
'("GstClockTime" "duration")
|
||||||
|
'("GstCaps*" "caps")
|
||||||
|
'("guint64" "offset")
|
||||||
|
'("guint64" "offset_end")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-miniobject Event
|
(define-miniobject Event
|
||||||
|
@ -158,6 +167,11 @@
|
||||||
(parent "GstMiniObject")
|
(parent "GstMiniObject")
|
||||||
(c-name "GstEvent")
|
(c-name "GstEvent")
|
||||||
(gtype-id "GST_TYPE_EVENT")
|
(gtype-id "GST_TYPE_EVENT")
|
||||||
|
(fields
|
||||||
|
'("GstEventType" "type")
|
||||||
|
'("guint64" "timestamp")
|
||||||
|
'("GstObject*" "src")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-miniobject Message
|
(define-miniobject Message
|
||||||
|
@ -165,6 +179,12 @@
|
||||||
(parent "GstMiniObject")
|
(parent "GstMiniObject")
|
||||||
(c-name "GstMessage")
|
(c-name "GstMessage")
|
||||||
(gtype-id "GST_TYPE_MESSAGE")
|
(gtype-id "GST_TYPE_MESSAGE")
|
||||||
|
(fields
|
||||||
|
'("GstMessageType" "type")
|
||||||
|
'("guint64" "timestamp")
|
||||||
|
'("GstObject*" "src")
|
||||||
|
'("GstStructure*" "structure")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-miniobject Query
|
(define-miniobject Query
|
||||||
|
@ -172,6 +192,10 @@
|
||||||
(parent "GstMiniObject")
|
(parent "GstMiniObject")
|
||||||
(c-name "GstQuery")
|
(c-name "GstQuery")
|
||||||
(gtype-id "GST_TYPE_QUERY")
|
(gtype-id "GST_TYPE_QUERY")
|
||||||
|
(fields
|
||||||
|
'("GstQueryType" "type")
|
||||||
|
'("GstStructure*" "structure")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -887,6 +911,7 @@
|
||||||
'("failure" "GST_STATE_FAILURE")
|
'("failure" "GST_STATE_FAILURE")
|
||||||
'("success" "GST_STATE_SUCCESS")
|
'("success" "GST_STATE_SUCCESS")
|
||||||
'("async" "GST_STATE_ASYNC")
|
'("async" "GST_STATE_ASYNC")
|
||||||
|
'("no-preroll" "GST_STATE_NO_PREROLL")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
10
gst/gst.defs
10
gst/gst.defs
|
@ -4416,6 +4416,16 @@
|
||||||
(return-type "gint")
|
(return-type "gint")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(define-method nth_field_name
|
||||||
|
(of-object "GstStructure")
|
||||||
|
(c-name "gst_structure_nth_field_name")
|
||||||
|
(return-type "const-gchar*")
|
||||||
|
(parameters
|
||||||
|
'("guint" "index")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
(define-method has_field
|
(define-method has_field
|
||||||
(of-object "GstStructure")
|
(of-object "GstStructure")
|
||||||
(c-name "gst_structure_has_field")
|
(c-name "gst_structure_has_field")
|
||||||
|
|
|
@ -40,32 +40,32 @@ pygst_caps_map_add (PyObject *structure, PyObject *caps)
|
||||||
g_hash_table_insert (structure_caps_map, structure, caps);
|
g_hash_table_insert (structure_caps_map, structure, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static void */
|
static void
|
||||||
/* pygst_caps_map_remove_structure (PyObject *structure) */
|
pygst_caps_map_remove_structure (PyObject *structure)
|
||||||
/* { */
|
{
|
||||||
/* g_hash_table_remove (structure_caps_map, structure); */
|
g_hash_table_remove (structure_caps_map, structure);
|
||||||
/* } */
|
}
|
||||||
|
|
||||||
/* static gboolean */
|
static gboolean
|
||||||
/* pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match) */
|
pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match)
|
||||||
/* { */
|
{
|
||||||
/* PyGBoxed *boxed = structure; */
|
PyGBoxed *boxed = structure;
|
||||||
|
|
||||||
/* if (match != caps) */
|
if (match != caps)
|
||||||
/* return FALSE; */
|
return FALSE;
|
||||||
|
|
||||||
/* /\* we can't have free_on_dealloc stuff in here *\/ */
|
/* we can't have free_on_dealloc stuff in here */
|
||||||
/* g_assert (boxed->free_on_dealloc == FALSE); */
|
g_assert (boxed->free_on_dealloc == FALSE);
|
||||||
/* boxed->boxed = gst_structure_copy (boxed->boxed); */
|
boxed->boxed = gst_structure_copy (boxed->boxed);
|
||||||
/* boxed->free_on_dealloc = TRUE; */
|
boxed->free_on_dealloc = TRUE;
|
||||||
/* return TRUE; */
|
return TRUE;
|
||||||
/* } */
|
}
|
||||||
|
|
||||||
/* static void */
|
static void
|
||||||
/* pygst_caps_map_modified (PyObject *caps) */
|
pygst_caps_map_modified (PyObject *caps)
|
||||||
/* { */
|
{
|
||||||
/* g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps); */
|
g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps);
|
||||||
/* } */
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
init
|
init
|
||||||
|
@ -418,7 +418,7 @@ _wrap_gst_caps_tp_dealloc (PyObject *self)
|
||||||
PyGBoxed *boxed = (PyGBoxed *) self;
|
PyGBoxed *boxed = (PyGBoxed *) self;
|
||||||
|
|
||||||
if (boxed->free_on_dealloc && boxed->boxed) {
|
if (boxed->free_on_dealloc && boxed->boxed) {
|
||||||
pygst_caps_map_modified (self);
|
pygst_caps_map_modified (self);
|
||||||
gst_caps_unref (boxed->boxed);
|
gst_caps_unref (boxed->boxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,21 @@ _wrap_gst_element_set_state(PyGObject *self, PyObject *args, PyObject *kwargs)
|
||||||
return PyInt_FromLong(ret);
|
return PyInt_FromLong(ret);
|
||||||
}
|
}
|
||||||
%%
|
%%
|
||||||
|
override gst_element_get_state kwargs
|
||||||
|
static PyObject *
|
||||||
|
_wrap_gst_element_get_state(PyGObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
{
|
||||||
|
GstElementState state;
|
||||||
|
GstElementStateReturn ret;
|
||||||
|
|
||||||
|
ret = gst_element_get_state(GST_ELEMENT (self->obj), &state, NULL, NULL);
|
||||||
|
if (!ret) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "conversion could not be performed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pyg_flags_from_gtype(GST_TYPE_ELEMENT_STATE, state);
|
||||||
|
}
|
||||||
|
%%
|
||||||
/* override gst_element_query kwargs */
|
/* override gst_element_query kwargs */
|
||||||
/* static PyObject * */
|
/* static PyObject * */
|
||||||
/* _wrap_gst_element_query(PyGObject *self, PyObject *args, PyObject *kwargs) */
|
/* _wrap_gst_element_query(PyGObject *self, PyObject *args, PyObject *kwargs) */
|
||||||
|
|
Loading…
Reference in a new issue