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>
|
||||
|
||||
* codegen/argtypes.py:
|
||||
|
|
|
@ -3,6 +3,7 @@ import sys
|
|||
import string
|
||||
import traceback
|
||||
import keyword
|
||||
import struct
|
||||
|
||||
class VarList:
|
||||
"""Nicely format a C variable list"""
|
||||
|
@ -188,13 +189,82 @@ class IntArg(ArgType):
|
|||
info.varlist.add('int', '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):
|
||||
def write_return(self, ptype, ownsreturn, info):
|
||||
info.varlist.add('int', 'ret')
|
||||
info.varlist.add('PyObject', '*py_ret')
|
||||
info.codeafter.append(' py_ret = ret ? Py_True : Py_False;\n'
|
||||
' Py_INCREF(py_ret);\n'
|
||||
' return py_ret;')
|
||||
info.codeafter.append(' return PyBool_FromLong(ret);\n')
|
||||
|
||||
class TimeTArg(ArgType):
|
||||
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||
|
@ -333,7 +403,7 @@ class EnumArg(ArgType):
|
|||
info.add_parselist('O', ['&py_' + pname], [pname]);
|
||||
def write_return(self, ptype, ownsreturn, info):
|
||||
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):
|
||||
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])
|
||||
def write_return(self, ptype, ownsreturn, info):
|
||||
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):
|
||||
# should change these checks to more typesafe versions that check
|
||||
|
@ -404,7 +474,7 @@ class ObjectArg(ArgType):
|
|||
info.codebefore.append(self.dflt % {'name':pname,
|
||||
'cast':self.cast})
|
||||
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])
|
||||
else:
|
||||
info.varlist.add('PyGObject', '*' + pname)
|
||||
|
@ -417,6 +487,7 @@ class ObjectArg(ArgType):
|
|||
if ownsreturn:
|
||||
info.varlist.add('PyObject', '*py_ret')
|
||||
info.codeafter.append(' py_ret = pygobject_new((GObject *)ret);\n'
|
||||
' if (ret != NULL)\n'
|
||||
' g_object_unref(ret);\n'
|
||||
' return py_ret;')
|
||||
else:
|
||||
|
@ -620,10 +691,20 @@ class PointerArg(ArgType):
|
|||
' return pyg_pointer_new(' + self.typecode + ', &ret);')
|
||||
|
||||
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'
|
||||
' if (PyErr_Occurred())\n'
|
||||
' return NULL;\n')
|
||||
def write_param(self, ptype, pname, pdflt, pnull, info):
|
||||
if pdflt:
|
||||
info.varlist.add('GdkAtom', pname + ' = ' + pdflt)
|
||||
info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
|
||||
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})
|
||||
|
@ -631,7 +712,7 @@ class AtomArg(IntArg):
|
|||
info.add_parselist('O', ['&py_' + pname], [pname])
|
||||
def write_return(self, ptype, ownsreturn, info):
|
||||
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):
|
||||
gtype = (' if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n'
|
||||
|
@ -669,12 +750,6 @@ class GtkTreePathArg(ArgType):
|
|||
' return NULL;\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'
|
||||
' gtk_tree_path_free(%(name)s);\n')
|
||||
def __init__(self):
|
||||
|
@ -761,9 +836,16 @@ class PyObjectArg(ArgType):
|
|||
class ArgMatcher:
|
||||
def __init__(self):
|
||||
self.argtypes = {}
|
||||
self.reverse_argtypes = {}
|
||||
self.reverse_rettypes = {}
|
||||
|
||||
def register(self, 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):
|
||||
if typecode is None:
|
||||
typecode = "G_TYPE_NONE"
|
||||
|
@ -806,6 +888,39 @@ class ArgMatcher:
|
|||
if ptype[:8] == 'GdkEvent' and ptype[-1] == '*':
|
||||
return self.argtypes['GdkEvent*']
|
||||
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):
|
||||
if otype == None: return 0
|
||||
if otype == parent: return 1
|
||||
|
@ -844,19 +959,24 @@ matcher.register('gunichar', arg)
|
|||
arg = IntArg()
|
||||
matcher.register('int', arg)
|
||||
matcher.register('gint', arg)
|
||||
matcher.register('guint', arg)
|
||||
matcher.register('short', arg)
|
||||
matcher.register('gshort', arg)
|
||||
matcher.register('gushort', arg)
|
||||
matcher.register('long', arg)
|
||||
matcher.register('glong', arg)
|
||||
matcher.register('gsize', arg)
|
||||
matcher.register('gssize', arg)
|
||||
matcher.register('gsize', SizeArg())
|
||||
matcher.register('gssize', SSizeArg())
|
||||
matcher.register('guint8', arg)
|
||||
matcher.register('gint8', arg)
|
||||
matcher.register('guint16', arg)
|
||||
matcher.register('gint16', 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()
|
||||
matcher.register('gboolean', arg)
|
||||
|
|
|
@ -1,6 +1,32 @@
|
|||
import sys, os, string
|
||||
import getopt, traceback, keyword
|
||||
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():
|
||||
#traceback.print_exc()
|
||||
|
@ -60,7 +86,7 @@ class Wrapper:
|
|||
' sizeof(%(tp_basicsize)s), /* tp_basicsize */\n' \
|
||||
' 0, /* tp_itemsize */\n' \
|
||||
' /* methods */\n' \
|
||||
' (destructor)0, /* tp_dealloc */\n' \
|
||||
' (destructor)%(tp_dealloc)s, /* tp_dealloc */\n' \
|
||||
' (printfunc)0, /* tp_print */\n' \
|
||||
' (getattrfunc)%(tp_getattr)s, /* tp_getattr */\n' \
|
||||
' (setattrfunc)%(tp_setattr)s, /* tp_setattr */\n' \
|
||||
|
@ -72,13 +98,13 @@ class Wrapper:
|
|||
' (hashfunc)%(tp_hash)s, /* tp_hash */\n' \
|
||||
' (ternaryfunc)%(tp_call)s, /* tp_call */\n' \
|
||||
' (reprfunc)%(tp_str)s, /* tp_str */\n' \
|
||||
' (getattrofunc)0, /* tp_getattro */\n' \
|
||||
' (setattrofunc)0, /* tp_setattro */\n' \
|
||||
' (getattrofunc)%(tp_getattro)s, /* tp_getattro */\n' \
|
||||
' (setattrofunc)%(tp_setattro)s, /* tp_setattro */\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' \
|
||||
' (traverseproc)0, /* tp_traverse */\n' \
|
||||
' (inquiry)0, /* tp_clear */\n' \
|
||||
' (traverseproc)%(tp_traverse)s, /* tp_traverse */\n' \
|
||||
' (inquiry)%(tp_clear)s, /* tp_clear */\n' \
|
||||
' (richcmpfunc)%(tp_richcompare)s, /* tp_richcompare */\n' \
|
||||
' %(tp_weaklistoffset)s, /* tp_weaklistoffset */\n' \
|
||||
' (getiterfunc)%(tp_iter)s, /* tp_iter */\n' \
|
||||
|
@ -98,11 +124,13 @@ class Wrapper:
|
|||
' (inquiry)%(tp_is_gc)s /* tp_is_gc */\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_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
|
||||
'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 = \
|
||||
'static PyObject *\n' \
|
||||
|
@ -145,6 +173,27 @@ class Wrapper:
|
|||
'%(codeafter)s\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
|
||||
constructor_tmpl = None
|
||||
method_tmpl = None
|
||||
|
@ -173,6 +222,8 @@ class Wrapper:
|
|||
def write_class(self):
|
||||
self.fp.write('\n/* ----------- ' + self.objinfo.c_name + ' ----------- */\n\n')
|
||||
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
|
||||
if self.overrides.modulename:
|
||||
substdict['classname'] = '%s.%s' % (self.overrides.modulename,
|
||||
|
@ -189,8 +240,6 @@ class Wrapper:
|
|||
|
||||
# handle slots ...
|
||||
for slot in self.slots_list:
|
||||
if substdict.has_key(slot) and substdict[slot] != '0':
|
||||
continue
|
||||
|
||||
slotname = '%s.%s' % (self.objinfo.c_name, slot)
|
||||
slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
|
||||
|
@ -201,10 +250,13 @@ class Wrapper:
|
|||
self.write_function(slotname, data)
|
||||
substdict[slot] = slotfunc
|
||||
else:
|
||||
if not substdict.has_key(slot):
|
||||
substdict[slot] = '0'
|
||||
|
||||
self.fp.write(self.type_tmpl % substdict)
|
||||
|
||||
self.write_virtuals()
|
||||
|
||||
def write_function_wrapper(self, function_obj, template,
|
||||
handle_return=0, is_method=0, kwargs_needed=0,
|
||||
substdict=None):
|
||||
|
@ -223,11 +275,12 @@ class Wrapper:
|
|||
if function_obj.varargs:
|
||||
raise ValueError, "varargs functions not supported"
|
||||
|
||||
for ptype, pname, pdflt, pnull in function_obj.params:
|
||||
if pdflt and '|' not in info.parsestr:
|
||||
for param in function_obj.params:
|
||||
if param.pdflt and '|' not in info.parsestr:
|
||||
info.add_parselist('|', [], [])
|
||||
handler = argtypes.matcher.get(ptype)
|
||||
handler.write_param(ptype, pname, pdflt, pnull, info)
|
||||
handler = argtypes.matcher.get(param.ptype)
|
||||
handler.write_param(param.ptype, param.pname, param.pdflt,
|
||||
param.pnull, info)
|
||||
|
||||
substdict['setreturn'] = ''
|
||||
if handle_return:
|
||||
|
@ -249,7 +302,7 @@ class Wrapper:
|
|||
|
||||
if self.objinfo:
|
||||
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['typecodes'] = info.parsestr
|
||||
substdict['parselist'] = info.get_parselist()
|
||||
|
@ -284,6 +337,16 @@ class Wrapper:
|
|||
data = self.overrides.override(funcname)
|
||||
self.write_function(funcname, data)
|
||||
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 ...
|
||||
code = self.write_function_wrapper(constructor,
|
||||
self.constructor_tmpl,
|
||||
|
@ -294,12 +357,12 @@ class Wrapper:
|
|||
except:
|
||||
sys.stderr.write('Could not write constructor for %s: %s\n'
|
||||
% (self.objinfo.c_name, exc_info()))
|
||||
# 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'
|
||||
initfunc = self.write_noconstructor()
|
||||
else:
|
||||
initfunc = self.write_default_constructor()
|
||||
return initfunc
|
||||
|
||||
def write_noconstructor(self):
|
||||
# this is a hack ...
|
||||
if not hasattr(self.overrides, 'no_constructor_written'):
|
||||
self.fp.write(self.noconstructor)
|
||||
|
@ -307,6 +370,9 @@ class Wrapper:
|
|||
initfunc = 'pygobject_no_constructor'
|
||||
return initfunc
|
||||
|
||||
def write_default_constructor(self):
|
||||
return self.write_noconstructor()
|
||||
|
||||
def get_methflags(self, funcname):
|
||||
if self.overrides.wants_kwargs(funcname):
|
||||
return 'METH_VARARGS|METH_KEYWORDS'
|
||||
|
@ -322,6 +388,15 @@ class Wrapper:
|
|||
self.fp.resetline()
|
||||
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):
|
||||
methods = []
|
||||
klass = self.objinfo.c_name
|
||||
|
@ -347,7 +422,9 @@ class Wrapper:
|
|||
{ 'name': fixname(meth.name),
|
||||
'cname': '_wrap_' + method_name,
|
||||
'flags': methflags})
|
||||
methods_coverage.declare_wrapped()
|
||||
except:
|
||||
methods_coverage.declare_not_wrapped()
|
||||
sys.stderr.write('Could not write method %s.%s: %s\n'
|
||||
% (klass, meth.name, exc_info()))
|
||||
|
||||
|
@ -360,16 +437,22 @@ class Wrapper:
|
|||
try:
|
||||
data = self.overrides.define(klass, method_name)
|
||||
self.write_function(method_name, data)
|
||||
self.get_methflags(method_name)
|
||||
methflags = self.get_methflags(method_name)
|
||||
|
||||
methods.append(self.methdef_tmpl %
|
||||
{ 'name': method_name,
|
||||
'cname': '_wrap_' + c_name,
|
||||
'flags': methflags})
|
||||
methods_coverage.declare_wrapped()
|
||||
except:
|
||||
methods_coverage.declare_not_wrapped()
|
||||
sys.stderr.write('Could not write method %s.%s: %s\n'
|
||||
% (klass, meth.name, exc_info()))
|
||||
|
||||
# Add GObject virtual method accessors, for chaining to parent
|
||||
# virtuals from subclasses
|
||||
methods += self.write_virtual_accessors()
|
||||
|
||||
if methods:
|
||||
methoddefs = '_Py%s_methods' % self.objinfo.c_name
|
||||
# write the PyMethodDef structure
|
||||
|
@ -381,6 +464,112 @@ class Wrapper:
|
|||
methoddefs = 'NULL'
|
||||
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):
|
||||
lower_name = self.get_lower_name()
|
||||
getsets_name = lower_name + '_getsets'
|
||||
|
@ -456,7 +645,9 @@ class Wrapper:
|
|||
{ 'name': func.name,
|
||||
'cname': '_wrap_' + funcname,
|
||||
'flags': methflags })
|
||||
functions_coverage.declare_wrapped()
|
||||
except:
|
||||
functions_coverage.declare_not_wrapped()
|
||||
sys.stderr.write('Could not write function %s: %s\n'
|
||||
% (func.name, exc_info()))
|
||||
|
||||
|
@ -470,7 +661,9 @@ class Wrapper:
|
|||
{ 'name': funcname,
|
||||
'cname': '_wrap_' + funcname,
|
||||
'flags': methflags })
|
||||
functions_coverage.declare_wrapped()
|
||||
except:
|
||||
functions_coverage.declare_not_wrapped()
|
||||
sys.stderr.write('Could not write function %s: %s\n'
|
||||
% (funcname, exc_info()))
|
||||
|
||||
|
@ -527,11 +720,6 @@ class GObjectWrapper(Wrapper):
|
|||
|
||||
def 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'):
|
||||
substdict['aftercreate'] = " g_object_ref(self->obj); /* we don't own the first reference of windows */\n"
|
||||
elif argtypes.matcher.object_is_a(self.objinfo.c_name, 'GtkInvisible'):
|
||||
substdict['aftercreate'] = " g_object_ref(self->obj); /* we don't own the first reference of invisibles */\n"
|
||||
else:
|
||||
if not constructor.caller_owns_return:
|
||||
substdict['aftercreate'] = " g_object_ref(self->obj);\n"
|
||||
else:
|
||||
|
@ -542,6 +730,91 @@ class GObjectWrapper(Wrapper):
|
|||
substdict = Wrapper.get_initial_method_substdict(self, method)
|
||||
substdict['cast'] = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
|
||||
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)
|
||||
class GstMiniObjectWrapper(Wrapper):
|
||||
|
@ -615,6 +888,70 @@ class GInterfaceWrapper(GObjectWrapper):
|
|||
# interfaces have no fields ...
|
||||
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):
|
||||
constructor_tmpl = \
|
||||
'static int\n' \
|
||||
|
@ -702,7 +1039,7 @@ class GPointerWrapper(GBoxedWrapper):
|
|||
return substdict
|
||||
|
||||
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('#include <Python.h>\n\n\n')
|
||||
fp.write(data)
|
||||
|
@ -751,15 +1088,17 @@ def write_enums(parser, prefix, fp=sys.stdout):
|
|||
% (value, value))
|
||||
else:
|
||||
if enum.deftype == 'enum':
|
||||
fp.write(' pyg_enum_add_constants(module, %s, strip_prefix);\n'
|
||||
% (enum.typecode,))
|
||||
fp.write(' pyg_enum_add(module, "%s", strip_prefix, %s);\n' % (enum.name, enum.typecode))
|
||||
else:
|
||||
fp.write(' pyg_flags_add_constants(module, %s, strip_prefix);\n'
|
||||
% (enum.typecode,))
|
||||
fp.write(' pyg_flags_add(module, "%s", strip_prefix, %s);\n' % (enum.name, enum.typecode))
|
||||
|
||||
fp.write('\n')
|
||||
fp.write(' if (PyErr_Occurred())\n')
|
||||
fp.write(' PyErr_Print();\n')
|
||||
fp.write('}\n\n')
|
||||
|
||||
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')
|
||||
imports = overrides.get_imports()[:]
|
||||
if imports:
|
||||
|
@ -798,6 +1137,9 @@ def write_registers(parser, fp):
|
|||
fp.write(' pyg_register_interface(d, "' + interface.name +
|
||||
'", '+ interface.typecode + ', &Py' + interface.c_name +
|
||||
'_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[:]
|
||||
pos = 0
|
||||
|
@ -825,6 +1167,9 @@ def write_registers(parser, fp):
|
|||
fp.write(' pygobject_register_class(d, "' + obj.c_name +
|
||||
'", ' + obj.typecode + ', &Py' + obj.c_name +
|
||||
'_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
|
||||
miniobjects = parser.miniobjects[:]
|
||||
for obj in miniobjects:
|
||||
|
@ -917,9 +1262,17 @@ def main(argv):
|
|||
p = defsparser.DefsParser(args[0], defines)
|
||||
if not outfilename:
|
||||
outfilename = os.path.splitext(args[0])[0] + '.c'
|
||||
|
||||
p.startParsing()
|
||||
|
||||
register_types(p)
|
||||
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__':
|
||||
sys.exit(main(sys.argv))
|
||||
|
|
|
@ -1,5 +1,41 @@
|
|||
# -*- Mode: Python; py-indent-offset: 4 -*-
|
||||
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:
|
||||
def __init__(self, *args):
|
||||
|
@ -13,6 +49,16 @@ class Definition:
|
|||
"""write out this definition in defs file format"""
|
||||
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):
|
||||
def __init__(self, name, *args):
|
||||
self.name = name
|
||||
|
@ -22,9 +68,8 @@ class ObjectDef(Definition):
|
|||
self.typecode = None
|
||||
self.fields = []
|
||||
self.implements = []
|
||||
for arg in args:
|
||||
if type(arg) != type(()) or len(arg) < 2:
|
||||
continue
|
||||
self.class_init_func = None
|
||||
for arg in get_valid_scheme_definitions(args):
|
||||
if arg[0] == 'in-module':
|
||||
self.module = arg[1]
|
||||
elif arg[0] == 'parent':
|
||||
|
@ -120,16 +165,20 @@ class InterfaceDef(Definition):
|
|||
self.module = None
|
||||
self.c_name = None
|
||||
self.typecode = None
|
||||
self.vtable = None
|
||||
self.fields = []
|
||||
for arg in args:
|
||||
if type(arg) != type(()) or len(arg) < 2:
|
||||
continue
|
||||
self.interface_info = None
|
||||
for arg in get_valid_scheme_definitions(args):
|
||||
if arg[0] == 'in-module':
|
||||
self.module = arg[1]
|
||||
elif arg[0] == 'c-name':
|
||||
self.c_name = arg[1]
|
||||
elif arg[0] == 'gtype-id':
|
||||
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):
|
||||
fp.write('(define-interface ' + self.name + '\n')
|
||||
if self.module:
|
||||
|
@ -148,9 +197,7 @@ class EnumDef(Definition):
|
|||
self.c_name = None
|
||||
self.typecode = None
|
||||
self.values = []
|
||||
for arg in args:
|
||||
if type(arg) != type(()) or len(arg) < 2:
|
||||
continue
|
||||
for arg in get_valid_scheme_definitions(args):
|
||||
if arg[0] == 'in-module':
|
||||
self.in_module = arg[1]
|
||||
elif arg[0] == 'c-name':
|
||||
|
@ -189,9 +236,7 @@ class BoxedDef(Definition):
|
|||
self.copy = None
|
||||
self.release = None
|
||||
self.fields = []
|
||||
for arg in args:
|
||||
if type(arg) != type(()) or len(arg) < 2:
|
||||
continue
|
||||
for arg in get_valid_scheme_definitions(args):
|
||||
if arg[0] == 'in-module':
|
||||
self.module = arg[1]
|
||||
elif arg[0] == 'c-name':
|
||||
|
@ -236,9 +281,7 @@ class PointerDef(Definition):
|
|||
self.c_name = None
|
||||
self.typecode = None
|
||||
self.fields = []
|
||||
for arg in args:
|
||||
if type(arg) != type(()) or len(arg) < 2:
|
||||
continue
|
||||
for arg in get_valid_scheme_definitions(args):
|
||||
if arg[0] == 'in-module':
|
||||
self.module = arg[1]
|
||||
elif arg[0] == 'c-name':
|
||||
|
@ -268,7 +311,7 @@ class PointerDef(Definition):
|
|||
fp.write(' )\n')
|
||||
fp.write(')\n\n')
|
||||
|
||||
class MethodDef(Definition):
|
||||
class MethodDefBase(Definition):
|
||||
def __init__(self, name, *args):
|
||||
dump = 0
|
||||
self.name = name
|
||||
|
@ -280,9 +323,7 @@ class MethodDef(Definition):
|
|||
self.params = [] # of form (type, name, default, nullok)
|
||||
self.varargs = 0
|
||||
self.deprecated = None
|
||||
for arg in args:
|
||||
if type(arg) != type(()) or len(arg) < 2:
|
||||
continue
|
||||
for arg in get_valid_scheme_definitions(args):
|
||||
if arg[0] == 'of-object':
|
||||
self.of_object = arg[1]
|
||||
elif arg[0] == 'c-name':
|
||||
|
@ -300,11 +341,12 @@ class MethodDef(Definition):
|
|||
pdflt = None
|
||||
pnull = 0
|
||||
for farg in parg[2:]:
|
||||
assert isinstance(farg, tuple)
|
||||
if farg[0] == 'default':
|
||||
pdflt = farg[1]
|
||||
elif farg[0] == 'null-ok':
|
||||
pnull = 1
|
||||
self.params.append((ptype, pname, pdflt, pnull))
|
||||
self.params.append(Parameter(ptype, pname, pdflt, pnull))
|
||||
elif arg[0] == 'varargs':
|
||||
self.varargs = arg[1] in ('t', '#t')
|
||||
elif arg[0] == 'deprecated':
|
||||
|
@ -317,33 +359,30 @@ class MethodDef(Definition):
|
|||
self.write_defs(sys.stderr)
|
||||
|
||||
if self.caller_owns_return is None and self.ret is not None:
|
||||
if self.ret[:6] == 'const-':
|
||||
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,)
|
||||
self.guess_return_value_ownership()
|
||||
|
||||
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.
|
||||
if not parmerge:
|
||||
self.params = deepcopy(old.params)
|
||||
return
|
||||
for i in range(len(self.params)):
|
||||
ptype, pname, pdflt, pnull = self.params[i]
|
||||
for p2 in old.params:
|
||||
if p2[1] == pname:
|
||||
self.params[i] = (ptype, pname, p2[2], p2[3])
|
||||
break
|
||||
def write_defs(self, fp=sys.stdout):
|
||||
fp.write('(define-method ' + self.name + '\n')
|
||||
def _write_defs(self, fp=sys.stdout):
|
||||
if self.of_object != (None, None):
|
||||
fp.write(' (of-object "' + self.of_object + '")\n')
|
||||
if self.c_name:
|
||||
fp.write(' (c-name "' + self.c_name + '")\n')
|
||||
if self.typecode:
|
||||
fp.write(' (gtype-id "' + self.typecode + '")\n')
|
||||
if self.caller_owns_return:
|
||||
fp.write(' (caller-owns-return #t)\n')
|
||||
if self.ret:
|
||||
fp.write(' (return-type "' + self.ret + '")\n')
|
||||
if self.deprecated:
|
||||
|
@ -356,8 +395,27 @@ class MethodDef(Definition):
|
|||
if pnull: fp.write(' (null-ok)')
|
||||
fp.write(')\n')
|
||||
fp.write(' )\n')
|
||||
if self.varargs:
|
||||
fp.write(' (varargs #t)\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):
|
||||
def __init__(self, name, *args):
|
||||
dump = 0
|
||||
|
@ -371,9 +429,7 @@ class FunctionDef(Definition):
|
|||
self.params = [] # of form (type, name, default, nullok)
|
||||
self.varargs = 0
|
||||
self.deprecated = None
|
||||
for arg in args:
|
||||
if type(arg) != type(()) or len(arg) < 2:
|
||||
continue
|
||||
for arg in get_valid_scheme_definitions(args):
|
||||
if arg[0] == 'in-module':
|
||||
self.in_module = arg[1]
|
||||
elif arg[0] == 'is-constructor-of':
|
||||
|
@ -397,7 +453,21 @@ class FunctionDef(Definition):
|
|||
pdflt = farg[1]
|
||||
elif farg[0] == 'null-ok':
|
||||
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':
|
||||
self.varargs = arg[1] in ('t', '#t')
|
||||
elif arg[0] == 'deprecated':
|
||||
|
@ -410,14 +480,7 @@ class FunctionDef(Definition):
|
|||
self.write_defs(sys.stderr)
|
||||
|
||||
if self.caller_owns_return is None and self.ret is not None:
|
||||
if self.ret[:6] == 'const-':
|
||||
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
|
||||
self.guess_return_value_ownership()
|
||||
for item in ('c_name',):
|
||||
if self.__dict__[item] == None:
|
||||
self.write_defs(sys.stderr)
|
||||
|
@ -425,14 +488,33 @@ class FunctionDef(Definition):
|
|||
|
||||
_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.
|
||||
for i in range(len(self.params)):
|
||||
ptype, pname, pdflt, pnull = self.params[i]
|
||||
for p2 in old.params:
|
||||
if p2[1] == pname:
|
||||
self.params[i] = (ptype, pname, p2[2], p2[3])
|
||||
break
|
||||
def merge_param(param):
|
||||
for old_param in old.params:
|
||||
if old_param.pname == param.pname:
|
||||
if isinstance(old_param, Property):
|
||||
# h2def never scans Property's, therefore if
|
||||
# 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:
|
||||
try:
|
||||
self.is_constructor_of = old.is_constructor_of
|
||||
|
@ -454,11 +536,14 @@ class FunctionDef(Definition):
|
|||
fp.write(' (c-name "' + self.c_name + '")\n')
|
||||
if self.typecode:
|
||||
fp.write(' (gtype-id "' + self.typecode + '")\n')
|
||||
if self.caller_owns_return:
|
||||
fp.write(' (caller-owns-return #t)\n')
|
||||
if self.ret:
|
||||
fp.write(' (return-type "' + self.ret + '")\n')
|
||||
if self.deprecated:
|
||||
fp.write(' (deprecated "' + self.deprecated + '")\n')
|
||||
if self.params:
|
||||
if isinstance(self.params[0], Parameter):
|
||||
fp.write(' (parameters\n')
|
||||
for ptype, pname, pdflt, pnull in self.params:
|
||||
fp.write(' \'("' + ptype + '" "' + pname +'"')
|
||||
|
@ -466,5 +551,16 @@ class FunctionDef(Definition):
|
|||
if pnull: fp.write(' (null-ok)')
|
||||
fp.write(')\n')
|
||||
fp.write(' )\n')
|
||||
fp.write(')\n\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.pointers = [] # pointer types
|
||||
self.functions = [] # functions and methods
|
||||
self.virtuals = [] # virtual methods
|
||||
self.c_name = {} # hash of c names of functions
|
||||
self.methods = {} # hash of methods of particular objects
|
||||
self.defines = defines # -Dfoo=bar options, as dictionary
|
||||
|
@ -66,13 +67,17 @@ class DefsParser(IncludeParser):
|
|||
mdef = apply(MethodDef, args)
|
||||
self.functions.append(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:
|
||||
if old.c_name.has_key(obj.c_name):
|
||||
obj.merge(old.c_name[obj.c_name])
|
||||
for f in self.functions:
|
||||
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):
|
||||
for obj in self.objects:
|
||||
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
|
||||
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):
|
||||
return filter(lambda func: isinstance(func, FunctionDef) and
|
||||
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]*"
|
||||
|
||||
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=[]):
|
||||
"""
|
||||
|
@ -312,7 +312,7 @@ proto_pat=re.compile(r"""
|
|||
(?P<ret>(-|\w|\&|\*)+\s*) # return type
|
||||
\s+ # skip whitespace
|
||||
(?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)
|
||||
#"""
|
||||
arg_split_pat = re.compile("\s*,\s*")
|
||||
|
@ -353,7 +353,7 @@ def write_func(fp, name, ret, args, prefix):
|
|||
obj = m.group(2)
|
||||
if munged_name[:len(obj)] == 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:
|
||||
l = len(prefix) + 1
|
||||
if mname[:l] == prefix and mname[l+1] == '_':
|
||||
|
|
|
@ -3,17 +3,23 @@
|
|||
|
||||
import sys
|
||||
import defsparser
|
||||
from optparse import OptionParser
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
sys.stderr.write("Usage: mergedefs.py generated-defs old-defs\n")
|
||||
sys.exit(1)
|
||||
parser = OptionParser(usage="usage: %prog [options] generated-defs old-defs")
|
||||
parser.add_option("-p", "--merge-parameters",
|
||||
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])
|
||||
oldp = defsparser.DefsParser(sys.argv[2])
|
||||
if len(args) != 2:
|
||||
parser.error("wrong number of arguments")
|
||||
|
||||
newp = defsparser.DefsParser(args[0])
|
||||
oldp = defsparser.DefsParser(args[1])
|
||||
|
||||
newp.startParsing()
|
||||
oldp.startParsing()
|
||||
|
||||
newp.merge(oldp)
|
||||
newp.merge(oldp, options.parmerge)
|
||||
|
||||
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")
|
||||
(c-name "GstBuffer")
|
||||
(gtype-id "GST_TYPE_BUFFER")
|
||||
(fields
|
||||
'("guint8*" "data")
|
||||
'("guint" "size")
|
||||
'("GstClockTime" "timestamp")
|
||||
'("GstClockTime" "duration")
|
||||
'("GstCaps*" "caps")
|
||||
'("guint64" "offset")
|
||||
'("guint64" "offset_end")
|
||||
)
|
||||
)
|
||||
|
||||
(define-miniobject Event
|
||||
|
@ -158,6 +167,11 @@
|
|||
(parent "GstMiniObject")
|
||||
(c-name "GstEvent")
|
||||
(gtype-id "GST_TYPE_EVENT")
|
||||
(fields
|
||||
'("GstEventType" "type")
|
||||
'("guint64" "timestamp")
|
||||
'("GstObject*" "src")
|
||||
)
|
||||
)
|
||||
|
||||
(define-miniobject Message
|
||||
|
@ -165,6 +179,12 @@
|
|||
(parent "GstMiniObject")
|
||||
(c-name "GstMessage")
|
||||
(gtype-id "GST_TYPE_MESSAGE")
|
||||
(fields
|
||||
'("GstMessageType" "type")
|
||||
'("guint64" "timestamp")
|
||||
'("GstObject*" "src")
|
||||
'("GstStructure*" "structure")
|
||||
)
|
||||
)
|
||||
|
||||
(define-miniobject Query
|
||||
|
@ -172,6 +192,10 @@
|
|||
(parent "GstMiniObject")
|
||||
(c-name "GstQuery")
|
||||
(gtype-id "GST_TYPE_QUERY")
|
||||
(fields
|
||||
'("GstQueryType" "type")
|
||||
'("GstStructure*" "structure")
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
@ -887,6 +911,7 @@
|
|||
'("failure" "GST_STATE_FAILURE")
|
||||
'("success" "GST_STATE_SUCCESS")
|
||||
'("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")
|
||||
)
|
||||
|
||||
(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
|
||||
(of-object "GstStructure")
|
||||
(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);
|
||||
}
|
||||
|
||||
/* static void */
|
||||
/* pygst_caps_map_remove_structure (PyObject *structure) */
|
||||
/* { */
|
||||
/* g_hash_table_remove (structure_caps_map, structure); */
|
||||
/* } */
|
||||
static void
|
||||
pygst_caps_map_remove_structure (PyObject *structure)
|
||||
{
|
||||
g_hash_table_remove (structure_caps_map, structure);
|
||||
}
|
||||
|
||||
/* static gboolean */
|
||||
/* pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match) */
|
||||
/* { */
|
||||
/* PyGBoxed *boxed = structure; */
|
||||
static gboolean
|
||||
pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match)
|
||||
{
|
||||
PyGBoxed *boxed = structure;
|
||||
|
||||
/* if (match != caps) */
|
||||
/* return FALSE; */
|
||||
if (match != caps)
|
||||
return FALSE;
|
||||
|
||||
/* /\* we can't have free_on_dealloc stuff in here *\/ */
|
||||
/* g_assert (boxed->free_on_dealloc == FALSE); */
|
||||
/* boxed->boxed = gst_structure_copy (boxed->boxed); */
|
||||
/* boxed->free_on_dealloc = TRUE; */
|
||||
/* return TRUE; */
|
||||
/* } */
|
||||
/* we can't have free_on_dealloc stuff in here */
|
||||
g_assert (boxed->free_on_dealloc == FALSE);
|
||||
boxed->boxed = gst_structure_copy (boxed->boxed);
|
||||
boxed->free_on_dealloc = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* static void */
|
||||
/* pygst_caps_map_modified (PyObject *caps) */
|
||||
/* { */
|
||||
/* g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps); */
|
||||
/* } */
|
||||
static void
|
||||
pygst_caps_map_modified (PyObject *caps)
|
||||
{
|
||||
g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps);
|
||||
}
|
||||
|
||||
%%
|
||||
init
|
||||
|
|
|
@ -85,6 +85,21 @@ _wrap_gst_element_set_state(PyGObject *self, PyObject *args, PyObject *kwargs)
|
|||
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 */
|
||||
/* static PyObject * */
|
||||
/* _wrap_gst_element_query(PyGObject *self, PyObject *args, PyObject *kwargs) */
|
||||
|
|
Loading…
Reference in a new issue