codegen/: Updated codegenerator to current pygtk one.

Original commit message from CVS:
* codegen/Makefile.am:
* codegen/argtypes.py:
* codegen/codegen.py:
* codegen/definitions.py:
* codegen/defsconvert.py:
* codegen/defsparser.py:
* codegen/docextract.py:
* codegen/docextract_to_xml.py:
* codegen/docgen.py:
* codegen/h2def.py:
* codegen/mergedefs.py:
* codegen/missingdefs.py:
* codegen/mkskel.py:
* codegen/override.py:
* codegen/reversewrapper.py:
Updated codegenerator to current pygtk one.
* gst/gst.defs:
* gst/gst.override:
* gst/gstpad.override:
Update defs for new constructor definition.
* testsuite/test_bin.py:
With new constructors, pygobject will try to convert the argument to the
proper GType (here a string).
This commit is contained in:
Edward Hervey 2006-06-09 10:50:21 +00:00
parent 6189051361
commit bc17f73dcb
20 changed files with 1950 additions and 1630 deletions

View File

@ -1,3 +1,29 @@
2006-06-09 Edward Hervey <edward@fluendo.com>
* codegen/Makefile.am:
* codegen/argtypes.py:
* codegen/codegen.py:
* codegen/definitions.py:
* codegen/defsconvert.py:
* codegen/defsparser.py:
* codegen/docextract.py:
* codegen/docextract_to_xml.py:
* codegen/docgen.py:
* codegen/h2def.py:
* codegen/mergedefs.py:
* codegen/missingdefs.py:
* codegen/mkskel.py:
* codegen/override.py:
* codegen/reversewrapper.py:
Updated codegenerator to current pygtk one.
* gst/gst.defs:
* gst/gst.override:
* gst/gstpad.override:
Update defs for new constructor definition.
* testsuite/test_bin.py:
With new constructors, pygobject will try to convert the argument to the
proper GType (here a string).
2006-06-09 Edward Hervey <edward@fluendo.com> 2006-06-09 Edward Hervey <edward@fluendo.com>
* gst/base.defs: * gst/base.defs:

View File

@ -3,15 +3,12 @@ EXTRA_DIST = \
code-coverage.py \ code-coverage.py \
codegen.py \ codegen.py \
definitions.py \ definitions.py \
defsconvert.py \
defsparser.py \ defsparser.py \
docextract.py \ docextract.py \
docextract_to_xml.py \
docgen.py \ docgen.py \
h2def.py \ h2def.py \
__init__.py \ __init__.py \
mergedefs.py \ mergedefs.py \
missingdefs.py \
mkskel.py \ mkskel.py \
override.py \ override.py \
reversewrapper.py \ reversewrapper.py \

View File

@ -1,7 +1,5 @@
# -*- Mode: Python; py-indent-offset: 4 -*- # -*- Mode: Python; py-indent-offset: 4 -*-
import sys
import string import string
import traceback
import keyword import keyword
import struct import struct
@ -66,7 +64,7 @@ class WrapperInfo:
self.kwlist.append('"%s"' % kw) self.kwlist.append('"%s"' % kw)
class ArgType: class ArgType:
def write_param(self, ptype, pname, pdflt, pnull, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
"""Add code to the WrapperInfo instance to handle """Add code to the WrapperInfo instance to handle
parameter.""" parameter."""
raise RuntimeError, "write_param not implemented for %s" % \ raise RuntimeError, "write_param not implemented for %s" % \
@ -284,22 +282,30 @@ class TimeTArg(ArgType):
info.codeafter.append(' return PyInt_FromLong(ret);') info.codeafter.append(' return PyInt_FromLong(ret);')
class ULongArg(ArgType): class ULongArg(ArgType):
dflt = ' if (py_%(name)s)\n' \
' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
before = ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pdflt: if pdflt:
info.varlist.add('gulong', pname + ' = ' + pdflt) info.varlist.add('unsigned long', pname + ' = ' + pdflt)
info.codebefore.append(self.dflt % {'name':pname})
else: else:
info.varlist.add('gulong', pname) info.varlist.add('unsigned long', pname)
info.codebefore.append(self.before % {'name':pname})
info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O!', ['&PyLong_Type', '&py_' + pname], [pname]) info.add_parselist('k', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('gulong', 'ret') info.varlist.add(ptype, 'ret')
info.codeafter.append(' return PyLong_FromUnsignedLong(ret);') info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n')
class UInt32Arg(ULongArg):
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
ULongArg.write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info)
## if sizeof(unsigned long) > sizeof(unsigned int), we need to
## check the value is within guint32 range
if struct.calcsize('L') > struct.calcsize('I'):
info.codebefore.append((
' if (%(pname)s > G_MAXUINT32) {\n'
' PyErr_SetString(PyExc_ValueError,\n'
' "Value out of range in conversion of"\n'
' " %(pname)s parameter to unsigned 32 bit integer");\n'
' return NULL;\n'
' }\n') % vars())
class Int64Arg(ArgType): class Int64Arg(ArgType):
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
@ -314,13 +320,19 @@ class Int64Arg(ArgType):
info.codeafter.append(' return PyLong_FromLongLong(ret);') info.codeafter.append(' return PyLong_FromLongLong(ret);')
class UInt64Arg(ArgType): class UInt64Arg(ArgType):
dflt = ' if (py_%(name)s)\n' \
' %(name)s = PyLong_AsUnsignedLongLong(py_%(name)s);\n'
before = ' %(name)s = PyLong_AsUnsignedLongLong(py_%(name)s);\n'
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pdflt: if pdflt:
info.varlist.add('guint64', pname + ' = ' + pdflt) info.varlist.add('guint64', pname + ' = ' + pdflt)
info.codebefore.append(self.dflt % {'name':pname})
else: else:
info.varlist.add('guint64', pname) info.varlist.add('guint64', pname)
info.codebefore.append(self.before % {'name':pname})
info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('K', ['&' + pname], [pname]) info.add_parselist('O!', ['&PyLong_Type', '&py_' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('guint64', 'ret') info.varlist.add('guint64', 'ret')
info.codeafter.append(' return PyLong_FromUnsignedLongLong(ret);') info.codeafter.append(' return PyLong_FromUnsignedLongLong(ret);')
@ -464,7 +476,17 @@ class ObjectArg(ArgType):
info.codebefore.append(self.null % {'name':pname, info.codebefore.append(self.null % {'name':pname,
'cast':self.cast, 'cast':self.cast,
'type':self.objname}) 'type':self.objname})
if ptype.endswith('*'):
typename = ptype[:-1]
try:
const, typename = typename.split('const-')
except ValueError:
const = ''
if typename != ptype:
info.arglist.append('(%s *) %s' % (ptype[:-1], pname))
else:
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
else: else:
if pdflt: if pdflt:
@ -481,8 +503,13 @@ class ObjectArg(ArgType):
info.add_parselist('O!', ['&Py%s_Type' % self.objname, info.add_parselist('O!', ['&Py%s_Type' % self.objname,
'&' + pname], [pname]) '&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
if ptype[-1] == '*': ptype = ptype[:-1] if ptype.endswith('*'):
info.varlist.add(ptype, '*ret') typename = ptype[:-1]
try:
const, typename = typename.split('const-')
except ValueError:
const = ''
info.varlist.add(typename, '*ret')
if ownsreturn: if ownsreturn:
info.varlist.add('PyObject', '*py_ret') info.varlist.add('PyObject', '*py_ret')
# < GLib 2.8: using our custom _new and _unref functions # < GLib 2.8: using our custom _new and _unref functions
@ -532,7 +559,17 @@ class MiniObjectArg(ArgType):
info.codebefore.append(self.null % {'name':pname, info.codebefore.append(self.null % {'name':pname,
'cast':self.cast, 'cast':self.cast,
'type':self.objname}) 'type':self.objname})
if ptype.endswith('*'):
typename = ptype[:-1]
try:
const, typename = typename.split('const-')
except ValueError:
const = ''
if typename != ptype:
info.arglist.append('(%s *) %s' % (ptype[:-1], pname))
else:
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
else: else:
if pdflt: if pdflt:
@ -551,8 +588,13 @@ class MiniObjectArg(ArgType):
if keeprefcount: if keeprefcount:
info.codebefore.append(' gst_mini_object_ref(GST_MINI_OBJECT(%s->obj));\n' % pname) info.codebefore.append(' gst_mini_object_ref(GST_MINI_OBJECT(%s->obj));\n' % pname)
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
if ptype[-1] == '*': ptype = ptype[:-1] if ptype.endswith('*'):
info.varlist.add(ptype, '*ret') typename = ptype[:-1]
try:
const, typename = typename.split('const-')
except ValueError:
const = ''
info.varlist.add(typename, '*ret')
if ownsreturn: if ownsreturn:
info.varlist.add('PyObject', '*py_ret') info.varlist.add('PyObject', '*py_ret')
info.codeafter.append(' py_ret = pygstminiobject_new((GstMiniObject *)ret);\n' info.codeafter.append(' py_ret = pygstminiobject_new((GstMiniObject *)ret);\n'
@ -716,7 +758,12 @@ class AtomArg(IntArg):
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('GdkAtom', 'ret') info.varlist.add('GdkAtom', 'ret')
info.codeafter.append(' return PyString_FromString(gdk_atom_name(ret));') info.varlist.add('PyObject *', 'py_ret')
info.varlist.add('gchar *', 'name')
info.codeafter.append(' name = gdk_atom_name(ret);\n'
' py_ret = PyString_FromString(name);\n'
' g_free(name);\n'
' return py_ret;')
class GTypeArg(ArgType): class GTypeArg(ArgType):
gtype = (' if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n' gtype = (' if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n'
@ -862,6 +909,7 @@ class ArgMatcher:
oa = ObjectArg(ptype, parent, typecode) oa = ObjectArg(ptype, parent, typecode)
self.register(ptype, oa) # in case I forget the * in the .defs self.register(ptype, oa) # in case I forget the * in the .defs
self.register(ptype+'*', oa) self.register(ptype+'*', oa)
self.register('const-'+ptype+'*', oa)
if ptype == 'GdkPixmap': if ptype == 'GdkPixmap':
# hack to handle GdkBitmap synonym. # hack to handle GdkBitmap synonym.
self.register('GdkBitmap', oa) self.register('GdkBitmap', oa)
@ -994,13 +1042,7 @@ matcher.register('gboolean', arg)
arg = TimeTArg() arg = TimeTArg()
matcher.register('time_t', arg) matcher.register('time_t', arg)
# If the system maxint is smaller than unsigned int, we need to use matcher.register('guint32', UInt32Arg())
# Long objects with PyLong_AsUnsignedLong
if sys.maxint >= (1L << 32):
matcher.register('guint32', arg)
else:
arg = ULongArg()
matcher.register('guint32', arg)
arg = ULongArg() arg = ULongArg()
matcher.register('gulong', arg) matcher.register('gulong', arg)

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,25 @@
# -*- Mode: Python; py-indent-offset: 4 -*- # -*- Mode: Python; py-indent-offset: 4 -*-
import copy
import sys import sys
from copy import *
def get_valid_scheme_definitions(defs): def get_valid_scheme_definitions(defs):
return [x for x in defs if isinstance(x, tuple) and len(x) >= 2] return [x for x in defs if isinstance(x, tuple) and len(x) >= 2]
def unescape(s):
s = s.replace('\r\n', '\\r\\n').replace('\t', '\\t')
return s.replace('\r', '\\r').replace('\n', '\\n')
def make_docstring(lines):
return "(char *) " + '\n'.join(['"%s"' % unescape(s) for s in lines])
# New Parameter class, wich emulates a tuple for compatibility reasons # New Parameter class, wich emulates a tuple for compatibility reasons
class Parameter(object): class Parameter(object):
def __init__(self, ptype, pname, pdflt, pnull, prop=None, keeprefcount=False): def __init__(self, ptype, pname, pdflt, pnull, pdir=None, keeprefcount = False):
self.ptype = ptype self.ptype = ptype
self.pname = pname self.pname = pname
self.pdflt = pdflt self.pdflt = pdflt
self.pnull = pnull self.pnull = pnull
self.pdir = pdir
self.keeprefcount = keeprefcount self.keeprefcount = keeprefcount
def __len__(self): return 4 def __len__(self): return 4
@ -39,6 +47,7 @@ class Property(object):
class Definition: class Definition:
docstring = "NULL"
def __init__(self, *args): def __init__(self, *args):
"""Create a new defs object of this type. The arguments are the """Create a new defs object of this type. The arguments are the
components of the definition""" components of the definition"""
@ -70,9 +79,12 @@ class ObjectDef(Definition):
self.fields = [] self.fields = []
self.implements = [] self.implements = []
self.class_init_func = None self.class_init_func = None
self.has_new_constructor_api = False
for arg in get_valid_scheme_definitions(args): for arg in get_valid_scheme_definitions(args):
if arg[0] == 'in-module': if arg[0] == 'in-module':
self.module = arg[1] self.module = arg[1]
elif arg[0] == 'docstring':
self.docstring = make_docstring(arg[1:])
elif arg[0] == 'parent': elif arg[0] == 'parent':
self.parent = arg[1] self.parent = arg[1]
elif arg[0] == 'c-name': elif arg[0] == 'c-name':
@ -172,6 +184,8 @@ class InterfaceDef(Definition):
for arg in get_valid_scheme_definitions(args): for arg in get_valid_scheme_definitions(args):
if arg[0] == 'in-module': if arg[0] == 'in-module':
self.module = arg[1] self.module = arg[1]
elif arg[0] == 'docstring':
self.docstring = make_docstring(arg[1:])
elif arg[0] == 'c-name': elif arg[0] == 'c-name':
self.c_name = arg[1] self.c_name = arg[1]
elif arg[0] == 'gtype-id': elif arg[0] == 'gtype-id':
@ -318,6 +332,7 @@ class MethodDefBase(Definition):
self.name = name self.name = name
self.ret = None self.ret = None
self.caller_owns_return = None self.caller_owns_return = None
self.unblock_threads = None
self.c_name = None self.c_name = None
self.typecode = None self.typecode = None
self.of_object = None self.of_object = None
@ -327,6 +342,8 @@ class MethodDefBase(Definition):
for arg in get_valid_scheme_definitions(args): for arg in get_valid_scheme_definitions(args):
if arg[0] == 'of-object': if arg[0] == 'of-object':
self.of_object = arg[1] self.of_object = arg[1]
elif arg[0] == 'docstring':
self.docstring = make_docstring(arg[1:])
elif arg[0] == 'c-name': elif arg[0] == 'c-name':
self.c_name = arg[1] self.c_name = arg[1]
elif arg[0] == 'gtype-id': elif arg[0] == 'gtype-id':
@ -335,12 +352,15 @@ class MethodDefBase(Definition):
self.ret = arg[1] self.ret = arg[1]
elif arg[0] == 'caller-owns-return': elif arg[0] == 'caller-owns-return':
self.caller_owns_return = arg[1] in ('t', '#t') self.caller_owns_return = arg[1] in ('t', '#t')
elif arg[0] == 'unblock-threads':
self.unblock_threads = arg[1] in ('t', '#t')
elif arg[0] == 'parameters': elif arg[0] == 'parameters':
for parg in arg[1:]: for parg in arg[1:]:
ptype = parg[0] ptype = parg[0]
pname = parg[1] pname = parg[1]
pdflt = None pdflt = None
pnull = 0 pnull = 0
pdir = None
keeprefcount = False keeprefcount = False
for farg in parg[2:]: for farg in parg[2:]:
assert isinstance(farg, tuple) assert isinstance(farg, tuple)
@ -348,9 +368,11 @@ class MethodDefBase(Definition):
pdflt = farg[1] pdflt = farg[1]
elif farg[0] == 'null-ok': elif farg[0] == 'null-ok':
pnull = 1 pnull = 1
elif farg[0] == 'direction':
pdir = farg[1]
elif farg[0] == 'keep-refcount': elif farg[0] == 'keep-refcount':
keeprefcount = True keeprefcount = True
self.params.append(Parameter(ptype, pname, pdflt, pnull, self.params.append(Parameter(ptype, pname, pdflt, pnull, pdir,
keeprefcount=keeprefcount)) keeprefcount=keeprefcount))
elif arg[0] == 'varargs': elif arg[0] == 'varargs':
self.varargs = arg[1] in ('t', '#t') self.varargs = arg[1] in ('t', '#t')
@ -371,7 +393,7 @@ class MethodDefBase(Definition):
self.varargs = old.varargs self.varargs = old.varargs
# here we merge extra parameter flags accross to the new object. # here we merge extra parameter flags accross to the new object.
if not parmerge: if not parmerge:
self.params = deepcopy(old.params) self.params = copy.deepcopy(old.params)
return return
for i in range(len(self.params)): for i in range(len(self.params)):
ptype, pname, pdflt, pnull = self.params[i] ptype, pname, pdflt, pnull = self.params[i]
@ -388,6 +410,8 @@ class MethodDefBase(Definition):
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.caller_owns_return: if self.caller_owns_return:
fp.write(' (caller-owns-return #t)\n') fp.write(' (caller-owns-return #t)\n')
if self.unblock_threads:
fp.write(' (unblock_threads #t)\n')
if self.ret: if self.ret:
fp.write(' (return-type "' + self.ret + '")\n') fp.write(' (return-type "' + self.ret + '")\n')
if self.deprecated: if self.deprecated:
@ -404,6 +428,7 @@ class MethodDefBase(Definition):
fp.write(' (varargs #t)\n') fp.write(' (varargs #t)\n')
fp.write(')\n\n') fp.write(')\n\n')
class MethodDef(MethodDefBase): class MethodDef(MethodDefBase):
def __init__(self, name, *args): def __init__(self, name, *args):
MethodDefBase.__init__(self, name, *args) MethodDefBase.__init__(self, name, *args)
@ -429,6 +454,7 @@ class FunctionDef(Definition):
self.is_constructor_of = None self.is_constructor_of = None
self.ret = None self.ret = None
self.caller_owns_return = None self.caller_owns_return = None
self.unblock_threads = None
self.c_name = None self.c_name = None
self.typecode = None self.typecode = None
self.params = [] # of form (type, name, default, nullok) self.params = [] # of form (type, name, default, nullok)
@ -437,6 +463,8 @@ class FunctionDef(Definition):
for arg in get_valid_scheme_definitions(args): for arg in get_valid_scheme_definitions(args):
if arg[0] == 'in-module': if arg[0] == 'in-module':
self.in_module = arg[1] self.in_module = arg[1]
elif arg[0] == 'docstring':
self.docstring = make_docstring(arg[1:])
elif arg[0] == 'is-constructor-of': elif arg[0] == 'is-constructor-of':
self.is_constructor_of = arg[1] self.is_constructor_of = arg[1]
elif arg[0] == 'c-name': elif arg[0] == 'c-name':
@ -447,6 +475,8 @@ class FunctionDef(Definition):
self.ret = arg[1] self.ret = arg[1]
elif arg[0] == 'caller-owns-return': elif arg[0] == 'caller-owns-return':
self.caller_owns_return = arg[1] in ('t', '#t') self.caller_owns_return = arg[1] in ('t', '#t')
elif arg[0] == 'unblock-threads':
self.unblock_threads = arg[1] in ('t', '#t')
elif arg[0] == 'parameters': elif arg[0] == 'parameters':
for parg in arg[1:]: for parg in arg[1:]:
ptype = parg[0] ptype = parg[0]
@ -501,7 +531,7 @@ class FunctionDef(Definition):
self.caller_owns_return = old.caller_owns_return self.caller_owns_return = old.caller_owns_return
self.varargs = old.varargs self.varargs = old.varargs
if not parmerge: if not parmerge:
self.params = deepcopy(old.params) self.params = copy.deepcopy(old.params)
return return
# here we merge extra parameter flags accross to the new object. # here we merge extra parameter flags accross to the new object.
def merge_param(param): def merge_param(param):
@ -511,7 +541,7 @@ class FunctionDef(Definition):
# h2def never scans Property's, therefore if # h2def never scans Property's, therefore if
# we have one it was manually written, so we # we have one it was manually written, so we
# keep it. # keep it.
return deepcopy(old_param) return copy.deepcopy(old_param)
else: else:
param.merge(old_param) param.merge(old_param)
return param return param
@ -522,7 +552,7 @@ class FunctionDef(Definition):
except RuntimeError: except RuntimeError:
# parameter names changed and we can't find a match; it's # parameter names changed and we can't find a match; it's
# safer to keep the old parameter list untouched. # safer to keep the old parameter list untouched.
self.params = deepcopy(old.params) self.params = copy.deepcopy(old.params)
if not self.is_constructor_of: if not self.is_constructor_of:
try: try:
@ -547,6 +577,8 @@ class FunctionDef(Definition):
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.caller_owns_return: if self.caller_owns_return:
fp.write(' (caller-owns-return #t)\n') fp.write(' (caller-owns-return #t)\n')
if self.unblock_threads:
fp.write(' (unblock-threads #t)\n')
if self.ret: if self.ret:
fp.write(' (return-type "' + self.ret + '")\n') fp.write(' (return-type "' + self.ret + '")\n')
if self.deprecated: if self.deprecated:

View File

@ -1,135 +0,0 @@
import sys
import string, re
# ------------------ Create typecodes from typenames ---------
_upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])')
_upperstr_pat2 = re.compile(r'([A-Z][A-Z])([A-Z][0-9a-z])')
_upperstr_pat3 = re.compile(r'^([A-Z])([A-Z])')
def to_upper_str(name):
"""Converts a typename to the equivalent upercase and underscores
name. This is used to form the type conversion macros and enum/flag
name variables"""
name = _upperstr_pat1.sub(r'\1_\2', name)
name = _upperstr_pat2.sub(r'\1_\2', name)
name = _upperstr_pat3.sub(r'\1_\2', name, count=1)
return string.upper(name)
def typecode(typename):
"""create a typecode (eg. GTK_TYPE_WIDGET) from a typename"""
return string.replace(to_upper_str(typename), '_', '_TYPE_', 1)
STATE_START = 0
STATE_OBJECT = 1
STATE_INTERFACE = 2
STATE_BOXED = 3
STATE_ENUM = 4
STATE_FLAGS = 5
STATE_METHOD = 6
STATE_FUNCTION = 7
STATE_MINIOBJECT = 8
def convert(infp=sys.stdin, outfp=sys.stdout):
state = STATE_START
seen_params = 0
line = infp.readline()
while line:
if line[:8] == '(object ':
state = STATE_OBJECT
seen_params = 0
outfp.write('(define-object ' + line[8:])
elif line[:13] == '(mini-object ':
state = STATE_MINI_OBJECT
seen_params = 0
outfp.write('(define mini-object ' + line[13:])
elif line[:11] == '(interface ':
state = STATE_INTERFACE
seen_params = 0
outfp.write('(define-interface ' + line[11:])
elif line[:7] == '(boxed ':
state = STATE_BOXED
seen_params = 0
outfp.write('(define-boxed ' + line[7:])
elif line[:6] == '(enum ':
state = STATE_ENUM
seen_params = 0
outfp.write('(define-enum ' + line[6:])
elif line[:7] == '(flags ':
state = STATE_FLAGS
seen_params = 0
outfp.write('(define-flags ' + line[7:])
elif line[:8] == '(method ':
state = STATE_METHOD
seen_params = 0
outfp.write('(define-method ' + line[8:])
elif line[:10] == '(function ':
state = STATE_FUNCTION
seen_params = 0
outfp.write('(define-function ' + line[10:])
elif line[:13] == ' (in-module ':
outfp.write(re.sub(r'^(\s+\(in-module\s+)(\w+)(.*)$',
r'\1"\2"\3', line))
elif line[:10] == ' (parent ':
outfp.write(re.sub(r'^(\s+\(parent\s+)(\w+)(\s+\((\w+)\))?(.*)$',
r'\1"\4\2"\5', line))
elif line[:14] == ' (implements ':
outfp.write(re.sub(r'^(\s+\(implements\s+)([^\s]+)(\s*\))$',
r'\1"\2"\3', line))
elif line[:13] == ' (of-object ':
outfp.write(re.sub(r'^(\s+\(of-object\s+)(\w+)(\s+\((\w+)\))?(.*)$',
r'\1"\4\2"\5', line))
elif line[:10] == ' (c-name ':
outfp.write(re.sub(r'^(\s+\(c-name\s+)([^\s]+)(\s*\))$',
r'\1"\2"\3', line))
if state in (STATE_OBJECT, STATE_INTERFACE, STATE_BOXED,
STATE_ENUM, STATE_FLAGS):
c_name = re.match(r'^\s+\(c-name\s+([^\s]+)\s*\)$',
line).group(1)
outfp.write(' (gtype-id "%s")\n' % typecode(c_name))
elif line[:15] == ' (return-type ':
outfp.write(re.sub(r'^(\s+\(return-type\s+)([^\s]+)(\s*\))$',
r'\1"\2"\3', line))
elif line[:13] == ' (copy-func ':
outfp.write(re.sub(r'^(\s+\(copy-func\s+)(\w+)(.*)$',
r'\1"\2"\3', line))
elif line[:16] == ' (release-func ':
outfp.write(re.sub(r'^(\s+\(release-func\s+)(\w+)(.*)$',
r'\1"\2"\3', line))
elif line[:9] == ' (field ':
if not seen_params:
outfp.write(' (fields\n')
seen_params = 1
outfp.write(re.sub(r'^\s+\(field\s+\(type-and-name\s+([^\s]+)\s+([^\s]+)\s*\)\s*\)$',
' \'("\\1" "\\2")', line))
elif line[:9] == ' (value ':
if not seen_params:
outfp.write(' (values\n')
seen_params = 1
outfp.write(re.sub(r'^\s+\(value\s+\(name\s+([^\s]+)\)\s+\(c-name\s+([^\s]+)\s*\)\s*\)$',
' \'("\\1" "\\2")', line))
elif line[:13] == ' (parameter ':
if not seen_params:
outfp.write(' (parameters\n')
seen_params = 1
outfp.write(re.sub(r'^\s+\(parameter\s+\(type-and-name\s+([^\s]+)\s+([^\s]+)\s*\)(\s*.*)\)$',
' \'("\\1" "\\2"\\3)', line))
elif line[:11] == ' (varargs ':
if seen_params:
outfp.write(' )\n')
seen_params = 0
outfp.write(' (varargs #t)\n')
elif line[0] == ')':
if seen_params:
outfp.write(' )\n')
seen_params = 0
state = STATE_START
outfp.write(line)
else:
outfp.write(line)
line = infp.readline()
if __name__ == '__main__':
convert()

View File

@ -1,7 +1,9 @@
# -*- Mode: Python; py-indent-offset: 4 -*- # -*- Mode: Python; py-indent-offset: 4 -*-
import os, sys import os, sys
import scmexpr import scmexpr
from definitions import * from definitions import BoxedDef, EnumDef, FlagsDef, FunctionDef, \
InterfaceDef, MethodDef, ObjectDef, MiniObjectDef, PointerDef, \
VirtualDef
class IncludeParser(scmexpr.Parser): class IncludeParser(scmexpr.Parser):
"""A simple parser that follows include statements automatically""" """A simple parser that follows include statements automatically"""
@ -139,4 +141,3 @@ class DefsParser(IncludeParser):
if args[0] not in self.defines: if args[0] not in self.defines:
for arg in args[1:]: for arg in args[1:]:
self.handle(arg) self.handle(arg)

View File

@ -83,10 +83,10 @@ def parse_file(fp, doc_dict):
if match: if match:
# assume the last return statement was really part of the # assume the last return statement was really part of the
# description # description
cur_doc.description = cur_doc.description + return_start + \
cur_doc.ret
return_start = match.group(1) return_start = match.group(1)
cur_doc.ret = match.group(2) cur_doc.ret = match.group(2)
cur_doc.description = cur_doc.description + return_start + \
cur_doc.ret
else: else:
cur_doc.append_return(line) cur_doc.append_return(line)
elif in_description: elif in_description:

View File

@ -1,78 +0,0 @@
#!/usr/bin/env python
# -*- Mode: Python; py-indent-offset: 4 -*-
#
# This litte script outputs the C doc comments to an XML format.
# So far it's only used by gtkmm (The C++ bindings). Murray Cumming.
# Usage example:
# # ./docextract_to_xml.py -s /gnome/head/cvs/gtk+/gtk/ -s /gnome/head/cvs/gtk+/docs/reference/gtk/tmpl/ > gtk_docs.xml
import sys, os, string, re, getopt
import docextract
import string
def escape_text(unescaped_text):
escaped_text = unescaped_text
escaped_text = string.replace(escaped_text, '<', '&lt;')
escaped_text = string.replace(escaped_text, '>', '&gt;')
escaped_text = string.replace(escaped_text, '&', '&amp;')
escaped_text = string.replace(escaped_text, '\'', '&apos;')
escaped_text = string.replace(escaped_text, '\"', '&quot;')
#Apparently this is an undefined symbol:
escaped_text = string.replace(escaped_text, '&mdash;', ' mdash ')
return escaped_text
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], "d:s:o:",
["source-dir="])
except getopt.error, e:
sys.stderr.write('docgen.py: %s\n' % e)
sys.stderr.write(
'usage: docgen.py [-s /src/dir]\n')
sys.exit(1)
source_dirs = []
for opt, arg in opts:
if opt in ('-s', '--source-dir'):
source_dirs.append(arg)
if len(args) != 0:
sys.stderr.write(
'usage: docgen.py [-s /src/dir]\n')
sys.exit(1)
docs = docextract.extract(source_dirs);
docextract.extract_tmpl(source_dirs, docs); #Try the tmpl sgml files too.
# print d.docs
if docs:
print "<root>"
for name, value in docs.items():
print "<function name=\"" + escape_text(name) + "\">"
print "<description>"
#The value is a docextract.FunctionDoc
print escape_text(value.description)
print "</description>"
# Loop through the parameters:
print "<parameters>"
for name, description in value.params:
print "<parameter name=\"" + escape_text(name) + "\">"
print "<parameter_description>" + escape_text(description) + "</parameter_description>"
print "</parameter>"
print "</parameters>"
# Show the return-type:
print "<return>" + escape_text(value.ret) + "</return>"
print "</function>\n"
print "</root>"

View File

@ -32,13 +32,12 @@ def build_object_tree(parser):
root = Node(None) root = Node(None)
nodes = { None: root } nodes = { None: root }
for obj_def in objects: for obj_def in objects:
print obj_def.name
parent_node = nodes[obj_def.parent] parent_node = nodes[obj_def.parent]
node = Node(obj_def.c_name, obj_def.implements) node = Node(obj_def.c_name, obj_def.implements)
parent_node.add_child(node) parent_node.add_child(node)
nodes[node.name] = node nodes[node.name] = node
# TODO: Add mini-object
if parser.interfaces: if parser.interfaces:
interfaces = Node('gobject.GInterface') interfaces = Node('gobject.GInterface')
root.add_child(interfaces) root.add_child(interfaces)

View File

@ -4,13 +4,19 @@
# For each prototype, generate a scheme style definition. # For each prototype, generate a scheme style definition.
# GPL'ed # GPL'ed
# Toby D. Reeves <toby@max.rl.plh.af.mil> # Toby D. Reeves <toby@max.rl.plh.af.mil>
#
# Modified by James Henstridge <james@daa.com.au> to output stuff in # Modified by James Henstridge <james@daa.com.au> to output stuff in
# Havoc's new defs format. Info on this format can be seen at: # Havoc's new defs format. Info on this format can be seen at:
# http://www.gnome.org/mailing-lists/archives/gtk-devel-list/2000-January/0085.shtml # http://www.gnome.org/mailing-lists/archives/gtk-devel-list/2000-January/0085.shtml
# Updated to be PEP-8 compatible and refactored to use OOP
import getopt
import os
import re
import string
import sys
import string, sys, re, types import defsparser
# ------------------ Create typecodes from typenames --------- # ------------------ Create typecodes from typenames ---------
@ -114,7 +120,8 @@ def find_obj_defs(buf, objdefs=[]):
objdefs.append(t) objdefs.append(t)
pos = m.end() pos = m.end()
# now find all structures that look like they might represent a class inherited from GTypeInterface: # now find all structures that look like they might represent
# a class inherited from GTypeInterface:
pat = re.compile("struct _(" + obj_name_pat + ")Class\s*{\s*" + pat = re.compile("struct _(" + obj_name_pat + ")Class\s*{\s*" +
"GTypeInterface\s+", re.MULTILINE) "GTypeInterface\s+", re.MULTILINE)
pos = 0 pos = 0
@ -129,7 +136,8 @@ def find_obj_defs(buf, objdefs=[]):
objdefs.append(t) objdefs.append(t)
pos = m.end() pos = m.end()
# now find all structures that look like they might represent an Iface inherited from GTypeInterface: # now find all structures that look like they might represent
# an Iface inherited from GTypeInterface:
pat = re.compile("struct _(" + obj_name_pat + ")Iface\s*{\s*" + pat = re.compile("struct _(" + obj_name_pat + ")Iface\s*{\s*" +
"GTypeInterface\s+", re.MULTILINE) "GTypeInterface\s+", re.MULTILINE)
pos = 0 pos = 0
@ -159,35 +167,6 @@ def sort_obj_defs(objdefs):
pos = pos + 1 pos = pos + 1
return objdefs return objdefs
def write_obj_defs(objdefs, output):
if type(output)==types.StringType:
fp=open(output,'w')
elif type(output)==types.FileType:
fp=output
else:
fp=sys.stdout
fp.write(';; -*- scheme -*-\n')
fp.write('; object definitions ...\n')
for klass, parent in objdefs:
m = split_prefix_pat.match(klass)
cmodule = None
cname = klass
if m:
cmodule = m.group(1)
cname = m.group(2)
fp.write('(define-object ' + cname + '\n')
if cmodule:
fp.write(' (in-module "' + cmodule + '")\n')
if parent:
fp.write(' (parent "' + parent + '")\n')
fp.write(' (c-name "' + klass + '")\n')
fp.write(' (gtype-id "' + typecode(klass) + '")\n')
# should do something about accessible fields
fp.write(')\n\n')
# ------------------ Find enum definitions ----------------- # ------------------ Find enum definitions -----------------
def find_enum_defs(buf, enums=[]): def find_enum_defs(buf, enums=[]):
@ -216,17 +195,115 @@ def find_enum_defs(buf, enums=[]):
pos = m.end() pos = m.end()
def write_enum_defs(enums, output=None): # ------------------ Find function definitions -----------------
if type(output)==types.StringType:
fp=open(output,'w') def clean_func(buf):
elif type(output)==types.FileType: """
fp=output Ideally would make buf have a single prototype on each line.
else: Actually just cuts out a good deal of junk, but leaves lines
fp=sys.stdout where a regex can figure prototypes out.
"""
# bulk comments
buf = strip_comments(buf)
# compact continued lines
pat = re.compile(r"""\\\n""", re.MULTILINE)
buf = pat.sub('', buf)
# Preprocess directives
pat = re.compile(r"""^[#].*?$""", re.MULTILINE)
buf = pat.sub('', buf)
#typedefs, stucts, and enums
pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""",
re.MULTILINE)
buf = pat.sub('', buf)
#strip DECLS macros
pat = re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS""", re.MULTILINE)
buf = pat.sub('', buf)
#extern "C"
pat = re.compile(r"""^\s*(extern)\s+\"C\"\s+{""", re.MULTILINE)
buf = pat.sub('', buf)
#multiple whitespace
pat = re.compile(r"""\s+""", re.MULTILINE)
buf = pat.sub(' ', buf)
#clean up line ends
pat = re.compile(r""";\s*""", re.MULTILINE)
buf = pat.sub('\n', buf)
buf = buf.lstrip()
#associate *, &, and [] with type instead of variable
#pat = re.compile(r'\s+([*|&]+)\s*(\w+)')
pat = re.compile(r' \s* ([*|&]+) \s* (\w+)', re.VERBOSE)
buf = pat.sub(r'\1 \2', buf)
pat = re.compile(r'\s+ (\w+) \[ \s* \]', re.VERBOSE)
buf = pat.sub(r'[] \1', buf)
# make return types that are const work.
buf = string.replace(buf, 'G_CONST_RETURN ', 'const-')
buf = string.replace(buf, 'const ', 'const-')
return buf
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 (
\s*(?P<args>.*?)\s*[)] # group the function arguments
""", re.IGNORECASE|re.VERBOSE)
#"""
arg_split_pat = re.compile("\s*,\s*")
get_type_pat = re.compile(r'(const-)?([A-Za-z0-9]+)\*?\s+')
pointer_pat = re.compile('.*\*$')
func_new_pat = re.compile('(\w+)_new$')
class DefsWriter:
def __init__(self, fp=None, prefix=None, verbose=False,
defsfilter=None):
if not fp:
fp = sys.stdout
self.fp = fp
self.prefix = prefix
self.verbose = verbose
self._enums = {}
self._objects = {}
self._functions = {}
if defsfilter:
filter = defsparser.DefsParser(defsfilter)
filter.startParsing()
for func in filter.functions + filter.methods.values():
self._functions[func.c_name] = func
for obj in filter.objects + filter.boxes + filter.interfaces:
self._objects[obj.c_name] = func
for obj in filter.enums:
self._enums[obj.c_name] = func
def write_def(self, deffile):
buf = open(deffile).read()
self.fp.write('\n;; From %s\n\n' % os.path.basename(deffile))
self._define_func(buf)
self.fp.write('\n')
def write_enum_defs(self, enums, fp=None):
if not fp:
fp = self.fp
fp.write(';; Enumerations and flags ...\n\n') fp.write(';; Enumerations and flags ...\n\n')
trans = string.maketrans(string.uppercase + '_', string.lowercase + '-') trans = string.maketrans(string.uppercase + '_',
string.lowercase + '-')
filter = self._enums
for cname, isflags, entries in enums: for cname, isflags, entries in enums:
if filter:
if cname in filter:
continue
name = cname name = cname
module = None module = None
m = split_prefix_pat.match(cname) m = split_prefix_pat.match(cname)
@ -255,146 +332,85 @@ def write_enum_defs(enums, output=None):
fp.write(' )\n') fp.write(' )\n')
fp.write(')\n\n') fp.write(')\n\n')
# ------------------ Find function definitions ----------------- def write_obj_defs(self, objdefs, fp=None):
if not fp:
fp = self.fp
def clean_func(buf): fp.write(';; -*- scheme -*-\n')
""" fp.write('; object definitions ...\n')
Ideally would make buf have a single prototype on each line.
Actually just cuts out a good deal of junk, but leaves lines
where a regex can figure prototypes out.
"""
# bulk comments
buf = strip_comments(buf)
# compact continued lines filter = self._objects
pat = re.compile(r"""\\\n""", re.MULTILINE) for klass, parent in objdefs:
buf=pat.sub('',buf) if filter:
if klass in filter:
continue
m = split_prefix_pat.match(klass)
cmodule = None
cname = klass
if m:
cmodule = m.group(1)
cname = m.group(2)
fp.write('(define-object ' + cname + '\n')
if cmodule:
fp.write(' (in-module "' + cmodule + '")\n')
if parent:
fp.write(' (parent "' + parent + '")\n')
fp.write(' (c-name "' + klass + '")\n')
fp.write(' (gtype-id "' + typecode(klass) + '")\n')
# should do something about accessible fields
fp.write(')\n\n')
# Preprocess directives def _define_func(self, buf):
pat = re.compile(r"""^[#].*?$""", re.MULTILINE) buf = clean_func(buf)
buf=pat.sub('',buf) buf = string.split(buf,'\n')
filter = self._functions
#typedefs, stucts, and enums
pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re.MULTILINE)
buf=pat.sub('',buf)
#strip DECLS macros
pat = re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS""", re.MULTILINE)
buf=pat.sub('',buf)
#extern "C"
pat = re.compile(r"""^\s*(extern)\s+\"C\"\s+{""", re.MULTILINE)
buf=pat.sub('',buf)
#multiple whitespace
pat = re.compile(r"""\s+""", re.MULTILINE)
buf=pat.sub(' ',buf)
#clean up line ends
pat = re.compile(r""";\s*""", re.MULTILINE)
buf=pat.sub('\n',buf)
buf = buf.lstrip()
#associate *, &, and [] with type instead of variable
#pat=re.compile(r'\s+([*|&]+)\s*(\w+)')
pat=re.compile(r' \s* ([*|&]+) \s* (\w+)',re.VERBOSE)
buf=pat.sub(r'\1 \2', buf)
pat=re.compile(r'\s+ (\w+) \[ \s* \]',re.VERBOSE)
buf=pat.sub(r'[] \1', buf)
# make return types that are const work.
buf = string.replace(buf, 'G_CONST_RETURN ', 'const-')
buf = string.replace(buf, 'const ', 'const-')
return buf
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 (
\s*(?P<args>.*?)[)] # group the function arguments
""", re.IGNORECASE|re.VERBOSE)
#"""
arg_split_pat = re.compile("\s*,\s*")
def define_func(buf,fp, prefix):
buf=clean_func(buf)
buf=string.split(buf,'\n')
for p in buf: for p in buf:
if len(p)==0: continue if not p:
m=proto_pat.match(p) continue
if m==None: m = proto_pat.match(p)
if verbose: if m == None:
sys.stderr.write('No match:|%s|\n'%p) if self.verbose:
sys.stderr.write('No match:|%s|\n' % p)
continue continue
func = m.group('func') func = m.group('func')
if func[0] == '_': if func[0] == '_':
continue continue
if filter:
if func in filter:
continue
ret = m.group('ret') ret = m.group('ret')
args=m.group('args') args = m.group('args')
args=arg_split_pat.split(args) args = arg_split_pat.split(args)
for i in range(len(args)): for i in range(len(args)):
spaces = string.count(args[i], ' ') spaces = string.count(args[i], ' ')
if spaces > 1: if spaces > 1:
args[i] = string.replace(args[i], ' ', '-', spaces - 1) args[i] = string.replace(args[i], ' ', '-', spaces - 1)
write_func(fp, func, ret, args, prefix) self._write_func(func, ret, args)
get_type_pat = re.compile(r'(const-)?([A-Za-z0-9]+)\*?\s+') def _write_func(self, name, ret, args):
pointer_pat = re.compile('.*\*$')
func_new_pat = re.compile('(\w+)_new$')
def write_func(fp, name, ret, args, prefix):
if len(args) >= 1: if len(args) >= 1:
# methods must have at least one argument # methods must have at least one argument
munged_name = string.replace(name, '_', '') munged_name = name.replace('_', '')
m = get_type_pat.match(args[0]) m = get_type_pat.match(args[0])
if m: if m:
obj = m.group(2) obj = m.group(2)
if munged_name[:len(obj)] == string.lower(obj): if munged_name[:len(obj)] == obj.lower():
regex = string.join(map(lambda x: x+'_?',string.lower(obj)),'') self._write_method(obj, name, ret, args)
mname = re.sub(regex, '', name, 1)
if prefix:
l = len(prefix) + 1
if mname[:l] == prefix and mname[l+1] == '_':
mname = mname[l+1:]
fp.write('(define-method ' + mname + '\n')
fp.write(' (of-object "' + obj + '")\n')
fp.write(' (c-name "' + name + '")\n')
if ret != 'void':
fp.write(' (return-type "' + ret + '")\n')
else:
fp.write(' (return-type "none")\n')
is_varargs = 0
has_args = len(args) > 1
for arg in args[1:]:
if arg == '...':
is_varargs = 1
elif arg in ('void', 'void '):
has_args = 0
if has_args:
fp.write(' (parameters\n')
for arg in args[1:]:
if arg != '...':
tupleArg = tuple(string.split(arg))
if len(tupleArg) == 2:
fp.write(' \'("%s" "%s")\n' % tupleArg)
fp.write(' )\n')
if is_varargs:
fp.write(' (varargs #t)\n')
fp.write(')\n\n')
return return
if prefix:
l = len(prefix) if self.prefix:
if name[:l] == prefix and name[l] == '_': l = len(self.prefix)
if name[:l] == self.prefix and name[l] == '_':
fname = name[l+1:] fname = name[l+1:]
else: else:
fname = name fname = name
else: else:
fname = name fname = name
# it is either a constructor or normal function # it is either a constructor or normal function
fp.write('(define-function ' + fname + '\n') self.fp.write('(define-function ' + fname + '\n')
fp.write(' (c-name "' + name + '")\n') self.fp.write(' (c-name "' + name + '")\n')
# Hmmm... Let's asume that a constructor function name # Hmmm... Let's asume that a constructor function name
# ends with '_new' and it returns a pointer. # ends with '_new' and it returns a pointer.
@ -404,12 +420,31 @@ def write_func(fp, name, ret, args, prefix):
for s in m.group(1).split ('_'): for s in m.group(1).split ('_'):
cname += s.title() cname += s.title()
if cname != '': if cname != '':
fp.write(' (is-constructor-of "' + cname + '")\n') self.fp.write(' (is-constructor-of "' + cname + '")\n')
self._write_return(ret)
self._write_arguments(args)
def _write_method(self, obj, name, ret, args):
regex = string.join(map(lambda x: x+'_?', string.lower(obj)),'')
mname = re.sub(regex, '', name, 1)
if self.prefix:
l = len(self.prefix) + 1
if mname[:l] == self.prefix and mname[l+1] == '_':
mname = mname[l+1:]
self.fp.write('(define-method ' + mname + '\n')
self.fp.write(' (of-object "' + obj + '")\n')
self.fp.write(' (c-name "' + name + '")\n')
self._write_return(ret)
self._write_arguments(args[1:])
def _write_return(self, ret):
if ret != 'void': if ret != 'void':
fp.write(' (return-type "' + ret + '")\n') self.fp.write(' (return-type "' + ret + '")\n')
else: else:
fp.write(' (return-type "none")\n') self.fp.write(' (return-type "none")\n')
def _write_arguments(self, args):
is_varargs = 0 is_varargs = 0
has_args = len(args) > 0 has_args = len(args) > 0
for arg in args: for arg in args:
@ -418,58 +453,43 @@ def write_func(fp, name, ret, args, prefix):
elif arg in ('void', 'void '): elif arg in ('void', 'void '):
has_args = 0 has_args = 0
if has_args: if has_args:
fp.write(' (parameters\n') self.fp.write(' (parameters\n')
for arg in args: for arg in args:
if arg != '...': if arg != '...':
tupleArg = tuple(string.split(arg)) tupleArg = tuple(string.split(arg))
if len(tupleArg) == 2: if len(tupleArg) == 2:
fp.write(' \'("%s" "%s")\n' % tupleArg) self.fp.write(' \'("%s" "%s")\n' % tupleArg)
fp.write(' )\n') self.fp.write(' )\n')
if is_varargs: if is_varargs:
fp.write(' (varargs #t)\n') self.fp.write(' (varargs #t)\n')
fp.write(')\n\n') self.fp.write(')\n\n')
def write_def(input,output=None, prefix=None):
fp = open(input)
buf = fp.read()
fp.close()
if type(output) == types.StringType:
fp = open(output,'w')
elif type(output) == types.FileType:
fp = output
else:
fp = sys.stdout
fp.write('\n;; From %s\n\n' % input)
buf = define_func(buf, fp, prefix)
fp.write('\n')
# ------------------ Main function ----------------- # ------------------ Main function -----------------
verbose=0
def main(args): def main(args):
import getopt verbose = False
global verbose onlyenums = False
onlyobjdefs = False
onlyenums = 0 separate = False
onlyobjdefs = 0
separate = 0
modulename = None modulename = None
opts, args = getopt.getopt(args[1:], 'vs:m:', defsfilter = None
opts, args = getopt.getopt(args[1:], 'vs:m:f:',
['onlyenums', 'onlyobjdefs', ['onlyenums', 'onlyobjdefs',
'modulename=', 'separate=']) 'modulename=', 'separate=',
'defsfilter='])
for o, v in opts: for o, v in opts:
if o == '-v': if o == '-v':
verbose = 1 verbose = True
if o == '--onlyenums': if o == '--onlyenums':
onlyenums = 1 onlyenums = True
if o == '--onlyobjdefs': if o == '--onlyobjdefs':
onlyobjdefs = 1 onlyobjdefs = True
if o in ('-s', '--separate'): if o in ('-s', '--separate'):
separate = v separate = v
if o in ('-m', '--modulename'): if o in ('-m', '--modulename'):
modulename = v modulename = v
if o in ('-f', '--defsfilter'):
defsfilter = v
if not args[0:1]: if not args[0:1]:
print 'Must specify at least one input file name' print 'Must specify at least one input file name'
@ -485,29 +505,32 @@ def main(args):
objdefs = sort_obj_defs(objdefs) objdefs = sort_obj_defs(objdefs)
if separate: if separate:
types = file(separate + '-types.defs', 'w')
methods = file(separate + '.defs', 'w') methods = file(separate + '.defs', 'w')
types = file(separate + '-types.defs', 'w')
write_obj_defs(objdefs,types) dw = DefsWriter(methods, prefix=modulename, verbose=verbose,
write_enum_defs(enums,types) defsfilter=defsfilter)
types.close() dw.write_obj_defs(objdefs, types)
dw.write_enum_defs(enums, types)
print "Wrote %s-types.defs" % separate print "Wrote %s-types.defs" % separate
for filename in args: for filename in args:
write_def(filename,methods,prefix=modulename) dw.write_def(filename)
methods.close()
print "Wrote %s.defs" % separate print "Wrote %s.defs" % separate
else: else:
dw = DefsWriter(prefix=modulename, verbose=verbose,
defsfilter=defsfilter)
if onlyenums: if onlyenums:
write_enum_defs(enums,None) dw.write_enum_defs(enums)
elif onlyobjdefs: elif onlyobjdefs:
write_obj_defs(objdefs,None) dw.write_obj_defs(objdefs)
else: else:
write_obj_defs(objdefs,None) dw.write_obj_defs(objdefs)
write_enum_defs(enums,None) dw.write_enum_defs(enums)
for filename in args: for filename in args:
write_def(filename,None,prefix=modulename) dw.write_def(filename)
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main(sys.argv)) sys.exit(main(sys.argv))

View File

@ -1,11 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- Mode: Python; py-indent-offset: 4 -*- # -*- Mode: Python; py-indent-offset: 4 -*-
import sys import optparse
import defsparser
from optparse import OptionParser
parser = OptionParser(usage="usage: %prog [options] generated-defs old-defs") import defsparser
parser = optparse.OptionParser(
usage="usage: %prog [options] generated-defs old-defs")
parser.add_option("-p", "--merge-parameters", parser.add_option("-p", "--merge-parameters",
help="Merge changes in function/methods parameter lists", help="Merge changes in function/methods parameter lists",
action="store_true", dest="parmerge", default=False) action="store_true", dest="parmerge", default=False)

View File

@ -1,17 +0,0 @@
#!/usr/bin/env python
# -*- Mode: Python; py-indent-offset: 4 -*-
import sys
import defsparser
if len(sys.argv) < 3:
sys.stderr.write("Usage: missingdefs.py generated-defs old-defs\n")
sys.exit(1)
newp = defsparser.DefsParser(sys.argv[1])
oldp = defsparser.DefsParser(sys.argv[2])
newp.startParsing()
oldp.startParsing()
newp.printMissing(oldp)

View File

@ -31,14 +31,19 @@ class Overrides:
self.overridden = {} self.overridden = {}
self.kwargs = {} self.kwargs = {}
self.noargs = {} self.noargs = {}
self.onearg = {}
self.staticmethod = {}
self.classmethod = {}
self.startlines = {} self.startlines = {}
self.override_attrs = {} self.override_attrs = {}
self.override_slots = {} self.override_slots = {}
self.headers = '' self.headers = ''
self.body = ''
self.init = '' self.init = ''
self.imports = [] self.imports = []
self.defines = {} self.defines = {}
self.functions = {} self.functions = {}
self.newstyle_constructors = {}
self.path = path self.path = path
if filename: if filename:
self.handle_file(filename) self.handle_file(filename)
@ -118,12 +123,21 @@ class Overrides:
for typename in string.split(rest): for typename in string.split(rest):
self.type_ignores[typename] = 1 self.type_ignores[typename] = 1
elif command == 'override': elif command == 'override':
"override function/method [kwargs,noargs]" "override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
func = words[1] func = words[1]
if 'kwargs' in words[1:]: if 'kwargs' in words[1:]:
self.kwargs[func] = 1 self.kwargs[func] = 1
elif 'noargs' in words[1:]: elif 'noargs' in words[1:]:
self.noargs[func] = 1 self.noargs[func] = 1
elif 'onearg' in words[1:]:
self.onearg[func] = True
if 'staticmethod' in words[1:]:
self.staticmethod[func] = True
elif 'classmethod' in words[1:]:
self.classmethod[func] = True
if func in self.overrides:
raise RuntimeError("Function %s is being overridden more than once" % (func,))
self.overrides[func] = rest self.overrides[func] = rest
self.startlines[func] = (startline + 1, filename) self.startlines[func] = (startline + 1, filename)
elif command == 'override-attr': elif command == 'override-attr':
@ -140,6 +154,10 @@ class Overrides:
"headers" "headers"
self.headers = '%s\n#line %d "%s"\n%s' % \ self.headers = '%s\n#line %d "%s"\n%s' % \
(self.headers, startline + 1, filename, rest) (self.headers, startline + 1, filename, rest)
elif command == 'body':
"body"
self.body = '%s\n#line %d "%s"\n%s' % \
(self.body, startline + 1, filename, rest)
elif command == 'init': elif command == 'init':
"init" "init"
self.init = '%s\n#line %d "%s"\n%s' % \ self.init = '%s\n#line %d "%s"\n%s' % \
@ -160,8 +178,8 @@ class Overrides:
if match: if match:
self.imports.append(match.groups()) self.imports.append(match.groups())
elif command == 'define': elif command == 'define':
"define funcname [kwargs,noargs]" "define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
"define Class.method [kwargs,noargs]" "define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
func = words[1] func = words[1]
klass = None klass = None
if func.find('.') != -1: if func.find('.') != -1:
@ -177,9 +195,21 @@ class Overrides:
self.kwargs[func] = 1 self.kwargs[func] = 1
elif 'noargs' in words[1:]: elif 'noargs' in words[1:]:
self.noargs[func] = 1 self.noargs[func] = 1
elif 'onearg' in words[1:]:
self.onearg[func] = 1
if 'staticmethod' in words[1:]:
self.staticmethod[func] = True
elif 'classmethod' in words[1:]:
self.classmethod[func] = True
self.startlines[func] = (startline + 1, filename) self.startlines[func] = (startline + 1, filename)
elif command == 'new-constructor':
"new-constructor GType"
gtype, = words[1:]
self.newstyle_constructors[gtype] = True
def is_ignored(self, name): def is_ignored(self, name):
if self.ignores.has_key(name): if self.ignores.has_key(name):
return 1 return 1
@ -217,6 +247,15 @@ class Overrides:
def wants_noargs(self, name): def wants_noargs(self, name):
return self.noargs.has_key(name) return self.noargs.has_key(name)
def wants_onearg(self, name):
return self.onearg.has_key(name)
def is_staticmethod(self, name):
return self.staticmethod.has_key(name)
def is_classmethod(self, name):
return self.classmethod.has_key(name)
def attr_is_overriden(self, attr): def attr_is_overriden(self, attr):
return self.override_attrs.has_key(attr) return self.override_attrs.has_key(attr)
@ -232,6 +271,9 @@ class Overrides:
def get_headers(self): def get_headers(self):
return self.headers return self.headers
def get_body(self):
return self.body
def get_init(self): def get_init(self):
return self.init return self.init

View File

@ -2,6 +2,9 @@
### Code to generate "Reverse Wrappers", i.e. C->Python wrappers ### Code to generate "Reverse Wrappers", i.e. C->Python wrappers
### (C) 2004 Gustavo Carneiro <gjc@gnome.org> ### (C) 2004 Gustavo Carneiro <gjc@gnome.org>
import argtypes import argtypes
import os
DEBUG_MODE = ('PYGTK_CODEGEN_DEBUG' in os.environ)
def join_ctype_name(ctype, name): def join_ctype_name(ctype, name):
'''Joins a C type and a variable name into a single string''' '''Joins a C type and a variable name into a single string'''
@ -83,10 +86,12 @@ class ReverseWrapper(object):
self.parameters = [] self.parameters = []
self.declarations = MemoryCodeSink() self.declarations = MemoryCodeSink()
self.post_return_code = MemoryCodeSink()
self.body = MemoryCodeSink() self.body = MemoryCodeSink()
self.cleanup_actions = [] self.cleanup_actions = []
self.pyargv_items = [] self.pyargv_items = []
self.pyargv_optional_items = [] self.pyargv_optional_items = []
self.pyret_parse_items = [] # list of (format_spec, parameter)
def set_call_target(self, called_pyobj, method_name=None): def set_call_target(self, called_pyobj, method_name=None):
assert called_pyobj is not None assert called_pyobj is not None
@ -111,10 +116,18 @@ class ReverseWrapper(object):
else: else:
self.pyargv_items.append(variable) self.pyargv_items.append(variable)
def add_pyret_parse_item(self, format_specifier, parameter, prepend=False):
if prepend:
self.pyret_parse_items.insert(0, (format_specifier, parameter))
else:
self.pyret_parse_items.append((format_specifier, parameter))
def write_code(self, code, def write_code(self, code,
cleanup=None, cleanup=None,
failure_expression=None, failure_expression=None,
failure_cleanup=None): failure_cleanup=None,
failure_exception=None,
code_sink=None):
'''Add a chunk of code with cleanup and error handling '''Add a chunk of code with cleanup and error handling
This method is to be used by TypeHandlers when generating code This method is to be used by TypeHandlers when generating code
@ -127,23 +140,39 @@ class ReverseWrapper(object):
if anything failed (default None) if anything failed (default None)
failure_cleanup -- code to cleanup any dynamic resources failure_cleanup -- code to cleanup any dynamic resources
created by @code in case of failure (default None) created by @code in case of failure (default None)
failure_exception -- code to raise an exception in case of
failure (which will be immediately
printed and cleared), (default None)
code_sink -- "code sink" to use; by default,
ReverseWrapper.body is used, which writes the
main body of the wrapper, before calling the
python method. Alternatively,
ReverseWrapper.after_pyret_parse can be used, to
write code after the PyArg_ParseTuple that
parses the python method return value.
''' '''
if code_sink is None:
code_sink = self.body
if code is not None: if code is not None:
self.body.writeln(code) code_sink.writeln(code)
if failure_expression is not None: if failure_expression is not None:
self.body.writeln("if (%s) {" % failure_expression) code_sink.writeln("if (%s) {" % (failure_expression,))
self.body.indent() code_sink.indent()
self.body.writeln("if (PyErr_Occurred())") if failure_exception is None:
self.body.indent() code_sink.writeln("if (PyErr_Occurred())")
self.body.writeln("PyErr_Print();") code_sink.indent()
self.body.unindent() code_sink.writeln("PyErr_Print();")
code_sink.unindent()
else:
code_sink.writeln(failure_exception)
code_sink.writeln("PyErr_Print();")
if failure_cleanup is not None: if failure_cleanup is not None:
self.body.writeln(failure_cleanup) code_sink.writeln(failure_cleanup)
for cleanup_action in self.cleanup_actions: for cleanup_action in self.cleanup_actions:
self.body.writeln(cleanup_action) code_sink.writeln(cleanup_action)
self.return_type.write_error_return() self.return_type.write_error_return()
self.body.unindent() code_sink.unindent()
self.body.writeln("}") code_sink.writeln("}")
if cleanup is not None: if cleanup is not None:
self.cleanup_actions.insert(0, cleanup) self.cleanup_actions.insert(0, cleanup)
@ -151,6 +180,11 @@ class ReverseWrapper(object):
'''Generate the code into a CodeSink object''' '''Generate the code into a CodeSink object'''
assert isinstance(sink, CodeSink) assert isinstance(sink, CodeSink)
if DEBUG_MODE:
self.declarations.writeln("/* begin declarations */")
self.body.writeln("/* begin main body */")
self.post_return_code.writeln("/* begin post-return code */")
self.add_declaration("PyGILState_STATE __py_state;") self.add_declaration("PyGILState_STATE __py_state;")
self.write_code(code="__py_state = pyg_gil_state_ensure();", self.write_code(code="__py_state = pyg_gil_state_ensure();",
cleanup="pyg_gil_state_release(__py_state);") cleanup="pyg_gil_state_release(__py_state);")
@ -227,7 +261,7 @@ class ReverseWrapper(object):
self.body.writeln() self.body.writeln()
# call it ## Call the python method
if self.method_name is None: if self.method_name is None:
self.write_code("py_retval = PyObject_Call(%s, %s);" self.write_code("py_retval = PyObject_Call(%s, %s);"
% (self.called_pyobj, py_args), % (self.called_pyobj, py_args),
@ -244,13 +278,43 @@ class ReverseWrapper(object):
cleanup="Py_DECREF(py_retval);", cleanup="Py_DECREF(py_retval);",
failure_expression="!py_retval") failure_expression="!py_retval")
## -- Handle the return value --
## we need to check if the return_type object is prepared to cooperate with multiple return values
len_before = len(self.pyret_parse_items)
self.return_type.write_conversion() self.return_type.write_conversion()
len_after = len(self.pyret_parse_items)
assert (self.return_type.get_c_type() == 'void'
or not (len_before == len_after and len_after > 0)),\
("Bug in reverse wrappers: return type handler %s"
" is not prepared to cooperate multiple return values") % (type(self.return_type),)
sink.indent() sink.indent()
if len(self.pyret_parse_items) == 1:
## if retval is one item only, pack it in a tuple so we
## can use PyArg_ParseTuple as usual..
self.write_code('py_retval = Py_BuildValue("(N)", py_retval);')
if len(self.pyret_parse_items) > 0:
## Parse return values using PyArg_ParseTuple
self.write_code(code=None, failure_expression=(
'!PyArg_ParseTuple(py_retval, "%s", %s)' % (
"".join([format for format, param in self.pyret_parse_items]),
", ".join([param for format, param in self.pyret_parse_items]))))
if DEBUG_MODE:
self.declarations.writeln("/* end declarations */")
self.declarations.flush_to(sink) self.declarations.flush_to(sink)
sink.writeln() sink.writeln()
if DEBUG_MODE:
self.body.writeln("/* end main body */")
self.body.flush_to(sink) self.body.flush_to(sink)
sink.writeln() sink.writeln()
if DEBUG_MODE:
self.post_return_code.writeln("/* end post-return code */")
self.post_return_code.flush_to(sink)
sink.writeln()
for cleanup_action in self.cleanup_actions: for cleanup_action in self.cleanup_actions:
sink.writeln(cleanup_action) sink.writeln(cleanup_action)
if self.return_type.get_c_type() != 'void': if self.return_type.get_c_type() != 'void':
@ -325,7 +389,7 @@ class StringParam(Parameter):
for ctype in ('char*', 'gchar*', 'const-char*', 'char-const*', 'const-gchar*', for ctype in ('char*', 'gchar*', 'const-char*', 'char-const*', 'const-gchar*',
'gchar-const*', 'string', 'static_string'): 'gchar-const*', 'string', 'static_string'):
argtypes.matcher.register_reverse(ctype, StringParam) argtypes.matcher.register_reverse(ctype, StringParam)
del ctype
class StringReturn(ReturnType): class StringReturn(ReturnType):
@ -339,15 +403,12 @@ class StringReturn(ReturnType):
self.wrapper.write_code("return NULL;") self.wrapper.write_code("return NULL;")
def write_conversion(self): def write_conversion(self):
self.wrapper.write_code( self.wrapper.add_pyret_parse_item("s", "&retval", prepend=True)
code=None, self.wrapper.write_code("retval = g_strdup(retval);", code_sink=self.wrapper.post_return_code)
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*'): for ctype in ('char*', 'gchar*'):
argtypes.matcher.register_reverse(ctype, StringReturn) argtypes.matcher.register_reverse_ret(ctype, StringReturn)
del ctype
class VoidReturn(ReturnType): class VoidReturn(ReturnType):
@ -401,6 +462,10 @@ class GObjectReturn(ReturnType):
self.wrapper.write_code("return NULL;") self.wrapper.write_code("return NULL;")
def write_conversion(self): def write_conversion(self):
self.wrapper.write_code(
code=None,
failure_expression="!PyObject_TypeCheck(py_retval, &PyGObject_Type)",
failure_exception='PyErr_SetString(PyExc_TypeError, "retval should be a GObject");')
self.wrapper.write_code("retval = (%s) pygobject_get(py_retval);" self.wrapper.write_code("retval = (%s) pygobject_get(py_retval);"
% self.get_c_type()) % self.get_c_type())
self.wrapper.write_code("g_object_ref((GObject *) retval);") self.wrapper.write_code("g_object_ref((GObject *) retval);")
@ -429,17 +494,35 @@ class IntReturn(ReturnType):
def write_error_return(self): def write_error_return(self):
self.wrapper.write_code("return -G_MAXINT;") self.wrapper.write_code("return -G_MAXINT;")
def write_conversion(self): def write_conversion(self):
self.wrapper.write_code( self.wrapper.add_pyret_parse_item("i", "&retval", prepend=True)
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', for argtype in ('int', 'gint', 'guint', 'short', 'gshort', 'gushort', 'long',
'glong', 'gsize', 'gssize', 'guint8', 'gint8', 'guint16', 'glong', 'gsize', 'gssize', 'guint8', 'gint8', 'guint16',
'gint16', 'gint32', 'GTime'): 'gint16', 'gint32', 'GTime'):
argtypes.matcher.register_reverse(argtype, IntParam) argtypes.matcher.register_reverse(argtype, IntParam)
argtypes.matcher.register_reverse_ret(argtype, IntReturn) argtypes.matcher.register_reverse_ret(argtype, IntReturn)
del argtype
class IntPtrParam(Parameter):
def __init__(self, wrapper, name, **props):
if "direction" not in props:
raise ValueError("cannot use int* parameter without direction")
if props["direction"] not in ("out", "inout"):
raise ValueError("cannot use int* parameter with direction '%s'" % (props["direction"],))
Parameter.__init__(self, wrapper, name, **props)
def get_c_type(self):
return self.props.get('c_type', 'int*')
def convert_c2py(self):
if self.props["direction"] == "inout":
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)
self.wrapper.add_pyret_parse_item("i", self.name)
for argtype in ('int*', 'gint*'):
argtypes.matcher.register_reverse(argtype, IntPtrParam)
del argtype
class GEnumReturn(IntReturn): class GEnumReturn(IntReturn):
@ -500,10 +583,13 @@ class BooleanReturn(ReturnType):
return "gboolean" return "gboolean"
def write_decl(self): def write_decl(self):
self.wrapper.add_declaration("gboolean retval;") self.wrapper.add_declaration("gboolean retval;")
self.wrapper.add_declaration("PyObject *py_main_retval;")
def write_error_return(self): def write_error_return(self):
self.wrapper.write_code("return FALSE;") self.wrapper.write_code("return FALSE;")
def write_conversion(self): def write_conversion(self):
self.wrapper.write_code("retval = PyObject_IsTrue(py_retval)? TRUE : FALSE;") self.wrapper.add_pyret_parse_item("O", "&py_main_retval", prepend=True)
self.wrapper.write_code("retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE;",
code_sink=self.wrapper.post_return_code)
argtypes.matcher.register_reverse_ret("gboolean", BooleanReturn) argtypes.matcher.register_reverse_ret("gboolean", BooleanReturn)
class BooleanParam(Parameter): class BooleanParam(Parameter):
@ -528,6 +614,21 @@ class DoubleParam(Parameter):
cleanup=("Py_DECREF(py_%s);" % self.name)) cleanup=("Py_DECREF(py_%s);" % self.name))
self.wrapper.add_pyargv_item("py_%s" % self.name) self.wrapper.add_pyargv_item("py_%s" % self.name)
class DoublePtrParam(Parameter):
def __init__(self, wrapper, name, **props):
if "direction" not in props:
raise ValueError("cannot use double* parameter without direction")
if props["direction"] not in ("out", ): # inout not yet implemented
raise ValueError("cannot use double* parameter with direction '%s'" % (props["direction"],))
Parameter.__init__(self, wrapper, name, **props)
def get_c_type(self):
return self.props.get('c_type', 'double*')
def convert_c2py(self):
self.wrapper.add_pyret_parse_item("d", self.name)
for argtype in ('double*', 'gdouble*'):
argtypes.matcher.register_reverse(argtype, DoublePtrParam)
del argtype
class DoubleReturn(ReturnType): class DoubleReturn(ReturnType):
def get_c_type(self): def get_c_type(self):
return self.props.get('c_type', 'gdouble') return self.props.get('c_type', 'gdouble')
@ -594,13 +695,13 @@ class GdkRectanglePtrParam(Parameter):
def convert_c2py(self): def convert_c2py(self):
self.wrapper.add_declaration("PyObject *py_%s;" % self.name) self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
self.wrapper.write_code( self.wrapper.write_code(
code=('py_%(name)s = Py_BuildValue("(ffff)", %(name)s->x, %(name)s->y,\n' code=('py_%s = pyg_boxed_new(GDK_TYPE_RECTANGLE, %s, TRUE, TRUE);' %
' %(name)s->width, %(name)s->height);' (self.name, self.name)),
% dict(name=self.name)),
cleanup=("Py_DECREF(py_%s);" % self.name)) cleanup=("Py_DECREF(py_%s);" % self.name))
self.wrapper.add_pyargv_item("py_%s" % self.name) self.wrapper.add_pyargv_item("py_%s" % self.name)
argtypes.matcher.register_reverse("GdkRectangle*", GdkRectanglePtrParam) argtypes.matcher.register_reverse("GdkRectangle*", GdkRectanglePtrParam)
argtypes.matcher.register_reverse('GtkAllocation*', GdkRectanglePtrParam)
class PyGObjectMethodParam(Parameter): class PyGObjectMethodParam(Parameter):
@ -649,13 +750,16 @@ class CallbackInUserDataParam(Parameter):
def _test(): def _test():
import sys import sys
if 1:
wrapper = ReverseWrapper("this_is_the_c_function_name", is_static=True) wrapper = ReverseWrapper("this_is_the_c_function_name", is_static=True)
wrapper.set_return_type(StringReturn(wrapper)) wrapper.set_return_type(StringReturn(wrapper))
wrapper.add_parameter(PyGObjectMethodParam(wrapper, "self", method_name="do_xxx")) wrapper.add_parameter(PyGObjectMethodParam(wrapper, "self", method_name="do_xxx"))
wrapper.add_parameter(StringParam(wrapper, "param2", optional=True)) wrapper.add_parameter(StringParam(wrapper, "param2", optional=True))
wrapper.add_parameter(GObjectParam(wrapper, "param3")) wrapper.add_parameter(GObjectParam(wrapper, "param3"))
#wrapper.add_parameter(InoutIntParam(wrapper, "param4"))
wrapper.generate(FileCodeSink(sys.stderr)) wrapper.generate(FileCodeSink(sys.stderr))
if 0:
wrapper = ReverseWrapper("this_a_callback_wrapper") wrapper = ReverseWrapper("this_a_callback_wrapper")
wrapper.set_return_type(VoidReturn(wrapper)) wrapper.set_return_type(VoidReturn(wrapper))
wrapper.add_parameter(StringParam(wrapper, "param1", optional=False)) wrapper.add_parameter(StringParam(wrapper, "param1", optional=False))

View File

@ -74,8 +74,8 @@
(c-name "gst_bin_new") (c-name "gst_bin_new")
(is-constructor-of "GstBin") (is-constructor-of "GstBin")
(return-type "GstElement*") (return-type "GstElement*")
(parameters (properties
'("const-gchar*" "name" (null-ok) (default "NULL")) '("name" (argname "name") (optional))
) )
) )
@ -2342,10 +2342,10 @@
(c-name "gst_index_factory_new") (c-name "gst_index_factory_new")
(is-constructor-of "GstIndexFactory") (is-constructor-of "GstIndexFactory")
(return-type "GstIndexFactory*") (return-type "GstIndexFactory*")
(parameters (properties
'("const-gchar*" "name") '("name" (argname "name"))
'("const-gchar*" "longdesc") '("longdesc" (argname "longdesc"))
'("GType" "type") '("type" (argname "type"))
) )
) )
@ -3324,9 +3324,9 @@
(c-name "gst_pad_new") (c-name "gst_pad_new")
(is-constructor-of "GstPad") (is-constructor-of "GstPad")
(return-type "GstPad*") (return-type "GstPad*")
(parameters (properties
'("const-gchar*" "name") '("name" (argname "name"))
'("GstPadDirection" "direction") '("direction" (argname "direction"))
) )
) )
@ -4043,8 +4043,8 @@
(c-name "gst_pipeline_new") (c-name "gst_pipeline_new")
(is-constructor-of "GstPipeline") (is-constructor-of "GstPipeline")
(return-type "GstElement*") (return-type "GstElement*")
(parameters (properties
'("const-gchar*" "name" (null-ok) (default "NULL")) '("name" (argname "name") (optional))
) )
) )

View File

@ -552,6 +552,8 @@ _wrap_gst_registry_get_feature_list_by_plugin (PyGObject *self, PyObject *args,
return list; return list;
} }
%%
new-constructor GST_TYPE_XML
%% %%
override gst_xml_new noargs override gst_xml_new noargs

View File

@ -506,6 +506,8 @@ _wrap_gst_pad_template_get_caps_by_name(PyGObject *self, PyObject *args, PyObjec
return pyg_boxed_new(GST_TYPE_CAPS, ret, TRUE, TRUE); return pyg_boxed_new(GST_TYPE_CAPS, ret, TRUE, TRUE);
} }
%% %%
new-constructor GST_TYPE_PAD
%%
override gst_pad_new kwargs override gst_pad_new kwargs
static int static int
_wrap_gst_pad_new(PyGObject *self, PyObject *args, PyObject *kwargs) _wrap_gst_pad_new(PyGObject *self, PyObject *args, PyObject *kwargs)
@ -658,7 +660,7 @@ _wrap_gst_pad_template_tp_getattr(PyObject *self, char *attr)
} else if (IS_ATTR ("caps")) { } else if (IS_ATTR ("caps")) {
return pyg_boxed_new (GST_TYPE_CAPS, GST_PAD_TEMPLATE_CAPS(templ), TRUE, TRUE); return pyg_boxed_new (GST_TYPE_CAPS, GST_PAD_TEMPLATE_CAPS(templ), TRUE, TRUE);
} }
return Py_FindMethod(_PyGstPadTemplate_methods, self, attr); return Py_FindMethod((PyMethodDef*) _PyGstPadTemplate_methods, self, attr);
} }
%% %%
override gst_pad_query_position args override gst_pad_query_position args

View File

@ -186,8 +186,11 @@ class ConstructorTest(TestCase):
bin = gst.Bin('myname') bin = gst.Bin('myname')
def testBad(self): def testBad(self):
self.assertRaises(TypeError, gst.Bin, 0) # these are now valid. pygobject will take care of converting
self.assertRaises(TypeError, gst.Bin, gst.Bin()) # the arguments to a string.
#self.assertRaises(TypeError, gst.Bin, 0)
#self.assertRaises(TypeError, gst.Bin, gst.Bin())
pass
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()