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:
Edward Hervey 2005-06-26 13:59:34 +00:00
parent febd74992d
commit 685c434a03
12 changed files with 1489 additions and 162 deletions

View file

@ -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:

View file

@ -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)

View file

@ -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(&params[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))

View file

@ -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')

View file

@ -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)

View file

@ -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] == '_':

View file

@ -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
View 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()

View file

@ -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")
)
)

View file

@ -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")

View file

@ -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

View file

@ -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) */