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,31 +1,29 @@
# -*- 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
class VarList: class VarList:
"""Nicely format a C variable list""" """Nicely format a C variable list"""
def __init__(self): def __init__(self):
self.vars = {} self.vars = {}
def add(self, ctype, name): def add(self, ctype, name):
if self.vars.has_key(ctype): if self.vars.has_key(ctype):
self.vars[ctype] = self.vars[ctype] + (name,) self.vars[ctype] = self.vars[ctype] + (name,)
else: else:
self.vars[ctype] = (name,) self.vars[ctype] = (name,)
def __str__(self): def __str__(self):
ret = [] ret = []
for type in self.vars.keys(): for type in self.vars.keys():
ret.append(' ') ret.append(' ')
ret.append(type) ret.append(type)
ret.append(' ') ret.append(' ')
ret.append(string.join(self.vars[type], ', ')) ret.append(string.join(self.vars[type], ', '))
ret.append(';\n') ret.append(';\n')
if ret: if ret:
ret.append('\n') ret.append('\n')
return string.join(ret, '') return string.join(ret, '')
return '' return ''
class WrapperInfo: class WrapperInfo:
"""A class that holds information about variable defs, code """A class that holds information about variable defs, code
@ -66,16 +64,16 @@ 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" % \
self.__class__.__name__ self.__class__.__name__
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
"""Adds a variable named ret of the return type to """Adds a variable named ret of the return type to
info.varlist, and add any required code to info.codeafter to info.varlist, and add any required code to info.codeafter to
convert the return value to a python object.""" convert the return value to a python object."""
raise RuntimeError, "write_return not implemented for %s" % \ raise RuntimeError, "write_return not implemented for %s" % \
self.__class__.__name__ self.__class__.__name__
class NoneArg(ArgType): class NoneArg(ArgType):
@ -85,20 +83,20 @@ class NoneArg(ArgType):
class StringArg(ArgType): class StringArg(ArgType):
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pdflt: if pdflt:
if pdflt != 'NULL': pdflt = '"' + pdflt + '"' if pdflt != 'NULL': pdflt = '"' + pdflt + '"'
info.varlist.add('char', '*' + pname + ' = ' + pdflt) info.varlist.add('char', '*' + pname + ' = ' + pdflt)
else: else:
info.varlist.add('char', '*' + pname) info.varlist.add('char', '*' + pname)
info.arglist.append(pname) info.arglist.append(pname)
if pnull: if pnull:
info.add_parselist('z', ['&' + pname], [pname]) info.add_parselist('z', ['&' + pname], [pname])
else: else:
info.add_parselist('s', ['&' + pname], [pname]) info.add_parselist('s', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
if ownsreturn: if ownsreturn:
# have to free result ... # have to free result ...
info.varlist.add('gchar', '*ret') info.varlist.add('gchar', '*ret')
info.codeafter.append(' if (ret) {\n' + info.codeafter.append(' if (ret) {\n' +
' PyObject *py_ret = PyString_FromString(ret);\n' + ' PyObject *py_ret = PyString_FromString(ret);\n' +
' g_free(ret);\n' + ' g_free(ret);\n' +
@ -106,8 +104,8 @@ class StringArg(ArgType):
' }\n' + ' }\n' +
' Py_INCREF(Py_None);\n' + ' Py_INCREF(Py_None);\n' +
' return Py_None;') ' return Py_None;')
else: else:
info.varlist.add('const gchar', '*ret') info.varlist.add('const gchar', '*ret')
info.codeafter.append(' if (ret)\n' + info.codeafter.append(' if (ret)\n' +
' return PyString_FromString(ret);\n'+ ' return PyString_FromString(ret);\n'+
' Py_INCREF(Py_None);\n' + ' Py_INCREF(Py_None);\n' +
@ -116,29 +114,29 @@ class StringArg(ArgType):
class UCharArg(ArgType): class UCharArg(ArgType):
# allows strings with embedded NULLs. # allows strings with embedded NULLs.
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('guchar', '*' + pname + ' = "' + pdflt + '"') info.varlist.add('guchar', '*' + pname + ' = "' + pdflt + '"')
else: else:
info.varlist.add('guchar', '*' + pname) info.varlist.add('guchar', '*' + pname)
info.varlist.add('int', pname + '_len') info.varlist.add('int', pname + '_len')
info.arglist.append(pname) info.arglist.append(pname)
if pnull: if pnull:
info.add_parselist('z#', ['&' + pname, '&' + pname + '_len'], info.add_parselist('z#', ['&' + pname, '&' + pname + '_len'],
[pname]) [pname])
else: else:
info.add_parselist('s#', ['&' + pname, '&' + pname + '_len'], info.add_parselist('s#', ['&' + pname, '&' + pname + '_len'],
[pname]) [pname])
class CharArg(ArgType): class CharArg(ArgType):
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('char', pname + " = '" + pdflt + "'") info.varlist.add('char', pname + " = '" + pdflt + "'")
else: else:
info.varlist.add('char', pname) info.varlist.add('char', pname)
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('c', ['&' + pname], [pname]) info.add_parselist('c', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('gchar', 'ret') info.varlist.add('gchar', 'ret')
info.codeafter.append(' return PyString_FromStringAndSize(&ret, 1);') info.codeafter.append(' return PyString_FromStringAndSize(&ret, 1);')
class GUniCharArg(ArgType): class GUniCharArg(ArgType):
ret_tmpl = ('#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2\n' ret_tmpl = ('#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2\n'
@ -150,25 +148,25 @@ class GUniCharArg(ArgType):
' py_ret = (Py_UNICODE)ret;\n' ' py_ret = (Py_UNICODE)ret;\n'
' return PyUnicode_FromUnicode(&py_ret, 1);\n') ' return PyUnicode_FromUnicode(&py_ret, 1);\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('gunichar', pname + " = '" + pdflt + "'") info.varlist.add('gunichar', pname + " = '" + pdflt + "'")
else: else:
info.varlist.add('gunichar', pname) info.varlist.add('gunichar', pname)
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O&', ['pyg_pyobj_to_unichar_conv', '&' + pname], [pname]) info.add_parselist('O&', ['pyg_pyobj_to_unichar_conv', '&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('gunichar', 'ret') info.varlist.add('gunichar', 'ret')
info.varlist.add('Py_UNICODE', 'py_ret') info.varlist.add('Py_UNICODE', 'py_ret')
info.codeafter.append(self.ret_tmpl) info.codeafter.append(self.ret_tmpl)
class IntArg(ArgType): class IntArg(ArgType):
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('int', pname + ' = ' + pdflt) info.varlist.add('int', pname + ' = ' + pdflt)
else: else:
info.varlist.add('int', pname) info.varlist.add('int', pname)
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('i', ['&' + pname], [pname]) info.add_parselist('i', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('int', 'ret') info.varlist.add('int', 'ret')
@ -212,13 +210,13 @@ class SizeArg(ArgType):
llp64 = True llp64 = True
else: else:
llp64 = False llp64 = False
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(ptype, pname + ' = ' + pdflt) info.varlist.add(ptype, pname + ' = ' + pdflt)
else: else:
info.varlist.add(ptype, pname) info.varlist.add(ptype, pname)
info.arglist.append(pname) info.arglist.append(pname)
if self.llp64: if self.llp64:
info.add_parselist('k', ['&' + pname], [pname]) info.add_parselist('k', ['&' + pname], [pname])
else: else:
@ -236,13 +234,13 @@ class SSizeArg(ArgType):
llp64 = True llp64 = True
else: else:
llp64 = False llp64 = False
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(ptype, pname + ' = ' + pdflt) info.varlist.add(ptype, pname + ' = ' + pdflt)
else: else:
info.varlist.add(ptype, pname) info.varlist.add(ptype, pname)
info.arglist.append(pname) info.arglist.append(pname)
if self.llp64: if self.llp64:
info.add_parselist('l', ['&' + pname], [pname]) info.add_parselist('l', ['&' + pname], [pname])
else: else:
@ -256,11 +254,11 @@ class SSizeArg(ArgType):
class LongArg(ArgType): class LongArg(ArgType):
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(ptype, pname + ' = ' + pdflt) info.varlist.add(ptype, pname + ' = ' + pdflt)
else: else:
info.varlist.add(ptype, pname) info.varlist.add(ptype, pname)
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('l', ['&' + pname], [pname]) info.add_parselist('l', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add(ptype, 'ret') info.varlist.add(ptype, 'ret')
@ -273,66 +271,80 @@ class BoolArg(IntArg):
class TimeTArg(ArgType): class TimeTArg(ArgType):
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('time_t', pname + ' = ' + pdflt) info.varlist.add('time_t', pname + ' = ' + pdflt)
else: else:
info.varlist.add('time_t', pname) info.varlist.add('time_t', pname)
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('i', ['&' + pname], [pname]) info.add_parselist('i', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('time_t', 'ret') info.varlist.add('time_t', 'ret')
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):
if pdflt: if pdflt:
info.varlist.add('gint64', pname + ' = ' + pdflt) info.varlist.add('gint64', pname + ' = ' + pdflt)
else: else:
info.varlist.add('gint64', pname) info.varlist.add('gint64', pname)
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('L', ['&' + pname], [pname]) info.add_parselist('L', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('gint64', 'ret') info.varlist.add('gint64', 'ret')
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)
else: info.codebefore.append(self.dflt % {'name':pname})
info.varlist.add('guint64', pname) else:
info.arglist.append(pname) info.varlist.add('guint64', pname)
info.add_parselist('K', ['&' + pname], [pname]) info.codebefore.append(self.before % {'name':pname})
info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
info.arglist.append(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);')
class DoubleArg(ArgType): class DoubleArg(ArgType):
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('double', pname + ' = ' + pdflt) info.varlist.add('double', pname + ' = ' + pdflt)
else: else:
info.varlist.add('double', pname) info.varlist.add('double', pname)
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('d', ['&' + pname], [pname]) info.add_parselist('d', ['&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('double', 'ret') info.varlist.add('double', 'ret')
@ -345,7 +357,7 @@ class FileArg(ArgType):
' %s = PyFile_AsFile(py_%(name)s);\n' ' %s = PyFile_AsFile(py_%(name)s);\n'
' else if (py_%(name)s) {\n' ' else if (py_%(name)s) {\n'
' PyErr_SetString(PyExc_TypeError, "%(name)s should be a file object or None");\n' ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a file object or None");\n'
' return NULL;\n' ' return NULL;\n'
' }') ' }')
null = (' if (py_%(name)s && PyFile_Check(py_%(name)s)\n' null = (' if (py_%(name)s && PyFile_Check(py_%(name)s)\n'
' %(name)s = PyFile_AsFile(py_%(name)s);\n' ' %(name)s = PyFile_AsFile(py_%(name)s);\n'
@ -356,29 +368,29 @@ class FileArg(ArgType):
dflt = (' if (py_%(name)s)\n' dflt = (' if (py_%(name)s)\n'
' %(name)s = PyFile_AsFile(py_%(name)s);\n') ' %(name)s = PyFile_AsFile(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 pnull: if pnull:
if pdflt: if pdflt:
info.varlist.add('FILE', '*' + pname + ' = ' + pdflt) info.varlist.add('FILE', '*' + pname + ' = ' + pdflt)
info.varlist.add('PyObject', '*py_' + pname + ' = NULL') info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
info.codebefore.append(self.nulldflt % {'name':pname}) info.codebefore.append(self.nulldflt % {'name':pname})
else: else:
info.varlist.add('FILE', '*' + pname + ' = NULL') info.varlist.add('FILE', '*' + pname + ' = NULL')
info.varlist.add('PyObject', '*py_' + pname) info.varlist.add('PyObject', '*py_' + pname)
info.codebefore.append(self.null & {'name':pname}) info.codebefore.append(self.null & {'name':pname})
info.arglist.appned(pname) info.arglist.appned(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
else: else:
if pdflt: if pdflt:
info.varlist.add('FILE', '*' + pname + ' = ' + pdflt) info.varlist.add('FILE', '*' + pname + ' = ' + pdflt)
info.varlist.add('PyObject', '*py_' + pname + ' = NULL') info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
info.codebefore.append(self.dflt % {'name':pname}) info.codebefore.append(self.dflt % {'name':pname})
info.arglist.append(pname) info.arglist.append(pname)
else: else:
info.varlist.add('PyObject', '*' + pname) info.varlist.add('PyObject', '*' + pname)
info.arglist.append('PyFile_AsFile(' + pname + ')') info.arglist.append('PyFile_AsFile(' + pname + ')')
info.add_parselist('O!', ['&PyFile_Type', '&' + pname], [pname]) info.add_parselist('O!', ['&PyFile_Type', '&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('FILE', '*ret') info.varlist.add('FILE', '*ret')
info.codeafter.append(' if (ret)\n' + info.codeafter.append(' if (ret)\n' +
' return PyFile_FromFile(ret, "", "", fclose);\n' + ' return PyFile_FromFile(ret, "", "", fclose);\n' +
' Py_INCREF(Py_None);\n' + ' Py_INCREF(Py_None);\n' +
@ -388,17 +400,17 @@ class EnumArg(ArgType):
enum = (' if (pyg_enum_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n' enum = (' if (pyg_enum_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
' return NULL;\n') ' return NULL;\n')
def __init__(self, enumname, typecode): def __init__(self, enumname, typecode):
self.enumname = enumname self.enumname = enumname
self.typecode = typecode self.typecode = typecode
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(self.enumname, pname + ' = ' + pdflt) info.varlist.add(self.enumname, pname + ' = ' + pdflt)
else: else:
info.varlist.add(self.enumname, pname) info.varlist.add(self.enumname, pname)
info.varlist.add('PyObject', '*py_' + pname + ' = NULL') info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
info.codebefore.append(self.enum % { 'typecode': self.typecode, info.codebefore.append(self.enum % { 'typecode': self.typecode,
'name': pname}) 'name': pname})
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]); info.add_parselist('O', ['&py_' + pname], [pname]);
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('gint', 'ret') info.varlist.add('gint', 'ret')
@ -408,20 +420,20 @@ class FlagsArg(ArgType):
flag = (' if (%(default)spyg_flags_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n' flag = (' if (%(default)spyg_flags_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
' return NULL;\n') ' return NULL;\n')
def __init__(self, flagname, typecode): def __init__(self, flagname, typecode):
self.flagname = flagname self.flagname = flagname
self.typecode = typecode self.typecode = typecode
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(self.flagname, pname + ' = ' + pdflt) info.varlist.add(self.flagname, pname + ' = ' + pdflt)
default = "py_%s && " % (pname,) default = "py_%s && " % (pname,)
else: else:
info.varlist.add(self.flagname, pname) info.varlist.add(self.flagname, pname)
default = "" default = ""
info.varlist.add('PyObject', '*py_' + pname + ' = NULL') info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
info.codebefore.append(self.flag % {'default':default, info.codebefore.append(self.flag % {'default':default,
'typecode':self.typecode, 'typecode':self.typecode,
'name':pname}) 'name':pname})
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('guint', 'ret') info.varlist.add('guint', 'ret')
@ -447,42 +459,57 @@ class ObjectArg(ArgType):
dflt = ' if (py_%(name)s)\n' \ dflt = ' if (py_%(name)s)\n' \
' %(name)s = %(cast)s(py_%(name)s->obj);\n' ' %(name)s = %(cast)s(py_%(name)s->obj);\n'
def __init__(self, objname, parent, typecode): def __init__(self, objname, parent, typecode):
self.objname = objname self.objname = objname
self.cast = string.replace(typecode, '_TYPE_', '_', 1) self.cast = string.replace(typecode, '_TYPE_', '_', 1)
self.parent = parent self.parent = parent
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pnull: if pnull:
if pdflt: if pdflt:
info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt) info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
info.varlist.add('PyGObject', '*py_' + pname + ' = NULL') info.varlist.add('PyGObject', '*py_' + pname + ' = NULL')
info.codebefore.append(self.nulldflt % {'name':pname, info.codebefore.append(self.nulldflt % {'name':pname,
'cast':self.cast, 'cast':self.cast,
'type':self.objname}) 'type':self.objname})
else: else:
info.varlist.add(self.objname, '*' + pname + ' = NULL') info.varlist.add(self.objname, '*' + pname + ' = NULL')
info.varlist.add('PyGObject', '*py_' + pname) info.varlist.add('PyGObject', '*py_' + pname)
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})
info.arglist.append(pname) 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.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
else: else:
if pdflt: if pdflt:
info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt) info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
info.varlist.add('PyGObject', '*py_' + pname + ' = NULL') info.varlist.add('PyGObject', '*py_' + pname + ' = NULL')
info.codebefore.append(self.dflt % {'name':pname, info.codebefore.append(self.dflt % {'name':pname,
'cast':self.cast}) 'cast':self.cast})
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O!', ['&Py%s_Type' % self.objname, info.add_parselist('O!', ['&Py%s_Type' % self.objname,
'&py_' + pname], [pname]) '&py_' + pname], [pname])
else: else:
info.varlist.add('PyGObject', '*' + pname) info.varlist.add('PyGObject', '*' + pname)
info.arglist.append('%s(%s->obj)' % (self.cast, pname)) info.arglist.append('%s(%s->obj)' % (self.cast, pname))
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})
info.arglist.append(pname) 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.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'
@ -578,19 +620,19 @@ class BoxedArg(ArgType):
' return NULL;\n' ' return NULL;\n'
' }\n') ' }\n')
def __init__(self, ptype, typecode): def __init__(self, ptype, typecode):
self.typename = ptype self.typename = ptype
self.typecode = typecode self.typecode = typecode
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pnull: if pnull:
info.varlist.add(self.typename, '*' + pname + ' = NULL') info.varlist.add(self.typename, '*' + pname + ' = NULL')
info.varlist.add('PyObject', '*py_' + pname + ' = Py_None') info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
info.codebefore.append(self.null % {'name': pname, info.codebefore.append(self.null % {'name': pname,
'typename': self.typename, 'typename': self.typename,
'typecode': self.typecode}) 'typecode': self.typecode})
else: else:
info.varlist.add(self.typename, '*' + pname + ' = NULL') info.varlist.add(self.typename, '*' + pname + ' = NULL')
info.varlist.add('PyObject', '*py_' + pname) info.varlist.add('PyObject', '*py_' + pname)
info.codebefore.append(self.check % {'name': pname, info.codebefore.append(self.check % {'name': pname,
'typename': self.typename, 'typename': self.typename,
'typecode': self.typecode}) 'typecode': self.typecode})
if ptype[-1] == '*': if ptype[-1] == '*':
@ -627,23 +669,23 @@ class CustomBoxedArg(ArgType):
' return NULL;\n' ' return NULL;\n'
' }\n') ' }\n')
def __init__(self, ptype, pytype, getter, new): def __init__(self, ptype, pytype, getter, new):
self.pytype = pytype self.pytype = pytype
self.getter = getter self.getter = getter
self.checker = 'Py' + ptype + '_Check' self.checker = 'Py' + ptype + '_Check'
self.new = new self.new = new
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pnull: if pnull:
info.varlist.add(ptype[:-1], '*' + pname + ' = NULL') info.varlist.add(ptype[:-1], '*' + pname + ' = NULL')
info.varlist.add('PyObject', '*py_' + pname + ' = Py_None') info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
info.codebefore.append(self.null % {'name': pname, info.codebefore.append(self.null % {'name': pname,
'get': self.getter, 'get': self.getter,
'check': self.checker, 'check': self.checker,
'type': ptype[:-1]}) 'type': ptype[:-1]})
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
else: else:
info.varlist.add('PyObject', '*' + pname) info.varlist.add('PyObject', '*' + pname)
info.arglist.append(self.getter + '(' + pname + ')') info.arglist.append(self.getter + '(' + pname + ')')
info.add_parselist('O!', ['&' + self.pytype, '&' + pname], [pname]) info.add_parselist('O!', ['&' + self.pytype, '&' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add(ptype[:-1], '*ret') info.varlist.add(ptype[:-1], '*ret')
@ -667,19 +709,19 @@ class PointerArg(ArgType):
' return NULL;\n' ' return NULL;\n'
' }\n') ' }\n')
def __init__(self, ptype, typecode): def __init__(self, ptype, typecode):
self.typename = ptype self.typename = ptype
self.typecode = typecode self.typecode = typecode
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pnull: if pnull:
info.varlist.add(self.typename, '*' + pname + ' = NULL') info.varlist.add(self.typename, '*' + pname + ' = NULL')
info.varlist.add('PyObject', '*py_' + pname + ' = Py_None') info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
info.codebefore.append(self.null % {'name': pname, info.codebefore.append(self.null % {'name': pname,
'typename': self.typename, 'typename': self.typename,
'typecode': self.typecode}) 'typecode': self.typecode})
else: else:
info.varlist.add(self.typename, '*' + pname + ' = NULL') info.varlist.add(self.typename, '*' + pname + ' = NULL')
info.varlist.add('PyObject', '*py_' + pname) info.varlist.add('PyObject', '*py_' + pname)
info.codebefore.append(self.check % {'name': pname, info.codebefore.append(self.check % {'name': pname,
'typename': self.typename, 'typename': self.typename,
'typecode': self.typecode}) 'typecode': self.typecode})
info.arglist.append(pname) info.arglist.append(pname)
@ -716,16 +758,21 @@ 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'
' return NULL;\n') ' return NULL;\n')
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
info.varlist.add('GType', pname) info.varlist.add('GType', pname)
info.varlist.add('PyObject', '*py_' + pname + ' = NULL') info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
info.codebefore.append(self.gtype % {'name': pname}) info.codebefore.append(self.gtype % {'name': pname})
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('GType', 'ret') info.varlist.add('GType', 'ret')
@ -759,17 +806,17 @@ class GtkTreePathArg(ArgType):
def __init__(self): def __init__(self):
pass pass
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
if pnull: if pnull:
info.varlist.add('GtkTreePath', '*' + pname + ' = NULL') info.varlist.add('GtkTreePath', '*' + pname + ' = NULL')
info.varlist.add('PyObject', '*py_' + pname + ' = Py_None') info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
info.codebefore.append(self.null % {'name': pname}) info.codebefore.append(self.null % {'name': pname})
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
else: else:
info.varlist.add('GtkTreePath', '*' + pname) info.varlist.add('GtkTreePath', '*' + pname)
info.varlist.add('PyObject', '*py_' + pname) info.varlist.add('PyObject', '*py_' + pname)
info.codebefore.append(self.normal % {'name': pname}) info.codebefore.append(self.normal % {'name': pname})
info.arglist.append(pname) info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname]) info.add_parselist('O', ['&py_' + pname], [pname])
info.codeafter.append(self.freepath % {'name': pname}) info.codeafter.append(self.freepath % {'name': pname})
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
@ -789,7 +836,7 @@ class GtkTreePathArg(ArgType):
' }\n' ' }\n'
' Py_INCREF(Py_None);\n' ' Py_INCREF(Py_None);\n'
' return Py_None;') ' return Py_None;')
class GdkRectanglePtrArg(ArgType): class GdkRectanglePtrArg(ArgType):
normal = (' if (!pygdk_rectangle_from_pyobject(py_%(name)s, &%(name)s))\n' normal = (' if (!pygdk_rectangle_from_pyobject(py_%(name)s, &%(name)s))\n'
' return NULL;\n') ' return NULL;\n')
@ -816,8 +863,8 @@ class GdkRectanglePtrArg(ArgType):
class GdkRectangleArg(ArgType): class GdkRectangleArg(ArgType):
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('GdkRectangle', 'ret') info.varlist.add('GdkRectangle', 'ret')
info.codeafter.append(' return pyg_boxed_new(GDK_TYPE_RECTANGLE, &ret, TRUE, TRUE);') info.codeafter.append(' return pyg_boxed_new(GDK_TYPE_RECTANGLE, &ret, TRUE, TRUE);')
class PyObjectArg(ArgType): class PyObjectArg(ArgType):
def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info): def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
@ -839,17 +886,17 @@ class PyObjectArg(ArgType):
class ArgMatcher: class ArgMatcher:
def __init__(self): def __init__(self):
self.argtypes = {} self.argtypes = {}
self.reverse_argtypes = {} self.reverse_argtypes = {}
self.reverse_rettypes = {} self.reverse_rettypes = {}
def register(self, ptype, handler): def register(self, ptype, handler):
self.argtypes[ptype] = handler self.argtypes[ptype] = handler
def register_reverse(self, ptype, handler): def register_reverse(self, ptype, handler):
self.reverse_argtypes[ptype] = handler self.reverse_argtypes[ptype] = handler
def register_reverse_ret(self, ptype, handler): def register_reverse_ret(self, ptype, handler):
self.reverse_rettypes[ptype] = handler self.reverse_rettypes[ptype] = handler
def register_enum(self, ptype, typecode): def register_enum(self, ptype, typecode):
if typecode is None: if typecode is None:
typecode = "G_TYPE_NONE" typecode = "G_TYPE_NONE"
@ -857,11 +904,12 @@ class ArgMatcher:
def register_flag(self, ptype, typecode): def register_flag(self, ptype, typecode):
if typecode is None: if typecode is None:
typecode = "G_TYPE_NONE" typecode = "G_TYPE_NONE"
self.register(ptype, FlagsArg(ptype, typecode)) self.register(ptype, FlagsArg(ptype, typecode))
def register_object(self, ptype, parent, typecode): def register_object(self, ptype, parent, typecode):
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)
@ -874,16 +922,16 @@ class ArgMatcher:
if self.argtypes.has_key(ptype): return if self.argtypes.has_key(ptype): return
arg = BoxedArg(ptype, typecode) arg = BoxedArg(ptype, typecode)
self.register(ptype, arg) self.register(ptype, arg)
self.register(ptype+'*', arg) self.register(ptype+'*', arg)
self.register('const-'+ptype+'*', arg) self.register('const-'+ptype+'*', arg)
def register_custom_boxed(self, ptype, pytype, getter, new): def register_custom_boxed(self, ptype, pytype, getter, new):
arg = CustomBoxedArg(ptype, pytype, getter, new) arg = CustomBoxedArg(ptype, pytype, getter, new)
self.register(ptype+'*', arg) self.register(ptype+'*', arg)
self.register('const-'+ptype+'*', arg) self.register('const-'+ptype+'*', arg)
def register_pointer(self, ptype, typecode): def register_pointer(self, ptype, typecode):
arg = PointerArg(ptype, typecode) arg = PointerArg(ptype, typecode)
self.register(ptype, arg) self.register(ptype, arg)
self.register(ptype+'*', arg) self.register(ptype+'*', arg)
self.register('const-'+ptype+'*', arg) self.register('const-'+ptype+'*', arg)
def get(self, ptype): def get(self, ptype):
@ -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,16 +47,17 @@ 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"""
raise RuntimeError, "this is an abstract class" raise RuntimeError, "this is an abstract class"
def merge(self, old): def merge(self, old):
"""Merge in customisations from older version of definition""" """Merge in customisations from older version of definition"""
raise RuntimeError, "this is an abstract class" raise RuntimeError, "this is an abstract class"
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
"""write out this definition in defs file format""" """write out this definition in defs file format"""
raise RuntimeError, "this is an abstract class" raise RuntimeError, "this is an abstract class"
def guess_return_value_ownership(self): def guess_return_value_ownership(self):
"return 1 if caller owns return value" "return 1 if caller owns return value"
@ -62,46 +71,49 @@ class Definition:
class ObjectDef(Definition): class ObjectDef(Definition):
def __init__(self, name, *args): def __init__(self, name, *args):
self.name = name self.name = name
self.module = None self.module = None
self.parent = None self.parent = None
self.c_name = None self.c_name = None
self.typecode = None self.typecode = None
self.fields = [] self.fields = []
self.implements = [] self.implements = []
self.class_init_func = None self.class_init_func = None
for arg in get_valid_scheme_definitions(args): self.has_new_constructor_api = False
if arg[0] == 'in-module': for arg in get_valid_scheme_definitions(args):
self.module = arg[1] if arg[0] == 'in-module':
elif arg[0] == 'parent': self.module = arg[1]
elif arg[0] == 'docstring':
self.docstring = make_docstring(arg[1:])
elif arg[0] == 'parent':
self.parent = arg[1] self.parent = arg[1]
elif arg[0] == 'c-name': elif arg[0] == 'c-name':
self.c_name = arg[1] self.c_name = arg[1]
elif arg[0] == 'gtype-id': elif arg[0] == 'gtype-id':
self.typecode = arg[1] self.typecode = arg[1]
elif arg[0] == 'fields': elif arg[0] == 'fields':
for parg in arg[1:]: for parg in arg[1:]:
self.fields.append((parg[0], parg[1])) self.fields.append((parg[0], parg[1]))
elif arg[0] == 'implements': elif arg[0] == 'implements':
self.implements.append(arg[1]) self.implements.append(arg[1])
def merge(self, old): def merge(self, old):
# currently the .h parser doesn't try to work out what fields of # currently the .h parser doesn't try to work out what fields of
# an object structure should be public, so we just copy the list # an object structure should be public, so we just copy the list
# from the old version ... # from the old version ...
self.fields = old.fields self.fields = old.fields
self.implements = old.implements self.implements = old.implements
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-object ' + self.name + '\n') fp.write('(define-object ' + self.name + '\n')
if self.module: if self.module:
fp.write(' (in-module "' + self.module + '")\n') fp.write(' (in-module "' + self.module + '")\n')
if self.parent != (None, None): if self.parent != (None, None):
fp.write(' (parent "' + self.parent + '")\n') fp.write(' (parent "' + self.parent + '")\n')
for interface in self.implements: for interface in self.implements:
fp.write(' (implements "' + interface + '")\n') fp.write(' (implements "' + interface + '")\n')
if self.c_name: if self.c_name:
fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (c-name "' + self.c_name + '")\n')
if self.typecode: if self.typecode:
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.fields: if self.fields:
fp.write(' (fields\n') fp.write(' (fields\n')
for (ftype, fname) in self.fields: for (ftype, fname) in self.fields:
@ -162,108 +174,110 @@ class MiniObjectDef(Definition):
class InterfaceDef(Definition): class InterfaceDef(Definition):
def __init__(self, name, *args): def __init__(self, name, *args):
self.name = name self.name = name
self.module = None self.module = None
self.c_name = None self.c_name = None
self.typecode = None self.typecode = None
self.vtable = None self.vtable = None
self.fields = [] self.fields = []
self.interface_info = None self.interface_info = None
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] == 'c-name': elif arg[0] == 'docstring':
self.c_name = arg[1] self.docstring = make_docstring(arg[1:])
elif arg[0] == 'gtype-id': elif arg[0] == 'c-name':
self.typecode = arg[1] self.c_name = arg[1]
elif arg[0] == 'vtable': elif arg[0] == 'gtype-id':
self.vtable = arg[1] self.typecode = arg[1]
elif arg[0] == 'vtable':
self.vtable = arg[1]
if self.vtable is None: if self.vtable is None:
self.vtable = self.c_name + "Iface" self.vtable = self.c_name + "Iface"
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-interface ' + self.name + '\n') fp.write('(define-interface ' + self.name + '\n')
if self.module: if self.module:
fp.write(' (in-module "' + self.module + '")\n') fp.write(' (in-module "' + self.module + '")\n')
if self.c_name: if self.c_name:
fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (c-name "' + self.c_name + '")\n')
if self.typecode: if self.typecode:
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
fp.write(')\n\n') fp.write(')\n\n')
class EnumDef(Definition): class EnumDef(Definition):
def __init__(self, name, *args): def __init__(self, name, *args):
self.deftype = 'enum' self.deftype = 'enum'
self.name = name self.name = name
self.in_module = None self.in_module = None
self.c_name = None self.c_name = None
self.typecode = None self.typecode = None
self.values = [] self.values = []
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] == 'c-name': elif arg[0] == 'c-name':
self.c_name = arg[1] self.c_name = arg[1]
elif arg[0] == 'gtype-id': elif arg[0] == 'gtype-id':
self.typecode = arg[1] self.typecode = arg[1]
elif arg[0] == 'values': elif arg[0] == 'values':
for varg in arg[1:]: for varg in arg[1:]:
self.values.append((varg[0], varg[1])) self.values.append((varg[0], varg[1]))
def merge(self, old): def merge(self, old):
pass pass
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-' + self.deftype + ' ' + self.name + '\n') fp.write('(define-' + self.deftype + ' ' + self.name + '\n')
if self.in_module: if self.in_module:
fp.write(' (in-module "' + self.in_module + '")\n') fp.write(' (in-module "' + self.in_module + '")\n')
fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (c-name "' + self.c_name + '")\n')
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.values: if self.values:
fp.write(' (values\n') fp.write(' (values\n')
for name, val in self.values: for name, val in self.values:
fp.write(' \'("' + name + '" "' + val + '")\n') fp.write(' \'("' + name + '" "' + val + '")\n')
fp.write(' )\n') fp.write(' )\n')
fp.write(')\n\n') fp.write(')\n\n')
class FlagsDef(EnumDef): class FlagsDef(EnumDef):
def __init__(self, *args): def __init__(self, *args):
apply(EnumDef.__init__, (self,) + args) apply(EnumDef.__init__, (self,) + args)
self.deftype = 'flags' self.deftype = 'flags'
class BoxedDef(Definition): class BoxedDef(Definition):
def __init__(self, name, *args): def __init__(self, name, *args):
self.name = name self.name = name
self.module = None self.module = None
self.c_name = None self.c_name = None
self.typecode = None self.typecode = None
self.copy = None self.copy = None
self.release = None self.release = None
self.fields = [] self.fields = []
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] == 'c-name': elif arg[0] == 'c-name':
self.c_name = arg[1] self.c_name = arg[1]
elif arg[0] == 'gtype-id': elif arg[0] == 'gtype-id':
self.typecode = arg[1] self.typecode = arg[1]
elif arg[0] == 'copy-func': elif arg[0] == 'copy-func':
self.copy = arg[1] self.copy = arg[1]
elif arg[0] == 'release-func': elif arg[0] == 'release-func':
self.release = arg[1] self.release = arg[1]
elif arg[0] == 'fields': elif arg[0] == 'fields':
for parg in arg[1:]: for parg in arg[1:]:
self.fields.append((parg[0], parg[1])) self.fields.append((parg[0], parg[1]))
def merge(self, old): def merge(self, old):
# currently the .h parser doesn't try to work out what fields of # currently the .h parser doesn't try to work out what fields of
# an object structure should be public, so we just copy the list # an object structure should be public, so we just copy the list
# from the old version ... # from the old version ...
self.fields = old.fields self.fields = old.fields
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-boxed ' + self.name + '\n') fp.write('(define-boxed ' + self.name + '\n')
if self.module: if self.module:
fp.write(' (in-module "' + self.module + '")\n') fp.write(' (in-module "' + self.module + '")\n')
if self.c_name: if self.c_name:
fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (c-name "' + self.c_name + '")\n')
if self.typecode: if self.typecode:
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.copy: if self.copy:
fp.write(' (copy-func "' + self.copy + '")\n') fp.write(' (copy-func "' + self.copy + '")\n')
if self.release: if self.release:
@ -273,74 +287,80 @@ class BoxedDef(Definition):
for (ftype, fname) in self.fields: for (ftype, fname) in self.fields:
fp.write(' \'("' + ftype + '" "' + fname + '")\n') fp.write(' \'("' + ftype + '" "' + fname + '")\n')
fp.write(' )\n') fp.write(' )\n')
fp.write(')\n\n') fp.write(')\n\n')
class PointerDef(Definition): class PointerDef(Definition):
def __init__(self, name, *args): def __init__(self, name, *args):
self.name = name self.name = name
self.module = None self.module = None
self.c_name = None self.c_name = None
self.typecode = None self.typecode = None
self.fields = [] self.fields = []
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] == 'c-name': elif arg[0] == 'c-name':
self.c_name = arg[1] self.c_name = arg[1]
elif arg[0] == 'gtype-id': elif arg[0] == 'gtype-id':
self.typecode = arg[1] self.typecode = arg[1]
elif arg[0] == 'fields': elif arg[0] == 'fields':
for parg in arg[1:]: for parg in arg[1:]:
self.fields.append((parg[0], parg[1])) self.fields.append((parg[0], parg[1]))
def merge(self, old): def merge(self, old):
# currently the .h parser doesn't try to work out what fields of # currently the .h parser doesn't try to work out what fields of
# an object structure should be public, so we just copy the list # an object structure should be public, so we just copy the list
# from the old version ... # from the old version ...
self.fields = old.fields self.fields = old.fields
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-pointer ' + self.name + '\n') fp.write('(define-pointer ' + self.name + '\n')
if self.module: if self.module:
fp.write(' (in-module "' + self.module + '")\n') fp.write(' (in-module "' + self.module + '")\n')
if self.c_name: if self.c_name:
fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (c-name "' + self.c_name + '")\n')
if self.typecode: if self.typecode:
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.fields: if self.fields:
fp.write(' (fields\n') fp.write(' (fields\n')
for (ftype, fname) in self.fields: for (ftype, fname) in self.fields:
fp.write(' \'("' + ftype + '" "' + fname + '")\n') fp.write(' \'("' + ftype + '" "' + fname + '")\n')
fp.write(' )\n') fp.write(' )\n')
fp.write(')\n\n') fp.write(')\n\n')
class MethodDefBase(Definition): class MethodDefBase(Definition):
def __init__(self, name, *args): def __init__(self, name, *args):
dump = 0 dump = 0
self.name = name self.name = name
self.ret = None self.ret = None
self.caller_owns_return = None self.caller_owns_return = None
self.c_name = None self.unblock_threads = None
self.c_name = None
self.typecode = None self.typecode = None
self.of_object = None self.of_object = None
self.params = [] # of form (type, name, default, nullok) self.params = [] # of form (type, name, default, nullok)
self.varargs = 0 self.varargs = 0
self.deprecated = None self.deprecated = None
for arg in 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] == 'c-name': elif arg[0] == 'docstring':
self.c_name = arg[1] self.docstring = make_docstring(arg[1:])
elif arg[0] == 'gtype-id': elif arg[0] == 'c-name':
self.typecode = arg[1] self.c_name = arg[1]
elif arg[0] == 'return-type': elif arg[0] == 'gtype-id':
self.ret = arg[1] self.typecode = arg[1]
elif arg[0] == 'return-type':
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] == 'parameters': elif arg[0] == 'unblock-threads':
self.unblock_threads = arg[1] in ('t', '#t')
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,16 +368,18 @@ 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')
elif arg[0] == 'deprecated': elif arg[0] == 'deprecated':
self.deprecated = arg[1] self.deprecated = arg[1]
else: else:
sys.stderr.write("Warning: %s argument unsupported.\n" sys.stderr.write("Warning: %s argument unsupported.\n"
% (arg[0])) % (arg[0]))
dump = 1 dump = 1
if dump: if dump:
@ -365,33 +387,35 @@ class MethodDefBase(Definition):
if self.caller_owns_return is None and self.ret is not None: if self.caller_owns_return is None and self.ret is not None:
self.guess_return_value_ownership() self.guess_return_value_ownership()
def merge(self, old, parmerge): def merge(self, old, parmerge):
self.caller_owns_return = old.caller_owns_return self.caller_owns_return = old.caller_owns_return
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]
for p2 in old.params: for p2 in old.params:
if p2[1] == pname: if p2[1] == pname:
self.params[i] = (ptype, pname, p2[2], p2[3]) self.params[i] = (ptype, pname, p2[2], p2[3])
break break
def _write_defs(self, fp=sys.stdout): def _write_defs(self, fp=sys.stdout):
if self.of_object != (None, None): if self.of_object != (None, None):
fp.write(' (of-object "' + self.of_object + '")\n') fp.write(' (of-object "' + self.of_object + '")\n')
if self.c_name: if self.c_name:
fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (c-name "' + self.c_name + '")\n')
if self.typecode: if self.typecode:
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.caller_owns_return: if self.caller_owns_return:
fp.write(' (caller-owns-return #t)\n') fp.write(' (caller-owns-return #t)\n')
if self.ret: if self.unblock_threads:
fp.write(' (return-type "' + self.ret + '")\n') fp.write(' (unblock_threads #t)\n')
if self.deprecated: if self.ret:
fp.write(' (deprecated "' + self.deprecated + '")\n') fp.write(' (return-type "' + self.ret + '")\n')
if self.deprecated:
fp.write(' (deprecated "' + self.deprecated + '")\n')
if self.params: if self.params:
fp.write(' (parameters\n') fp.write(' (parameters\n')
for ptype, pname, pdflt, pnull in self.params: for ptype, pname, pdflt, pnull in self.params:
@ -400,9 +424,10 @@ class MethodDefBase(Definition):
if pnull: fp.write(' (null-ok)') if pnull: fp.write(' (null-ok)')
fp.write(')\n') fp.write(')\n')
fp.write(' )\n') fp.write(' )\n')
if self.varargs: if self.varargs:
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):
@ -411,43 +436,48 @@ class MethodDef(MethodDefBase):
if self.__dict__[item] == None: if self.__dict__[item] == None:
self.write_defs(sys.stderr) self.write_defs(sys.stderr)
raise RuntimeError, "definition missing required %s" % (item,) raise RuntimeError, "definition missing required %s" % (item,)
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-method ' + self.name + '\n') fp.write('(define-method ' + self.name + '\n')
self._write_defs(fp) self._write_defs(fp)
class VirtualDef(MethodDefBase): class VirtualDef(MethodDefBase):
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-virtual ' + self.name + '\n') fp.write('(define-virtual ' + self.name + '\n')
self._write_defs(fp) self._write_defs(fp)
class FunctionDef(Definition): class FunctionDef(Definition):
def __init__(self, name, *args): def __init__(self, name, *args):
dump = 0 dump = 0
self.name = name self.name = name
self.in_module = None self.in_module = None
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.c_name = None self.unblock_threads = 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)
self.varargs = 0 self.varargs = 0
self.deprecated = None self.deprecated = None
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] == 'is-constructor-of': elif arg[0] == 'docstring':
self.is_constructor_of = arg[1] self.docstring = make_docstring(arg[1:])
elif arg[0] == 'c-name': elif arg[0] == 'is-constructor-of':
self.c_name = arg[1] self.is_constructor_of = arg[1]
elif arg[0] == 'gtype-id': elif arg[0] == 'c-name':
self.typecode = arg[1] self.c_name = arg[1]
elif arg[0] == 'return-type': elif arg[0] == 'gtype-id':
self.ret = arg[1] self.typecode = arg[1]
elif arg[0] == 'return-type':
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] == 'parameters': elif arg[0] == 'unblock-threads':
self.unblock_threads = arg[1] in ('t', '#t')
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]
@ -501,17 +531,17 @@ 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):
for old_param in old.params: for old_param in old.params:
if old_param.pname == param.pname: if old_param.pname == param.pname:
if isinstance(old_param, Property): if isinstance(old_param, Property):
# 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,35 +552,37 @@ 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:
self.is_constructor_of = old.is_constructor_of self.is_constructor_of = old.is_constructor_of
except AttributeError: except AttributeError:
pass pass
if isinstance(old, MethodDef): if isinstance(old, MethodDef):
self.name = old.name self.name = old.name
# transmogrify from function into method ... # transmogrify from function into method ...
self.write_defs = self._method_write_defs self.write_defs = self._method_write_defs
self.of_object = old.of_object self.of_object = old.of_object
del self.params[0] del self.params[0]
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-function ' + self.name + '\n') fp.write('(define-function ' + self.name + '\n')
if self.in_module: if self.in_module:
fp.write(' (in-module "' + self.in_module + '")\n') fp.write(' (in-module "' + self.in_module + '")\n')
if self.is_constructor_of: if self.is_constructor_of:
fp.write(' (is-constructor-of "' + self.is_constructor_of +'")\n') fp.write(' (is-constructor-of "' + self.is_constructor_of +'")\n')
if self.c_name: if self.c_name:
fp.write(' (c-name "' + self.c_name + '")\n') fp.write(' (c-name "' + self.c_name + '")\n')
if self.typecode: if self.typecode:
fp.write(' (gtype-id "' + self.typecode + '")\n') fp.write(' (gtype-id "' + self.typecode + '")\n')
if self.caller_owns_return: if self.caller_owns_return:
fp.write(' (caller-owns-return #t)\n') fp.write(' (caller-owns-return #t)\n')
if self.ret: if self.unblock_threads:
fp.write(' (return-type "' + self.ret + '")\n') fp.write(' (unblock-threads #t)\n')
if self.deprecated: if self.ret:
fp.write(' (deprecated "' + self.deprecated + '")\n') fp.write(' (return-type "' + self.ret + '")\n')
if self.deprecated:
fp.write(' (deprecated "' + self.deprecated + '")\n')
if self.params: if self.params:
if isinstance(self.params[0], Parameter): if isinstance(self.params[0], Parameter):
fp.write(' (parameters\n') fp.write(' (parameters\n')
@ -569,7 +601,7 @@ class FunctionDef(Definition):
fp.write(' )\n') fp.write(' )\n')
else: else:
assert False, "strange parameter list %r" % self.params[0] assert False, "strange parameter list %r" % self.params[0]
if self.varargs: if self.varargs:
fp.write(' (varargs #t)\n') fp.write(' (varargs #t)\n')
fp.write(')\n\n') fp.write(')\n\n')

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"""
@ -21,14 +23,14 @@ class DefsParser(IncludeParser):
self.objects = [] self.objects = []
self.miniobjects = [] self.miniobjects = []
self.interfaces = [] self.interfaces = []
self.enums = [] # enums and flags self.enums = [] # enums and flags
self.boxes = [] # boxed types self.boxes = [] # boxed types
self.pointers = [] # pointer types self.pointers = [] # pointer types
self.functions = [] # functions and methods self.functions = [] # functions and methods
self.virtuals = [] # virtual methods self.virtuals = [] # virtual methods
self.c_name = {} # hash of c names of functions self.c_name = {} # hash of c names of functions
self.methods = {} # hash of methods of particular objects self.methods = {} # hash of methods of particular objects
self.defines = defines # -Dfoo=bar options, as dictionary self.defines = defines # -Dfoo=bar options, as dictionary
def define_object(self, *args): def define_object(self, *args):
odef = apply(ObjectDef, args) odef = apply(ObjectDef, args)
@ -60,16 +62,16 @@ class DefsParser(IncludeParser):
self.pointers.append(pdef) self.pointers.append(pdef)
self.c_name[pdef.c_name] = pdef self.c_name[pdef.c_name] = pdef
def define_function(self, *args): def define_function(self, *args):
fdef = apply(FunctionDef, args) fdef = apply(FunctionDef, args)
self.functions.append(fdef) self.functions.append(fdef)
self.c_name[fdef.c_name] = fdef self.c_name[fdef.c_name] = fdef
def define_method(self, *args): def define_method(self, *args):
mdef = apply(MethodDef, args) mdef = apply(MethodDef, args)
self.functions.append(mdef) self.functions.append(mdef)
self.c_name[mdef.c_name] = mdef self.c_name[mdef.c_name] = mdef
def define_virtual(self, *args): def define_virtual(self, *args):
vdef = apply(VirtualDef, args) vdef = apply(VirtualDef, args)
self.virtuals.append(vdef) self.virtuals.append(vdef)
def merge(self, old, parmerge): def merge(self, old, parmerge):
for obj in self.objects: for obj in self.objects:
if old.c_name.has_key(obj.c_name): if old.c_name.has_key(obj.c_name):
@ -79,12 +81,12 @@ class DefsParser(IncludeParser):
f.merge(old.c_name[f.c_name], parmerge) f.merge(old.c_name[f.c_name], parmerge)
def printMissing(self, old): def printMissing(self, old):
for obj in self.objects: for obj in self.objects:
if not old.c_name.has_key(obj.c_name): if not old.c_name.has_key(obj.c_name):
obj.write_defs() obj.write_defs()
for f in self.functions: for f in self.functions:
if not old.c_name.has_key(f.c_name): if not old.c_name.has_key(f.c_name):
f.write_defs() f.write_defs()
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
for obj in self.objects: for obj in self.objects:
@ -92,14 +94,14 @@ class DefsParser(IncludeParser):
# TODO: Add miniobject # TODO: Add miniobject
for obj in self.miniobjects: for obj in self.miniobjects:
obj.write_defs(fp) obj.write_defs(fp)
for enum in self.enums: for enum in self.enums:
enum.write_defs(fp) enum.write_defs(fp)
for boxed in self.boxes: for boxed in self.boxes:
boxed.write_defs(fp) boxed.write_defs(fp)
for pointer in self.pointers: for pointer in self.pointers:
pointer.write_defs(fp) pointer.write_defs(fp)
for func in self.functions: for func in self.functions:
func.write_defs(fp) func.write_defs(fp)
def find_object(self, c_name): def find_object(self, c_name):
for obj in self.objects: for obj in self.objects:
@ -131,12 +133,11 @@ class DefsParser(IncludeParser):
not func.is_constructor_of, self.functions) not func.is_constructor_of, self.functions)
def ifdef(self, *args): def ifdef(self, *args):
if args[0] in self.defines: if args[0] in self.defines:
for arg in args[1:]: for arg in args[1:]:
self.handle(arg) self.handle(arg)
def ifndef(self, *args): def ifndef(self, *args):
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

@ -8,18 +8,18 @@ __all__ = ['extract']
class FunctionDoc: class FunctionDoc:
def __init__(self): def __init__(self):
self.name = None self.name = None
self.params = [] self.params = []
self.description = '' self.description = ''
self.ret = '' self.ret = ''
def set_name(self, name): def set_name(self, name):
self.name = name self.name = name
def add_param(self, name, description): def add_param(self, name, description):
if name == '...': if name == '...':
name = 'Varargs' name = 'Varargs'
self.params.append((name, description)) self.params.append((name, description))
def append_to_last_param(self, extra): def append_to_last_param(self, extra):
self.params[-1] = (self.params[-1][0], self.params[-1][1] + extra) self.params[-1] = (self.params[-1][0], self.params[-1][1] + extra)
def append_to_named_param(self, name, extra): def append_to_named_param(self, name, extra):
for i in range(len(self.params)): for i in range(len(self.params)):
if self.params[i][0] == name: if self.params[i][0] == name:
@ -28,9 +28,9 @@ class FunctionDoc:
# fall through to adding extra parameter ... # fall through to adding extra parameter ...
self.add_param(name, extra) self.add_param(name, extra)
def append_description(self, extra): def append_description(self, extra):
self.description = self.description + extra self.description = self.description + extra
def append_return(self, extra): def append_return(self, extra):
self.ret = self.ret + extra self.ret = self.ret + extra
def get_param_description(self, name): def get_param_description(self, name):
for param, description in self.params: for param, description in self.params:
@ -44,97 +44,97 @@ comment_end_pat = re.compile(r'^\s*\*+/')
comment_line_lead = re.compile(r'^\s*\*\s*') comment_line_lead = re.compile(r'^\s*\*\s*')
funcname_pat = re.compile(r'^(\w+)\s*:?') funcname_pat = re.compile(r'^(\w+)\s*:?')
return_pat = re.compile(r'^(returns:|return\s+value:|returns\s*)(.*\n?)$', return_pat = re.compile(r'^(returns:|return\s+value:|returns\s*)(.*\n?)$',
re.IGNORECASE) re.IGNORECASE)
param_pat = re.compile(r'^@(\S+)\s*:(.*\n?)$') param_pat = re.compile(r'^@(\S+)\s*:(.*\n?)$')
def parse_file(fp, doc_dict): def parse_file(fp, doc_dict):
line = fp.readline() line = fp.readline()
in_comment_block = 0 in_comment_block = 0
while line: while line:
if not in_comment_block: if not in_comment_block:
if comment_start_pat.match(line): if comment_start_pat.match(line):
in_comment_block = 1 in_comment_block = 1
cur_doc = FunctionDoc() cur_doc = FunctionDoc()
in_description = 0 in_description = 0
in_return = 0 in_return = 0
line = fp.readline() line = fp.readline()
continue continue
# we are inside a comment block ...
if comment_end_pat.match(line):
if not cur_doc.name:
sys.stderr.write("no function name found in doc comment\n")
else:
doc_dict[cur_doc.name] = cur_doc
in_comment_block = 0
line = fp.readline()
continue
# inside a comment block, and not the end of the block ... # we are inside a comment block ...
line = comment_line_lead.sub('', line) if comment_end_pat.match(line):
if not line: line = '\n' if not cur_doc.name:
sys.stderr.write("no function name found in doc comment\n")
else:
doc_dict[cur_doc.name] = cur_doc
in_comment_block = 0
line = fp.readline()
continue
if not cur_doc.name: # inside a comment block, and not the end of the block ...
match = funcname_pat.match(line) line = comment_line_lead.sub('', line)
if match: if not line: line = '\n'
cur_doc.set_name(match.group(1))
elif in_return: if not cur_doc.name:
match = return_pat.match(line) match = funcname_pat.match(line)
if match: if match:
# assume the last return statement was really part of the cur_doc.set_name(match.group(1))
# description elif in_return:
cur_doc.description = cur_doc.description + return_start + \ match = return_pat.match(line)
cur_doc.ret if match:
return_start = match.group(1) # assume the last return statement was really part of the
cur_doc.ret = match.group(2) # description
else: return_start = match.group(1)
cur_doc.append_return(line) cur_doc.ret = match.group(2)
elif in_description: cur_doc.description = cur_doc.description + return_start + \
if line[:12] == 'Description:': cur_doc.ret
line = line[12:] else:
match = return_pat.match(line) cur_doc.append_return(line)
if match: elif in_description:
in_return = 1 if line[:12] == 'Description:':
return_start = match.group(1) line = line[12:]
cur_doc.append_return(match.group(2)) match = return_pat.match(line)
else: if match:
cur_doc.append_description(line) in_return = 1
elif line == '\n': return_start = match.group(1)
# end of parameters cur_doc.append_return(match.group(2))
in_description = 1 else:
else: cur_doc.append_description(line)
match = param_pat.match(line) elif line == '\n':
if match: # end of parameters
param = match.group(1) in_description = 1
desc = match.group(2) else:
match = param_pat.match(line)
if match:
param = match.group(1)
desc = match.group(2)
if param == 'returns': if param == 'returns':
cur_doc.ret = desc cur_doc.ret = desc
else: else:
cur_doc.add_param(param, desc) cur_doc.add_param(param, desc)
else: else:
# must be continuation # must be continuation
try: try:
if param == 'returns': if param == 'returns':
cur_doc.append_return(line) cur_doc.append_return(line)
else: else:
cur_doc.append_to_last_param(line) cur_doc.append_to_last_param(line)
except: except:
sys.stderr.write('something weird while reading param\n') sys.stderr.write('something weird while reading param\n')
line = fp.readline() line = fp.readline()
def parse_dir(dir, doc_dict): def parse_dir(dir, doc_dict):
for file in os.listdir(dir): for file in os.listdir(dir):
if file in ('.', '..'): continue if file in ('.', '..'): continue
path = os.path.join(dir, file) path = os.path.join(dir, file)
if os.path.isdir(path): if os.path.isdir(path):
parse_dir(path, doc_dict) parse_dir(path, doc_dict)
if len(file) > 2 and file[-2:] == '.c': if len(file) > 2 and file[-2:] == '.c':
parse_file(open(path, 'r'), doc_dict) parse_file(open(path, 'r'), doc_dict)
def extract(dirs, doc_dict=None): def extract(dirs, doc_dict=None):
if not doc_dict: doc_dict = {} if not doc_dict: doc_dict = {}
for dir in dirs: for dir in dirs:
parse_dir(dir, doc_dict) parse_dir(dir, doc_dict)
return doc_dict return doc_dict
tmpl_section_pat = re.compile(r'^<!-- ##### (\w+) (\w+) ##### -->$') tmpl_section_pat = re.compile(r'^<!-- ##### (\w+) (\w+) ##### -->$')

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)
@ -70,7 +69,7 @@ def build_object_tree(parser):
class DocWriter: class DocWriter:
def __init__(self): def __init__(self):
# parse the defs file # parse the defs file
self.parser = defsparser.DefsParser(()) self.parser = defsparser.DefsParser(())
self.overrides = override.Overrides() self.overrides = override.Overrides()
self.classmap = {} self.classmap = {}
@ -116,12 +115,12 @@ class DocWriter:
self.write_full_hierarchy(hierarchy, fp) self.write_full_hierarchy(hierarchy, fp)
fp.close() fp.close()
obj_defs = self.parser.objects + self.parser.interfaces + \ obj_defs = self.parser.objects + self.parser.interfaces + \
self.parser.boxes + self.parser.pointers self.parser.boxes + self.parser.pointers
obj_defs.sort(self.__compare) obj_defs.sort(self.__compare)
for obj_def in obj_defs: for obj_def in obj_defs:
filename = self.create_filename(obj_def.c_name, output_prefix) filename = self.create_filename(obj_def.c_name, output_prefix)
fp = open(filename, 'w') fp = open(filename, 'w')
if isinstance(obj_def, definitions.ObjectDef): if isinstance(obj_def, definitions.ObjectDef):
self.output_object_docs(obj_def, fp) self.output_object_docs(obj_def, fp)
elif isinstance(obj_def, definitions.InterfaceDef): elif isinstance(obj_def, definitions.InterfaceDef):
@ -130,24 +129,24 @@ class DocWriter:
self.output_boxed_docs(obj_def, fp) self.output_boxed_docs(obj_def, fp)
elif isinstance(obj_def, definitions.PointerDef): elif isinstance(obj_def, definitions.PointerDef):
self.output_boxed_docs(obj_def, fp) self.output_boxed_docs(obj_def, fp)
fp.close() fp.close()
files.append((os.path.basename(filename), obj_def)) files.append((os.path.basename(filename), obj_def))
if files: if files:
filename = self.create_toc_filename(output_prefix) filename = self.create_toc_filename(output_prefix)
fp = open(filename, 'w') fp = open(filename, 'w')
self.output_toc(files, fp) self.output_toc(files, fp)
fp.close() fp.close()
def output_object_docs(self, obj_def, fp=sys.stdout): def output_object_docs(self, obj_def, fp=sys.stdout):
self.write_class_header(obj_def.c_name, fp) self.write_class_header(obj_def.c_name, fp)
self.write_heading('Synopsis', fp) self.write_heading('Synopsis', fp)
self.write_synopsis(obj_def, fp) self.write_synopsis(obj_def, fp)
self.close_section(fp) self.close_section(fp)
# construct the inheritence hierarchy ... # construct the inheritence hierarchy ...
ancestry = [ (obj_def.c_name, obj_def.implements) ] ancestry = [ (obj_def.c_name, obj_def.implements) ]
try: try:
parent = obj_def.parent parent = obj_def.parent
while parent != None: while parent != None:
@ -185,7 +184,7 @@ class DocWriter:
self.write_class_footer(obj_def.c_name, fp) self.write_class_footer(obj_def.c_name, fp)
def output_interface_docs(self, int_def, fp=sys.stdout): def output_interface_docs(self, int_def, fp=sys.stdout):
self.write_class_header(int_def.c_name, fp) self.write_class_header(int_def.c_name, fp)
self.write_heading('Synopsis', fp) self.write_heading('Synopsis', fp)
self.write_synopsis(int_def, fp) self.write_synopsis(int_def, fp)
@ -203,7 +202,7 @@ class DocWriter:
self.write_class_footer(int_def.c_name, fp) self.write_class_footer(int_def.c_name, fp)
def output_boxed_docs(self, box_def, fp=sys.stdout): def output_boxed_docs(self, box_def, fp=sys.stdout):
self.write_class_header(box_def.c_name, fp) self.write_class_header(box_def.c_name, fp)
self.write_heading('Synopsis', fp) self.write_heading('Synopsis', fp)
self.write_synopsis(box_def, fp) self.write_synopsis(box_def, fp)
@ -235,8 +234,8 @@ class DocWriter:
# override the following to create a more complex output format # override the following to create a more complex output format
def create_filename(self, obj_name, output_prefix): def create_filename(self, obj_name, output_prefix):
'''Create output filename for this particular object''' '''Create output filename for this particular object'''
return output_prefix + '-' + string.lower(obj_name) + '.txt' return output_prefix + '-' + string.lower(obj_name) + '.txt'
def create_toc_filename(self, output_prefix): def create_toc_filename(self, output_prefix):
return self.create_filename(self, 'docs', output_prefix) return self.create_filename(self, 'docs', output_prefix)
@ -269,8 +268,8 @@ class DocWriter:
')' ')'
def write_class_header(self, obj_name, fp): def write_class_header(self, obj_name, fp):
fp.write('Class %s\n' % obj_name) fp.write('Class %s\n' % obj_name)
fp.write('======%s\n\n' % ('=' * len(obj_name))) fp.write('======%s\n\n' % ('=' * len(obj_name)))
def write_class_footer(self, obj_name, fp): def write_class_footer(self, obj_name, fp):
pass pass
def write_heading(self, text, fp): def write_heading(self, text, fp):
@ -352,9 +351,9 @@ class DocbookDocWriter(DocWriter):
def __init__(self, use_xml=0): def __init__(self, use_xml=0):
DocWriter.__init__(self) DocWriter.__init__(self)
self.use_xml = use_xml self.use_xml = use_xml
def create_filename(self, obj_name, output_prefix): def create_filename(self, obj_name, output_prefix):
'''Create output filename for this particular object''' '''Create output filename for this particular object'''
stem = output_prefix + '-' + string.lower(obj_name) stem = output_prefix + '-' + string.lower(obj_name)
if self.use_xml: if self.use_xml:
return stem + '.xml' return stem + '.xml'
@ -429,7 +428,7 @@ class DocbookDocWriter(DocWriter):
'</classname></link>' '</classname></link>'
# fall through through # fall through through
return '<literal>' + match.group(1) + '</literal>' return '<literal>' + match.group(1) + '</literal>'
def reformat_text(self, text, singleline=0): def reformat_text(self, text, singleline=0):
# replace special strings ... # replace special strings ...
text = self.__function_pat.sub(self.__format_function, text) text = self.__function_pat.sub(self.__format_function, text)
@ -439,7 +438,7 @@ class DocbookDocWriter(DocWriter):
# don't bother with <para> expansion for single line text. # don't bother with <para> expansion for single line text.
if singleline: return text if singleline: return text
lines = string.split(string.strip(text), '\n') lines = string.split(string.strip(text), '\n')
for index in range(len(lines)): for index in range(len(lines)):
if string.strip(lines[index]) == '': if string.strip(lines[index]) == '':
@ -538,7 +537,7 @@ class DocbookDocWriter(DocWriter):
sgml.append(' <methodparam></methodparam>') sgml.append(' <methodparam></methodparam>')
sgml.append(' </methodsynopsis>') sgml.append(' </methodsynopsis>')
return string.join(sgml, '') return string.join(sgml, '')
def write_class_header(self, obj_name, fp): def write_class_header(self, obj_name, fp):
if self.use_xml: if self.use_xml:
fp.write('<?xml version="1.0" standalone="no"?>\n') fp.write('<?xml version="1.0" standalone="no"?>\n')
@ -680,7 +679,7 @@ class DocbookDocWriter(DocWriter):
# fp.write('&' + string.translate(obj_def.c_name, # fp.write('&' + string.translate(obj_def.c_name,
# self.__transtable) + ';\n') # self.__transtable) + ';\n')
#fp.write('</reference>\n') #fp.write('</reference>\n')
fp.write('<reference id="class-reference" xmlns:xi="http://www.w3.org/2001/XInclude">\n') fp.write('<reference id="class-reference" xmlns:xi="http://www.w3.org/2001/XInclude">\n')
fp.write(' <title>Class Reference</title>\n') fp.write(' <title>Class Reference</title>\n')
for filename, obj_def in files: for filename, obj_def in files:
@ -726,25 +725,25 @@ if __name__ == '__main__':
"output-prefix="]) "output-prefix="])
except getopt.error, e: except getopt.error, e:
sys.stderr.write('docgen.py: %s\n' % e) sys.stderr.write('docgen.py: %s\n' % e)
sys.stderr.write( sys.stderr.write(
'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n') 'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
sys.exit(1) sys.exit(1)
defs_file = None defs_file = None
overrides_file = None overrides_file = None
source_dirs = [] source_dirs = []
output_prefix = 'docs' output_prefix = 'docs'
for opt, arg in opts: for opt, arg in opts:
if opt in ('-d', '--defs-file'): if opt in ('-d', '--defs-file'):
defs_file = arg defs_file = arg
if opt in ('--override',): if opt in ('--override',):
overrides_file = arg overrides_file = arg
elif opt in ('-s', '--source-dir'): elif opt in ('-s', '--source-dir'):
source_dirs.append(arg) source_dirs.append(arg)
elif opt in ('-o', '--output-prefix'): elif opt in ('-o', '--output-prefix'):
output_prefix = arg output_prefix = arg
if len(args) != 0 or not defs_file: if len(args) != 0 or not defs_file:
sys.stderr.write( sys.stderr.write(
'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n') 'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
sys.exit(1) sys.exit(1)
d = DocbookDocWriter() d = DocbookDocWriter()

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=[]):
@ -196,7 +175,7 @@ def find_enum_defs(buf, enums=[]):
buf = strip_comments(buf) buf = strip_comments(buf)
buf = re.sub('\n', ' ', buf) buf = re.sub('\n', ' ', buf)
enum_pat = re.compile(r'enum\s*{([^}]*)}\s*([A-Z][A-Za-z]*)(\s|;)') enum_pat = re.compile(r'enum\s*{([^}]*)}\s*([A-Z][A-Za-z]*)(\s|;)')
splitter = re.compile(r'\s*,\s', re.MULTILINE) splitter = re.compile(r'\s*,\s', re.MULTILINE)
pos = 0 pos = 0
@ -213,48 +192,9 @@ def find_enum_defs(buf, enums=[]):
entries.append(string.split(val)[0]) entries.append(string.split(val)[0])
if name != 'GdkCursorType': if name != 'GdkCursorType':
enums.append((name, isflags, entries)) enums.append((name, isflags, entries))
pos = m.end() pos = m.end()
def write_enum_defs(enums, output=None):
if type(output)==types.StringType:
fp=open(output,'w')
elif type(output)==types.FileType:
fp=output
else:
fp=sys.stdout
fp.write(';; Enumerations and flags ...\n\n')
trans = string.maketrans(string.uppercase + '_', string.lowercase + '-')
for cname, isflags, entries in enums:
name = cname
module = None
m = split_prefix_pat.match(cname)
if m:
module = m.group(1)
name = m.group(2)
if isflags:
fp.write('(define-flags ' + name + '\n')
else:
fp.write('(define-enum ' + name + '\n')
if module:
fp.write(' (in-module "' + module + '")\n')
fp.write(' (c-name "' + cname + '")\n')
fp.write(' (gtype-id "' + typecode(cname) + '")\n')
prefix = entries[0]
for ent in entries:
# shorten prefix til we get a match ...
# and handle GDK_FONT_FONT, GDK_FONT_FONTSET case
while ent[:len(prefix)] != prefix or len(prefix) >= len(ent):
prefix = prefix[:-1]
prefix_len = len(prefix)
fp.write(' (values\n')
for ent in entries:
fp.write(' \'("%s" "%s")\n' %
(string.translate(ent[prefix_len:], trans), ent))
fp.write(' )\n')
fp.write(')\n\n')
# ------------------ Find function definitions ----------------- # ------------------ Find function definitions -----------------
def clean_func(buf): def clean_func(buf):
@ -267,40 +207,41 @@ def clean_func(buf):
buf = strip_comments(buf) buf = strip_comments(buf)
# compact continued lines # compact continued lines
pat = re.compile(r"""\\\n""", re.MULTILINE) pat = re.compile(r"""\\\n""", re.MULTILINE)
buf=pat.sub('',buf) buf = pat.sub('', buf)
# Preprocess directives # Preprocess directives
pat = re.compile(r"""^[#].*?$""", re.MULTILINE) pat = re.compile(r"""^[#].*?$""", re.MULTILINE)
buf=pat.sub('',buf) buf = pat.sub('', buf)
#typedefs, stucts, and enums #typedefs, stucts, and enums
pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re.MULTILINE) pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""",
buf=pat.sub('',buf) re.MULTILINE)
buf = pat.sub('', buf)
#strip DECLS macros #strip DECLS macros
pat = re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS""", re.MULTILINE) pat = re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS""", re.MULTILINE)
buf=pat.sub('',buf) buf = pat.sub('', buf)
#extern "C" #extern "C"
pat = re.compile(r"""^\s*(extern)\s+\"C\"\s+{""", re.MULTILINE) pat = re.compile(r"""^\s*(extern)\s+\"C\"\s+{""", re.MULTILINE)
buf=pat.sub('',buf) buf = pat.sub('', buf)
#multiple whitespace #multiple whitespace
pat = re.compile(r"""\s+""", re.MULTILINE) pat = re.compile(r"""\s+""", re.MULTILINE)
buf=pat.sub(' ',buf) buf = pat.sub(' ', buf)
#clean up line ends #clean up line ends
pat = re.compile(r""";\s*""", re.MULTILINE) pat = re.compile(r""";\s*""", re.MULTILINE)
buf=pat.sub('\n',buf) buf = pat.sub('\n', buf)
buf = buf.lstrip() buf = buf.lstrip()
#associate *, &, and [] with type instead of variable #associate *, &, and [] with type instead of variable
#pat=re.compile(r'\s+([*|&]+)\s*(\w+)') #pat = re.compile(r'\s+([*|&]+)\s*(\w+)')
pat=re.compile(r' \s* ([*|&]+) \s* (\w+)',re.VERBOSE) pat = re.compile(r' \s* ([*|&]+) \s* (\w+)', re.VERBOSE)
buf=pat.sub(r'\1 \2', buf) buf = pat.sub(r'\1 \2', buf)
pat=re.compile(r'\s+ (\w+) \[ \s* \]',re.VERBOSE) pat = re.compile(r'\s+ (\w+) \[ \s* \]', re.VERBOSE)
buf=pat.sub(r'[] \1', buf) buf = pat.sub(r'[] \1', buf)
# make return types that are const work. # make return types that are const work.
buf = string.replace(buf, 'G_CONST_RETURN ', 'const-') buf = string.replace(buf, 'G_CONST_RETURN ', 'const-')
@ -312,165 +253,244 @@ proto_pat=re.compile(r"""
(?P<ret>(-|\w|\&|\*)+\s*) # return type (?P<ret>(-|\w|\&|\*)+\s*) # return type
\s+ # skip whitespace \s+ # skip whitespace
(?P<func>\w+)\s*[(] # match the function name until the opening ( (?P<func>\w+)\s*[(] # match the function name until the opening (
\s*(?P<args>.*?)[)] # group the function arguments \s*(?P<args>.*?)\s*[)] # group the function arguments
""", re.IGNORECASE|re.VERBOSE) """, re.IGNORECASE|re.VERBOSE)
#""" #"""
arg_split_pat = re.compile("\s*,\s*") arg_split_pat = re.compile("\s*,\s*")
def define_func(buf,fp, prefix):
buf=clean_func(buf)
buf=string.split(buf,'\n')
for p in buf:
if len(p)==0: continue
m=proto_pat.match(p)
if m==None:
if verbose:
sys.stderr.write('No match:|%s|\n'%p)
continue
func = m.group('func')
if func[0] == '_':
continue
ret = m.group('ret')
args=m.group('args')
args=arg_split_pat.split(args)
for i in range(len(args)):
spaces = string.count(args[i], ' ')
if spaces > 1:
args[i] = string.replace(args[i], ' ', '-', spaces - 1)
write_func(fp, func, ret, args, prefix)
get_type_pat = re.compile(r'(const-)?([A-Za-z0-9]+)\*?\s+') get_type_pat = re.compile(r'(const-)?([A-Za-z0-9]+)\*?\s+')
pointer_pat = re.compile('.*\*$') pointer_pat = re.compile('.*\*$')
func_new_pat = re.compile('(\w+)_new$') func_new_pat = re.compile('(\w+)_new$')
def write_func(fp, name, ret, args, prefix): class DefsWriter:
if len(args) >= 1: def __init__(self, fp=None, prefix=None, verbose=False,
# methods must have at least one argument defsfilter=None):
munged_name = string.replace(name, '_', '') if not fp:
m = get_type_pat.match(args[0]) fp = sys.stdout
if m:
obj = m.group(2) self.fp = fp
if munged_name[:len(obj)] == string.lower(obj): self.prefix = prefix
regex = string.join(map(lambda x: x+'_?',string.lower(obj)),'') self.verbose = verbose
mname = re.sub(regex, '', name, 1)
if prefix: self._enums = {}
l = len(prefix) + 1 self._objects = {}
if mname[:l] == prefix and mname[l+1] == '_': self._functions = {}
mname = mname[l+1:] if defsfilter:
fp.write('(define-method ' + mname + '\n') filter = defsparser.DefsParser(defsfilter)
fp.write(' (of-object "' + obj + '")\n') filter.startParsing()
fp.write(' (c-name "' + name + '")\n') for func in filter.functions + filter.methods.values():
if ret != 'void': self._functions[func.c_name] = func
fp.write(' (return-type "' + ret + '")\n') for obj in filter.objects + filter.boxes + filter.interfaces:
else: self._objects[obj.c_name] = func
fp.write(' (return-type "none")\n') for obj in filter.enums:
is_varargs = 0 self._enums[obj.c_name] = func
has_args = len(args) > 1
for arg in args[1:]: def write_def(self, deffile):
if arg == '...': buf = open(deffile).read()
is_varargs = 1
elif arg in ('void', 'void '): self.fp.write('\n;; From %s\n\n' % os.path.basename(deffile))
has_args = 0 self._define_func(buf)
if has_args: self.fp.write('\n')
fp.write(' (parameters\n')
for arg in args[1:]: def write_enum_defs(self, enums, fp=None):
if arg != '...': if not fp:
tupleArg = tuple(string.split(arg)) fp = self.fp
if len(tupleArg) == 2:
fp.write(' \'("%s" "%s")\n' % tupleArg) fp.write(';; Enumerations and flags ...\n\n')
fp.write(' )\n') trans = string.maketrans(string.uppercase + '_',
if is_varargs: string.lowercase + '-')
fp.write(' (varargs #t)\n') filter = self._enums
fp.write(')\n\n') for cname, isflags, entries in enums:
return if filter:
if prefix: if cname in filter:
l = len(prefix) continue
if name[:l] == prefix and name[l] == '_': name = cname
fname = name[l+1:] module = None
m = split_prefix_pat.match(cname)
if m:
module = m.group(1)
name = m.group(2)
if isflags:
fp.write('(define-flags ' + name + '\n')
else:
fp.write('(define-enum ' + name + '\n')
if module:
fp.write(' (in-module "' + module + '")\n')
fp.write(' (c-name "' + cname + '")\n')
fp.write(' (gtype-id "' + typecode(cname) + '")\n')
prefix = entries[0]
for ent in entries:
# shorten prefix til we get a match ...
# and handle GDK_FONT_FONT, GDK_FONT_FONTSET case
while ent[:len(prefix)] != prefix or len(prefix) >= len(ent):
prefix = prefix[:-1]
prefix_len = len(prefix)
fp.write(' (values\n')
for ent in entries:
fp.write(' \'("%s" "%s")\n' %
(string.translate(ent[prefix_len:], trans), ent))
fp.write(' )\n')
fp.write(')\n\n')
def write_obj_defs(self, objdefs, fp=None):
if not fp:
fp = self.fp
fp.write(';; -*- scheme -*-\n')
fp.write('; object definitions ...\n')
filter = self._objects
for klass, parent in objdefs:
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')
def _define_func(self, buf):
buf = clean_func(buf)
buf = string.split(buf,'\n')
filter = self._functions
for p in buf:
if not p:
continue
m = proto_pat.match(p)
if m == None:
if self.verbose:
sys.stderr.write('No match:|%s|\n' % p)
continue
func = m.group('func')
if func[0] == '_':
continue
if filter:
if func in filter:
continue
ret = m.group('ret')
args = m.group('args')
args = arg_split_pat.split(args)
for i in range(len(args)):
spaces = string.count(args[i], ' ')
if spaces > 1:
args[i] = string.replace(args[i], ' ', '-', spaces - 1)
self._write_func(func, ret, args)
def _write_func(self, name, ret, args):
if len(args) >= 1:
# methods must have at least one argument
munged_name = name.replace('_', '')
m = get_type_pat.match(args[0])
if m:
obj = m.group(2)
if munged_name[:len(obj)] == obj.lower():
self._write_method(obj, name, ret, args)
return
if self.prefix:
l = len(self.prefix)
if name[:l] == self.prefix and name[l] == '_':
fname = name[l+1:]
else:
fname = name
else: else:
fname = name fname = name
else:
fname = name
# it is either a constructor or normal function
fp.write('(define-function ' + fname + '\n')
fp.write(' (c-name "' + name + '")\n')
# Hmmm... Let's asume that a constructor function name # it is either a constructor or normal function
# ends with '_new' and it returns a pointer. self.fp.write('(define-function ' + fname + '\n')
m = func_new_pat.match(name) self.fp.write(' (c-name "' + name + '")\n')
if pointer_pat.match(ret) and m:
cname = ''
for s in m.group(1).split ('_'):
cname += s.title()
if cname != '':
fp.write(' (is-constructor-of "' + cname + '")\n')
if ret != 'void': # Hmmm... Let's asume that a constructor function name
fp.write(' (return-type "' + ret + '")\n') # ends with '_new' and it returns a pointer.
else: m = func_new_pat.match(name)
fp.write(' (return-type "none")\n') if pointer_pat.match(ret) and m:
is_varargs = 0 cname = ''
has_args = len(args) > 0 for s in m.group(1).split ('_'):
for arg in args: cname += s.title()
if arg == '...': if cname != '':
is_varargs = 1 self.fp.write(' (is-constructor-of "' + cname + '")\n')
elif arg in ('void', 'void '):
has_args = 0 self._write_return(ret)
if has_args: self._write_arguments(args)
fp.write(' (parameters\n')
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':
self.fp.write(' (return-type "' + ret + '")\n')
else:
self.fp.write(' (return-type "none")\n')
def _write_arguments(self, args):
is_varargs = 0
has_args = len(args) > 0
for arg in args: for arg in args:
if arg != '...': if arg == '...':
tupleArg = tuple(string.split(arg)) is_varargs = 1
if len(tupleArg) == 2: elif arg in ('void', 'void '):
fp.write(' \'("%s" "%s")\n' % tupleArg) has_args = 0
fp.write(' )\n') if has_args:
if is_varargs: self.fp.write(' (parameters\n')
fp.write(' (varargs #t)\n') for arg in args:
fp.write(')\n\n') if arg != '...':
tupleArg = tuple(string.split(arg))
def write_def(input,output=None, prefix=None): if len(tupleArg) == 2:
fp = open(input) self.fp.write(' \'("%s" "%s")\n' % tupleArg)
buf = fp.read() self.fp.write(' )\n')
fp.close() if is_varargs:
self.fp.write(' (varargs #t)\n')
if type(output) == types.StringType: self.fp.write(')\n\n')
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'
return -1 return -1
@ -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)
write_enum_defs(enums,types) dw = DefsWriter(methods, prefix=modulename, verbose=verbose,
types.close() defsfilter=defsfilter)
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

@ -52,11 +52,11 @@ override_template = \
def open_with_backup(file): def open_with_backup(file):
if os.path.exists(file): if os.path.exists(file):
try: try:
os.rename(file, file+'~') os.rename(file, file+'~')
except OSError: except OSError:
# fail silently if we can't make a backup # fail silently if we can't make a backup
pass pass
return open(file, 'w') return open(file, 'w')
def write_skels(fileprefix, prefix, module): def write_skels(fileprefix, prefix, module):
@ -69,21 +69,21 @@ def write_skels(fileprefix, prefix, module):
if __name__ == '__main__': if __name__ == '__main__':
opts, args = getopt.getopt(sys.argv[1:], 'f:p:m:h', opts, args = getopt.getopt(sys.argv[1:], 'f:p:m:h',
['file-prefix=', 'prefix=', 'module=', 'help']) ['file-prefix=', 'prefix=', 'module=', 'help'])
fileprefix = None fileprefix = None
prefix = None prefix = None
module = None module = None
for opt, arg in opts: for opt, arg in opts:
if opt in ('-f', '--file-prefix'): if opt in ('-f', '--file-prefix'):
fileprefix = arg fileprefix = arg
elif opt in ('-p', '--prefix'): elif opt in ('-p', '--prefix'):
prefix = arg prefix = arg
elif opt in ('-m', '--module'): elif opt in ('-m', '--module'):
module = arg module = arg
elif opt in ('-h', '--help'): elif opt in ('-h', '--help'):
print 'usage: mkskel.py -f fileprefix -p prefix -m module' print 'usage: mkskel.py -f fileprefix -p prefix -m module'
sys.exit(0) sys.exit(0)
if not fileprefix or not prefix or not module: if not fileprefix or not prefix or not module:
print 'usage: mkskel.py -f fileprefix -p prefix -m module' print 'usage: mkskel.py -f fileprefix -p prefix -m module'
sys.exit(1) sys.exit(1)
write_skels(fileprefix, prefix, module) write_skels(fileprefix, prefix, module)

View File

@ -18,27 +18,32 @@ def class2cname(klass, method):
else: else:
c_name += c c_name += c
return c_name[1:] + '_' + method return c_name[1:] + '_' + method
import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)') import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)')
class Overrides: class Overrides:
def __init__(self, filename=None, path=[]): def __init__(self, filename=None, path=[]):
self.modulename = None self.modulename = None
self.ignores = {} self.ignores = {}
self.glob_ignores = [] self.glob_ignores = []
self.type_ignores = {} self.type_ignores = {}
self.overrides = {} self.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)
@ -61,8 +66,8 @@ class Overrides:
if dirname != oldpath: if dirname != oldpath:
os.chdir(dirname) os.chdir(dirname)
# read all the components of the file ... # read all the components of the file ...
bufs = [] bufs = []
startline = 1 startline = 1
lines = [] lines = []
@ -80,36 +85,36 @@ class Overrides:
linenum = linenum + 1 linenum = linenum + 1
if lines: if lines:
bufs.append((string.join(lines, ''), startline)) bufs.append((string.join(lines, ''), startline))
if not bufs: return if not bufs: return
for buf, startline in bufs: for buf, startline in bufs:
self.__parse_override(buf, startline, filename) self.__parse_override(buf, startline, filename)
os.chdir(oldpath) os.chdir(oldpath)
def __parse_override(self, buffer, startline, filename): def __parse_override(self, buffer, startline, filename):
pos = string.find(buffer, '\n') pos = string.find(buffer, '\n')
if pos >= 0: if pos >= 0:
line = buffer[:pos] line = buffer[:pos]
rest = buffer[pos+1:] rest = buffer[pos+1:]
else: else:
line = buffer ; rest = '' line = buffer ; rest = ''
words = string.split(line) words = string.split(line)
command = words[0] command = words[0]
if (command == 'ignore' or if (command == 'ignore' or
command == 'ignore-' + sys.platform): command == 'ignore-' + sys.platform):
"ignore/ignore-platform [functions..]" "ignore/ignore-platform [functions..]"
for func in words[1:]: for func in words[1:]:
self.ignores[func] = 1 self.ignores[func] = 1
for func in string.split(rest): for func in string.split(rest):
self.ignores[func] = 1 self.ignores[func] = 1
elif (command == 'ignore-glob' or elif (command == 'ignore-glob' or
command == 'ignore-glob-' + sys.platform): command == 'ignore-glob-' + sys.platform):
"ignore-glob/ignore-glob-platform [globs..]" "ignore-glob/ignore-glob-platform [globs..]"
for func in words[1:]: for func in words[1:]:
self.glob_ignores.append(func)
for func in string.split(rest):
self.glob_ignores.append(func) self.glob_ignores.append(func)
for func in string.split(rest):
self.glob_ignores.append(func)
elif (command == 'ignore-type' or elif (command == 'ignore-type' or
command == 'ignore-type-' + sys.platform): command == 'ignore-type-' + sys.platform):
"ignore-type/ignore-type-platform [typenames..]" "ignore-type/ignore-type-platform [typenames..]"
@ -117,14 +122,23 @@ class Overrides:
self.type_ignores[typename] = 1 self.type_ignores[typename] = 1
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
self.overrides[func] = rest 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.startlines[func] = (startline + 1, filename) self.startlines[func] = (startline + 1, filename)
elif command == 'override-attr': elif command == 'override-attr':
"override-slot Class.attr" "override-slot Class.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' % \
@ -149,9 +167,9 @@ class Overrides:
self.modulename = words[1] self.modulename = words[1]
elif command == 'include': elif command == 'include':
"include filename" "include filename"
for filename in words[1:]: for filename in words[1:]:
self.handle_file(filename) self.handle_file(filename)
for filename in string.split(rest): for filename in string.split(rest):
self.handle_file(filename) self.handle_file(filename)
elif command == 'import': elif command == 'import':
"import module1 [\n module2, \n module3 ...]" "import module1 [\n module2, \n module3 ...]"
@ -160,9 +178,9 @@ 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:
klass, func = func.split('.', 1) klass, func = func.split('.', 1)
@ -173,30 +191,42 @@ class Overrides:
else: else:
self.functions[func] = rest self.functions[func] = rest
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] = 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
for glob in self.glob_ignores: for glob in self.glob_ignores:
if fnmatch.fnmatchcase(name, glob): if fnmatch.fnmatchcase(name, glob):
return 1 return 1
return 0 return 0
def is_type_ignored(self, name): def is_type_ignored(self, name):
return name in self.type_ignores return name in self.type_ignores
def is_overriden(self, name): def is_overriden(self, name):
return self.overrides.has_key(name) return self.overrides.has_key(name)
def is_already_included(self, name): def is_already_included(self, name):
return self.overridden.has_key(name) return self.overridden.has_key(name)
def override(self, name): def override(self, name):
self.overridden[name] = 1 self.overridden[name] = 1
return self.overrides[name] return self.overrides[name]
@ -207,39 +237,51 @@ class Overrides:
def function(self, name): def function(self, name):
return self.functions[name] return self.functions[name]
def getstartline(self, name): def getstartline(self, name):
return self.startlines[name] return self.startlines[name]
def wants_kwargs(self, name): def wants_kwargs(self, name):
return self.kwargs.has_key(name) return self.kwargs.has_key(name)
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)
def attr_override(self, attr): def attr_override(self, attr):
return self.override_attrs[attr] return self.override_attrs[attr]
def slot_is_overriden(self, slot): def slot_is_overriden(self, slot):
return self.override_slots.has_key(slot) return self.override_slots.has_key(slot)
def slot_override(self, slot): def slot_override(self, slot):
return self.override_slots[slot] return self.override_slots[slot]
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
def get_imports(self): def get_imports(self):
return self.imports return self.imports
def get_defines_for(self, klass): def get_defines_for(self, klass):
return self.defines.get(klass, {}) return self.defines.get(klass, {})
def get_functions(self): def get_functions(self):
return self.functions return self.functions

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'''
@ -24,10 +27,10 @@ class CodeSink(object):
if l[-1]: if l[-1]:
l.append('') l.append('')
return '\n'.join(l) return '\n'.join(l)
def writeln(self, line=''): def writeln(self, line=''):
raise NotImplementedError raise NotImplementedError
def indent(self, level=4): def indent(self, level=4):
'''Add a certain ammount of indentation to all lines written '''Add a certain ammount of indentation to all lines written
from now on and until unindent() is called''' from now on and until unindent() is called'''
@ -75,18 +78,20 @@ class ReverseWrapper(object):
assert isinstance(cname, str) assert isinstance(cname, str)
self.cname = cname self.cname = cname
## function object we will call, or object whose method we will call ## function object we will call, or object whose method we will call
self.called_pyobj = None self.called_pyobj = None
## name of method of self.called_pyobj we will call ## name of method of self.called_pyobj we will call
self.method_name = None self.method_name = None
self.is_static = is_static self.is_static = is_static
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);")
@ -201,7 +235,7 @@ class ReverseWrapper(object):
argc = None argc = None
self.body.writeln() self.body.writeln()
if py_args != "NULL": if py_args != "NULL":
self.write_code("py_args = PyTuple_New(%s);" % argc, self.write_code("py_args = PyTuple_New(%s);" % argc,
cleanup="Py_DECREF(py_args);") cleanup="Py_DECREF(py_args);")
@ -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),
@ -243,14 +277,44 @@ class ReverseWrapper(object):
% (py_args,), % (py_args,),
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,19 +750,22 @@ class CallbackInUserDataParam(Parameter):
def _test(): def _test():
import sys import sys
wrapper = ReverseWrapper("this_is_the_c_function_name", is_static=True) if 1:
wrapper.set_return_type(StringReturn(wrapper)) wrapper = ReverseWrapper("this_is_the_c_function_name", is_static=True)
wrapper.add_parameter(PyGObjectMethodParam(wrapper, "self", method_name="do_xxx")) wrapper.set_return_type(StringReturn(wrapper))
wrapper.add_parameter(StringParam(wrapper, "param2", optional=True)) wrapper.add_parameter(PyGObjectMethodParam(wrapper, "self", method_name="do_xxx"))
wrapper.add_parameter(GObjectParam(wrapper, "param3")) wrapper.add_parameter(StringParam(wrapper, "param2", optional=True))
wrapper.generate(FileCodeSink(sys.stderr)) wrapper.add_parameter(GObjectParam(wrapper, "param3"))
#wrapper.add_parameter(InoutIntParam(wrapper, "param4"))
wrapper.generate(FileCodeSink(sys.stderr))
wrapper = ReverseWrapper("this_a_callback_wrapper") if 0:
wrapper.set_return_type(VoidReturn(wrapper)) wrapper = ReverseWrapper("this_a_callback_wrapper")
wrapper.add_parameter(StringParam(wrapper, "param1", optional=False)) wrapper.set_return_type(VoidReturn(wrapper))
wrapper.add_parameter(GObjectParam(wrapper, "param2")) wrapper.add_parameter(StringParam(wrapper, "param1", optional=False))
wrapper.add_parameter(CallbackInUserDataParam(wrapper, "data", free_it=True)) wrapper.add_parameter(GObjectParam(wrapper, "param2"))
wrapper.generate(FileCodeSink(sys.stderr)) wrapper.add_parameter(CallbackInUserDataParam(wrapper, "data", free_it=True))
wrapper.generate(FileCodeSink(sys.stderr))
if __name__ == '__main__': if __name__ == '__main__':
_test() _test()

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