r4658 - in trunk/src/host/pye17: . codegen edje evas

marek at docs.openmoko.org marek at docs.openmoko.org
Sat Sep 20 18:37:20 CEST 2008


Author: marek
Date: 2008-09-20 18:37:19 +0200 (Sat, 20 Sep 2008)
New Revision: 4658

Added:
   trunk/src/host/pye17/Makefile
   trunk/src/host/pye17/codegen/
   trunk/src/host/pye17/codegen/__init__.py
   trunk/src/host/pye17/codegen/argtypes.py
   trunk/src/host/pye17/codegen/codegen.py
   trunk/src/host/pye17/codegen/createdefs.py
   trunk/src/host/pye17/codegen/definitions.py
   trunk/src/host/pye17/codegen/defsparser.py
   trunk/src/host/pye17/codegen/docextract.py
   trunk/src/host/pye17/codegen/docgen.py
   trunk/src/host/pye17/codegen/h2def.py
   trunk/src/host/pye17/codegen/mergedefs.py
   trunk/src/host/pye17/codegen/mkskel.py
   trunk/src/host/pye17/codegen/override.py
   trunk/src/host/pye17/codegen/reversewrapper.py
   trunk/src/host/pye17/codegen/scmexpr.py
   trunk/src/host/pye17/edje/
   trunk/src/host/pye17/edje/Makefile
   trunk/src/host/pye17/edje/edje.override
   trunk/src/host/pye17/edje/edjemodule.c
   trunk/src/host/pye17/evas/
   trunk/src/host/pye17/evas/Makefile
   trunk/src/host/pye17/evas/evas.override
   trunk/src/host/pye17/evas/evas_data.defs
   trunk/src/host/pye17/evas/evasmodule.c
Log:
initial python binding upload
simply type "make" in the base folder to start compiling

known issues:
evas does not fully compile yet
makefiles are not ready for crosscompile environment (include dirs are hardcoded)
even if the binding compiles errors are to be expected


Added: trunk/src/host/pye17/Makefile
===================================================================
--- trunk/src/host/pye17/Makefile	                        (rev 0)
+++ trunk/src/host/pye17/Makefile	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,37 @@
+
+if-exists = $(if ($wildcard $1),$2,$3)
+
+# E_PATH not given (env variable)
+ifeq ($(wildcard $(E_PATH)),)
+
+E_PATH_TMP=~/openmoko/e17/libs
+ifneq ($(wildcard $(E_PATH_TMP)),)
+E_PATH = $(E_PATH_TMP)
+endif
+
+endif
+
+ifeq ($(wildcard $(E_PATH)),)
+$(error Path to enlightenment libaries variable is missing, please set E_PATH)
+endif
+
+
+PWD := $(shell pwd)
+CODEGEN_PATH = $(PWD)/codegen
+PYTHON = $(shell which python)
+
+
+e_bindings = evas edje
+
+e_bindings_mk = $(e_bindings:=.mk)
+
+.PHONY: all clean
+
+
+all:	$(e_bindings_mk)
+
+clean:	all
+
+%.mk:
+	make -C $*/ CODEGEN_PATH=$(CODEGEN_PATH) E_PATH=$(E_PATH) PYTHON=$(PYTHON) $(MAKECMDGOALS)
+

Added: trunk/src/host/pye17/codegen/__init__.py
===================================================================
--- trunk/src/host/pye17/codegen/__init__.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/__init__.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,15 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+
+__all__ = [
+    'argtypes',
+    'codegen',
+    'definitions',
+    'defsparser',
+    'docextract',
+    'docgen',
+    'h2def',
+    'mergedefs',
+    'mkskel',
+    'override',
+    'scmexpr'
+]

Added: trunk/src/host/pye17/codegen/argtypes.py
===================================================================
--- trunk/src/host/pye17/codegen/argtypes.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/argtypes.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,1115 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+import string
+import keyword
+import struct
+
+py_ssize_t_clean = False
+
+class ArgTypeError(Exception):
+    pass
+
+class ArgTypeNotFoundError(ArgTypeError):
+    pass
+
+class ArgTypeConfigurationError(ArgTypeError):
+    pass
+
+
+class VarList:
+    """Nicely format a C variable list"""
+    def __init__(self):
+        self.vars = {}
+    def add(self, ctype, name):
+        if self.vars.has_key(ctype):
+            self.vars[ctype] = self.vars[ctype] + (name,)
+        else:
+            self.vars[ctype] = (name,)
+    def __str__(self):
+        ret = []
+        for type in self.vars.keys():
+            ret.append('    ')
+            ret.append(type)
+            ret.append(' ')
+            ret.append(string.join(self.vars[type], ', '))
+            ret.append(';\n')
+        if ret:
+            ret.append('\n')
+            return string.join(ret, '')
+        return ''
+
+class WrapperInfo:
+    """A class that holds information about variable defs, code
+    snippets, etcd for use in writing out the function/method
+    wrapper."""
+    def __init__(self):
+        self.varlist = VarList()
+        self.parsestr = ''
+        self.parselist = ['', 'kwlist']
+        self.codebefore = []
+        self.codeafter = []
+        self.arglist = []
+        self.kwlist = []
+    def get_parselist(self):
+        return string.join(self.parselist, ', ')
+    def get_codebefore(self):
+        return string.join(self.codebefore, '')
+    def get_codeafter(self):
+        return string.join(self.codeafter, '')
+    def get_arglist(self):
+        return string.join(self.arglist, ', ')
+    def get_varlist(self):
+        return str(self.varlist)
+    def get_kwlist(self):
+        ret = '    static char *kwlist[] = { %s };\n' % \
+              string.join(self.kwlist + [ 'NULL' ], ', ')
+        if not self.get_varlist():
+            ret = ret + '\n'
+        return ret
+
+    def add_parselist(self, codes, parseargs, keywords):
+        self.parsestr = self.parsestr + codes
+        for arg in parseargs:
+            self.parselist.append(arg)
+        for kw in keywords:
+            if keyword.iskeyword(kw):
+                kw = kw + '_'
+            self.kwlist.append('"%s"' % kw)
+
+class ArgType:
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        """Add code to the WrapperInfo instance to handle
+        parameter."""
+        raise RuntimeError, "write_param not implemented for %s" % \
+              self.__class__.__name__
+    def write_return(self, ptype, ownsreturn, info):
+        """Adds a variable named ret of the return type to
+        info.varlist, and add any required code to info.codeafter to
+        convert the return value to a python object."""
+        raise RuntimeError, "write_return not implemented for %s" % \
+              self.__class__.__name__
+
+class NoneArg(ArgType):
+    def write_return(self, ptype, ownsreturn, info):
+        info.codeafter.append('    Py_INCREF(Py_None);\n' +
+                              '    return Py_None;')
+
+class StringArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt != None:
+            if pdflt != 'NULL': pdflt = '"' + pdflt + '"'
+            info.varlist.add('char', '*' + pname + ' = ' + pdflt)
+        else:
+            info.varlist.add('char', '*' + pname)
+        info.arglist.append(pname)
+        if pnull:
+            info.add_parselist('z', ['&' + pname], [pname])
+        else:
+            info.add_parselist('s', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        if ownsreturn:
+            # have to free result ...
+            info.varlist.add('gchar', '*ret')
+            info.codeafter.append('    if (ret) {\n' +
+                                  '        PyObject *py_ret = PyString_FromString(ret);\n' +
+                                  '        g_free(ret);\n' +
+                                  '        return py_ret;\n' +
+                                  '    }\n' +
+                                  '    Py_INCREF(Py_None);\n' +
+                                  '    return Py_None;')
+        else:
+            info.varlist.add('const gchar', '*ret')
+            info.codeafter.append('    if (ret)\n' +
+                                  '        return PyString_FromString(ret);\n'+
+                                  '    Py_INCREF(Py_None);\n' +
+                                  '    return Py_None;')
+
+class StringPtrArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt != None:
+            if pdflt != 'NULL': pdflt = '"' + pdflt + '"'
+            info.varlist.add('char', '**' + pname + ' = ' + pdflt)
+        else:
+            info.varlist.add('char', '**' + pname)
+        info.arglist.append(pname)
+        if pnull:
+            info.add_parselist('z', ['&' + pname], [pname])
+        else:
+            info.add_parselist('s', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        if ownsreturn:
+            # have to free result ...
+            info.varlist.add('gchar', '*ret')
+            info.codeafter.append('    if (ret) {\n' +
+                                  '        PyObject *py_ret = PyString_FromString(ret);\n' +
+                                  '        g_free(ret);\n' +
+                                  '        return py_ret;\n' +
+                                  '    }\n' +
+                                  '    Py_INCREF(Py_None);\n' +
+                                  '    return Py_None;')
+        else:
+            info.varlist.add('const gchar', '*ret')
+            info.codeafter.append('    if (ret)\n' +
+                                  '        return PyString_FromString(ret);\n'+
+                                  '    Py_INCREF(Py_None);\n' +
+                                  '    return Py_None;')
+
+class UCharArg(ArgType):
+    # allows strings with embedded NULLs.
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('guchar', '*' + pname + ' = "' + pdflt + '"')
+        else:
+            info.varlist.add('guchar', '*' + pname)
+        if py_ssize_t_clean:
+            info.varlist.add('Py_ssize_t', pname + '_len')
+        else:
+            info.varlist.add('int', pname + '_len')
+        info.arglist.append(pname)
+        if pnull:
+            info.add_parselist('z#', ['&' + pname, '&' + pname + '_len'],
+                               [pname])
+        else:
+            info.add_parselist('s#', ['&' + pname, '&' + pname + '_len'],
+                               [pname])
+
+class CharArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('char', pname + " = '" + pdflt + "'")
+        else:
+            info.varlist.add('char', pname)
+        info.arglist.append(pname)
+        info.add_parselist('c', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('gchar', 'ret')
+        info.codeafter.append('    return PyString_FromStringAndSize(&ret, 1);')
+class GUniCharArg(ArgType):
+    ret_tmpl = ('#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2\n'
+                '    if (ret > 0xffff) {\n'
+                '        PyErr_SetString(PyExc_RuntimeError, "returned character can not be represented in 16-bit unicode");\n'
+                '        return NULL;\n'
+                '    }\n'
+                '#endif\n'
+                '    py_ret = (Py_UNICODE)ret;\n'
+                '    return PyUnicode_FromUnicode(&py_ret, 1);\n')
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('gunichar', pname + " = '" + pdflt + "'")
+        else:
+            info.varlist.add('gunichar', pname)
+        info.arglist.append(pname)
+        info.add_parselist('O&', ['pyg_pyobj_to_unichar_conv', '&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('gunichar', 'ret')
+        info.varlist.add('Py_UNICODE', 'py_ret')
+        info.codeafter.append(self.ret_tmpl)
+
+
+class IntArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('int', pname + ' = ' + pdflt)
+        else:
+            info.varlist.add('int', pname)
+        info.arglist.append(pname)
+        info.add_parselist('i', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('int', 'ret')
+        info.codeafter.append('    return PyInt_FromLong(ret);')
+
+class UIntArg(ArgType):
+    dflt = ('    if (py_%(name)s) {\n'
+            '        if (PyLong_Check(py_%(name)s))\n'
+            '            %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
+            '        else if (PyInt_Check(py_%(name)s))\n'
+            '            %(name)s = PyInt_AsLong(py_%(name)s);\n'
+            '        else\n'
+            '            PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
+            '        if (PyErr_Occurred())\n'
+            '            return NULL;\n'
+            '    }\n')
+    before = ('    if (PyLong_Check(py_%(name)s))\n'
+              '        %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
+              '    else if (PyInt_Check(py_%(name)s))\n'
+              '        %(name)s = PyInt_AsLong(py_%(name)s);\n'
+              '    else\n'
+              '        PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
+              '    if (PyErr_Occurred())\n'
+              '        return NULL;\n')
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if not pdflt:
+            pdflt = '0';
+
+	if ptype == 'unsigned-int':
+		info.varlist.add("unsigned int", pname + ' = ' + pdflt)
+	else:
+		info.varlist.add(ptype, pname + ' = ' + pdflt)
+        info.codebefore.append(self.dflt % {'name':pname})
+        info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
+        info.arglist.append(pname)
+        info.add_parselist('O', ['&py_' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add(ptype, 'ret')
+        info.codeafter.append('    return PyLong_FromUnsignedLong(ret);')
+
+class SizeArg(ArgType):
+
+    if struct.calcsize('P') <= struct.calcsize('l'):
+        llp64 = True
+    else:
+        llp64 = False
+
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add(ptype, pname + ' = ' + pdflt)
+        else:
+            info.varlist.add(ptype, pname)
+        info.arglist.append(pname)
+        if self.llp64:
+            info.add_parselist('k', ['&' + pname], [pname])
+        else:
+            info.add_parselist('K', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add(ptype, 'ret')
+        if self.llp64:
+            info.codeafter.append('    return PyLong_FromUnsignedLongLong(ret);\n')
+        else:
+            info.codeafter.append('    return PyLong_FromUnsignedLong(ret);\n')
+
+class SSizeArg(ArgType):
+
+    if struct.calcsize('P') <= struct.calcsize('l'):
+        llp64 = True
+    else:
+        llp64 = False
+
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add(ptype, pname + ' = ' + pdflt)
+        else:
+            info.varlist.add(ptype, pname)
+        info.arglist.append(pname)
+        if self.llp64:
+            info.add_parselist('l', ['&' + pname], [pname])
+        else:
+            info.add_parselist('L', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add(ptype, 'ret')
+        if self.llp64:
+            info.codeafter.append('    return PyLong_FromLongLong(ret);\n')
+        else:
+            info.codeafter.append('    return PyLong_FromLong(ret);\n')
+
+class LongArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add(ptype, pname + ' = ' + pdflt)
+        else:
+            info.varlist.add(ptype, pname)
+        info.arglist.append(pname)
+        info.add_parselist('l', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add(ptype, 'ret')
+        info.codeafter.append('    return PyInt_FromLong(ret);\n')
+
+class BoolArg(IntArg):
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('int', 'ret')
+        info.codeafter.append('    return PyBool_FromLong(ret);\n')
+
+class TimeTArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('time_t', pname + ' = ' + pdflt)
+        else:
+            info.varlist.add('time_t', pname)
+        info.arglist.append(pname)
+        info.add_parselist('i', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('time_t', 'ret')
+        info.codeafter.append('    return PyInt_FromLong(ret);')
+
+class ULongArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('unsigned long', pname + ' = ' + pdflt)
+        else:
+            info.varlist.add('unsigned long', pname)
+        info.arglist.append(pname)
+        info.add_parselist('k', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add(ptype, 'ret')
+        info.codeafter.append('    return PyLong_FromUnsignedLong(ret);\n')
+
+class UInt32Arg(ULongArg):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        ULongArg.write_param(self, ptype, pname, pdflt, pnull, 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):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('gint64', pname + ' = ' + pdflt)
+        else:
+            info.varlist.add('gint64', pname)
+        info.arglist.append(pname)
+        info.add_parselist('L', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('gint64', 'ret')
+        info.codeafter.append('    return PyLong_FromLongLong(ret);')
+
+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, info):
+        if pdflt:
+            info.varlist.add('guint64', pname + ' = ' + pdflt)
+            info.codebefore.append(self.dflt % {'name':pname})
+        else:
+            info.varlist.add('guint64', 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):
+        info.varlist.add('guint64', 'ret')
+        info.codeafter.append('    return PyLong_FromUnsignedLongLong(ret);')
+
+
+class DoubleArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('double', pname + ' = ' + pdflt)
+        else:
+            info.varlist.add('double', pname)
+        info.arglist.append(pname)
+        info.add_parselist('d', ['&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('double', 'ret')
+        info.codeafter.append('    return PyFloat_FromDouble(ret);')
+
+class FileArg(ArgType):
+    nulldflt = ('    if (py_%(name)s == Py_None)\n'
+                '        %(name)s = NULL;\n'
+                '    else if (py_%(name)s && PyFile_Check(py_%(name)s)\n'
+                '        %s = PyFile_AsFile(py_%(name)s);\n'
+                '    else if (py_%(name)s) {\n'
+                '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a file object or None");\n'
+                '        return NULL;\n'
+                '    }')
+    null = ('    if (py_%(name)s && PyFile_Check(py_%(name)s)\n'
+            '        %(name)s = PyFile_AsFile(py_%(name)s);\n'
+            '    else if (py_%(name)s != Py_None) {\n'
+            '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a file object or None");\n'
+            '        return NULL;\n'
+            '    }\n')
+    dflt = ('    if (py_%(name)s)\n'
+            '        %(name)s = PyFile_AsFile(py_%(name)s);\n')
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pnull:
+            if pdflt:
+                info.varlist.add('FILE', '*' + pname + ' = ' + pdflt)
+                info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+                info.codebefore.append(self.nulldflt % {'name':pname})
+            else:
+                info.varlist.add('FILE', '*' + pname + ' = NULL')
+                info.varlist.add('PyObject', '*py_' + pname)
+                info.codebefore.append(self.null & {'name':pname})
+            info.arglist.appned(pname)
+            info.add_parselist('O', ['&py_' + pname], [pname])
+        else:
+            if pdflt:
+                info.varlist.add('FILE', '*' + pname + ' = ' + pdflt)
+                info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+                info.codebefore.append(self.dflt % {'name':pname})
+                info.arglist.append(pname)
+            else:
+                info.varlist.add('PyObject', '*' + pname)
+                info.arglist.append('PyFile_AsFile(' + pname + ')')
+            info.add_parselist('O!', ['&PyFile_Type', '&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('FILE', '*ret')
+        info.codeafter.append('    if (ret)\n' +
+                              '        return PyFile_FromFile(ret, "", "", fclose);\n' +
+                              '    Py_INCREF(Py_None);\n' +
+                              '    return Py_None;')
+
+class EnumArg(ArgType):
+    enum = ('    if (pyg_enum_get_value(%(typecode)s, py_%(name)s, (gpointer)&%(name)s))\n'
+            '        return NULL;\n')
+    def __init__(self, enumname, typecode):
+        self.enumname = enumname
+        self.typecode = typecode
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add(self.enumname, pname + ' = ' + pdflt)
+        else:
+            info.varlist.add(self.enumname, pname)
+        info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+        info.codebefore.append(self.enum % { 'typecode': self.typecode,
+                                             'name': pname})
+        info.arglist.append(pname)
+        info.add_parselist('O', ['&py_' + pname], [pname]);
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('gint', 'ret')
+        info.codeafter.append('    return pyg_enum_from_gtype(%s, ret);' % self.typecode)
+
+class FlagsArg(ArgType):
+    flag = ('    if (%(default)spyg_flags_get_value(%(typecode)s, py_%(name)s, (gpointer)&%(name)s))\n'
+            '        return NULL;\n')
+    def __init__(self, flagname, typecode):
+        self.flagname = flagname
+        self.typecode = typecode
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add(self.flagname, pname + ' = ' + pdflt)
+            default = "py_%s && " % (pname,)
+        else:
+            info.varlist.add(self.flagname, pname)
+            default = ""
+        info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+        info.codebefore.append(self.flag % {'default':default,
+                                            'typecode':self.typecode,
+                                            'name':pname})
+        info.arglist.append(pname)
+        info.add_parselist('O', ['&py_' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('guint', 'ret')
+        info.codeafter.append('    return pyg_flags_from_gtype(%s, ret);' % self.typecode)
+
+class ObjectArg(ArgType):
+    # should change these checks to more typesafe versions that check
+    # a little further down in the class heirachy.
+    nulldflt = ('    if ((PyObject *)py_%(name)s == Py_None)\n'
+                '        %(name)s = NULL;\n'
+                '    else if (py_%(name)s && pygobject_check(py_%(name)s, &Py%(type)s_Type))\n'
+                '        %(name)s = %(cast)s(py_%(name)s->obj);\n'
+                '    else if (py_%(name)s) {\n'
+                '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
+                '        return NULL;\n'
+                '    }\n')
+    null = ('    if (py_%(name)s && pygobject_check(py_%(name)s, &Py%(type)s_Type))\n'
+            '        %(name)s = %(cast)s(py_%(name)s->obj);\n'
+            '    else if ((PyObject *)py_%(name)s != Py_None) {\n'
+            '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
+            '        return NULL;\n'
+            '    }\n')
+    dflt = '    if (py_%(name)s)\n' \
+           '        %(name)s = %(cast)s(py_%(name)s->obj);\n'
+    def __init__(self, objname, parent, typecode):
+        self.objname = objname
+        self.cast = string.replace(typecode, '_TYPE_', '_', 1)
+        self.parent = parent
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pnull:
+            if pdflt:
+                info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
+                info.varlist.add('PyGObject', '*py_' + pname + ' = NULL')
+                info.codebefore.append(self.nulldflt % {'name':pname,
+                                                        'cast':self.cast,
+                                                        'type':self.objname})
+            else:
+                info.varlist.add(self.objname, '*' + pname + ' = NULL')
+                info.varlist.add('PyGObject', '*py_' + pname)
+                info.codebefore.append(self.null % {'name':pname,
+                                                    'cast':self.cast,
+                                                    'type':self.objname})
+            if ptype.endswith('*'):
+                typename = ptype[:-1]
+                try:
+                    const, typename = typename.split('const-')
+                except ValueError:
+                    const = ''
+
+            #fd = open("/tmp/codegen.log","a+")
+	    #fd.write("ObjectArg == typename: " + typename + "; ptype: " + ptype + " \n")
+	    #fd.close
+
+            if typename != ptype:
+	        info.arglist.append('(%s *) %s' % (ptype[:-1], pname))
+            else:
+                info.arglist.append(pname)
+
+            info.add_parselist('O', ['&py_' + pname], [pname])
+        else:
+            if pdflt:
+                info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
+                info.varlist.add('PyGObject', '*py_' + pname + ' = NULL')
+                info.codebefore.append(self.dflt % {'name':pname,
+                                                    'cast':self.cast})
+                info.arglist.append(pname)
+                info.add_parselist('O!', ['&Py%s_Type' % self.objname,
+                                         '&py_' + pname], [pname])
+            else:
+                info.varlist.add('PyGObject', '*' + pname)
+                info.arglist.append('(%s *)(%s->obj)' % (self.cast, pname))
+                info.add_parselist('O!', ['&Py%s_Type' % self.objname,
+                                          '&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        if ptype.endswith('*'):
+            typename = ptype[:-1]
+            try:
+                const, typename = typename.split('const-')
+            except ValueError:
+                const = ''
+        info.varlist.add(typename, '*ret')
+        if ownsreturn:
+            info.varlist.add('PyObject', '*py_ret')
+            info.codeafter.append('    py_ret = pygobject_new((GObject *)ret);\n'
+                                  '    if (ret != NULL)\n'
+                                  '        g_object_unref(ret);\n'
+                                  '    return py_ret;')
+        else:
+            info.codeafter.append('    /* pygobject_new handles NULL checking */\n' +
+                                  '    return pygobject_new((GObject *)ret);')
+
+class BoxedArg(ArgType):
+    # haven't done support for default args.  Is it needed?
+    check = ('    if (pyg_boxed_check(py_%(name)s, %(typecode)s))\n'
+             '        %(name)s = pyg_boxed_get(py_%(name)s, %(typename)s);\n'
+             '    else {\n'
+             '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s");\n'
+             '        return NULL;\n'
+             '    }\n')
+    null = ('    if (pyg_boxed_check(py_%(name)s, %(typecode)s))\n'
+            '        %(name)s = pyg_boxed_get(py_%(name)s, %(typename)s);\n'
+            '    else if (py_%(name)s != Py_None) {\n'
+            '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s or None");\n'
+            '        return NULL;\n'
+            '    }\n')
+    def __init__(self, ptype, typecode):
+        self.typename = ptype
+        self.typecode = typecode
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pnull:
+            info.varlist.add(self.typename, '*' + pname + ' = NULL')
+            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
+            info.codebefore.append(self.null % {'name':  pname,
+                                                'typename': self.typename,
+                                                'typecode': self.typecode})
+        else:
+            info.varlist.add(self.typename, '*' + pname + ' = NULL')
+            info.varlist.add('PyObject', '*py_' + pname)
+            info.codebefore.append(self.check % {'name':  pname,
+                                                 'typename': self.typename,
+                                                 'typecode': self.typecode})
+        if ptype[-1] == '*':
+            typename = ptype[:-1]
+            if typename[:6] == 'const-': typename = typename[6:]
+            if typename != self.typename:
+                info.arglist.append('(%s *)%s' % (ptype[:-1], pname))
+            else:
+                info.arglist.append(pname)
+        else:
+            info.arglist.append(pname)
+        info.add_parselist('O', ['&py_' + pname], [pname])
+    ret_tmpl = '    /* pyg_boxed_new handles NULL checking */\n' \
+               '    return pyg_boxed_new(%(typecode)s, %(ret)s, %(copy)s, TRUE);'
+    def write_return(self, ptype, ownsreturn, info):
+        if ptype[-1] == '*':
+            decl_type = self.typename
+            ret = 'ret'
+            if ptype[:6] == 'const-':
+                decl_type = 'const ' + self.typename
+                ret = '(%s*) ret' % (self.typename,)
+            info.varlist.add(decl_type, '*ret')
+        else:
+            info.varlist.add(self.typename, 'ret')
+            ret = '&ret'
+            ownsreturn = 0 # of course it can't own a ref to a local var ...
+        info.codeafter.append(self.ret_tmpl %
+                              { 'typecode': self.typecode,
+                                'ret': ret,
+                                'copy': ownsreturn and 'FALSE' or 'TRUE'})
+
+class CustomBoxedArg(ArgType):
+    # haven't done support for default args.  Is it needed?
+    null = ('    if (%(check)s(py_%(name)s))\n'
+            '        %(name)s = %(get)s(py_%(name)s);\n'
+            '    else if (py_%(name)s != Py_None) {\n'
+            '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
+            '        return NULL;\n'
+            '    }\n')
+    def __init__(self, ptype, pytype, getter, new):
+        self.pytype = pytype
+        self.getter = getter
+        self.checker = 'Py' + ptype + '_Check'
+        self.new = new
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pnull:
+            info.varlist.add(ptype[:-1], '*' + pname + ' = NULL')
+            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
+            info.codebefore.append(self.null % {'name':  pname,
+                                                'get':   self.getter,
+                                                'check': self.checker,
+                                                'type':  ptype[:-1]})
+            info.arglist.append(pname)
+            info.add_parselist('O', ['&py_' + pname], [pname])
+        else:
+            info.varlist.add('PyObject', '*' + pname)
+            info.arglist.append(self.getter + '(' + pname + ')')
+            info.add_parselist('O!', ['&' + self.pytype, '&' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add(ptype[:-1], '*ret')
+        info.codeafter.append('    if (ret)\n' +
+                              '        return ' + self.new + '(ret);\n' +
+                              '    Py_INCREF(Py_None);\n' +
+                              '    return Py_None;')
+
+class PointerArg(ArgType):
+    # haven't done support for default args.  Is it needed?
+    check = ('    if (pyg_pointer_check(py_%(name)s, %(typecode)s))\n'
+             '        %(name)s = pyg_pointer_get(py_%(name)s, %(typename)s);\n'
+             '    else {\n'
+             '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s");\n'
+             '        return NULL;\n'
+             '    }\n')
+    null = ('    if (pyg_pointer_check(py_%(name)s, %(typecode)s))\n'
+            '        %(name)s = pyg_pointer_get(py_%(name)s, %(typename)s);\n'
+            '    else if (py_%(name)s != Py_None) {\n'
+            '        PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s or None");\n'
+            '        return NULL;\n'
+            '    }\n')
+    def __init__(self, ptype, typecode):
+        self.typename = ptype
+        self.typecode = typecode
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+	if self.typename == "unsigned-int":
+		local_typename = "unsigned int"
+	else:
+		local_typename = self.typename
+
+        if pnull:
+            info.varlist.add(local_typename, '*' + pname + ' = NULL')
+            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
+            info.codebefore.append(self.null % {'name':  pname,
+                                                'typename': local_typename,
+                                                'typecode': self.typecode})
+        else:
+            info.varlist.add(local_typename, '*' + pname + ' = NULL')
+            info.varlist.add('PyObject', '*py_' + pname)
+            info.codebefore.append(self.check % {'name':  pname,
+                                                 'typename': local_typename,
+                                                 'typecode': self.typecode})
+        info.arglist.append(pname)
+        info.add_parselist('O', ['&py_' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        if ptype[-1] == '*':
+            info.varlist.add(self.typename, '*ret')
+            info.codeafter.append('    /* pyg_pointer_new handles NULL checking */\n' +
+                                  '    return pyg_pointer_new(' + self.typecode + ', ret);')
+        else:
+            info.varlist.add(self.typename, 'ret')
+            info.codeafter.append('    /* pyg_pointer_new handles NULL checking */\n' +
+                                  '    return pyg_pointer_new(' + self.typecode + ', &ret);')
+
+class AtomArg(IntArg):
+    dflt = '    if (py_%(name)s) {\n' \
+           '        %(name)s = pygdk_atom_from_pyobject(py_%(name)s);\n' \
+           '        if (PyErr_Occurred())\n' \
+           '            return NULL;\n' \
+           '    }\n'
+    atom = ('    %(name)s = pygdk_atom_from_pyobject(py_%(name)s);\n'
+            '    if (PyErr_Occurred())\n'
+            '        return NULL;\n')
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pdflt:
+            info.varlist.add('GdkAtom', pname + ' = ' + pdflt)
+            info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+            info.codebefore.append(self.dflt % {'name': pname})
+        else:
+            info.varlist.add('GdkAtom', pname)
+            info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+            info.codebefore.append(self.atom % {'name': pname})
+        info.arglist.append(pname)
+        info.add_parselist('O', ['&py_' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('GdkAtom', '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):
+    gtype = ('    if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n'
+             '        return NULL;\n')
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        info.varlist.add('GType', pname)
+        info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+        info.codebefore.append(self.gtype % {'name': pname})
+        info.arglist.append(pname)
+        info.add_parselist('O', ['&py_' + pname], [pname])
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('GType', 'ret')
+        info.codeafter.append('    return pyg_type_wrapper_new(ret);')
+
+# simple GError handler.
+class GErrorArg(ArgType):
+    handleerror = ('    if (pyg_error_check(&%(name)s))\n'
+                   '        return NULL;\n')
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        info.varlist.add('GError', '*' + pname + ' = NULL')
+        info.arglist.append('&' + pname)
+        info.codeafter.append(self.handleerror % { 'name': pname })
+
+class GtkTreePathArg(ArgType):
+    # haven't done support for default args.  Is it needed?
+    normal = ('    %(name)s = pygtk_tree_path_from_pyobject(py_%(name)s);\n'
+              '    if (!%(name)s) {\n'
+              '        PyErr_SetString(PyExc_TypeError, "could not convert %(name)s to a GtkTreePath");\n'
+              '        return NULL;\n'
+              '    }\n')
+    null = ('    if (py_%(name)s != Py_None) {\n'
+            '        %(name)s = pygtk_tree_path_from_pyobject(py_%(name)s);\n'
+            '        if (!%(name)s) {\n'
+            '            PyErr_SetString(PyExc_TypeError, "could not convert %(name)s to a GtkTreePath");\n'
+            '            return NULL;\n'
+            '        }\n'
+            '    }\n')
+    freepath = ('    if (%(name)s)\n'
+                '        gtk_tree_path_free(%(name)s);\n')
+    def __init__(self):
+        pass
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pnull:
+            info.varlist.add('GtkTreePath', '*' + pname + ' = NULL')
+            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
+            info.codebefore.append(self.null % {'name':  pname})
+            info.arglist.append(pname)
+            info.add_parselist('O', ['&py_' + pname], [pname])
+        else:
+            info.varlist.add('GtkTreePath', '*' + pname)
+            info.varlist.add('PyObject', '*py_' + pname)
+            info.codebefore.append(self.normal % {'name': pname})
+            info.arglist.append(pname)
+            info.add_parselist('O', ['&py_' + pname], [pname])
+        info.codeafter.append(self.freepath % {'name': pname})
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('GtkTreePath', '*ret')
+        if ownsreturn:
+            info.codeafter.append('    if (ret) {\n'
+                                  '        PyObject *py_ret = pygtk_tree_path_to_pyobject(ret);\n'
+                                  '        gtk_tree_path_free(ret);\n'
+                                  '        return py_ret;\n'
+                                  '    }\n'
+                                  '    Py_INCREF(Py_None);\n'
+                                  '    return Py_None;')
+        else:
+            info.codeafter.append('    if (ret) {\n'
+                                  '        PyObject *py_ret = pygtk_tree_path_to_pyobject(ret);\n'
+                                  '        return py_ret;\n'
+                                  '    }\n'
+                                  '    Py_INCREF(Py_None);\n'
+                                  '    return Py_None;')
+
+class GdkRectanglePtrArg(ArgType):
+    normal = ('    if (!pygdk_rectangle_from_pyobject(py_%(name)s, &%(name)s))\n'
+              '        return NULL;\n')
+    null =   ('    if (py_%(name)s == Py_None)\n'
+              '        %(name)s = NULL;\n'
+              '    else if (pygdk_rectangle_from_pyobject(py_%(name)s, &%(name)s_rect))\n'
+              '        %(name)s = &%(name)s_rect;\n'
+              '    else\n'
+              '            return NULL;\n')
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        if pnull:
+            info.varlist.add('GdkRectangle', pname + '_rect = { 0, 0, 0, 0 }')
+            info.varlist.add('GdkRectangle', '*' + pname)
+            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
+            info.add_parselist('O', ['&py_' + pname], [pname])
+            info.arglist.append(pname)
+            info.codebefore.append(self.null % {'name':  pname})
+        else:
+            info.varlist.add('GdkRectangle', pname + ' = { 0, 0, 0, 0 }')
+            info.varlist.add('PyObject', '*py_' + pname)
+            info.add_parselist('O', ['&py_' + pname], [pname])
+            info.arglist.append('&' + pname)
+            info.codebefore.append(self.normal % {'name':  pname})
+
+class GdkRectangleArg(ArgType):
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add('GdkRectangle', 'ret')
+        info.codeafter.append('    return pyg_boxed_new(GDK_TYPE_RECTANGLE, &ret, TRUE, TRUE);')
+
+class PyObjectArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        info.varlist.add('PyObject', '*' + pname)
+        info.add_parselist('O', ['&' + pname], [pname])
+        info.arglist.append(pname)
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add("PyObject", "*ret")
+        if ownsreturn:
+            info.codeafter.append('    if (ret) {\n'
+                                  '       return ret;\n'
+                                  '    }\n'
+                                  '    Py_INCREF(Py_None);\n'
+                                  '    return Py_None;')
+        else:
+            info.codeafter.append('    if (!ret) ret = Py_None;\n'
+                                  '    Py_INCREF(ret);\n'
+                                  '    return ret;')
+
+class CairoArg(ArgType):
+    def write_param(self, ptype, pname, pdflt, pnull, info):
+        info.varlist.add('PycairoContext', '*' + pname)
+        info.add_parselist('O!', ['&PycairoContext_Type', '&' + pname], [pname])
+        info.arglist.append('%s->ctx' % pname)
+    def write_return(self, ptype, ownsreturn, info):
+        info.varlist.add("cairo_t", "*ret")
+        if ownsreturn:
+            info.codeafter.append('    return PycairoContext_FromContext(ret, NULL, NULL);')
+        else:
+            info.codeafter.append('    cairo_reference(ret);\n'
+                                  '    return PycairoContext_FromContext(ret, NULL, NULL);')
+
+
+class ArgMatcher:
+    def __init__(self):
+        self.argtypes = {}
+        self.reverse_argtypes = {}
+        self.reverse_rettypes = {}
+
+    def register(self, ptype, handler, overwrite=False):
+        if not overwrite and ptype in self.argtypes:
+            return
+        self.argtypes[ptype] = handler
+    def register_reverse(self, ptype, handler):
+        self.reverse_argtypes[ptype] = handler
+    def register_reverse_ret(self, ptype, handler):
+        self.reverse_rettypes[ptype] = handler
+
+    def register_enum(self, ptype, typecode):
+        if typecode is None:
+            self.register(ptype, IntArg())
+        else:
+            self.register(ptype, EnumArg(ptype, typecode))
+    def register_flag(self, ptype, typecode):
+        if typecode is None:
+            self.register(ptype, IntArg())
+        else:
+            self.register(ptype, FlagsArg(ptype, typecode))
+    def register_object(self, ptype, parent, typecode):
+        #fd = open("/tmp/debug.log","a")
+        #fd.write("ptype: " + str(ptype) + ", parent:" + str(parent) + ", typecode: " + str(typecode) + "\n")
+        #fd.close()
+        oa = ObjectArg(ptype, parent, typecode)
+        self.register(ptype, oa)  # in case I forget the * in the .defs
+        self.register(ptype+'*', oa)
+        self.register('const-'+ptype+'*', oa)
+        if ptype == 'GdkPixmap':
+            # hack to handle GdkBitmap synonym.
+            self.register('GdkBitmap', oa)
+            self.register('GdkBitmap*', oa)
+    def register_boxed(self, ptype, typecode):
+        if self.argtypes.has_key(ptype): return
+        arg = BoxedArg(ptype, typecode)
+        self.register(ptype, arg)
+        self.register(ptype+'*', arg)
+        self.register('const-'+ptype+'*', arg)
+    def register_custom_boxed(self, ptype, pytype, getter, new):
+        arg = CustomBoxedArg(ptype, pytype, getter, new)
+        self.register(ptype+'*', arg)
+        self.register('const-'+ptype+'*', arg)
+    def register_pointer(self, ptype, typecode):
+        arg = PointerArg(ptype, typecode)
+	if ptype <> "int" and ptype <> "unsigned-int" and ptype <> "float":
+		self.register(ptype, arg)
+        self.register(ptype+'*', arg)
+        self.register('const-'+ptype+'*', arg)
+
+    def get(self, ptype):
+        try:
+            return self.argtypes[ptype]
+        except KeyError:
+            if ptype[:8] == 'GdkEvent' and ptype[-1] == '*':
+                return self.argtypes['GdkEvent*']
+            raise ArgTypeNotFoundError("No ArgType for %s" % (ptype,))
+    def _get_reverse_common(self, ptype, registry):
+        props = dict(c_type=ptype)
+        try:
+            return registry[ptype], props
+        except KeyError:
+            try:
+                handler = self.argtypes[ptype]
+            except KeyError:
+                if ptype.startswith('GdkEvent') and ptype.endswith('*'):
+                    handler = self.argtypes['GdkEvent*']
+                else:
+                    raise ArgTypeNotFoundError("No ArgType for %s" % (ptype,))
+            if isinstance(handler, ObjectArg):
+                return registry['GObject*'], props
+            elif isinstance(handler, EnumArg):
+                props['typecode'] = handler.typecode
+                props['enumname'] = handler.enumname
+                return registry['GEnum'], props
+            elif isinstance(handler, FlagsArg):
+                props['typecode'] = handler.typecode
+                props['flagname'] = handler.flagname
+                return registry['GFlags'], props
+            elif isinstance(handler, BoxedArg):
+                props['typecode'] = handler.typecode
+                props['typename'] = handler.typename
+                return registry['GBoxed'], props
+            else:
+                raise ArgTypeNotFoundError("No ArgType for %s" % (ptype,))
+    def get_reverse(self, ptype):
+        return self._get_reverse_common(ptype, self.reverse_argtypes)
+    def get_reverse_ret(self, ptype):
+        return self._get_reverse_common(ptype, self.reverse_rettypes)
+
+    def object_is_a(self, otype, parent):
+        if otype == None: return 0
+        if otype == parent: return 1
+        if not self.argtypes.has_key(otype): return 0
+        return self.object_is_a(self.get(otype).parent, parent)
+
+matcher = ArgMatcher()
+
+arg = NoneArg()
+matcher.register(None, arg)
+matcher.register('none', arg)
+
+arg = StringArg()
+matcher.register('char*', arg)
+matcher.register('gchar*', arg)
+matcher.register('const-char*', arg)
+matcher.register('char-const*', arg)
+matcher.register('const-gchar*', arg)
+matcher.register('gchar-const*', arg)
+matcher.register('string', arg)
+matcher.register('static_string', arg)
+
+arg = UCharArg()
+matcher.register('unsigned-char*', arg)
+matcher.register('const-guchar*', arg)
+matcher.register('const-guint8*', arg)
+matcher.register('guchar*', arg)
+
+arg = CharArg()
+matcher.register('char', arg)
+matcher.register('gchar', arg)
+matcher.register('guchar', arg)
+
+arg = GUniCharArg()
+matcher.register('gunichar', arg)
+
+arg = IntArg()
+matcher.register('int', arg)
+matcher.register('gint', arg)
+matcher.register('short', arg)
+matcher.register('gshort', arg)
+matcher.register('gushort', arg)
+matcher.register('gsize', SizeArg())
+matcher.register('gssize', SSizeArg())
+matcher.register('guint8', arg)
+matcher.register('gint8', arg)
+matcher.register('guint16', arg)
+matcher.register('gint16', arg)
+matcher.register('gint32', arg)
+matcher.register('GTime', arg)
+
+arg = LongArg()
+matcher.register('long', arg)
+matcher.register('glong', arg)
+
+arg = UIntArg()
+matcher.register('guint', arg)
+
+arg = BoolArg()
+matcher.register('gboolean', arg)
+
+arg = TimeTArg()
+matcher.register('time_t', arg)
+
+matcher.register('guint32', UInt32Arg())
+
+arg = ULongArg()
+matcher.register('gulong', arg)
+
+arg = Int64Arg()
+matcher.register('gint64', arg)
+matcher.register('long-long', arg)
+
+arg = UInt64Arg()
+matcher.register('guint64', arg)
+matcher.register('unsigned-long-long', arg)
+
+arg = DoubleArg()
+matcher.register('double', arg)
+matcher.register('gdouble', arg)
+matcher.register('float', arg)
+matcher.register('gfloat', arg)
+
+arg = FileArg()
+matcher.register('FILE*', arg)
+
+# enums, flags, objects
+
+matcher.register('GdkAtom', AtomArg())
+
+matcher.register('GType', GTypeArg())
+matcher.register('GtkType', GTypeArg())
+
+matcher.register('GError**', GErrorArg())
+matcher.register('GtkTreePath*', GtkTreePathArg())
+matcher.register('GdkRectangle*', GdkRectanglePtrArg())
+matcher.register('GtkAllocation*', GdkRectanglePtrArg())
+matcher.register('GdkRectangle', GdkRectangleArg())
+matcher.register('PyObject*', PyObjectArg())
+
+matcher.register('GdkNativeWindow', ULongArg())
+
+matcher.register_object('GObject', None, 'G_TYPE_OBJECT')
+
+del arg
+
+matcher.register('cairo_t*', CairoArg())
+
+### EFL ###
+
+# evas
+matcher.register('unsigned-int', UIntArg())
+matcher.register('Evas_Coord', IntArg())
+matcher.register('Evas_Bool', CharArg())
+matcher.register('Evas_Angle', IntArg())
+matcher.register('Evas_Font_Size', IntArg())
+matcher.register('Evas_Modifier_Mask', UInt64Arg())
+
+matcher.register('Evas_Colorspace', UIntArg())  # how to handle enum ?
+matcher.register('Evas_Text_Style_Type', UIntArg()) # enum
+matcher.register('Evas_Textblock_Text_Type', UIntArg()) # enum
+matcher.register('Evas_Aspect_Control', UIntArg()) # enum
+matcher.register('Evas_Render_Op', UIntArg()) # enum
+matcher.register('Evas_Object_Pointer_Mode', UIntArg()) # enum
+matcher.register('Evas_Callback_Type', UIntArg()) # enum
+matcher.register('Evas_Font_Hinting_Flags', UIntArg())
+
+matcher.register('char**', StringPtrArg())
+
+matcher.register_pointer('void', 'G_TYPE_NONE')
+matcher.register_pointer('int', '77')
+matcher.register_pointer('unsigned-int', '77')
+matcher.register_pointer('float', '77')
+matcher.register_pointer('Evas', '77')
+matcher.register_pointer('Evas_Object', '77')
+matcher.register_pointer('Evas_Object_Pointer_Mode', '77')
+matcher.register_pointer('Evas_Array_Hash', '77')
+matcher.register_pointer('Evas_Smart', '77')
+matcher.register_pointer('Evas_Lock', '77')
+matcher.register_pointer('Evas_Textblock_Cursor', '77')
+matcher.register_pointer('Evas_Imaging_Font', '77')
+matcher.register_pointer('Evas_Textblock_Style', '77')
+matcher.register_pointer('Evas_Modifier', '77')
+matcher.register_pointer('Evas_Imaging_Image', '77')

Added: trunk/src/host/pye17/codegen/codegen.py
===================================================================
--- trunk/src/host/pye17/codegen/codegen.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/codegen.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,1726 @@
+import getopt
+import keyword
+import os
+import string
+import sys
+
+import argtypes
+import definitions
+import defsparser
+import override
+import reversewrapper
+import warnings
+
+class Coverage(object):
+    def __init__(self, name):
+        self.name = name
+        self.wrapped = 0
+        self.not_wrapped = 0
+
+    def declare_wrapped(self):
+        self.wrapped += 1
+
+    def declare_not_wrapped(self):
+        self.not_wrapped += 1
+
+    def printstats(self):
+        total = self.wrapped + self.not_wrapped
+        fd = sys.stderr
+        if total:
+            fd.write("***INFO*** The coverage of %s is %.2f%% (%i/%i)\n" %
+                     (self.name,
+                      float(self.wrapped*100)/total,
+                      self.wrapped,
+                      total))
+        else:
+            fd.write("***INFO*** There are no declared %s.\n" % self.name)
+
+functions_coverage = Coverage("global functions")
+methods_coverage = Coverage("methods")
+vproxies_coverage = Coverage("virtual proxies")
+vaccessors_coverage = Coverage("virtual accessors")
+iproxies_coverage = Coverage("interface proxies")
+
+def exc_info():
+    warnings.warn("deprecated", DeprecationWarning, stacklevel=2)
+    #traceback.print_exc()
+    etype, value, tb = sys.exc_info()
+    ret = ""
+    try:
+        sval = str(value)
+        if etype == argtypes.ArgTypeError:
+            ret = "No ArgType for %s" % (sval,)
+        else:
+            ret = sval
+    finally:
+        del etype, value, tb
+    return ret
+
+def fixname(name):
+    if keyword.iskeyword(name):
+        return name + '_'
+    return name
+
+class FileOutput:
+    '''Simple wrapper for file object, that makes writing #line
+    statements easier.''' # "
+    def __init__(self, fp, filename=None):
+        self.fp = fp
+        self.lineno = 1
+        if filename:
+            self.filename = filename
+        else:
+            self.filename = self.fp.name
+    # handle writing to the file, and keep track of the line number ...
+    def write(self, str):
+        self.fp.write(str)
+        self.lineno = self.lineno + string.count(str, '\n')
+    def writelines(self, sequence):
+        for line in sequence:
+            self.write(line)
+    def close(self):
+        self.fp.close()
+    def flush(self):
+        self.fp.flush()
+
+    def setline(self, linenum, filename):
+        '''writes out a #line statement, for use by the C
+        preprocessor.''' # "
+        self.write('#line %d "%s"\n' % (linenum, filename))
+    def resetline(self):
+        '''resets line numbering to the original file'''
+        self.setline(self.lineno + 1, self.filename)
+
+class Wrapper:
+    type_tmpl = (
+        'PyTypeObject G_GNUC_INTERNAL Py%(typename)s_Type = {\n'
+        '    PyObject_HEAD_INIT(NULL)\n'
+        '    0,                                 /* ob_size */\n'
+        '    "%(classname)s",                   /* tp_name */\n'
+        '    sizeof(%(tp_basicsize)s),          /* tp_basicsize */\n'
+        '    0,                                 /* tp_itemsize */\n'
+        '    /* methods */\n'
+        '    (destructor)%(tp_dealloc)s,        /* tp_dealloc */\n'
+        '    (printfunc)0,                      /* tp_print */\n'
+        '    (getattrfunc)%(tp_getattr)s,       /* tp_getattr */\n'
+        '    (setattrfunc)%(tp_setattr)s,       /* tp_setattr */\n'
+        '    (cmpfunc)%(tp_compare)s,           /* tp_compare */\n'
+        '    (reprfunc)%(tp_repr)s,             /* tp_repr */\n'
+        '    (PyNumberMethods*)%(tp_as_number)s,     /* tp_as_number */\n'
+        '    (PySequenceMethods*)%(tp_as_sequence)s, /* tp_as_sequence */\n'
+        '    (PyMappingMethods*)%(tp_as_mapping)s,   /* tp_as_mapping */\n'
+        '    (hashfunc)%(tp_hash)s,             /* tp_hash */\n'
+        '    (ternaryfunc)%(tp_call)s,          /* tp_call */\n'
+        '    (reprfunc)%(tp_str)s,              /* tp_str */\n'
+        '    (getattrofunc)%(tp_getattro)s,     /* tp_getattro */\n'
+        '    (setattrofunc)%(tp_setattro)s,     /* tp_setattro */\n'
+        '    (PyBufferProcs*)%(tp_as_buffer)s,  /* tp_as_buffer */\n'
+        '    %(tp_flags)s,                      /* tp_flags */\n'
+        '    %(tp_doc)s,                        /* Documentation string */\n'
+        '    (traverseproc)%(tp_traverse)s,     /* tp_traverse */\n'
+        '    (inquiry)%(tp_clear)s,             /* tp_clear */\n'
+        '    (richcmpfunc)%(tp_richcompare)s,   /* tp_richcompare */\n'
+        '    %(tp_weaklistoffset)s,             /* tp_weaklistoffset */\n'
+        '    (getiterfunc)%(tp_iter)s,          /* tp_iter */\n'
+        '    (iternextfunc)%(tp_iternext)s,     /* tp_iternext */\n'
+        '    (struct PyMethodDef*)%(tp_methods)s, /* tp_methods */\n'
+        '    (struct PyMemberDef*)0,              /* tp_members */\n'
+        '    (struct PyGetSetDef*)%(tp_getset)s,  /* tp_getset */\n'
+        '    NULL,                              /* tp_base */\n'
+        '    NULL,                              /* tp_dict */\n'
+        '    (descrgetfunc)%(tp_descr_get)s,    /* tp_descr_get */\n'
+        '    (descrsetfunc)%(tp_descr_set)s,    /* tp_descr_set */\n'
+        '    %(tp_dictoffset)s,                 /* tp_dictoffset */\n'
+        '    (initproc)%(tp_init)s,             /* tp_init */\n'
+        '    (allocfunc)%(tp_alloc)s,           /* tp_alloc */\n'
+        '    (newfunc)%(tp_new)s,               /* tp_new */\n'
+        '    (freefunc)%(tp_free)s,             /* tp_free */\n'
+        '    (inquiry)%(tp_is_gc)s              /* tp_is_gc */\n'
+        '};\n\n'
+        )
+
+    slots_list = [
+        'tp_getattr', 'tp_setattr', 'tp_getattro', 'tp_setattro',
+        'tp_compare', 'tp_repr',
+        'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash',
+        'tp_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
+        'tp_iternext', 'tp_descr_get', 'tp_descr_set', 'tp_init',
+        'tp_alloc', 'tp_new', 'tp_free', 'tp_is_gc',
+        'tp_traverse', 'tp_clear', 'tp_dealloc', 'tp_flags', 'tp_doc'
+        ]
+
+    getter_tmpl = (
+        'static PyObject *\n'
+        '%(funcname)s(PyObject *self, void *closure)\n'
+        '{\n'
+        '%(varlist)s'
+        '    ret = %(field)s;\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    parse_tmpl = (
+        '    if (!PyArg_ParseTupleAndKeywords(args, kwargs,'
+        '"%(typecodes)s:%(name)s"%(parselist)s))\n'
+        '        return %(errorreturn)s;\n'
+        )
+
+    deprecated_tmpl = (
+        '    if (PyErr_Warn(PyExc_DeprecationWarning, '
+        '"%(deprecationmsg)s") < 0)\n'
+        '        return %(errorreturn)s;\n'
+        )
+
+    methdef_tmpl = (
+        '    { "%(name)s", (PyCFunction)%(cname)s, %(flags)s,\n'
+        '      %(docstring)s },\n'
+        )
+
+    noconstructor = (
+        'static int\n'
+        'pygobject_no_constructor(PyObject *self, PyObject *args, '
+        'PyObject *kwargs)\n'
+        '{\n'
+        '    gchar buf[512];\n'
+        '\n'
+        '    g_snprintf(buf, sizeof(buf), "%s is an abstract widget", '
+        'self->ob_type->tp_name);\n'
+        '    PyErr_SetString(PyExc_NotImplementedError, buf);\n'
+        '    return -1;\n'
+        '}\n\n'
+        )
+
+    function_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(begin_allow_threads)s\n'
+        '    %(setreturn)s%(cname)s(%(arglist)s);\n'
+        '    %(end_allow_threads)s\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    virtual_accessor_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
+        '{\n'
+        '    gpointer klass;\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    klass = g_type_class_ref(pyg_type_from_object(cls));\n'
+        '    if (%(class_cast_macro)s(klass)->%(virtual)s)\n'
+        '        %(setreturn)s%(class_cast_macro)s(klass)->'
+        '%(virtual)s(%(arglist)s);\n'
+        '    else {\n'
+        '        PyErr_SetString(PyExc_NotImplementedError, '
+        '"virtual method %(name)s not implemented");\n'
+        '        g_type_class_unref(klass);\n'
+        '        return NULL;\n'
+        '    }\n'
+        '    g_type_class_unref(klass);\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    # template for method calls
+    constructor_tmpl = None
+    method_tmpl = None
+
+    def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
+        self.parser = parser
+        self.objinfo = objinfo
+        self.overrides = overrides
+        self.fp = fp
+
+    def get_lower_name(self):
+        return string.lower(string.replace(self.objinfo.typecode,
+                                           '_TYPE_', '_', 1))
+
+    def get_field_accessor(self, fieldname):
+        raise NotImplementedError
+
+    def get_initial_class_substdict(self): return {}
+
+    def get_initial_constructor_substdict(self, constructor):
+        return { 'name': '%s.__init__' % self.objinfo.c_name,
+                 'errorreturn': '-1' }
+    def get_initial_method_substdict(self, method):
+        substdict = { 'name': '%s.%s' % (self.objinfo.c_name, method.name) }
+        if method.unblock_threads:
+            substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
+            substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
+        else:
+            substdict['begin_allow_threads'] = ''
+            substdict['end_allow_threads'] = ''
+        return substdict
+
+    def write_class(self):
+        if self.overrides.is_type_ignored(self.objinfo.c_name):
+            return
+        self.fp.write('\n/* ----------- %s ----------- */\n\n' %
+                      self.objinfo.c_name)
+        substdict = self.get_initial_class_substdict()
+        if not substdict.has_key('tp_flags'):
+            substdict['tp_flags'] = 'Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE'
+        substdict['typename'] = self.objinfo.c_name
+        if self.overrides.modulename:
+            substdict['classname'] = '%s.%s' % (self.overrides.modulename,
+                                           self.objinfo.name)
+        else:
+            substdict['classname'] = self.objinfo.name
+        substdict['tp_doc'] = self.objinfo.docstring
+
+        # Maybe this could be done in a nicer way, but I'll leave it as it is
+        # for now: -- Johan
+        if not self.overrides.slot_is_overriden('%s.tp_init' %
+                                                self.objinfo.c_name):
+            substdict['tp_init'] = self.write_constructor()
+        substdict['tp_methods'] = self.write_methods()
+        substdict['tp_getset'] = self.write_getsets()
+
+        # handle slots ...
+        for slot in self.slots_list:
+
+            slotname = '%s.%s' % (self.objinfo.c_name, slot)
+            slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
+            if slot[:6] == 'tp_as_':
+                slotfunc = '&' + slotfunc
+            if self.overrides.slot_is_overriden(slotname):
+                data = self.overrides.slot_override(slotname)
+                self.write_function(slotname, data)
+                substdict[slot] = slotfunc
+            else:
+                if not substdict.has_key(slot):
+                    substdict[slot] = '0'
+
+        self.fp.write(self.type_tmpl % substdict)
+
+        self.write_virtuals()
+
+    def write_function_wrapper(self, function_obj, template,
+                               handle_return=0, is_method=0, kwargs_needed=0,
+                               substdict=None):
+        '''This function is the guts of all functions that generate
+        wrappers for functions, methods and constructors.'''
+        if not substdict: substdict = {}
+
+        info = argtypes.WrapperInfo()
+
+        substdict.setdefault('errorreturn', 'NULL')
+
+        # for methods, we want the leading comma
+        if is_method:
+            info.arglist.append('')
+
+        if function_obj.varargs:
+            raise argtypes.ArgTypeNotFoundError("varargs functions not supported")
+
+	fd = open("/tmp/codegen.log","a+")
+	fd.write(">>> write_function_wrapper() >>>\n")
+	fd.write("arglist 1: " + str(info.get_arglist()) + "\n")
+
+        for param in function_obj.params:
+            if param.pdflt != None and '|' not in info.parsestr:
+                info.add_parselist('|', [], [])
+            handler = argtypes.matcher.get(param.ptype)
+	    fd.write("pname: " + param.pname + "; ptype: " + str(param.ptype) + "; pdflt: " + str(param.pdflt) + "; pnull: " + str(param.pnull) + "; handler: " + str(handler) + "\n")
+            handler.write_param(param.ptype, param.pname, param.pdflt,
+                                param.pnull, info)
+
+	fd.write("arglist 2: " + str(info.get_arglist()) + "\n")
+
+        substdict['setreturn'] = ''
+        if handle_return:
+            if function_obj.ret not in ('none', None):
+                substdict['setreturn'] = 'ret = '
+            handler = argtypes.matcher.get(function_obj.ret)
+            handler.write_return(function_obj.ret,
+                                 function_obj.caller_owns_return, info)
+
+	fd.write("arglist 3: " + str(info.get_arglist()) + "\n")
+
+        if function_obj.deprecated != None:
+            deprecated = self.deprecated_tmpl % {
+                'deprecationmsg': function_obj.deprecated,
+                'errorreturn': substdict['errorreturn'] }
+        else:
+            deprecated = ''
+
+        # if name isn't set, set it to function_obj.name
+        substdict.setdefault('name', function_obj.name)
+
+        if function_obj.unblock_threads:
+            substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
+            substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
+        else:
+            substdict['begin_allow_threads'] = ''
+            substdict['end_allow_threads'] = ''
+
+        if self.objinfo:
+            substdict['typename'] = self.objinfo.c_name
+        substdict.setdefault('cname',  function_obj.c_name)
+        substdict['varlist'] = info.get_varlist()
+        substdict['typecodes'] = info.parsestr
+        substdict['parselist'] = info.get_parselist()
+        substdict['arglist'] = info.get_arglist()
+        substdict['codebefore'] = deprecated + (
+            string.replace(info.get_codebefore(),
+            'return NULL', 'return ' + substdict['errorreturn'])
+            )
+        substdict['codeafter'] = (
+            string.replace(info.get_codeafter(),
+                           'return NULL',
+                           'return ' + substdict['errorreturn']))
+
+        if info.parsestr or kwargs_needed:
+            substdict['parseargs'] = self.parse_tmpl % substdict
+            substdict['extraparams'] = ', PyObject *args, PyObject *kwargs'
+            flags = 'METH_VARARGS|METH_KEYWORDS'
+
+            # prepend the keyword list to the variable list
+            substdict['varlist'] = info.get_kwlist() + substdict['varlist']
+        else:
+            substdict['parseargs'] = ''
+            substdict['extraparams'] = ''
+            flags = 'METH_NOARGS'
+
+	fd.write("arglist: " + str(info.get_arglist()) + "\n")
+	for key,item in substdict.iteritems():
+		fd.write("key: " + str(key) + ", item: " + str(item) + "\n")
+        fd.close()
+
+        return template % substdict, flags
+
+    def write_constructor(self):
+        initfunc = '0'
+        constructor = self.parser.find_constructor(self.objinfo,self.overrides)
+        if not constructor:
+            return self.write_default_constructor()
+
+        funcname = constructor.c_name
+        try:
+            if self.overrides.is_overriden(funcname):
+                data = self.overrides.override(funcname)
+                self.write_function(funcname, data)
+                self.objinfo.has_new_constructor_api = (
+                    self.objinfo.typecode in
+                    self.overrides.newstyle_constructors)
+            else:
+                # ok, a hack to determine if we should use
+                # new-style constructores :P
+                property_based = getattr(self,
+                                         'write_property_based_constructor',
+                                         None)
+                if property_based:
+                    if (len(constructor.params) == 0 or
+                        isinstance(constructor.params[0],
+                                   definitions.Property)):
+                        # write_property_based_constructor is only
+                        # implemented in GObjectWrapper
+                        return self.write_property_based_constructor(
+                            constructor)
+                    else:
+                        sys.stderr.write(
+                            "Warning: generating old-style constructor for:" +
+                            constructor.c_name + '\n')
+
+                # write constructor from template ...
+                code = self.write_function_wrapper(constructor,
+                    self.constructor_tmpl,
+                    handle_return=0, is_method=0, kwargs_needed=1,
+                    substdict=self.get_initial_constructor_substdict(
+                    constructor))[0]
+                self.fp.write(code)
+            initfunc = '_wrap_' + funcname
+        except argtypes.ArgTypeError, ex:
+            sys.stderr.write('Could not write constructor for %s: %s\n'
+                             % (self.objinfo.c_name, str(ex)))
+
+            initfunc = self.write_noconstructor()
+        return initfunc
+
+    def write_noconstructor(self):
+        # this is a hack ...
+        if not hasattr(self.overrides, 'no_constructor_written'):
+            self.fp.write(self.noconstructor)
+            self.overrides.no_constructor_written = 1
+        initfunc = 'pygobject_no_constructor'
+        return initfunc
+
+    def write_default_constructor(self):
+        return self.write_noconstructor()
+
+    def get_methflags(self, funcname):
+        if self.overrides.wants_kwargs(funcname):
+            flags = 'METH_VARARGS|METH_KEYWORDS'
+        elif self.overrides.wants_noargs(funcname):
+            flags = 'METH_NOARGS'
+        elif self.overrides.wants_onearg(funcname):
+            flags = 'METH_O'
+        else:
+            flags = 'METH_VARARGS'
+        if self.overrides.is_staticmethod(funcname):
+            flags += '|METH_STATIC'
+        elif self.overrides.is_classmethod(funcname):
+            flags += '|METH_CLASS'
+        return flags
+
+    def write_function(self, funcname, data):
+        lineno, filename = self.overrides.getstartline(funcname)
+        self.fp.setline(lineno, filename)
+        self.fp.write(data)
+        self.fp.resetline()
+        self.fp.write('\n\n')
+
+    def _get_class_virtual_substdict(self, meth, cname, parent):
+        substdict = self.get_initial_method_substdict(meth)
+        substdict['virtual'] = substdict['name'].split('.')[1]
+        substdict['cname'] = cname
+        substdict['class_cast_macro'] = parent.typecode.replace(
+            '_TYPE_', '_', 1) + "_CLASS"
+        substdict['typecode'] = self.objinfo.typecode
+        substdict['cast'] = string.replace(parent.typecode, '_TYPE_', '_', 1)
+        return substdict
+
+    def write_methods(self):
+        methods = []
+        klass = self.objinfo.c_name
+        # First, get methods from the defs files
+        for meth in self.parser.find_methods(self.objinfo):
+            method_name = meth.c_name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+
+                    methflags = self.get_methflags(method_name)
+                else:
+                    # write constructor from template ...
+                    code, methflags = self.write_function_wrapper(meth,
+                        self.method_tmpl, handle_return=1, is_method=1,
+                        substdict=self.get_initial_method_substdict(meth))
+                    self.fp.write(code)
+                methods.append(self.methdef_tmpl %
+                               { 'name':  fixname(meth.name),
+                                 'cname': '_wrap_' + method_name,
+                                 'flags': methflags,
+                                 'docstring': meth.docstring })
+                methods_coverage.declare_wrapped()
+            except argtypes.ArgTypeError, ex:
+                methods_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write method %s.%s: %s\n'
+                                % (klass, meth.name, str(ex)))
+
+        # Now try to see if there are any defined in the override
+        for method_name in self.overrides.get_defines_for(klass):
+            c_name = override.class2cname(klass, method_name)
+            if self.overrides.is_already_included(method_name):
+                continue
+
+            try:
+                data = self.overrides.define(klass, method_name)
+                self.write_function(method_name, data)
+                methflags = self.get_methflags(method_name)
+
+                methods.append(self.methdef_tmpl %
+                               { 'name':  method_name,
+                                 'cname': '_wrap_' + c_name,
+                                 'flags': methflags,
+                                 'docstring': 'NULL' })
+                methods_coverage.declare_wrapped()
+            except argtypes.ArgTypeError, ex:
+                methods_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write method %s.%s: %s\n'
+                                % (klass, method_name, str(ex)))
+
+        # Add GObject virtual method accessors, for chaining to parent
+        # virtuals from subclasses
+        methods += self.write_virtual_accessors()
+
+        if methods:
+            methoddefs = '_Py%s_methods' % self.objinfo.c_name
+            # write the PyMethodDef structure
+            methods.append('    { NULL, NULL, 0, NULL }\n')
+            self.fp.write('static const PyMethodDef %s[] = {\n' % methoddefs)
+            self.fp.write(string.join(methods, ''))
+            self.fp.write('};\n\n')
+        else:
+            methoddefs = 'NULL'
+        return methoddefs
+
+    def write_virtual_accessors(self):
+        klass = self.objinfo.c_name
+        methods = []
+        for meth in self.parser.find_virtuals(self.objinfo):
+            method_name = self.objinfo.c_name + "__do_" + meth.name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+                    methflags = self.get_methflags(method_name)
+                else:
+                    # temporarily add a 'self' parameter as first argument
+                    meth.params.insert(0, definitions.Parameter(
+                        ptype=(self.objinfo.c_name + '*'),
+                        pname='self', pdflt=None, pnull=None))
+                    try:
+                        # write method from template ...
+                        code, methflags = self.write_function_wrapper(
+                            meth, self.virtual_accessor_tmpl,
+                            handle_return=True, is_method=False,
+                            substdict=self._get_class_virtual_substdict(
+                            meth, method_name, self.objinfo))
+                        self.fp.write(code)
+                    finally:
+                        del meth.params[0]
+                methods.append(self.methdef_tmpl %
+                               { 'name':  "do_" + fixname(meth.name),
+                                 'cname': '_wrap_' + method_name,
+                                 'flags': methflags + '|METH_CLASS',
+                                 'docstring': 'NULL'})
+                vaccessors_coverage.declare_wrapped()
+            except argtypes.ArgTypeError, ex:
+                vaccessors_coverage.declare_not_wrapped()
+                sys.stderr.write(
+                    'Could not write virtual accessor method %s.%s: %s\n'
+                    % (klass, meth.name, str(ex)))
+        return methods
+
+    def write_virtuals(self):
+        '''
+        Write _wrap_FooBar__proxy_do_zbr() reverse wrapers for
+        GObject virtuals
+        '''
+        klass = self.objinfo.c_name
+        virtuals = []
+        for meth in self.parser.find_virtuals(self.objinfo):
+            method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+                else:
+                    # write virtual proxy ...
+                    ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
+                    wrapper = reversewrapper.ReverseWrapper(
+                        '_wrap_' + method_name, is_static=True)
+                    wrapper.set_return_type(ret(wrapper, **props))
+                    wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
+                        wrapper, "self", method_name="do_" + meth.name,
+                        c_type=(klass + ' *')))
+                    for param in meth.params:
+                        handler, props = argtypes.matcher.get_reverse(
+                            param.ptype)
+                        props["direction"] = param.pdir
+                        wrapper.add_parameter(handler(wrapper,
+                                                      param.pname, **props))
+                    buf = reversewrapper.MemoryCodeSink()
+                    wrapper.generate(buf)
+                    self.fp.write(buf.flush())
+                virtuals.append((fixname(meth.name), '_wrap_' + method_name))
+                vproxies_coverage.declare_wrapped()
+            except argtypes.ArgTypeError, ex:
+                vproxies_coverage.declare_not_wrapped()
+                virtuals.append((fixname(meth.name), None))
+                sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
+                                % (klass, meth.name, str(ex)))
+        if virtuals:
+            # Write a 'pygtk class init' function for this object,
+            # except when the object type is explicitly ignored (like
+            # GtkPlug and GtkSocket on win32).
+            if self.overrides.is_ignored(self.objinfo.typecode):
+                return
+            class_cast_macro = self.objinfo.typecode.replace(
+                '_TYPE_', '_', 1) + "_CLASS"
+            cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1)
+            funcname = "__%s_class_init" % klass
+            self.objinfo.class_init_func = funcname
+            have_implemented_virtuals = not not [True
+                                                 for name, cname in virtuals
+                                                     if cname is not None]
+            self.fp.write(
+            ('\nstatic int\n'
+             '%(funcname)s(gpointer gclass, PyTypeObject *pyclass)\n'
+             '{\n') % vars())
+
+            if have_implemented_virtuals:
+                self.fp.write('    PyObject *o;\n')
+                self.fp.write(
+                    '    %(klass)sClass *klass = '
+                    '%(class_cast_macro)s(gclass);\n'
+                    '    PyObject *gsignals = '
+                    'PyDict_GetItemString(pyclass->tp_dict, "__gsignals__");\n'
+                    % vars())
+
+            for name, cname in virtuals:
+                do_name = 'do_' + name
+                if cname is None:
+                    self.fp.write('\n    /* overriding %(do_name)s '
+                                  'is currently not supported */\n' % vars())
+                else:
+                    self.fp.write('''
+    o = PyObject_GetAttrString((PyObject *) pyclass, "%(do_name)s");
+    if (o == NULL)
+        PyErr_Clear();
+    else {
+        if (!PyObject_TypeCheck(o, &PyCFunction_Type)
+            && !(gsignals && PyDict_GetItemString(gsignals, "%(name)s")))
+            klass->%(name)s = %(cname)s;
+        Py_DECREF(o);
+    }
+''' % vars())
+            self.fp.write('    return 0;\n}\n')
+
+    def write_getsets(self):
+        lower_name = self.get_lower_name()
+        getsets_name = lower_name + '_getsets'
+        getterprefix = '_wrap_' + lower_name + '__get_'
+        setterprefix = '_wrap_' + lower_name + '__set_'
+
+        # no overrides for the whole function.  If no fields,
+        # don't write a func
+        if not self.objinfo.fields:
+            return '0'
+        getsets = []
+        for ftype, cfname in self.objinfo.fields:
+            fname = cfname.replace('.', '_')
+            gettername = '0'
+            settername = '0'
+            attrname = self.objinfo.c_name + '.' + fname
+            if self.overrides.attr_is_overriden(attrname):
+                code = self.overrides.attr_override(attrname)
+                self.write_function(attrname, code)
+                if string.find(code, getterprefix + fname) >= 0:
+                    gettername = getterprefix + fname
+                if string.find(code, setterprefix + fname) >= 0:
+                    settername = setterprefix + fname
+            if gettername == '0':
+                try:
+                    funcname = getterprefix + fname
+                    info = argtypes.WrapperInfo()
+                    handler = argtypes.matcher.get(ftype)
+                    # for attributes, we don't own the "return value"
+                    handler.write_return(ftype, 0, info)
+                    self.fp.write(self.getter_tmpl %
+                                  { 'funcname': funcname,
+                                    'varlist': info.varlist,
+                                    'field': self.get_field_accessor(cfname),
+                                    'codeafter': info.get_codeafter() })
+                    gettername = funcname
+                except argtypes.ArgTypeError, ex:
+                    sys.stderr.write(
+                        "Could not write getter for %s.%s: %s\n"
+                        % (self.objinfo.c_name, fname, str(ex)))
+            if gettername != '0' or settername != '0':
+                getsets.append('    { "%s", (getter)%s, (setter)%s },\n' %
+                               (fixname(fname), gettername, settername))
+
+        if not getsets:
+            return '0'
+        self.fp.write('static const PyGetSetDef %s[] = {\n' % getsets_name)
+        for getset in getsets:
+            self.fp.write(getset)
+        self.fp.write('    { NULL, (getter)0, (setter)0 },\n')
+        self.fp.write('};\n\n')
+
+        return getsets_name
+
+    def _write_get_symbol_names(self, writer, functions):
+        self.fp.write("""static PyObject *
+_wrap__get_symbol_names(PyObject *self)
+{
+    PyObject *pylist = PyList_New(0);
+
+""")
+        for obj, bases in writer.get_classes():
+            self.fp.write('    PyList_Append(pylist, '
+                          'PyString_FromString("%s"));\n' % (obj.name))
+
+        for name, cname, flags, docstring in functions:
+            self.fp.write('    PyList_Append(pylist, '
+                          'PyString_FromString("%s"));\n' % (name))
+
+        for enum in writer.get_enums():
+            self.fp.write('    PyList_Append(pylist, '
+                          'PyString_FromString("%s"));\n' % (enum.name))
+            for nick, value in enum.values:
+                name = value[len(self.overrides.modulename)+1:]
+                self.fp.write('    PyList_Append(pylist, '
+                              'PyString_FromString("%s"));\n' % (name))
+
+        self.fp.write("    return pylist;\n}\n\n");
+
+    def _write_get_symbol(self, writer, functions):
+        self.fp.write("""static PyObject *
+_wrap__get_symbol(PyObject *self, PyObject *args)
+{
+    PyObject *d;
+    char *name;
+    static PyObject *modulename = NULL;
+    static PyObject *module = NULL;
+    static char *strip_prefix = "%s";
+
+    if (!PyArg_ParseTuple(args, "Os", &d, &name))
+        return NULL;
+
+    if (!modulename)
+       modulename = PyString_FromString("%s");
+
+    if (!module)
+       module = PyDict_GetItemString(d, "__module__");
+
+""" % (self.overrides.modulename.upper() + '_',
+       self.overrides.modulename))
+
+        first = True
+        # Classes / GObjects
+        for obj, bases in writer.get_classes():
+            if first:
+                self.fp.write('    if (!strcmp(name, "%s")) {\n' % obj.name)
+                first = False
+            else:
+                self.fp.write('    } else if (!strcmp(name, "%s")) {\n' % obj.name)
+            self.fp.write(
+                '       return (PyObject*)pygobject_lookup_class(%s);\n' %
+                obj.typecode)
+        self.fp.write('    }\n')
+
+        # Functions
+        for name, cname, flags, docstring in functions:
+            self.fp.write('    else if (!strcmp(name, "%s")) {\n' % name)
+            self.fp.write('        static PyMethodDef ml = { '
+                          '"%s", (PyCFunction)%s, %s, "%s"};\n' % (
+                name, cname, flags, docstring))
+            self.fp.write('        return PyCFunction_NewEx(&ml, NULL, modulename);\n')
+            self.fp.write('    }\n')
+
+        # Enums
+        def write_enum(enum, returnobj=False):
+            if returnobj:
+                ret = 'return '
+            else:
+                ret = ''
+            if enum.deftype == 'enum':
+                self.fp.write(
+                    '        %spyg_enum_add(module, "%s", strip_prefix, %s);\n'
+                    % (ret, enum.name, enum.typecode))
+            else:
+                self.fp.write(
+                    '    %spyg_flags_add(module, "%s", strip_prefix, %s);\n'
+                    % (ret, enum.name, enum.typecode))
+
+        strip_len = len(self.overrides.modulename)+1 # GTK_
+        for enum in writer.get_enums():
+            # XXX: Implement without typecodes
+            self.fp.write('    else if (!strcmp(name, "%s")) {\n' % enum.name)
+            write_enum(enum, returnobj=True)
+            self.fp.write('    }\n')
+
+            for nick, value in enum.values:
+                value = value[strip_len:]
+                self.fp.write('    else if (!strcmp(name, "%s")) {\n' % value)
+                write_enum(enum)
+                self.fp.write('        return PyObject_GetAttrString(module, "%s");\n' %
+                              value)
+                self.fp.write('    }\n')
+
+        self.fp.write('    return Py_None;\n}\n\n');
+
+    def _write_function_bodies(self):
+        functions = []
+        # First, get methods from the defs files
+        for func in self.parser.find_functions():
+            funcname = func.c_name
+            if self.overrides.is_ignored(funcname):
+                continue
+            try:
+                if self.overrides.is_overriden(funcname):
+                    data = self.overrides.override(funcname)
+                    self.write_function(funcname, data)
+
+                    methflags = self.get_methflags(funcname)
+                else:
+                    # write constructor from template ...
+                    code, methflags = self.write_function_wrapper(func,
+                        self.function_tmpl, handle_return=1, is_method=0)
+                    self.fp.write(code)
+                functions.append((func.name, '_wrap_' + funcname,
+                                  methflags, func.docstring))
+                functions_coverage.declare_wrapped()
+            except argtypes.ArgTypeError, ex:
+                functions_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write function %s: %s\n'
+                                 % (func.name, str(ex)))
+
+        # Now try to see if there are any defined in the override
+        for funcname in self.overrides.get_functions():
+            try:
+                data = self.overrides.function(funcname)
+                self.write_function(funcname, data)
+                methflags = self.get_methflags(funcname)
+                functions.append((funcname, '_wrap_' + funcname,
+                                  methflags, 'NULL'))
+                functions_coverage.declare_wrapped()
+            except argtypes.ArgTypeError, ex:
+                functions_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write function %s: %s\n'
+                                 % (funcname, str(ex)))
+        return functions
+
+    def write_functions(self, writer, prefix):
+        self.fp.write('\n/* ----------- functions ----------- */\n\n')
+        functions = []
+        func_infos = self._write_function_bodies()
+
+        # If we have a dynamic namespace, write symbol and attribute getter
+        if self.overrides.dynamicnamespace:
+            self._write_get_symbol_names(writer, func_infos)
+            self._write_get_symbol(writer, func_infos)
+            for obj, bases in writer.get_classes():
+                self.fp.write("""static PyTypeObject *
+%s_register_type(const gchar *name, PyObject *unused)
+{
+    PyObject *m = PyImport_ImportModule("gtk");
+    PyObject *d = PyModule_GetDict(m);
+""" % obj.c_name)
+                writer.write_class(obj, bases, indent=1)
+                self.fp.write(
+                    '    return (%s)PyDict_GetItemString(d, "%s");\n' % (
+                    'PyTypeObject*', obj.name))
+                self.fp.write("}\n")
+
+            functions.append('    { "_get_symbol_names", '
+                             '(PyCFunction)_wrap__get_symbol_names, '
+                             'METH_NOARGS, NULL },\n')
+            functions.append('    { "_get_symbol", '
+                             '(PyCFunction)_wrap__get_symbol, '
+                             'METH_VARARGS, NULL },\n')
+        else:
+            for name, cname, flags, docstring in func_infos:
+                functions.append(self.methdef_tmpl % dict(name=name,
+                                                          cname=cname,
+                                                          flags=flags,
+                                                          docstring=docstring))
+
+        # write the PyMethodDef structure
+        functions.append('    { NULL, NULL, 0, NULL }\n')
+
+        self.fp.write('const PyMethodDef ' + prefix + '_functions[] = {\n')
+        self.fp.write(string.join(functions, ''))
+        self.fp.write('};\n\n')
+
+class GObjectWrapper(Wrapper):
+    constructor_tmpl = (
+        'static int\n'
+        '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    self->obj = (GObject *)%(cname)s(%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '    if (!self->obj) {\n'
+        '        PyErr_SetString(PyExc_RuntimeError, '
+        '"could not create %(typename)s object");\n'
+        '        return -1;\n'
+        '    }\n'
+        '%(aftercreate)s'
+        '    pygobject_register_wrapper((PyObject *)self);\n'
+        '    return 0;\n'
+        '}\n\n'
+        )
+
+    method_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(begin_allow_threads)s\n'
+        '    %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n'
+        '    %(end_allow_threads)s\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+    def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
+        Wrapper.__init__(self, parser, objinfo, overrides, fp)
+        if self.objinfo:
+            self.castmacro = string.replace(self.objinfo.typecode,
+                                            '_TYPE_', '_', 1)
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyGObject',
+                 'tp_weaklistoffset' : 'offsetof(PyGObject, weakreflist)',
+                 'tp_dictoffset'     : 'offsetof(PyGObject, inst_dict)' }
+
+    def get_field_accessor(self, fieldname):
+        castmacro = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
+        return '%s(pygobject_get(self))->%s' % (castmacro, fieldname)
+
+    def get_initial_constructor_substdict(self, constructor):
+        substdict = Wrapper.get_initial_constructor_substdict(self,
+                                                              constructor)
+        if not constructor.caller_owns_return:
+            substdict['aftercreate'] = "    g_object_ref(self->obj);\n"
+        else:
+            substdict['aftercreate'] = ''
+        return substdict
+
+    def get_initial_method_substdict(self, method):
+        substdict = Wrapper.get_initial_method_substdict(self, method)
+        substdict['cast'] = string.replace(self.objinfo.typecode,
+                                           '_TYPE_', '_', 1)
+        return substdict
+
+    def write_default_constructor(self):
+        try:
+            parent = self.parser.find_object(self.objinfo.parent)
+        except ValueError:
+            parent = None
+        if parent is not None:
+            ## just like the constructor is inheritted, we should
+            # inherit the new API compatibility flag
+            self.objinfo.has_new_constructor_api = (
+                parent.has_new_constructor_api)
+        elif self.objinfo.parent == 'GObject':
+            self.objinfo.has_new_constructor_api = True
+        return '0'
+
+    def write_property_based_constructor(self, constructor):
+        self.objinfo.has_new_constructor_api = True
+        out = self.fp
+        print >> out, "static int"
+        print >> out, '_wrap_%s(PyGObject *self, PyObject *args,' \
+              ' PyObject *kwargs)\n{' % constructor.c_name
+        if constructor.params:
+            s = "    GType obj_type = pyg_type_from_object((PyObject *) self);"
+            print >> out, s
+
+        def py_str_list_to_c(arg):
+            if arg:
+                return "{" + ", ".join(
+                    map(lambda s: '"' + s + '"', arg)) + ", NULL }"
+            else:
+                return "{ NULL }"
+
+        classname = '%s.%s' % (self.overrides.modulename,
+                               self.objinfo.name)
+
+        if constructor.params:
+            mandatory_arguments = [param for param in constructor.params
+                                             if not param.optional]
+            optional_arguments = [param for param in constructor.params
+                                            if param.optional]
+            arg_names = py_str_list_to_c(
+            [param.argname
+             for param in mandatory_arguments + optional_arguments])
+
+            prop_names = py_str_list_to_c(
+            [param.pname
+             for param in mandatory_arguments + optional_arguments])
+
+            print >> out, "    GParameter params[%i];" % \
+                  len(constructor.params)
+            print >> out, "    PyObject *parsed_args[%i] = {NULL, };" % \
+                  len(constructor.params)
+            print >> out, "    char *arg_names[] = %s;" % arg_names
+            print >> out, "    char *prop_names[] = %s;" % prop_names
+            print >> out, "    guint nparams, i;"
+            print >> out
+            if constructor.deprecated is not None:
+                out.write(
+                    '    if (PyErr_Warn(PyExc_DeprecationWarning, '
+                    '"%s") < 0)\n' %
+                    constructor.deprecated)
+                print >> out, '        return -1;'
+                print >> out
+            out.write("    if (!PyArg_ParseTupleAndKeywords(args, kwargs, ")
+            template = '"'
+            if mandatory_arguments:
+                template += "O"*len(mandatory_arguments)
+            if optional_arguments:
+                template += "|" + "O"*len(optional_arguments)
+            template += ':%s.__init__"' % classname
+            print >> out, template, ", arg_names",
+            for i in range(len(constructor.params)):
+                print >> out, ", &parsed_args[%i]" % i,
+
+            out.write(
+                "))\n"
+                "        return -1;\n"
+                "\n"
+                "    memset(params, 0, sizeof(GParameter)*%i);\n"
+                "    if (!pyg_parse_constructor_args(obj_type, arg_names,\n"
+                "                                    prop_names, params, \n"
+                "                                    &nparams, parsed_args))\n"
+                "        return -1;\n"
+                "    pygobject_constructv(self, nparams, params);\n"
+                "    for (i = 0; i < nparams; ++i)\n"
+                "        g_value_unset(&params[i].value);\n"
+                % len(constructor.params))
+        else:
+            out.write(
+                "    static char* kwlist[] = { NULL };\n"
+                "\n")
+
+            if constructor.deprecated is not None:
+                out.write(
+                    '    if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)\n'
+                    '        return -1;\n'
+                    '\n' % constructor.deprecated)
+
+            out.write(
+                '    if (!PyArg_ParseTupleAndKeywords(args, kwargs,\n'
+                '                                     ":%s.__init__",\n'
+                '                                     kwlist))\n'
+                '        return -1;\n'
+                '\n'
+                '    pygobject_constructv(self, 0, NULL);\n' % classname)
+        out.write(
+            '    if (!self->obj) {\n'
+            '        PyErr_SetString(\n'
+            '            PyExc_RuntimeError, \n'
+            '            "could not create %s object");\n'
+            '        return -1;\n'
+            '    }\n' % classname)
+
+        if not constructor.caller_owns_return:
+            print >> out, "    g_object_ref(self->obj);\n"
+
+        out.write(
+            '    return 0;\n'
+            '}\n\n')
+
+        return "_wrap_%s" % constructor.c_name
+
+
+class GInterfaceWrapper(GObjectWrapper):
+    virtual_accessor_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
+        '{\n'
+        '    %(vtable)s *iface;\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    iface = g_type_interface_peek('
+        'g_type_class_peek(pyg_type_from_object(cls)), %(typecode)s);\n'
+        '    if (iface->%(virtual)s)\n'
+        '        %(setreturn)siface->%(virtual)s(%(arglist)s);\n'
+        '    else {\n'
+        '        PyErr_SetString(PyExc_NotImplementedError, '
+        '"interface method %(name)s not implemented");\n'
+        '        return NULL;\n'
+        '    }\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyObject',
+                 'tp_weaklistoffset' : '0',
+                 'tp_dictoffset'     : '0'}
+
+    def write_constructor(self):
+        # interfaces have no constructors ...
+        return '0'
+    def write_getsets(self):
+        # interfaces have no fields ...
+        return '0'
+
+    def _get_class_virtual_substdict(self, meth, cname, parent):
+        substdict = self.get_initial_method_substdict(meth)
+        substdict['virtual'] = substdict['name'].split('.')[1]
+        substdict['cname'] = cname
+        substdict['typecode'] = self.objinfo.typecode
+        substdict['vtable'] = self.objinfo.vtable
+        return substdict
+
+    def write_virtuals(self):
+        ## Now write reverse method wrappers, which let python code
+        ## implement interface methods.
+        # First, get methods from the defs files
+        klass = self.objinfo.c_name
+        proxies = []
+        for meth in self.parser.find_virtuals(self.objinfo):
+            method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+                else:
+                    # write proxy ...
+                    ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
+                    wrapper = reversewrapper.ReverseWrapper(
+                        '_wrap_' + method_name, is_static=True)
+                    wrapper.set_return_type(ret(wrapper, **props))
+                    wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
+                        wrapper, "self", method_name="do_" + meth.name,
+                        c_type=(klass + ' *')))
+                    for param in meth.params:
+                        handler, props = argtypes.matcher.get_reverse(
+                            param.ptype)
+                        props["direction"] = param.pdir
+                        wrapper.add_parameter(
+                            handler(wrapper, param.pname, **props))
+                    buf = reversewrapper.MemoryCodeSink()
+                    wrapper.generate(buf)
+                    self.fp.write(buf.flush())
+                proxies.append((fixname(meth.name), '_wrap_' + method_name))
+                iproxies_coverage.declare_wrapped()
+            except argtypes.ArgTypeError, ex:
+                iproxies_coverage.declare_not_wrapped()
+                proxies.append((fixname(meth.name), None))
+                sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
+                                % (klass, meth.name, str(ex)))
+
+        if not proxies or not [cname for name, cname in proxies if cname]:
+            return
+
+        ## Write an interface init function for this object
+        funcname = "__%s__interface_init" % klass
+        vtable = self.objinfo.vtable
+        self.fp.write(
+            '\nstatic void\n'
+            '%(funcname)s(%(vtable)s *iface, PyTypeObject *pytype)\n'
+            '{\n'
+            '    %(vtable)s *parent_iface = '
+            'g_type_interface_peek_parent(iface);\n'
+            '    PyObject *py_method;\n'
+            '\n'
+            % vars())
+
+        for name, cname in proxies:
+            do_name = 'do_' + name
+            if cname is None:
+                continue
+
+            self.fp.write((
+                '    py_method = pytype? PyObject_GetAttrString('
+                '(PyObject *) pytype, "%(do_name)s") : NULL;\n'
+                '    if (py_method && !PyObject_TypeCheck(py_method, '
+                '&PyCFunction_Type)) {\n'
+                '        iface->%(name)s = %(cname)s;\n'
+                '    } else {\n'
+                '        PyErr_Clear();\n'
+                '        if (parent_iface) {\n'
+                '            iface->%(name)s = parent_iface->%(name)s;\n'
+                '        }\n'
+                '    Py_XDECREF(py_method);\n'
+                '    }\n'
+                ) % vars())
+        self.fp.write('}\n\n')
+        interface_info = "__%s__iinfo" % klass
+        self.fp.write('''
+static const GInterfaceInfo %s = {
+    (GInterfaceInitFunc) %s,
+    NULL,
+    NULL
+};
+''' % (interface_info, funcname))
+        self.objinfo.interface_info = interface_info
+
+class GBoxedWrapper(Wrapper):
+    constructor_tmpl = (
+        'static int\n'
+        '_wrap_%(cname)s(PyGBoxed *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    self->gtype = %(typecode)s;\n'
+        '    self->free_on_dealloc = FALSE;\n'
+        '    self->boxed = %(cname)s(%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '    if (!self->boxed) {\n'
+        '        PyErr_SetString(PyExc_RuntimeError, '
+        '"could not create %(typename)s object");\n'
+        '        return -1;\n'
+        '    }\n'
+        '    self->free_on_dealloc = TRUE;\n'
+        '    return 0;\n'
+        '}\n\n'
+        )
+
+    method_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(begin_allow_threads)s\n'
+        '    %(setreturn)s%(cname)s(pyg_boxed_get(self, '
+        '%(typename)s)%(arglist)s);\n'
+        '    %(end_allow_threads)s\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyGBoxed',
+                 'tp_weaklistoffset' : '0',
+                 'tp_dictoffset'     : '0' }
+
+    def get_field_accessor(self, fieldname):
+        return 'pyg_boxed_get(self, %s)->%s' % (self.objinfo.c_name, fieldname)
+
+    def get_initial_constructor_substdict(self, constructor):
+        substdict = Wrapper.get_initial_constructor_substdict(
+            self, constructor)
+        substdict['typecode'] = self.objinfo.typecode
+        return substdict
+
+class GPointerWrapper(GBoxedWrapper):
+    constructor_tmpl = (
+        'static int\n'
+        '_wrap_%(cname)s(PyGPointer *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    self->gtype = %(typecode)s;\n'
+        '    self->pointer = %(cname)s(%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '    if (!self->pointer) {\n'
+        '        PyErr_SetString(PyExc_RuntimeError, '
+        '"could not create %(typename)s object");\n'
+        '        return -1;\n'
+        '    }\n'
+        '    return 0;\n'
+        '}\n\n'
+        )
+
+    method_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(setreturn)s%(cname)s(pyg_pointer_get(self, '
+        '%(typename)s)%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyGPointer',
+                 'tp_weaklistoffset' : '0',
+                 'tp_dictoffset'     : '0' }
+
+    def get_field_accessor(self, fieldname):
+        return 'pyg_pointer_get(self, %s)->%s' % (self.objinfo.c_name,
+                                                  fieldname)
+
+    def get_initial_constructor_substdict(self, constructor):
+        substdict = Wrapper.get_initial_constructor_substdict(
+            self, constructor)
+        substdict['typecode'] = self.objinfo.typecode
+        return substdict
+
+class SourceWriter:
+    def __init__(self, parser, overrides, prefix, fp=FileOutput(sys.stdout)):
+        self.parser = parser
+        self.overrides = overrides
+        self.prefix = prefix
+        self.fp = fp
+
+    def write(self, py_ssize_t_clean=False):
+        argtypes.py_ssize_t_clean = py_ssize_t_clean
+
+        self.write_headers(py_ssize_t_clean)
+        self.write_imports()
+        self.write_type_declarations()
+        self.write_body()
+        self.write_classes()
+
+        wrapper = Wrapper(self.parser, None, self.overrides, self.fp)
+        wrapper.write_functions(self, self.prefix)
+
+        if not self.overrides.dynamicnamespace:
+            self.write_enums()
+        self.write_extension_init()
+        self.write_registers()
+
+        argtypes.py_ssize_t_clean = False
+
+    def write_headers(self, py_ssize_t_clean):
+        self.fp.write('/* -- THIS FILE IS GENERATED - DO NOT EDIT */')
+        self.fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
+        if py_ssize_t_clean:
+            self.fp.write('#define PY_SSIZE_T_CLEAN\n')
+        self.fp.write('#include <Python.h>\n\n\n')
+        if py_ssize_t_clean:
+            self.fp.write('''
+
+#if PY_VERSION_HEX < 0x02050000
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+typedef inquiry lenfunc;
+typedef intargfunc ssizeargfunc;
+typedef intobjargproc ssizeobjargproc;
+#endif
+
+''')
+        self.fp.write(self.overrides.get_headers())
+        self.fp.resetline()
+        self.fp.write('\n\n')
+
+    def write_imports(self):
+        self.fp.write('/* ---------- types from other modules ---------- */\n')
+        for module, pyname, cname in self.overrides.get_imports():
+            self.fp.write('static PyTypeObject *_%s;\n' % cname)
+            self.fp.write('#define %s (*_%s)\n' % (cname, cname))
+        self.fp.write('\n\n')
+
+    def write_type_declarations(self):
+        #todo use 'static' if used only in one file
+        self.fp.write('/* ---------- forward type declarations ---------- */\n')
+        for obj in self.parser.boxes:
+            if not self.overrides.is_type_ignored(obj.c_name):
+                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
+        for obj in self.parser.objects:
+            if not self.overrides.is_type_ignored(obj.c_name):
+                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
+        for interface in self.parser.interfaces:
+            if not self.overrides.is_type_ignored(interface.c_name):
+                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + interface.c_name + '_Type;\n')
+        self.fp.write('\n')
+
+    def write_body(self):
+        self.fp.write(self.overrides.get_body())
+        self.fp.resetline()
+        self.fp.write('\n\n')
+
+    def _sort_parent_children(self, objects):
+        objects = list(objects)
+        modified = True
+        while modified:
+            modified = False
+            parent_index = None
+            child_index = None
+            for i, obj in enumerate(objects):
+                if obj.parent == 'GObject':
+                    continue
+                if obj.parent not in [info.c_name for info in objects[:i]]:
+                    for j, info in enumerate(objects[i+1:]):
+                        if info.c_name == obj.parent:
+                            parent_index = i + 1 + j
+                            child_index = i
+                            break
+                    else:
+                        continue
+                    break
+            if child_index is not None and parent_index is not None:
+                if child_index != parent_index:
+                    objects.insert(child_index, objects.pop(parent_index))
+                    modified = True
+        return objects
+
+    def write_classes(self):
+        ## Sort the objects, so that we generate code for the parent types
+        ## before their children.
+        objects = self._sort_parent_children(self.parser.objects)
+
+        for klass, items in ((GBoxedWrapper, self.parser.boxes),
+                             (GPointerWrapper, self.parser.pointers),
+                             (GObjectWrapper, objects),
+                             (GInterfaceWrapper, self.parser.interfaces)):
+            for item in items:
+                instance = klass(self.parser, item, self.overrides, self.fp)
+                instance.write_class()
+                self.fp.write('\n')
+
+    def get_enums(self):
+        enums = []
+        for enum in self.parser.enums:
+            if self.overrides.is_type_ignored(enum.c_name):
+                continue
+            enums.append(enum)
+        return enums
+
+    def write_enums(self):
+        if not self.parser.enums:
+            return
+
+        self.fp.write('\n/* ----------- enums and flags ----------- */\n\n')
+        self.fp.write(
+            'void\n' + self.prefix +
+            '_add_constants(PyObject *module, const gchar *strip_prefix)\n{\n')
+
+        self.fp.write(
+            '#ifdef VERSION\n'
+            '    PyModule_AddStringConstant(module, "__version__", VERSION);\n'
+            '#endif\n')
+
+        for enum in self.get_enums():
+            if enum.typecode is None:
+                for nick, value in enum.values:
+                    self.fp.write(
+                        '    PyModule_AddIntConstant(module, '
+                        '(char *) pyg_constant_strip_prefix("%s", strip_prefix), %s);\n'
+                        % (value, value))
+            else:
+                if enum.deftype == 'enum':
+                    self.fp.write('  pyg_enum_add(module, "%s", strip_prefix, %s);\n'
+                                  % (enum.name, enum.typecode))
+                else:
+                    self.fp.write('  pyg_flags_add(module, "%s", strip_prefix, %s);\n'
+                                  % (enum.name, enum.typecode))
+
+        self.fp.write('\n')
+        self.fp.write('  if (PyErr_Occurred())\n')
+        self.fp.write('    PyErr_Print();\n')
+        self.fp.write('}\n\n')
+
+    def write_object_imports(self, retval=''):
+        imports = self.overrides.get_imports()[:]
+        if not imports:
+            return
+
+        bymod = {}
+        for module, pyname, cname in imports:
+            bymod.setdefault(module, []).append((pyname, cname))
+        self.fp.write('    PyObject *module;\n\n')
+        for module in bymod:
+            self.fp.write(
+                '    if ((module = PyImport_ImportModule("%s")) != NULL) {\n'
+                % module)
+            #self.fp.write(
+            #    '        PyObject *moddict = PyModule_GetDict(module);\n\n')
+            for pyname, cname in bymod[module]:
+                #self.fp.write(
+                #    '        _%s = (PyTypeObject *)PyDict_GetItemString('
+                #    'moddict, "%s");\n' % (cname, pyname))
+                self.fp.write(
+                    '        _%s = (PyTypeObject *)PyObject_GetAttrString('
+                    'module, "%s");\n' % (cname, pyname))
+                self.fp.write('        if (_%s == NULL) {\n' % cname)
+                self.fp.write('            PyErr_SetString(PyExc_ImportError,\n')
+                self.fp.write('                "cannot import name %s from %s");\n'
+                         % (pyname, module))
+                self.fp.write('            return %s;\n' % retval)
+                self.fp.write('        }\n')
+            self.fp.write('    } else {\n')
+            self.fp.write('        PyErr_SetString(PyExc_ImportError,\n')
+            self.fp.write('            "could not import %s");\n' % module)
+            self.fp.write('        return %s;\n' % retval)
+            self.fp.write('    }\n')
+        self.fp.write('\n')
+
+    def write_extension_init(self):
+        self.fp.write('/* initialise stuff extension classes */\n')
+        self.fp.write('void\n' + self.prefix + '_register_classes(PyObject *d)\n{\n')
+        self.write_object_imports()
+        self.fp.write(self.overrides.get_init() + '\n')
+        self.fp.resetline()
+
+    def get_classes(self):
+        objects = self.parser.objects[:]
+        pos = 0
+        while pos < len(objects):
+            parent = objects[pos].parent
+            for i in range(pos+1, len(objects)):
+                if objects[i].c_name == parent:
+                    objects.insert(i+1, objects[pos])
+                    del objects[pos]
+                    break
+            else:
+                pos = pos + 1
+
+        retval = []
+        for obj in objects:
+            if self.overrides.is_type_ignored(obj.c_name):
+                continue
+            bases = []
+            if obj.parent != None:
+                bases.append(obj.parent)
+            bases = bases + obj.implements
+            retval.append((obj, bases))
+
+        return retval
+
+    def write_registers(self):
+        for boxed in self.parser.boxes:
+            if not self.overrides.is_type_ignored(boxed.c_name):
+                self.fp.write('    pyg_register_boxed(d, "' + boxed.name +
+                              '", ' + boxed.typecode +
+                              ', &Py' + boxed.c_name +
+                          '_Type);\n')
+        for pointer in self.parser.pointers:
+            if not self.overrides.is_type_ignored(pointer.c_name):
+                self.fp.write('    pyg_register_pointer(d, "' + pointer.name +
+                              '", ' + pointer.typecode +
+                              ', &Py' + pointer.c_name + '_Type);\n')
+        for interface in self.parser.interfaces:
+            if not self.overrides.is_type_ignored(interface.c_name):
+                self.fp.write('    pyg_register_interface(d, "'
+                              + interface.name + '", '+ interface.typecode
+                              + ', &Py' + interface.c_name + '_Type);\n')
+                if interface.interface_info is not None:
+                    self.fp.write('    pyg_register_interface_info(%s, &%s);\n' %
+                                  (interface.typecode, interface.interface_info))
+
+        if not self.overrides.dynamicnamespace:
+            for obj, bases in self.get_classes():
+                self.write_class(obj, bases)
+        else:
+            for obj, bases in self.get_classes():
+                self.fp.write(
+                    '    pyg_type_register_custom_callback("%s", '
+                    '(PyGTypeRegistrationFunction)%s_register_type, d);\n' %
+                    (obj.c_name, obj.c_name))
+
+        self.fp.write('}\n')
+
+    def _can_direct_ref(self, base):
+        if not self.overrides.dynamicnamespace:
+            return True
+        if base == 'GObject':
+            return True
+        obj = get_object_by_name(base)
+        if obj.module.lower() != self.overrides.modulename:
+            return True
+        return False
+
+    def write_class(self, obj, bases, indent=1):
+        indent_str = ' ' * (indent * 4)
+        if bases:
+            bases_str = 'Py_BuildValue("(%s)"' % (len(bases) * 'O')
+
+            for base in bases:
+                if self._can_direct_ref(base):
+                    bases_str += ', &Py%s_Type' % base
+                else:
+                    baseobj = get_object_by_name(base)
+                    bases_str += ', PyObject_GetAttrString(m, "%s")' % baseobj.name
+            bases_str += ')'
+        else:
+            bases_str = 'NULL'
+
+        self.fp.write(
+                '%(indent)spygobject_register_class(d, "%(c_name)s", %(typecode)s, &Py%(c_name)s_Type, %(bases)s);\n'
+                % dict(indent=indent_str, c_name=obj.c_name, typecode=obj.typecode, bases=bases_str))
+
+        if obj.has_new_constructor_api:
+            self.fp.write(
+                indent_str + 'pyg_set_object_has_new_constructor(%s);\n' %
+                obj.typecode)
+        else:
+            print >> sys.stderr, (
+                "Warning: Constructor for %s needs to be updated to new API\n"
+                "         See http://live.gnome.org/PyGTK_2fWhatsNew28"
+                "#update-constructors") % obj.c_name
+
+        if obj.class_init_func is not None:
+            self.fp.write(
+                indent_str + 'pyg_register_class_init(%s, %s);\n' %
+                (obj.typecode, obj.class_init_func))
+
+_objects = {}
+
+def get_object_by_name(c_name):
+    global _objects
+    return _objects[c_name]
+
+def register_types(parser):
+    global _objects
+    for boxed in parser.boxes:
+        argtypes.matcher.register_boxed(boxed.c_name, boxed.typecode)
+        _objects[boxed.c_name] = boxed
+    for pointer in parser.pointers:
+        argtypes.matcher.register_pointer(pointer.c_name, pointer.typecode)
+    for obj in parser.objects:
+        argtypes.matcher.register_object(obj.c_name, obj.parent, obj.typecode)
+        _objects[obj.c_name] = obj
+    for iface in parser.interfaces:
+        argtypes.matcher.register_object(iface.c_name, None, iface.typecode)
+        _objects[iface.c_name] = iface
+    for enum in parser.enums:
+        if enum.deftype == 'flags':
+            argtypes.matcher.register_flag(enum.c_name, enum.typecode)
+        else:
+            argtypes.matcher.register_enum(enum.c_name, enum.typecode)
+
+usage = 'usage: codegen.py [-o overridesfile] [-p prefix] defsfile'
+def main(argv):
+    o = override.Overrides()
+    prefix = 'pygtk'
+    outfilename = None
+    errorfilename = None
+    opts, args = getopt.getopt(argv[1:], "o:p:r:t:D:I:",
+                        ["override=", "prefix=", "register=", "outfilename=",
+                         "load-types=", "errorfilename=", "py_ssize_t-clean"])
+    defines = {} # -Dkey[=val] options
+    py_ssize_t_clean = False
+    for opt, arg in opts:
+        if opt in ('-o', '--override'):
+            o = override.Overrides(arg)
+        elif opt in ('-p', '--prefix'):
+            prefix = arg
+        elif opt in ('-r', '--register'):
+            # Warning: user has to make sure all -D options appear before -r
+            p = defsparser.DefsParser(arg, defines)
+            p.startParsing()
+            register_types(p)
+            del p
+        elif opt == '--outfilename':
+            outfilename = arg
+        elif opt == '--errorfilename':
+            errorfilename = arg
+        elif opt in ('-t', '--load-types'):
+            globals = {}
+            execfile(arg, globals)
+        elif opt == '-D':
+            nameval = arg.split('=')
+            try:
+                defines[nameval[0]] = nameval[1]
+            except IndexError:
+                defines[nameval[0]] = None
+        elif opt == '-I':
+            defsparser.include_path.insert(0, arg)
+        elif opt == '--py_ssize_t-clean':
+            py_ssize_t_clean = True
+    if len(args) < 1:
+        print >> sys.stderr, usage
+        return 1
+    if errorfilename:
+        sys.stderr = open(errorfilename, "w")
+    p = defsparser.DefsParser(args[0], defines)
+    if not outfilename:
+        outfilename = os.path.splitext(args[0])[0] + '.c'
+
+    p.startParsing()
+
+    register_types(p)
+    sw = SourceWriter(p, o, prefix, FileOutput(sys.stdout, outfilename))
+    sw.write(py_ssize_t_clean)
+
+    functions_coverage.printstats()
+    methods_coverage.printstats()
+    vproxies_coverage.printstats()
+    vaccessors_coverage.printstats()
+    iproxies_coverage.printstats()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))


Property changes on: trunk/src/host/pye17/codegen/codegen.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/host/pye17/codegen/createdefs.py
===================================================================
--- trunk/src/host/pye17/codegen/createdefs.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/createdefs.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+import sys
+
+def main(args):
+    output = args[1]
+    input = args[2:]
+    outfd = open(output, 'w')
+    outfd.write(';; -*- scheme -*-\n')
+    outfd.write(';; THIS FILE IS GENERATED - DO NOT EDIT\n')
+    for filename in input:
+        outfd.write('(include "%s")\n' % filename)
+    outfd.close()
+
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))


Property changes on: trunk/src/host/pye17/codegen/createdefs.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/host/pye17/codegen/definitions.py
===================================================================
--- trunk/src/host/pye17/codegen/definitions.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/definitions.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,547 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+import copy
+import sys
+
+def get_valid_scheme_definitions(defs):
+    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
+class Parameter(object):
+    def __init__(self, ptype, pname, pdflt, pnull, pdir=None):
+        self.ptype = ptype
+        self.pname = pname
+        self.pdflt = pdflt
+        self.pnull = pnull
+        self.pdir = pdir
+
+    def __len__(self): return 4
+    def __getitem__(self, i):
+        return (self.ptype, self.pname, self.pdflt, self.pnull)[i]
+
+    def merge(self, old):
+        if old.pdflt is not None:
+            self.pdflt = old.pdflt
+        if old.pnull is not None:
+            self.pnull = old.pnull
+
+# Parameter for property based constructors
+class Property(object):
+    def __init__(self, pname, optional, argname):
+        self.pname = pname
+        self.optional = optional
+        self.argname = argname
+
+    def merge(self, old):
+        if old.optional is not None:
+            self.optional = old.optional
+        if old.argname is not None:
+            self.argname = old.argname
+
+
+class Definition:
+    docstring = "NULL"
+    def __init__(self, *args):
+        """Create a new defs object of this type.  The arguments are the
+        components of the definition"""
+        raise RuntimeError, "this is an abstract class"
+    def merge(self, old):
+        """Merge in customisations from older version of definition"""
+        raise RuntimeError, "this is an abstract class"
+    def write_defs(self, fp=sys.stdout):
+        """write out this definition in defs file format"""
+        raise RuntimeError, "this is an abstract class"
+
+    def guess_return_value_ownership(self):
+        "return 1 if caller owns return value"
+        if getattr(self, 'is_constructor_of', False):
+            self.caller_owns_return = True
+        elif self.ret in ('char*', 'gchar*', 'string'):
+            self.caller_owns_return = True
+        else:
+            self.caller_owns_return = False
+
+
+class ObjectDef(Definition):
+    def __init__(self, name, *args):
+        self.name = name
+        self.module = None
+        self.parent = None
+        self.c_name = None
+        self.typecode = None
+        self.fields = []
+        self.implements = []
+        self.class_init_func = None
+        self.has_new_constructor_api = False
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'in-module':
+                self.module = arg[1]
+            elif arg[0] == 'docstring':
+                self.docstring = make_docstring(arg[1:])
+            elif arg[0] == 'parent':
+                self.parent = arg[1]
+            elif arg[0] == 'c-name':
+                self.c_name = arg[1]
+            elif arg[0] == 'gtype-id':
+                self.typecode = arg[1]
+            elif arg[0] == 'fields':
+                for parg in arg[1:]:
+                    self.fields.append((parg[0], parg[1]))
+            elif arg[0] == 'implements':
+                self.implements.append(arg[1])
+    def merge(self, old):
+        # 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
+        # from the old version ...
+        self.fields = old.fields
+        self.implements = old.implements
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-object ' + self.name + '\n')
+        if self.module:
+            fp.write('  (in-module "' + self.module + '")\n')
+        if self.parent != (None, None):
+            fp.write('  (parent "' + self.parent + '")\n')
+        for interface in self.implements:
+            fp.write('  (implements "' + interface + '")\n')
+        if self.c_name:
+            fp.write('  (c-name "' + self.c_name + '")\n')
+        if self.typecode:
+            fp.write('  (gtype-id "' + self.typecode + '")\n')
+        if self.fields:
+            fp.write('  (fields\n')
+            for (ftype, fname) in self.fields:
+                fp.write('    \'("' + ftype + '" "' + fname + '")\n')
+            fp.write('  )\n')
+        fp.write(')\n\n')
+
+class InterfaceDef(Definition):
+    def __init__(self, name, *args):
+        self.name = name
+        self.module = None
+        self.c_name = None
+        self.typecode = None
+        self.vtable = None
+        self.fields = []
+        self.interface_info = None
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'in-module':
+                self.module = arg[1]
+            elif arg[0] == 'docstring':
+                self.docstring = make_docstring(arg[1:])
+            elif arg[0] == 'c-name':
+                self.c_name = arg[1]
+            elif arg[0] == 'gtype-id':
+                self.typecode = arg[1]
+            elif arg[0] == 'vtable':
+                self.vtable = arg[1]
+        if self.vtable is None:
+            self.vtable = self.c_name + "Iface"
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-interface ' + self.name + '\n')
+        if self.module:
+            fp.write('  (in-module "' + self.module + '")\n')
+        if self.c_name:
+            fp.write('  (c-name "' + self.c_name + '")\n')
+        if self.typecode:
+            fp.write('  (gtype-id "' + self.typecode + '")\n')
+        fp.write(')\n\n')
+
+class EnumDef(Definition):
+    def __init__(self, name, *args):
+        self.deftype = 'enum'
+        self.name = name
+        self.in_module = None
+        self.c_name = None
+        self.typecode = None
+        self.values = []
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'in-module':
+                self.in_module = arg[1]
+            elif arg[0] == 'c-name':
+                self.c_name = arg[1]
+            elif arg[0] == 'gtype-id':
+                self.typecode = arg[1]
+            elif arg[0] == 'values':
+                for varg in arg[1:]:
+                    self.values.append((varg[0], varg[1]))
+    def merge(self, old):
+        pass
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-' + self.deftype + ' ' + self.name + '\n')
+        if self.in_module:
+            fp.write('  (in-module "' + self.in_module + '")\n')
+        fp.write('  (c-name "' + self.c_name + '")\n')
+        fp.write('  (gtype-id "' + self.typecode + '")\n')
+        if self.values:
+            fp.write('  (values\n')
+            for name, val in self.values:
+                fp.write('    \'("' + name + '" "' + val + '")\n')
+            fp.write('  )\n')
+        fp.write(')\n\n')
+
+class FlagsDef(EnumDef):
+    def __init__(self, *args):
+        apply(EnumDef.__init__, (self,) + args)
+        self.deftype = 'flags'
+
+class BoxedDef(Definition):
+    def __init__(self, name, *args):
+        self.name = name
+        self.module = None
+        self.c_name = None
+        self.typecode = None
+        self.copy = None
+        self.release = None
+        self.fields = []
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'in-module':
+                self.module = arg[1]
+            elif arg[0] == 'c-name':
+                self.c_name = arg[1]
+            elif arg[0] == 'gtype-id':
+                self.typecode = arg[1]
+            elif arg[0] == 'copy-func':
+                self.copy = arg[1]
+            elif arg[0] == 'release-func':
+                self.release = arg[1]
+            elif arg[0] == 'fields':
+                for parg in arg[1:]:
+                    self.fields.append((parg[0], parg[1]))
+    def merge(self, old):
+        # 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
+        # from the old version ...
+        self.fields = old.fields
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-boxed ' + self.name + '\n')
+        if self.module:
+            fp.write('  (in-module "' + self.module + '")\n')
+        if self.c_name:
+            fp.write('  (c-name "' + self.c_name + '")\n')
+        if self.typecode:
+            fp.write('  (gtype-id "' + self.typecode + '")\n')
+        if self.copy:
+            fp.write('  (copy-func "' + self.copy + '")\n')
+        if self.release:
+            fp.write('  (release-func "' + self.release + '")\n')
+        if self.fields:
+            fp.write('  (fields\n')
+            for (ftype, fname) in self.fields:
+                fp.write('    \'("' + ftype + '" "' + fname + '")\n')
+            fp.write('  )\n')
+        fp.write(')\n\n')
+
+class PointerDef(Definition):
+    def __init__(self, name, *args):
+        self.name = name
+        self.module = None
+        self.c_name = None
+        self.typecode = None
+        self.fields = []
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'in-module':
+                self.module = arg[1]
+            elif arg[0] == 'c-name':
+                self.c_name = arg[1]
+            elif arg[0] == 'gtype-id':
+                self.typecode = arg[1]
+            elif arg[0] == 'fields':
+                for parg in arg[1:]:
+                    self.fields.append((parg[0], parg[1]))
+    def merge(self, old):
+        # 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
+        # from the old version ...
+        self.fields = old.fields
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-pointer ' + self.name + '\n')
+        if self.module:
+            fp.write('  (in-module "' + self.module + '")\n')
+        if self.c_name:
+            fp.write('  (c-name "' + self.c_name + '")\n')
+        if self.typecode:
+            fp.write('  (gtype-id "' + self.typecode + '")\n')
+        if self.fields:
+            fp.write('  (fields\n')
+            for (ftype, fname) in self.fields:
+                fp.write('    \'("' + ftype + '" "' + fname + '")\n')
+            fp.write('  )\n')
+        fp.write(')\n\n')
+
+class MethodDefBase(Definition):
+    def __init__(self, name, *args):
+        dump = 0
+        self.name = name
+        self.ret = None
+        self.caller_owns_return = None
+        self.unblock_threads = None
+        self.c_name = None
+        self.typecode = None
+        self.of_object = None
+        self.params = [] # of form (type, name, default, nullok)
+        self.varargs = 0
+        self.deprecated = None
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'of-object':
+                self.of_object = arg[1]
+            elif arg[0] == 'docstring':
+                self.docstring = make_docstring(arg[1:])
+            elif arg[0] == 'c-name':
+                self.c_name = arg[1]
+            elif arg[0] == 'gtype-id':
+                self.typecode = arg[1]
+            elif arg[0] == 'return-type':
+                self.ret = arg[1]
+            elif arg[0] == 'caller-owns-return':
+                self.caller_owns_return = arg[1] in ('t', '#t')
+            elif arg[0] == 'unblock-threads':
+                self.unblock_threads = arg[1] in ('t', '#t')
+            elif arg[0] == 'parameters':
+                for parg in arg[1:]:
+                    ptype = parg[0]
+                    pname = parg[1]
+                    pdflt = None
+                    pnull = 0
+                    pdir = None
+                    for farg in parg[2:]:
+                        assert isinstance(farg, tuple)
+                        if farg[0] == 'default':
+                            pdflt = farg[1]
+                        elif farg[0] == 'null-ok':
+                            pnull = 1
+                        elif farg[0] == 'direction':
+                            pdir = farg[1]
+                    self.params.append(Parameter(ptype, pname, pdflt, pnull, pdir))
+            elif arg[0] == 'varargs':
+                self.varargs = arg[1] in ('t', '#t')
+            elif arg[0] == 'deprecated':
+                self.deprecated = arg[1]
+            else:
+                sys.stderr.write("Warning: %s argument unsupported.\n"
+                                 % (arg[0]))
+                dump = 1
+        if dump:
+            self.write_defs(sys.stderr)
+
+        if self.caller_owns_return is None and self.ret is not None:
+            self.guess_return_value_ownership()
+
+    def merge(self, old, parmerge):
+        self.caller_owns_return = old.caller_owns_return
+        self.varargs = old.varargs
+        # here we merge extra parameter flags accross to the new object.
+        if not parmerge:
+            self.params = copy.deepcopy(old.params)
+            return
+        for i in range(len(self.params)):
+            ptype, pname, pdflt, pnull = self.params[i]
+            for p2 in old.params:
+                if p2[1] == pname:
+                    self.params[i] = (ptype, pname, p2[2], p2[3])
+                    break
+    def _write_defs(self, fp=sys.stdout):
+        if self.of_object != (None, None):
+            fp.write('  (of-object "' + self.of_object + '")\n')
+        if self.c_name:
+            fp.write('  (c-name "' + self.c_name + '")\n')
+        if self.typecode:
+            fp.write('  (gtype-id "' + self.typecode + '")\n')
+        if self.caller_owns_return:
+            fp.write('  (caller-owns-return #t)\n')
+        if self.unblock_threads:
+            fp.write('  (unblock_threads #t)\n')
+        if self.ret:
+            fp.write('  (return-type "' + self.ret + '")\n')
+        if self.deprecated:
+            fp.write('  (deprecated "' + self.deprecated + '")\n')
+        if self.params:
+            fp.write('  (parameters\n')
+            for ptype, pname, pdflt, pnull in self.params:
+                fp.write('    \'("' + ptype + '" "' + pname +'"')
+                if pdflt: fp.write(' (default "' + pdflt + '")')
+                if pnull: fp.write(' (null-ok)')
+                fp.write(')\n')
+            fp.write('  )\n')
+        if self.varargs:
+            fp.write('  (varargs #t)\n')
+        fp.write(')\n\n')
+
+
+class MethodDef(MethodDefBase):
+    def __init__(self, name, *args):
+        MethodDefBase.__init__(self, name, *args)
+        for item in ('c_name', 'of_object'):
+            if self.__dict__[item] == None:
+                self.write_defs(sys.stderr)
+                raise RuntimeError, "definition missing required %s" % (item,)
+
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-method ' + self.name + '\n')
+        self._write_defs(fp)
+
+class VirtualDef(MethodDefBase):
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-virtual ' + self.name + '\n')
+        self._write_defs(fp)
+
+class FunctionDef(Definition):
+    def __init__(self, name, *args):
+        dump = 0
+        self.name = name
+        self.in_module = None
+        self.is_constructor_of = None
+        self.ret = None
+        self.caller_owns_return = None
+        self.unblock_threads = None
+        self.c_name = None
+        self.typecode = None
+        self.params = [] # of form (type, name, default, nullok)
+        self.varargs = 0
+        self.deprecated = None
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'in-module':
+                self.in_module = arg[1]
+            elif arg[0] == 'docstring':
+                self.docstring = make_docstring(arg[1:])
+            elif arg[0] == 'is-constructor-of':
+                self.is_constructor_of = arg[1]
+            elif arg[0] == 'c-name':
+                self.c_name = arg[1]
+            elif arg[0] == 'gtype-id':
+                self.typecode = arg[1]
+            elif arg[0] == 'return-type':
+                self.ret = arg[1]
+            elif arg[0] == 'caller-owns-return':
+                self.caller_owns_return = arg[1] in ('t', '#t')
+            elif arg[0] == 'unblock-threads':
+                self.unblock_threads = arg[1] in ('t', '#t')
+            elif arg[0] == 'parameters':
+                for parg in arg[1:]:
+                    ptype = parg[0]
+                    pname = parg[1]
+                    pdflt = None
+                    pnull = 0
+                    for farg in parg[2:]:
+                        if farg[0] == 'default':
+                            pdflt = farg[1]
+                        elif farg[0] == 'null-ok':
+                            pnull = 1
+                    self.params.append(Parameter(ptype, pname, pdflt, pnull))
+            elif arg[0] == 'properties':
+                if self.is_constructor_of is None:
+                    print >> sys.stderr, "Warning: (properties ...) "\
+                          "is only valid for constructors"
+                for prop in arg[1:]:
+                    pname = prop[0]
+                    optional = False
+                    argname = pname
+                    for farg in prop[1:]:
+                        if farg[0] == 'optional':
+                            optional = True
+                        elif farg[0] == 'argname':
+                            argname = farg[1]
+                    self.params.append(Property(pname, optional, argname))
+            elif arg[0] == 'varargs':
+                self.varargs = arg[1] in ('t', '#t')
+            elif arg[0] == 'deprecated':
+                self.deprecated = arg[1]
+            else:
+                sys.stderr.write("Warning: %s argument unsupported\n"
+                                 % (arg[0],))
+                dump = 1
+        if dump:
+            self.write_defs(sys.stderr)
+
+        if self.caller_owns_return is None and self.ret is not None:
+            self.guess_return_value_ownership()
+        for item in ('c_name',):
+            if self.__dict__[item] == None:
+                self.write_defs(sys.stderr)
+                raise RuntimeError, "definition missing required %s" % (item,)
+
+    _method_write_defs = MethodDef.__dict__['write_defs']
+
+    def merge(self, old, parmerge):
+        self.caller_owns_return = old.caller_owns_return
+        self.varargs = old.varargs
+        if not parmerge:
+            self.params = copy.deepcopy(old.params)
+            return
+        # here we merge extra parameter flags accross to the new object.
+        def merge_param(param):
+            for old_param in old.params:
+                if old_param.pname == param.pname:
+                    if isinstance(old_param, Property):
+                        # h2def never scans Property's, therefore if
+                        # we have one it was manually written, so we
+                        # keep it.
+                        return copy.deepcopy(old_param)
+                    else:
+                        param.merge(old_param)
+                        return param
+            raise RuntimeError, "could not find %s in old_parameters %r" % (
+                param.pname, [p.pname for p in old.params])
+        try:
+            self.params = map(merge_param, self.params)
+        except RuntimeError:
+            # parameter names changed and we can't find a match; it's
+            # safer to keep the old parameter list untouched.
+            self.params = copy.deepcopy(old.params)
+
+        if not self.is_constructor_of:
+            try:
+                self.is_constructor_of = old.is_constructor_of
+            except AttributeError:
+                pass
+        if isinstance(old, MethodDef):
+            self.name = old.name
+            # transmogrify from function into method ...
+            self.write_defs = self._method_write_defs
+            self.of_object = old.of_object
+            del self.params[0]
+    def write_defs(self, fp=sys.stdout):
+        fp.write('(define-function ' + self.name + '\n')
+        if self.in_module:
+            fp.write('  (in-module "' + self.in_module + '")\n')
+        if self.is_constructor_of:
+            fp.write('  (is-constructor-of "' + self.is_constructor_of +'")\n')
+        if self.c_name:
+            fp.write('  (c-name "' + self.c_name + '")\n')
+        if self.typecode:
+            fp.write('  (gtype-id "' + self.typecode + '")\n')
+        if self.caller_owns_return:
+            fp.write('  (caller-owns-return #t)\n')
+        if self.unblock_threads:
+            fp.write('  (unblock-threads #t)\n')
+        if self.ret:
+            fp.write('  (return-type "' + self.ret + '")\n')
+        if self.deprecated:
+            fp.write('  (deprecated "' + self.deprecated + '")\n')
+        if self.params:
+            if isinstance(self.params[0], Parameter):
+                fp.write('  (parameters\n')
+                for ptype, pname, pdflt, pnull in self.params:
+                    fp.write('    \'("' + ptype + '" "' + pname +'"')
+                    if pdflt: fp.write(' (default "' + pdflt + '")')
+                    if pnull: fp.write(' (null-ok)')
+                    fp.write(')\n')
+                fp.write('  )\n')
+            elif isinstance(self.params[0], Property):
+                fp.write('  (properties\n')
+                for prop in self.params:
+                    fp.write('    \'("' + prop.pname +'"')
+                    if prop.optional: fp.write(' (optional)')
+                    fp.write(')\n')
+                fp.write('  )\n')
+            else:
+                assert False, "strange parameter list %r" % self.params[0]
+        if self.varargs:
+            fp.write('  (varargs #t)\n')
+
+        fp.write(')\n\n')

Added: trunk/src/host/pye17/codegen/defsparser.py
===================================================================
--- trunk/src/host/pye17/codegen/defsparser.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/defsparser.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,153 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+import os, sys
+import scmexpr
+from definitions import BoxedDef, EnumDef, FlagsDef, FunctionDef, \
+     InterfaceDef, MethodDef, ObjectDef, PointerDef, VirtualDef
+
+include_path = ['.']
+
+class IncludeParser(scmexpr.Parser):
+    """A simple parser that follows include statements automatically"""
+    def include(self, input_filename):
+        global include_path
+        if os.path.isabs(input_filename):
+            filename = input_filename
+            # set self.filename to the include name, to handle recursive includes
+            oldfile = self.filename
+            self.filename = filename
+            self.startParsing()
+            self.filename = oldfile
+        else:
+            inc_path = [os.path.dirname(self.filename)] + include_path
+            for filename in [os.path.join(path_entry, input_filename)
+                             for path_entry in inc_path]:
+                if not os.path.exists(filename):
+                    continue
+                # set self.filename to the include name, to handle recursive includes
+                oldfile = self.filename
+                self.filename = filename
+                self.startParsing()
+                self.filename = oldfile
+                break
+            else:
+                raise IOError("%s not found in include path %s" % (input_filename, inc_path))
+
+class DefsParser(IncludeParser):
+    def __init__(self, arg, defines={}):
+        IncludeParser.__init__(self, arg)
+        self.objects = []
+        self.interfaces = []
+        self.enums = []      # enums and flags
+        self.boxes = []      # boxed types
+        self.pointers = []   # pointer types
+        self.functions = []  # functions and methods
+        self.virtuals = []   # virtual methods
+        self.c_name = {}     # hash of c names of functions
+        self.methods = {}    # hash of methods of particular objects
+        self.defines = defines      # -Dfoo=bar options, as dictionary
+
+    def define_object(self, *args):
+        odef = apply(ObjectDef, args)
+        self.objects.append(odef)
+        self.c_name[odef.c_name] = odef
+    def define_interface(self, *args):
+        idef = apply(InterfaceDef, args)
+        self.interfaces.append(idef)
+        self.c_name[idef.c_name] = idef
+    def define_enum(self, *args):
+        edef = apply(EnumDef, args)
+        self.enums.append(edef)
+        self.c_name[edef.c_name] = edef
+    def define_flags(self, *args):
+        fdef = apply(FlagsDef, args)
+        self.enums.append(fdef)
+        self.c_name[fdef.c_name] = fdef
+    def define_boxed(self, *args):
+        bdef = apply(BoxedDef, args)
+        self.boxes.append(bdef)
+        self.c_name[bdef.c_name] = bdef
+    def define_pointer(self, *args):
+        pdef = apply(PointerDef, args)
+        self.pointers.append(pdef)
+        self.c_name[pdef.c_name] = pdef
+    def define_function(self, *args):
+        fdef = apply(FunctionDef, args)
+        self.functions.append(fdef)
+        self.c_name[fdef.c_name] = fdef
+    def define_method(self, *args):
+        mdef = apply(MethodDef, args)
+        self.functions.append(mdef)
+        self.c_name[mdef.c_name] = mdef
+    def define_virtual(self, *args):
+        vdef = apply(VirtualDef, args)
+        self.virtuals.append(vdef)
+    def merge(self, old, parmerge):
+        for obj in self.objects:
+            if old.c_name.has_key(obj.c_name):
+                obj.merge(old.c_name[obj.c_name])
+        for f in self.functions:
+            if old.c_name.has_key(f.c_name):
+                f.merge(old.c_name[f.c_name], parmerge)
+
+    def printMissing(self, old):
+        for obj in self.objects:
+            if not old.c_name.has_key(obj.c_name):
+                obj.write_defs()
+        for f in self.functions:
+            if not old.c_name.has_key(f.c_name):
+                f.write_defs()
+
+    def write_defs(self, fp=sys.stdout):
+        for obj in self.objects:
+            obj.write_defs(fp)
+        for enum in self.enums:
+            enum.write_defs(fp)
+        for boxed in self.boxes:
+            boxed.write_defs(fp)
+        for pointer in self.pointers:
+            pointer.write_defs(fp)
+        for func in self.functions:
+            func.write_defs(fp)
+
+    def find_object(self, c_name):
+        for obj in self.objects:
+            if obj.c_name == c_name:
+                return obj
+        else:
+            raise ValueError('object %r not found' % c_name)
+
+    def find_constructor(self, obj, overrides):
+        for func in self.functions:
+            if isinstance(func, FunctionDef) and \
+               func.is_constructor_of == obj.c_name and \
+               not overrides.is_ignored(func.c_name):
+                return func
+
+    def find_methods(self, obj):
+        objname = obj.c_name
+        return filter(lambda func, on=objname: isinstance(func, MethodDef) and
+                      func.of_object == on, self.functions)
+
+    def find_virtuals(self, obj):
+        objname = obj.c_name
+        retval = filter(lambda func, on=objname: isinstance(func, VirtualDef) and
+                        func.of_object == on, self.virtuals)
+        return retval
+
+    def find_functions(self):
+        return filter(lambda func: isinstance(func, FunctionDef) and
+                      not func.is_constructor_of, self.functions)
+
+    def ifdef(self, *args):
+        if args[0] in self.defines:
+            for arg in args[1:]:
+                #print >> sys.stderr, "-----> Handling conditional definition (%s): %s" % (args[0], arg)
+                self.handle(arg)
+        else:
+            pass
+            #print >> sys.stderr, "-----> Conditional %s is not true" % (args[0],)
+
+    def ifndef(self, *args):
+        if args[0] not in self.defines:
+            for arg in args[1:]:
+                self.handle(arg)

Added: trunk/src/host/pye17/codegen/docextract.py
===================================================================
--- trunk/src/host/pye17/codegen/docextract.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/docextract.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,185 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+'''Simple module for extracting GNOME style doc comments from C
+sources, so I can use them for other purposes.'''
+
+import sys, os, string, re
+
+__all__ = ['extract']
+
+class FunctionDoc:
+    def __init__(self):
+        self.name = None
+        self.params = []
+        self.description = ''
+        self.ret = ''
+    def set_name(self, name):
+        self.name = name
+    def add_param(self, name, description):
+        if name == '...':
+            name = 'Varargs'
+        self.params.append((name, description))
+    def append_to_last_param(self, extra):
+        self.params[-1] = (self.params[-1][0], self.params[-1][1] + extra)
+    def append_to_named_param(self, name, extra):
+        for i in range(len(self.params)):
+            if self.params[i][0] == name:
+                self.params[i] = (name, self.params[i][1] + extra)
+                return
+        # fall through to adding extra parameter ...
+        self.add_param(name, extra)
+    def append_description(self, extra):
+        self.description = self.description + extra
+    def append_return(self, extra):
+        self.ret = self.ret + extra
+
+    def get_param_description(self, name):
+        for param, description in self.params:
+            if param == name:
+                return description
+        else:
+            return ''
+
+comment_start_pat = re.compile(r'^\s*/\*\*\s')
+comment_end_pat = re.compile(r'^\s*\*+/')
+comment_line_lead = re.compile(r'^\s*\*\s*')
+funcname_pat = re.compile(r'^(\w+)\s*:?')
+return_pat = re.compile(r'^(returns:|return\s+value:|returns\s*)(.*\n?)$',
+                        re.IGNORECASE)
+param_pat = re.compile(r'^@(\S+)\s*:(.*\n?)$')
+
+def parse_file(fp, doc_dict):
+    line = fp.readline()
+    in_comment_block = 0
+    while line:
+        if not in_comment_block:
+            if comment_start_pat.match(line):
+                in_comment_block = 1
+                cur_doc = FunctionDoc()
+                in_description = 0
+                in_return = 0
+            line = fp.readline()
+            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 ...
+        line = comment_line_lead.sub('', line)
+        if not line: line = '\n'
+
+        if not cur_doc.name:
+            match = funcname_pat.match(line)
+            if match:
+                cur_doc.set_name(match.group(1))
+        elif in_return:
+            match = return_pat.match(line)
+            if match:
+                # assume the last return statement was really part of the
+                # description
+                return_start = match.group(1)
+                cur_doc.ret = match.group(2)
+                cur_doc.description = cur_doc.description + return_start + \
+                                      cur_doc.ret
+            else:
+                cur_doc.append_return(line)
+        elif in_description:
+            if line[:12] == 'Description:':
+                line = line[12:]
+            match = return_pat.match(line)
+            if match:
+                in_return = 1
+                return_start = match.group(1)
+                cur_doc.append_return(match.group(2))
+            else:
+                cur_doc.append_description(line)
+        elif line == '\n':
+            # end of parameters
+            in_description = 1
+        else:
+            match = param_pat.match(line)
+            if match:
+                param = match.group(1)
+                desc = match.group(2)
+                if param == 'returns':
+                    cur_doc.ret = desc
+                else:
+                    cur_doc.add_param(param, desc)
+            else:
+                # must be continuation
+                try:
+                    if param == 'returns':
+                        cur_doc.append_return(line)
+                    else:
+                        cur_doc.append_to_last_param(line)
+                except:
+                    sys.stderr.write('something weird while reading param\n')
+        line = fp.readline()
+
+def parse_dir(dir, doc_dict):
+    for file in os.listdir(dir):
+        if file in ('.', '..'): continue
+        path = os.path.join(dir, file)
+        if os.path.isdir(path):
+            parse_dir(path, doc_dict)
+        if len(file) > 2 and file[-2:] == '.c':
+            parse_file(open(path, 'r'), doc_dict)
+
+def extract(dirs, doc_dict=None):
+    if not doc_dict: doc_dict = {}
+    for dir in dirs:
+        parse_dir(dir, doc_dict)
+    return doc_dict
+
+tmpl_section_pat = re.compile(r'^<!-- ##### (\w+) (\w+) ##### -->$')
+def parse_tmpl(fp, doc_dict):
+    cur_doc = None
+
+    line = fp.readline()
+    while line:
+        match = tmpl_section_pat.match(line)
+        if match:
+            cur_doc = None  # new input shouldn't affect the old doc dict
+            sect_type = match.group(1)
+            sect_name = match.group(2)
+
+            if sect_type == 'FUNCTION':
+                cur_doc = doc_dict.get(sect_name)
+                if not cur_doc:
+                    cur_doc = FunctionDoc()
+                    cur_doc.set_name(sect_name)
+                    doc_dict[sect_name] = cur_doc
+        elif line == '<!-- # Unused Parameters # -->\n':
+            cur_doc = None # don't worry about unused params.
+        elif cur_doc:
+            if line[:10] == '@Returns: ':
+                if string.strip(line[10:]):
+                    cur_doc.append_return(line[10:])
+            elif line[0] == '@':
+                pos = string.find(line, ':')
+                if pos >= 0:
+                    cur_doc.append_to_named_param(line[1:pos], line[pos+1:])
+                else:
+                    cur_doc.append_description(line)
+            else:
+                cur_doc.append_description(line)
+
+        line = fp.readline()
+
+def extract_tmpl(dirs, doc_dict=None):
+    if not doc_dict: doc_dict = {}
+    for dir in dirs:
+        for file in os.listdir(dir):
+            if file in ('.', '..'): continue
+            path = os.path.join(dir, file)
+            if os.path.isdir(path):
+                continue
+            if len(file) > 2 and file[-2:] == '.sgml':
+                parse_tmpl(open(path, 'r'), doc_dict)
+    return doc_dict

Added: trunk/src/host/pye17/codegen/docgen.py
===================================================================
--- trunk/src/host/pye17/codegen/docgen.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/docgen.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,751 @@
+#!/usr/bin/env python
+# -*- Mode: Python; py-indent-offset: 4 -*-
+import sys, os, string, re, getopt
+
+import defsparser
+import definitions
+import override
+import docextract
+
+class Node:
+    def __init__(self, name, interfaces=[]):
+        self.name = name
+        self.interfaces = interfaces
+        self.subclasses = []
+    def add_child(self, node):
+        self.subclasses.append(node)
+
+def build_object_tree(parser):
+    # reorder objects so that parent classes come first ...
+    objects = parser.objects[:]
+    pos = 0
+    while pos < len(objects):
+        parent = objects[pos].parent
+        for i in range(pos+1, len(objects)):
+            if objects[i].c_name == parent:
+                objects.insert(i+1, objects[pos])
+                del objects[pos]
+                break
+        else:
+            pos = pos + 1
+
+    root = Node(None)
+    nodes = { None: root }
+    for obj_def in objects:
+        parent_node = nodes[obj_def.parent]
+        node = Node(obj_def.c_name, obj_def.implements)
+        parent_node.add_child(node)
+        nodes[node.name] = node
+
+    if parser.interfaces:
+        interfaces = Node('gobject.GInterface')
+        root.add_child(interfaces)
+        nodes[interfaces.name] = interfaces
+        for obj_def in parser.interfaces:
+            node = Node(obj_def.c_name)
+            interfaces.add_child(node)
+            nodes[node.name] = node
+
+    if parser.boxes:
+        boxed = Node('gobject.GBoxed')
+        root.add_child(boxed)
+        nodes[boxed.name] = boxed
+        for obj_def in parser.boxes:
+            node = Node(obj_def.c_name)
+            boxed.add_child(node)
+            nodes[node.name] = node
+
+    if parser.pointers:
+        pointers = Node('gobject.GPointer')
+        root.add_child(pointers)
+        nodes[pointers.name] = pointers
+        for obj_def in parser.pointers:
+            node = Node(obj_def.c_name)
+            pointers.add_child(node)
+            nodes[node.name] = node
+
+    return root
+
+class DocWriter:
+    def __init__(self):
+        # parse the defs file
+        self.parser = defsparser.DefsParser(())
+        self.overrides = override.Overrides()
+        self.classmap = {}
+        self.docs = {}
+
+    def add_sourcedirs(self, source_dirs):
+        self.docs = docextract.extract(source_dirs, self.docs)
+    def add_tmpldirs(self, tmpl_dirs):
+        self.docs = docextract.extract_tmpl(tmpl_dirs, self.docs)
+
+    def add_docs(self, defs_file, overrides_file, module_name):
+        '''parse information about a given defs file'''
+        self.parser.filename = defs_file
+        self.parser.startParsing(defs_file)
+        if overrides_file:
+            self.overrides.handle_file(overrides_file)
+
+        for obj in self.parser.objects:
+            if not self.classmap.has_key(obj.c_name):
+                self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
+        for obj in self.parser.interfaces:
+            if not self.classmap.has_key(obj.c_name):
+                self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
+        for obj in self.parser.boxes:
+            if not self.classmap.has_key(obj.c_name):
+                self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
+        for obj in self.parser.pointers:
+            if not self.classmap.has_key(obj.c_name):
+                self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
+
+    def pyname(self, name):
+        return self.classmap.get(name, name)
+
+    def __compare(self, obja, objb):
+        return cmp(self.pyname(obja.c_name), self.pyname(objb.c_name))
+    def output_docs(self, output_prefix):
+        files = []
+
+        # class hierarchy
+        hierarchy = build_object_tree(self.parser)
+        filename = self.create_filename('hierarchy', output_prefix)
+        fp = open(filename, 'w')
+        self.write_full_hierarchy(hierarchy, fp)
+        fp.close()
+
+        obj_defs = self.parser.objects + self.parser.interfaces + \
+                   self.parser.boxes + self.parser.pointers
+        obj_defs.sort(self.__compare)
+        for obj_def in obj_defs:
+            filename = self.create_filename(obj_def.c_name, output_prefix)
+            fp = open(filename, 'w')
+            if isinstance(obj_def, definitions.ObjectDef):
+                self.output_object_docs(obj_def, fp)
+            elif isinstance(obj_def, definitions.InterfaceDef):
+                self.output_interface_docs(obj_def, fp)
+            elif isinstance(obj_def, definitions.BoxedDef):
+                self.output_boxed_docs(obj_def, fp)
+            elif isinstance(obj_def, definitions.PointerDef):
+                self.output_boxed_docs(obj_def, fp)
+            fp.close()
+            files.append((os.path.basename(filename), obj_def))
+
+        if files:
+            filename = self.create_toc_filename(output_prefix)
+            fp = open(filename, 'w')
+            self.output_toc(files, fp)
+            fp.close()
+
+    def output_object_docs(self, obj_def, fp=sys.stdout):
+        self.write_class_header(obj_def.c_name, fp)
+
+        self.write_heading('Synopsis', fp)
+        self.write_synopsis(obj_def, fp)
+        self.close_section(fp)
+
+        # construct the inheritence hierarchy ...
+        ancestry = [ (obj_def.c_name, obj_def.implements) ]
+        try:
+            parent = obj_def.parent
+            while parent != None:
+                if parent == 'GObject':
+                    ancestry.append(('GObject', []))
+                    parent = None
+                else:
+                    parent_def = self.parser.find_object(parent)
+                    ancestry.append((parent_def.c_name, parent_def.implements))
+                    parent = parent_def.parent
+        except ValueError:
+            pass
+        ancestry.reverse()
+        self.write_heading('Ancestry', fp)
+        self.write_hierarchy(obj_def.c_name, ancestry, fp)
+        self.close_section(fp)
+
+        constructor = self.parser.find_constructor(obj_def, self.overrides)
+        if constructor:
+            self.write_heading('Constructor', fp)
+            self.write_constructor(constructor,
+                                   self.docs.get(constructor.c_name, None),
+                                   fp)
+            self.close_section(fp)
+
+        methods = self.parser.find_methods(obj_def)
+        methods = filter(lambda meth, self=self:
+                         not self.overrides.is_ignored(meth.c_name), methods)
+        if methods:
+            self.write_heading('Methods', fp)
+            for method in methods:
+                self.write_method(method, self.docs.get(method.c_name, None), fp)
+            self.close_section(fp)
+
+        self.write_class_footer(obj_def.c_name, fp)
+
+    def output_interface_docs(self, int_def, fp=sys.stdout):
+        self.write_class_header(int_def.c_name, fp)
+
+        self.write_heading('Synopsis', fp)
+        self.write_synopsis(int_def, fp)
+        self.close_section(fp)
+
+        methods = self.parser.find_methods(int_def)
+        methods = filter(lambda meth, self=self:
+                         not self.overrides.is_ignored(meth.c_name), methods)
+        if methods:
+            self.write_heading('Methods', fp)
+            for method in methods:
+                self.write_method(method, self.docs.get(method.c_name, None), fp)
+            self.close_section(fp)
+
+        self.write_class_footer(int_def.c_name, fp)
+
+    def output_boxed_docs(self, box_def, fp=sys.stdout):
+        self.write_class_header(box_def.c_name, fp)
+
+        self.write_heading('Synopsis', fp)
+        self.write_synopsis(box_def, fp)
+        self.close_section(fp)
+
+        constructor = self.parser.find_constructor(box_def, self.overrides)
+        if constructor:
+            self.write_heading('Constructor', fp)
+            self.write_constructor(constructor,
+                                   self.docs.get(constructor.c_name, None),
+                                   fp)
+            self.close_section(fp)
+
+        methods = self.parser.find_methods(box_def)
+        methods = filter(lambda meth, self=self:
+                         not self.overrides.is_ignored(meth.c_name), methods)
+        if methods:
+            self.write_heading('Methods', fp)
+            for method in methods:
+                self.write_method(method, self.docs.get(method.c_name, None), fp)
+            self.close_section(fp)
+
+        self.write_class_footer(box_def.c_name, fp)
+
+    def output_toc(self, files, fp=sys.stdout):
+        fp.write('TOC\n\n')
+        for filename, obj_def in files:
+            fp.write(obj_def.c_name + ' - ' + filename + '\n')
+
+    # override the following to create a more complex output format
+    def create_filename(self, obj_name, output_prefix):
+        '''Create output filename for this particular object'''
+        return output_prefix + '-' + string.lower(obj_name) + '.txt'
+    def create_toc_filename(self, output_prefix):
+        return self.create_filename(self, 'docs', output_prefix)
+
+    def write_full_hierarchy(self, hierarchy, fp):
+        def handle_node(node, fp, indent=''):
+            for child in node.subclasses:
+                fp.write(indent + node.name)
+                if node.interfaces:
+                    fp.write(' (implements ')
+                    fp.write(string.join(node.interfaces, ', '))
+                    fp.write(')\n')
+                else:
+                    fp.write('\n')
+                handle_node(child, fp, indent + '  ')
+        handle_node(hierarchy, fp)
+
+    # these need to handle default args ...
+    def create_constructor_prototype(self, func_def):
+        return func_def.is_constructor_of + '(' + \
+               string.join(map(lambda x: x[1], func_def.params), ', ') + \
+               ')'
+    def create_function_prototype(self, func_def):
+        return func_def.name + '(' + \
+               string.join(map(lambda x: x[1], func_def.params), ', ') + \
+               ')'
+    def create_method_prototype(self, meth_def):
+        return meth_def.of_object + '.' + \
+               meth_def.name + '(' + \
+               string.join(map(lambda x: x[1], meth_def.params), ', ') + \
+               ')'
+
+    def write_class_header(self, obj_name, fp):
+        fp.write('Class %s\n' % obj_name)
+        fp.write('======%s\n\n' % ('=' * len(obj_name)))
+    def write_class_footer(self, obj_name, fp):
+        pass
+    def write_heading(self, text, fp):
+        fp.write('\n' + text + '\n' + ('-' * len(text)) + '\n')
+    def close_section(self, fp):
+        pass
+    def write_synopsis(self, obj_def, fp):
+        fp.write('class %s' % obj_def.c_name)
+        if isinstance(obj_def, definitions.ObjectDef):
+            bases = []
+            if obj_def.parent: bases.append(obj_def.parent)
+            bases = bases = obj_def.implements
+            if bases:
+                fp.write('(%s)' % string.join(bases, ', '))
+        fp.write(':\n')
+
+        constructor = self.parser.find_constructor(obj_def, self.overrides)
+        if constructor:
+            prototype = self.create_constructor_prototype(constructor)
+            fp.write('    def %s\n' % prototype)
+        methods = self.parser.find_methods(obj_def)
+        methods = filter(lambda meth, self=self:
+                         not self.overrides.is_ignored(meth.c_name), methods)
+        for meth in methods:
+            prototype = self.create_method_prototype(meth)
+            fp.write('    def %s\n' % prototype)
+
+    def write_hierarchy(self, obj_name, ancestry, fp):
+        indent = ''
+        for name, interfaces in ancestry:
+            fp.write(indent + '+-- ' + name)
+            if interfaces:
+                fp.write(' (implements ')
+                fp.write(string.join(interfaces, ', '))
+                fp.write(')\n')
+            else:
+                fp.write('\n')
+            indent = indent + '  '
+        fp.write('\n')
+    def write_constructor(self, func_def, func_doc, fp):
+        prototype = self.create_constructor_prototype(func_def)
+        fp.write(prototype + '\n\n')
+        for type, name, dflt, null in func_def.params:
+            if func_doc:
+                descr = func_doc.get_param_description(name)
+            else:
+                descr = 'a ' + type
+            fp.write('  ' + name + ': ' + descr + '\n')
+        if func_def.ret and func_def.ret != 'none':
+            if func_doc and func_doc.ret:
+                descr = func_doc.ret
+            else:
+                descr = 'a ' + func_def.ret
+            fp.write('  Returns: ' + descr + '\n')
+        if func_doc and func_doc.description:
+            fp.write(func_doc.description)
+        fp.write('\n\n\n')
+    def write_method(self, meth_def, func_doc, fp):
+        prototype = self.create_method_prototype(meth_def)
+        fp.write(prototype + '\n\n')
+        for type, name, dflt, null in meth_def.params:
+            if func_doc:
+                descr = func_doc.get_param_description(name)
+            else:
+                descr = 'a ' + type
+            fp.write('  ' + name + ': ' + descr + '\n')
+        if meth_def.ret and meth_def.ret != 'none':
+            if func_doc and func_doc.ret:
+                descr = func_doc.ret
+            else:
+                descr = 'a ' + meth_def.ret
+            fp.write('  Returns: ' + descr + '\n')
+        if func_doc and func_doc.description:
+            fp.write('\n')
+            fp.write(func_doc.description)
+        fp.write('\n\n')
+
+class DocbookDocWriter(DocWriter):
+    def __init__(self, use_xml=0):
+        DocWriter.__init__(self)
+        self.use_xml = use_xml
+
+    def create_filename(self, obj_name, output_prefix):
+        '''Create output filename for this particular object'''
+        stem = output_prefix + '-' + string.lower(obj_name)
+        if self.use_xml:
+            return stem + '.xml'
+        else:
+            return stem + '.sgml'
+    def create_toc_filename(self, output_prefix):
+        if self.use_xml:
+            return self.create_filename('classes', output_prefix)
+        else:
+            return self.create_filename('docs', output_prefix)
+
+    # make string -> reference translation func
+    __transtable = [ '-' ] * 256
+    for digit in '0123456789':
+        __transtable[ord(digit)] = digit
+    for letter in 'abcdefghijklmnopqrstuvwxyz':
+        __transtable[ord(letter)] = letter
+        __transtable[ord(string.upper(letter))] = letter
+    __transtable = string.join(__transtable, '')
+
+    def make_class_ref(self, obj_name):
+        return 'class-' + string.translate(obj_name, self.__transtable)
+    def make_method_ref(self, meth_def):
+        return 'method-' + string.translate(meth_def.of_object,
+                                            self.__transtable) + \
+            '--' + string.translate(meth_def.name, self.__transtable)
+
+    __function_pat = re.compile(r'(\w+)\s*\(\)')
+    def __format_function(self, match):
+        info = self.parser.c_name.get(match.group(1), None)
+        if info:
+            if isinstance(info, defsparser.FunctionDef):
+                if info.is_constructor_of is not None:
+                    # should have a link here
+                    return '<function>%s()</function>' % \
+                           self.pyname(info.is_constructor_of)
+                else:
+                    return '<function>' + info.name + '()</function>'
+            if isinstance(info, defsparser.MethodDef):
+                return '<link linkend="' + self.make_method_ref(info) + \
+                       '"><function>' + self.pyname(info.of_object) + '.' + \
+                       info.name + '()</function></link>'
+        # fall through through
+        return '<function>' + match.group(1) + '()</function>'
+    __parameter_pat = re.compile(r'\@(\w+)')
+    def __format_param(self, match):
+        return '<parameter>' + match.group(1) + '</parameter>'
+    __constant_pat = re.compile(r'\%(-?\w+)')
+    def __format_const(self, match):
+        return '<literal>' + match.group(1) + '</literal>'
+    __symbol_pat = re.compile(r'#([\w-]+)')
+    def __format_symbol(self, match):
+        info = self.parser.c_name.get(match.group(1), None)
+        if info:
+            if isinstance(info, defsparser.FunctionDef):
+                if info.is_constructor_of is not None:
+                    # should have a link here
+                    return '<methodname>' + self.pyname(info.is_constructor_of) + \
+                           '</methodname>'
+                else:
+                    return '<function>' + info.name + '</function>'
+            if isinstance(info, defsparser.MethodDef):
+                return '<link linkend="' + self.make_method_ref(info) + \
+                       '"><methodname>' + self.pyname(info.of_object) + '.' + \
+                       info.name + '</methodname></link>'
+            if isinstance(info, defsparser.ObjectDef) or \
+                   isinstance(info, defsparser.InterfaceDef) or \
+                   isinstance(info, defsparser.BoxedDef) or \
+                   isinstance(info, defsparser.PointerDef):
+                return '<link linkend="' + self.make_class_ref(info.c_name) + \
+                       '"><classname>' + self.pyname(info.c_name) + \
+                       '</classname></link>'
+        # fall through through
+        return '<literal>' + match.group(1) + '</literal>'
+
+    def reformat_text(self, text, singleline=0):
+        # replace special strings ...
+        text = self.__function_pat.sub(self.__format_function, text)
+        text = self.__parameter_pat.sub(self.__format_param, text)
+        text = self.__constant_pat.sub(self.__format_const, text)
+        text = self.__symbol_pat.sub(self.__format_symbol, text)
+
+        # don't bother with <para> expansion for single line text.
+        if singleline: return text
+
+        lines = string.split(string.strip(text), '\n')
+        for index in range(len(lines)):
+            if string.strip(lines[index]) == '':
+                lines[index] = '</para>\n<para>'
+                continue
+        lines.insert(0, '<para>')
+        lines.append('</para>')
+        return string.join(lines, '\n')
+
+    # write out hierarchy
+    def write_full_hierarchy(self, hierarchy, fp):
+        def handle_node(node, fp, indent=''):
+            if node.name:
+                fp.write('%s<link linkend="%s">%s</link>' %
+                         (indent, self.make_class_ref(node.name),
+                          self.pyname(node.name)))
+                if node.interfaces:
+                    fp.write(' (implements ')
+                    for i in range(len(node.interfaces)):
+                        fp.write('<link linkend="%s">%s</link>' %
+                                 (self.make_class_ref(node.interfaces[i]),
+                                  self.pyname(node.interfaces[i])))
+                        if i != len(node.interfaces) - 1:
+                            fp.write(', ')
+                    fp.write(')\n')
+                else:
+                    fp.write('\n')
+
+                indent = indent + '  '
+            node.subclasses.sort(lambda a,b:
+                                 cmp(self.pyname(a.name), self.pyname(b.name)))
+            for child in node.subclasses:
+                handle_node(child, fp, indent)
+        if self.use_xml:
+            fp.write('<?xml version="1.0" standalone="no"?>\n')
+            fp.write('<!DOCTYPE synopsis PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n')
+            fp.write('    "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">\n')
+        fp.write('<synopsis>')
+        handle_node(hierarchy, fp)
+        fp.write('</synopsis>\n')
+
+    # these need to handle default args ...
+    def create_constructor_prototype(self, func_def):
+        sgml = [ '<constructorsynopsis language="python">\n']
+        sgml.append('    <methodname>__init__</methodname>\n')
+        for type, name, dflt, null in func_def.params:
+            sgml.append('    <methodparam><parameter>')
+            sgml.append(name)
+            sgml.append('</parameter>')
+            if dflt:
+                sgml.append('<initializer>')
+                sgml.append(dflt)
+                sgml.append('</initializer>')
+            sgml.append('</methodparam>\n')
+        if not func_def.params:
+            sgml.append('    <methodparam></methodparam>')
+        sgml.append('  </constructorsynopsis>')
+        return string.join(sgml, '')
+    def create_function_prototype(self, func_def):
+        sgml = [ '<funcsynopsis language="python">\n    <funcprototype>\n']
+        sgml.append('      <funcdef><function>')
+        sgml.append(func_def.name)
+        sgml.append('</function></funcdef>\n')
+        for type, name, dflt, null in func_def.params:
+            sgml.append('      <paramdef><parameter>')
+            sgml.append(name)
+            sgml.append('</parameter>')
+            if dflt:
+                sgml.append('<initializer>')
+                sgml.append(dflt)
+                sgml.append('</initializer>')
+            sgml.append('</paramdef>\n')
+        if not func_def.params:
+            sgml.append('      <paramdef></paramdef')
+        sgml.append('    </funcprototype>\n  </funcsynopsis>')
+        return string.join(sgml, '')
+    def create_method_prototype(self, meth_def, addlink=0):
+        sgml = [ '<methodsynopsis language="python">\n']
+        sgml.append('    <methodname>')
+        if addlink:
+            sgml.append('<link linkend="%s">' % self.make_method_ref(meth_def))
+        sgml.append(self.pyname(meth_def.name))
+        if addlink:
+            sgml.append('</link>')
+        sgml.append('</methodname>\n')
+        for type, name, dflt, null in meth_def.params:
+            sgml.append('    <methodparam><parameter>')
+            sgml.append(name)
+            sgml.append('</parameter>')
+            if dflt:
+                sgml.append('<initializer>')
+                sgml.append(dflt)
+                sgml.append('</initializer>')
+            sgml.append('</methodparam>\n')
+        if not meth_def.params:
+            sgml.append('    <methodparam></methodparam>')
+        sgml.append('  </methodsynopsis>')
+        return string.join(sgml, '')
+
+    def write_class_header(self, obj_name, fp):
+        if self.use_xml:
+            fp.write('<?xml version="1.0" standalone="no"?>\n')
+            fp.write('<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n')
+            fp.write('    "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">\n')
+        fp.write('<refentry id="' + self.make_class_ref(obj_name) + '">\n')
+        fp.write('  <refmeta>\n')
+        fp.write('    <refentrytitle>%s</refentrytitle>\n'
+                 % self.pyname(obj_name))
+        fp.write('    <manvolnum>3</manvolnum>\n')
+        fp.write('    <refmiscinfo>PyGTK Docs</refmiscinfo>\n')
+        fp.write('  </refmeta>\n\n')
+        fp.write('  <refnamediv>\n')
+        fp.write('    <refname>%s</refname><refpurpose></refpurpose>\n'
+                 % self.pyname(obj_name))
+        fp.write('  </refnamediv>\n\n')
+    def write_class_footer(self, obj_name, fp):
+        fp.write('</refentry>\n')
+    def write_heading(self, text, fp):
+        fp.write('  <refsect1>\n')
+        fp.write('    <title>' + text + '</title>\n\n')
+    def close_section(self, fp):
+        fp.write('  </refsect1>\n')
+
+    def write_synopsis(self, obj_def, fp):
+        fp.write('<classsynopsis language="python">\n')
+        fp.write('  <ooclass><classname>%s</classname></ooclass>\n'
+                 % self.pyname(obj_def.c_name))
+        if isinstance(obj_def, definitions.ObjectDef):
+            if obj_def.parent:
+                fp.write('  <ooclass><classname><link linkend="%s">%s'
+                         '</link></classname></ooclass>\n'
+                         % (self.make_class_ref(obj_def.parent),
+                            self.pyname(obj_def.parent)))
+            for base in obj_def.implements:
+                fp.write('  <ooclass><classname><link linkend="%s">%s'
+                         '</link></classname></ooclass>\n'
+                         % (self.make_class_ref(base), self.pyname(base)))
+        elif isinstance(obj_def, definitions.InterfaceDef):
+            fp.write('  <ooclass><classname>gobject.GInterface'
+                     '</classname></ooclass>\n')
+        elif isinstance(obj_def, definitions.BoxedDef):
+            fp.write('  <ooclass><classname>gobject.GBoxed'
+                     '</classname></ooclass>\n')
+        elif isinstance(obj_def, definitions.PointerDef):
+            fp.write('  <ooclass><classname>gobject.GPointer'
+                     '</classname></ooclass>\n')
+
+        constructor = self.parser.find_constructor(obj_def, self.overrides)
+        if constructor:
+            fp.write('%s\n' % self.create_constructor_prototype(constructor))
+        methods = self.parser.find_methods(obj_def)
+        methods = filter(lambda meth, self=self:
+                         not self.overrides.is_ignored(meth.c_name), methods)
+        for meth in methods:
+            fp.write('%s\n' % self.create_method_prototype(meth, addlink=1))
+        fp.write('</classsynopsis>\n\n')
+
+    def write_hierarchy(self, obj_name, ancestry, fp):
+        fp.write('<synopsis>')
+        indent = ''
+        for name, interfaces in ancestry:
+            fp.write(indent + '+-- <link linkend="' +
+                     self.make_class_ref(name) + '">'+ self.pyname(name) + '</link>')
+            if interfaces:
+                fp.write(' (implements ')
+                for i in range(len(interfaces)):
+                    fp.write('<link linkend="%s">%s</link>' %
+                             (self.make_class_ref(interfaces[i]),
+                              self.pyname(interfaces[i])))
+                    if i != len(interfaces) - 1:
+                        fp.write(', ')
+                fp.write(')\n')
+            else:
+                fp.write('\n')
+            indent = indent + '  '
+        fp.write('</synopsis>\n\n')
+
+    def write_params(self, params, ret, func_doc, fp):
+        if not params and (not ret or ret == 'none'):
+            return
+        fp.write('  <variablelist>\n')
+        for type, name, dflt, null in params:
+            if func_doc:
+                descr = string.strip(func_doc.get_param_description(name))
+            else:
+                descr = 'a ' + type
+            fp.write('    <varlistentry>\n')
+            fp.write('      <term><parameter>%s</parameter>&nbsp;:</term>\n' % name)
+            fp.write('      <listitem><simpara>%s</simpara></listitem>\n' %
+                     self.reformat_text(descr, singleline=1))
+            fp.write('    </varlistentry>\n')
+        if ret and ret != 'none':
+            if func_doc and func_doc.ret:
+                descr = string.strip(func_doc.ret)
+            else:
+                descr = 'a ' + ret
+            fp.write('    <varlistentry>\n')
+            fp.write('      <term><emphasis>Returns</emphasis>&nbsp;:</term>\n')
+            fp.write('      <listitem><simpara>%s</simpara></listitem>\n' %
+                     self.reformat_text(descr, singleline=1))
+            fp.write('    </varlistentry>\n')
+        fp.write('  </variablelist>\n')
+
+    def write_constructor(self, func_def, func_doc, fp):
+        prototype = self.create_constructor_prototype(func_def)
+        fp.write('<programlisting>%s</programlisting>\n' % prototype)
+        self.write_params(func_def.params, func_def.ret, func_doc, fp)
+
+        if func_doc and func_doc.description:
+            fp.write(self.reformat_text(func_doc.description))
+        fp.write('\n\n\n')
+
+    def write_method(self, meth_def, func_doc, fp):
+        fp.write('  <refsect2 id="' + self.make_method_ref(meth_def) + '">\n')
+        fp.write('    <title>' + self.pyname(meth_def.of_object) + '.' +
+                 meth_def.name + '</title>\n\n')
+        prototype = self.create_method_prototype(meth_def)
+        fp.write('<programlisting>%s</programlisting>\n' % prototype)
+        self.write_params(meth_def.params, meth_def.ret, func_doc, fp)
+        if func_doc and func_doc.description:
+            fp.write(self.reformat_text(func_doc.description))
+        fp.write('  </refsect2>\n\n\n')
+
+    def output_toc(self, files, fp=sys.stdout):
+        if self.use_xml:
+            fp.write('<?xml version="1.0" standalone="no"?>\n')
+            fp.write('<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n')
+            fp.write('    "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">\n')
+            #for filename, obj_def in files:
+            #    fp.write('  <!ENTITY ' + string.translate(obj_def.c_name,
+            #                                              self.__transtable) +
+            #             ' SYSTEM "' + filename + '" >\n')
+            #fp.write(']>\n\n')
+
+            #fp.write('<reference id="class-reference">\n')
+            #fp.write('  <title>Class Documentation</title>\n')
+            #for filename, obj_def in files:
+            #    fp.write('&' + string.translate(obj_def.c_name,
+            #                                    self.__transtable) + ';\n')
+            #fp.write('</reference>\n')
+
+            fp.write('<reference id="class-reference" xmlns:xi="http://www.w3.org/2001/XInclude">\n')
+            fp.write('  <title>Class Reference</title>\n')
+            for filename, obj_def in files:
+                fp.write('  <xi:include href="%s"/>\n' % filename)
+            fp.write('</reference>\n')
+        else:
+            fp.write('<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1.2//EN" [\n')
+            for filename, obj_def in files:
+                fp.write('  <!ENTITY ' + string.translate(obj_def.c_name,
+                                                          self.__transtable) +
+                         ' SYSTEM "' + filename + '" >\n')
+            fp.write(']>\n\n')
+
+            fp.write('<book id="index">\n\n')
+            fp.write('  <bookinfo>\n')
+            fp.write('    <title>PyGTK Docs</title>\n')
+            fp.write('    <authorgroup>\n')
+            fp.write('      <author>\n')
+            fp.write('        <firstname>James</firstname>\n')
+            fp.write('        <surname>Henstridge</surname>\n')
+            fp.write('      </author>\n')
+            fp.write('    </authorgroup>\n')
+            fp.write('  </bookinfo>\n\n')
+
+            fp.write('  <chapter id="class-hierarchy">\n')
+            fp.write('    <title>Class Hierarchy</title>\n')
+            fp.write('    <para>Not done yet</para>\n')
+            fp.write('  </chapter>\n\n')
+
+            fp.write('  <reference id="class-reference">\n')
+            fp.write('    <title>Class Documentation</title>\n')
+            for filename, obj_def in files:
+                fp.write('&' + string.translate(obj_def.c_name,
+                                                self.__transtable) + ';\n')
+
+            fp.write('  </reference>\n')
+            fp.write('</book>\n')
+
+if __name__ == '__main__':
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "d:s:o:",
+                                   ["defs-file=", "override=", "source-dir=",
+                                    "output-prefix="])
+    except getopt.error, e:
+        sys.stderr.write('docgen.py: %s\n' % e)
+        sys.stderr.write(
+            'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
+        sys.exit(1)
+    defs_file = None
+    overrides_file = None
+    source_dirs = []
+    output_prefix = 'docs'
+    for opt, arg in opts:
+        if opt in ('-d', '--defs-file'):
+            defs_file = arg
+        if opt in ('--override',):
+            overrides_file = arg
+        elif opt in ('-s', '--source-dir'):
+            source_dirs.append(arg)
+        elif opt in ('-o', '--output-prefix'):
+            output_prefix = arg
+    if len(args) != 0 or not defs_file:
+        sys.stderr.write(
+            'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
+        sys.exit(1)
+
+    d = DocbookDocWriter()
+    d.add_sourcedirs(source_dirs)
+    d.add_docs(defs_file, overrides_file, 'gtk')
+    d.output_docs(output_prefix)


Property changes on: trunk/src/host/pye17/codegen/docgen.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/host/pye17/codegen/h2def.py
===================================================================
--- trunk/src/host/pye17/codegen/h2def.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/h2def.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,636 @@
+#!/usr/bin/env python
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# Search through a header file looking for function prototypes.
+# For each prototype, generate a scheme style definition.
+# GPL'ed
+# Toby D. Reeves <toby at max.rl.plh.af.mil>
+#
+# Modified by James Henstridge <james at daa.com.au> to output stuff in
+# 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
+# Updated to be PEP-8 compatible and refactored to use OOP
+
+import getopt
+import os
+import re
+import string
+import sys
+
+#sys.path.append("/usr/share/pygtk/2.0/codegen/")
+
+import defsparser
+
+# ------------------ 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)
+    return typename
+
+
+# ------------------ Find object definitions -----------------
+
+def strip_comments(buf):
+    parts = []
+    lastpos = 0
+    while 1:
+        pos = string.find(buf, '/*', lastpos)
+        if pos >= 0:
+            parts.append(buf[lastpos:pos])
+            pos = string.find(buf, '*/', pos)
+            if pos >= 0:
+                lastpos = pos + 2
+            else:
+                break
+        else:
+            parts.append(buf[lastpos:])
+            break
+    return string.join(parts, '')
+
+obj_name_pat = "[A-Za-z0-9_]*"
+
+split_prefix_pat = re.compile('([A-Z]+[a-z]*)([A-Za-z0-9]+)')
+
+def find_obj_defs(buf, objdefs=[]):
+    """
+    Try to find object definitions in header files.
+    """
+
+    # filter out comments from buffer.
+    buf = strip_comments(buf)
+
+    struct_typedef = {}
+
+    # handle typedef enum style defs.
+    pat = re.compile("typedef struct\s*([_A-Za-z]*)\s*([_A-Za-z]*)\s*;", re.MULTILINE)
+    pos = 0
+    while pos < len(buf):
+        m = pat.search(buf, pos)
+        if not m: break
+	#print "typedef struct: " + m.group(1) + " => " + m.group(2)
+	struct_typedef[m.group(1)] = m.group(2)
+        pos = m.end()
+
+    # first find all structures that look like they may represent a GtkObject
+    pat = re.compile("^struct (" + obj_name_pat + ")\s*{\s*" +
+                     "(" + obj_name_pat + ")\s+", re.MULTILINE)
+    pos = 0
+    while pos < len(buf):
+        m = pat.search(buf, pos)
+        if not m: break
+	#print "struct: " + m.group(1) + " => " + m.group(2)
+
+	name = m.group(1)
+	if name in struct_typedef:
+		name = struct_typedef[name]
+
+        objdefs.append((name, None))
+        pos = m.end()
+
+    #maybeobjdefs = []  # contains all possible objects from file
+
+    ## handle typedef struct { ... } style struct defs.
+    #pat = re.compile("typedef struct\s+[_\w]*\s*{\s*" +
+                     #"(" + obj_name_pat + ")\s+[^}]*}\s*" +
+                     #"(" + obj_name_pat + ")\s*;", re.MULTILINE)
+    #pos = 0
+    #while pos < len(buf):
+        #m = pat.search(buf, pos)
+        #if not m: break
+        #maybeobjdefs.append((m.group(2), m.group(2)))
+        #pos = m.end()
+
+    ## now find all structures that look like they might represent a class:
+    #pat = re.compile("struct _(" + obj_name_pat + ")Class\s*{\s*" +
+                     #"(" + obj_name_pat + ")Class\s+", re.MULTILINE)
+    #pos = 0
+    #while pos < len(buf):
+        #m = pat.search(buf, pos)
+        #if not m: break
+        #t = (m.group(1), m.group(2))
+        ## if we find an object structure together with a corresponding
+        ## class structure, then we have probably found a GtkObject subclass.
+        #if t in maybeobjdefs:
+            #objdefs.append(t)
+        #pos = m.end()
+
+    #pat = re.compile("typedef struct\s+[_\w]*\s*{\s*" +
+                     #"(" + obj_name_pat + ")Class\s+[^}]*}\s*" +
+                     #"(" + obj_name_pat + ")Class\s*;", re.MULTILINE)
+    #pos = 0
+    #while pos < len(buf):
+        #m = pat.search(buf, pos)
+        #if not m: break
+        #t = (m.group(2), m.group(1))
+        ## if we find an object structure together with a corresponding
+        ## class structure, then we have probably found a GtkObject subclass.
+        #if t in maybeobjdefs:
+            #objdefs.append(t)
+        #pos = m.end()
+
+    ## 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*" +
+                     #"GTypeInterface\s+", re.MULTILINE)
+    #pos = 0
+    #while pos < len(buf):
+        #m = pat.search(buf, pos)
+        #if not m: break
+        #t = (m.group(1), '')
+        #t2 = (m.group(1)+'Class', 'GTypeInterface')
+        ## if we find an object structure together with a corresponding
+        ## class structure, then we have probably found a GtkObject subclass.
+        #if t2 in maybeobjdefs:
+            #objdefs.append(t)
+        #pos = m.end()
+
+    ## 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*" +
+                     #"GTypeInterface\s+", re.MULTILINE)
+    #pos = 0
+    #while pos < len(buf):
+        #m = pat.search(buf, pos)
+        #if not m: break
+        #t = (m.group(1), '')
+        #t2 = (m.group(1)+'Iface', 'GTypeInterface')
+        ## if we find an object structure together with a corresponding
+        ## class structure, then we have probably found a GtkObject subclass.
+        #if t2 in maybeobjdefs:
+            #objdefs.append(t)
+        #pos = m.end()
+
+def sort_obj_defs(objdefs):
+    objdefs.sort()  # not strictly needed, but looks nice
+    pos = 0
+    while pos < len(objdefs):
+        klass,parent = objdefs[pos]
+        for i in range(pos+1, len(objdefs)):
+            # parent below subclass ... reorder
+            if objdefs[i][0] == parent:
+                objdefs.insert(i+1, objdefs[pos])
+                del objdefs[pos]
+                break
+        else:
+            pos = pos + 1
+    return objdefs
+
+# ------------------ Find enum definitions -----------------
+
+def find_enum_defs(buf, enums=[]):
+    # strip comments
+    # bulk comments
+    buf = strip_comments(buf)
+
+    buf = re.sub('\n', ' ', buf)
+
+    enum_typedef = {}
+
+    # handle typedef enum style defs.
+    pat = re.compile("typedef enum\s*([_A-Za-z]*)\s*([_A-Za-z]*)\s*;", re.MULTILINE)
+    pos = 0
+    while pos < len(buf):
+        m = pat.search(buf, pos)
+        if not m: break
+	#print "typedef: " + m.group(1) + " => " + m.group(2)
+	enum_typedef[m.group(1)] = m.group(2)
+        pos = m.end()
+
+    #enum_pat = re.compile(r'enum\s*{([^}]*)}\s*([A-Z][A-Za-z]*)(\s|;)')
+    enum_pat = re.compile(r'enum\s*([_A-Za-z]*)\s*{([^}]*)}\s*([_A-Za-z]*)(\s|;)')
+    splitter = re.compile(r'\s*,\s', re.MULTILINE)
+    pos = 0
+    while pos < len(buf):
+        m = enum_pat.search(buf, pos)
+        if not m: break
+
+	#print "name: " + m.group(2)
+	#print "vals: " + m.group(1)
+	#print "alt. name: >" + m.group(3) + "<"
+
+        name = m.group(1)
+	if not name:
+		name = m.group(3)
+
+	if name in enum_typedef:
+		name = enum_typedef[name]
+
+        vals = m.group(2)
+
+        isflags = string.find(vals, '<<') >= 0
+        entries = []
+        for val in splitter.split(vals):
+            if not string.strip(val): continue
+            entries.append(string.split(val)[0])
+        if name != 'GdkCursorType':
+            enums.append((name, isflags, entries))
+
+        pos = m.end()
+
+# ------------------ Find function definitions -----------------
+
+def clean_func(buf):
+    """
+    Ideally would make buf have a single prototype on each line.
+    Actually just cuts out a good deal of junk, but leaves lines
+    where a regex can figure prototypes out.
+    """
+    # bulk comments
+    buf = strip_comments(buf)
+
+    # compact continued lines
+    pat = re.compile(r"""\\\n""", re.MULTILINE)
+    buf = pat.sub('', buf)
+    #print "functions 1: " + buf
+
+    # Preprocess directives
+    pat = re.compile(r"""^[#].*?$""", re.MULTILINE)
+    buf = pat.sub('', buf)
+    #print "functions 2: " + buf
+
+    #typedefs, structs, and enums
+    pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""",
+                     re.MULTILINE)
+    buf = pat.sub('', buf)
+    #print "functions 3: " + buf
+
+    #strip DECLS macros
+    pat = re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS""", re.MULTILINE)
+    buf = pat.sub('', buf)
+    #print "functions 4: " + buf
+
+    #extern "C"
+    pat = re.compile(r"""^\s*(extern)\s+\"C\"\s+{""", re.MULTILINE)
+    buf = pat.sub('', buf)
+    #print "functions 5: " + buf
+
+    #multiple whitespace
+    pat = re.compile(r"""\s+""", re.MULTILINE)
+    buf = pat.sub(' ', buf)
+    #print "functions 6: " + buf
+
+    #clean up line ends
+    pat = re.compile(r""";\s*""", re.MULTILINE)
+    buf = pat.sub('\n', buf)
+    buf = buf.lstrip()
+    #print "functions 7: " + buf
+
+    #associate *, &, and [] with type instead of variable
+    #pat = re.compile(r'\s+([*|&]+)\s*(\w+)')
+    pat = re.compile(r' \s* ([*|&]+) \s* (\w+)', re.VERBOSE)
+    buf = pat.sub(r'\1 \2', buf)
+    #print "functions 8: " + buf
+
+    pat = re.compile(r'\s+ (\w+) \[ \s* \]', re.VERBOSE)
+    buf = pat.sub(r'[] \1', buf)
+    #print "functions 9: " + buf
+
+    # make return types that are const work.
+    buf = string.replace(buf, 'G_CONST_RETURN ', 'const-')
+    buf = string.replace(buf, 'const ', 'const-')
+
+    # fix e stuff
+    buf = string.replace(buf, 'EAPI ', '')
+    #print "functions 10: >>" + buf + "<<"
+
+    return buf
+
+proto_pat=re.compile(r"""
+(?P<ret>(-|\w|\&|\*)+\s*)  # return type
+\s+                   # skip whitespace
+(?P<func>\w+)\s*[(]   # match the function name until the opening (
+\s*(?P<args>.*)\s*[)]     # group the function arguments
+""", re.IGNORECASE|re.VERBOSE)
+#"""
+arg_split_pat = re.compile("\s*,\s*")
+
+get_type_pat = re.compile(r'(const-)?([A-Za-z0-9]+)\*?\s+')
+pointer_pat = re.compile('.*\*$')
+func_new_pat = re.compile('(\w+)_new$')
+
+class DefsWriter:
+    def __init__(self, fp=None, prefix=None, verbose=False,
+                 defsfilter=None):
+        if not fp:
+            fp = sys.stdout
+
+        self.fp = fp
+        self.prefix = prefix
+        self.verbose = verbose
+
+        self._enums = {}
+        self._objects = {}
+        self._functions = {}
+        if defsfilter:
+            filter = defsparser.DefsParser(defsfilter)
+            filter.startParsing()
+            for func in filter.functions + filter.methods.values():
+                self._functions[func.c_name] = func
+            for obj in filter.objects + filter.boxes + filter.interfaces:
+                self._objects[obj.c_name] = func
+            for obj in filter.enums:
+                self._enums[obj.c_name] = func
+
+    def write_def(self, deffile):
+        buf = open(deffile).read()
+
+        self.fp.write('\n;; From %s\n\n' % os.path.basename(deffile))
+        self._define_func(buf)
+        self.fp.write('\n')
+
+    def write_enum_defs(self, enums, fp=None):
+        if not fp:
+            fp = self.fp
+
+        fp.write(';; Enumerations and flags ...\n\n')
+        trans = string.maketrans(string.uppercase + '_',
+                                 string.lowercase + '-')
+        filter = self._enums
+        for cname, isflags, entries in enums:
+            if filter:
+                if cname in filter:
+                    continue
+            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')
+
+    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
+	    #print "found function: " + str(p)
+            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')
+	    arguments = []
+	    #print "args: " + str(args)
+            #args = arg_split_pat.split(args)
+	    num_open_brackets = 0
+	    begin_copy = 0
+            for i in range(len(args)):
+		# either it is the end of an argument >'< or the last character
+		if args[i] == "," or i + 1 == len(args):
+			# no open brackets (we are not in a callback) or the last argument is a callback
+			if num_open_brackets == 0 or (i + 1 == len(args) and num_open_brackets == 1 and args[i] == ")"):
+				if args[i] == ",":
+					argument = args[begin_copy:i]
+				else:
+					argument = args[begin_copy:i + 1]
+				begin_copy = i + 1
+				argument = argument.lstrip(", ")
+				#print "argument: " + argument
+				callback = argument.find('(')
+				if callback > -1:
+					argument = 'void* callback'
+				spaces = string.count(argument, ' ')
+				if spaces > 1:
+					argument = string.replace(argument, ' ', '-', spaces - 1)
+				arguments.append(argument)
+
+		# look for callback parameters
+		if args[i] == ")":
+			if num_open_brackets > 0:
+				num_open_brackets -= 1
+		elif args[i] == "(":
+			num_open_brackets += 1
+
+	     #for i in range(len(args)):
+		#print "arg["+str(i)+"] / "+str(len(args))+": " + args[i]
+                #callback = args[i].find('(')
+		#if callback > -1:
+			#args[i] = 'void*'
+                #spaces = string.count(args[i], ' ')
+                #if spaces > 1:
+                    #args[i] = string.replace(args[i], ' ', '-', spaces - 1)
+
+            #print "arguments: " + str(arguments)
+            self._write_func(func, ret, arguments)
+
+    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:
+            fname = name
+
+        # it is either a constructor or normal function
+        self.fp.write('(define-function ' + fname + '\n')
+        self.fp.write('  (c-name "' + name + '")\n')
+
+        # Hmmm... Let's asume that a constructor function name
+        # ends with '_new' and it returns a pointer.
+        m = func_new_pat.match(name)
+        if pointer_pat.match(ret) and m:
+            cname = ''
+            for s in m.group(1).split ('_'):
+                cname += s.title()
+            if cname != '':
+                self.fp.write('  (is-constructor-of "' + cname + '")\n')
+
+        self._write_return(ret)
+        self._write_arguments(args)
+
+    def _write_method(self, obj, name, ret, args):
+        regex = string.join(map(lambda x: x+'_?', string.lower(obj)),'')
+        mname = re.sub(regex, '', name, 1)
+        if self.prefix:
+            l = len(self.prefix) + 1
+            if mname[:l] == self.prefix and mname[l+1] == '_':
+                mname = mname[l+1:]
+        self.fp.write('(define-method ' + mname + '\n')
+        self.fp.write('  (of-object "' + obj + '")\n')
+        self.fp.write('  (c-name "' + name + '")\n')
+        self._write_return(ret)
+        self._write_arguments(args[1:])
+
+    def _write_return(self, ret):
+        if ret != 'void':
+            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:
+            if arg == '...':
+                is_varargs = 1
+            elif arg in ('void', 'void '):
+                has_args = 0
+        if has_args:
+            self.fp.write('  (parameters\n')
+            for arg in args:
+                if arg != '...':
+                    tupleArg = tuple(string.split(arg))
+                    if len(tupleArg) == 2:
+			var_type = tupleArg[0]
+			# some variable types are not supported
+			#if var_type == "unsigned-int":
+				#var_type = "guint" # see gtypes.h
+			#print "var type: " + var_type
+                        self.fp.write('    \'("%s" "%s")\n' % (var_type, tupleArg[1]))
+            self.fp.write('  )\n')
+        if is_varargs:
+            self.fp.write('  (varargs #t)\n')
+        self.fp.write(')\n\n')
+
+# ------------------ Main function -----------------
+
+def main(args):
+    verbose = False
+    onlyenums = False
+    onlyobjdefs = False
+    separate = False
+    modulename = None
+    defsfilter = None
+    opts, args = getopt.getopt(args[1:], 'vs:m:f:',
+                               ['onlyenums', 'onlyobjdefs',
+                                'modulename=', 'separate=',
+                                'defsfilter='])
+    for o, v in opts:
+        if o == '-v':
+            verbose = True
+        if o == '--onlyenums':
+            onlyenums = True
+        if o == '--onlyobjdefs':
+            onlyobjdefs = True
+        if o in ('-s', '--separate'):
+            separate = v
+        if o in ('-m', '--modulename'):
+            modulename = v
+        if o in ('-f', '--defsfilter'):
+            defsfilter = v
+
+    if not args[0:1]:
+        print 'Must specify at least one input file name'
+        return -1
+
+    # read all the object definitions in
+    objdefs = []
+    enums = []
+    for filename in args:
+        buf = open(filename).read()
+        find_obj_defs(buf, objdefs)
+        find_enum_defs(buf, enums)
+    #objdefs = sort_obj_defs(objdefs)
+
+    if separate:
+        methods = file(separate + '.defs', 'w')
+        types = file(separate + '-types.defs', 'w')
+
+        dw = DefsWriter(methods, prefix=modulename, verbose=verbose,
+                        defsfilter=defsfilter)
+        dw.write_obj_defs(objdefs, types)
+        dw.write_enum_defs(enums, types)
+        print "Wrote %s-types.defs" % separate
+
+        for filename in args:
+            dw.write_def(filename)
+        print "Wrote %s.defs" % separate
+    else:
+        dw = DefsWriter(prefix=modulename, verbose=verbose,
+                        defsfilter=defsfilter)
+
+        if onlyenums:
+            dw.write_enum_defs(enums)
+        elif onlyobjdefs:
+            dw.write_obj_defs(objdefs)
+        else:
+            dw.write_obj_defs(objdefs)
+            dw.write_enum_defs(enums)
+
+            for filename in args:
+                dw.write_def(filename)
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))


Property changes on: trunk/src/host/pye17/codegen/h2def.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/host/pye17/codegen/mergedefs.py
===================================================================
--- trunk/src/host/pye17/codegen/mergedefs.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/mergedefs.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- Mode: Python; py-indent-offset: 4 -*-
+
+import optparse
+
+import defsparser
+
+parser = optparse.OptionParser(
+    usage="usage: %prog [options] generated-defs old-defs")
+parser.add_option("-p", "--merge-parameters",
+                  help="Merge changes in function/methods parameter lists",
+                  action="store_true", dest="parmerge", default=False)
+(options, args) = parser.parse_args()
+
+if len(args) != 2:
+    parser.error("wrong number of arguments")
+
+newp = defsparser.DefsParser(args[0])
+oldp = defsparser.DefsParser(args[1])
+
+newp.startParsing()
+oldp.startParsing()
+
+newp.merge(oldp, options.parmerge)
+
+newp.write_defs()


Property changes on: trunk/src/host/pye17/codegen/mergedefs.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/host/pye17/codegen/mkskel.py
===================================================================
--- trunk/src/host/pye17/codegen/mkskel.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/mkskel.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# -*- Mode: Python; py-indent-offset: 4 -*-
+
+import sys, os, getopt
+
+module_init_template = \
+'/* -*- Mode: C; c-basic-offset: 4 -*- */\n' + \
+'#ifdef HAVE_CONFIG_H\n' + \
+'#  include "config.h"\n' + \
+'#endif\n' + \
+'#include <Python.h>\n' + \
+'#include <pygtk.h>\n' + \
+'\n' + \
+'/* include any extra headers needed here */\n' + \
+'\n' + \
+'void %(prefix)s_register_classes(PyObject *d);\n' + \
+'extern PyMethodDef %(prefix)s_functions[];\n' + \
+'\n' + \
+'DL_EXPORT(void)\n' + \
+'init%(module)s(void)\n' + \
+'{\n' + \
+'    PyObject *m, *d;\n' + \
+'\n' + \
+'    /* perform any initialisation required by the library here */\n' + \
+'\n' + \
+'    m = Py_InitModule("%(module)s", %(prefix)s_functions);\n' + \
+'    d = PyModule_GetDict(m);\n' + \
+'\n' + \
+'    init_pygtk();\n' + \
+'\n' + \
+'    %(prefix)s_register_classes(d);\n' + \
+'\n' + \
+'    /* add anything else to the module dictionary (such as constants) */\n' +\
+'\n' + \
+'    if (PyErr_Occurred())\n' + \
+'        Py_FatalError("could not initialise module %(module)s");\n' + \
+'}\n'
+
+override_template = \
+'/* -*- Mode: C; c-basic-offset: 4 -*- */\n' + \
+'%%%%\n' + \
+'headers\n' + \
+'/* include any required headers here */\n' + \
+'%%%%\n' + \
+'init\n' + \
+'    /* include any code here that needs to be executed before the\n' + \
+'     * extension classes get initialised */\n' + \
+'%%%%\n' + \
+'\n' + \
+'/* you should add appropriate ignore, ignore-glob and\n' + \
+' * override sections here */\n'
+
+def open_with_backup(file):
+    if os.path.exists(file):
+        try:
+            os.rename(file, file+'~')
+        except OSError:
+            # fail silently if we can't make a backup
+            pass
+    return open(file, 'w')
+
+def write_skels(fileprefix, prefix, module):
+    fp = open_with_backup(fileprefix+'module.c')
+    fp.write(module_init_template % { 'prefix': prefix, 'module': module })
+    fp.close()
+    fp = open_with_backup(fileprefix+'.override')
+    fp.write(override_template % { 'prefix': prefix, 'module': module })
+    fp.close()
+
+if __name__ == '__main__':
+    opts, args = getopt.getopt(sys.argv[1:], 'f:p:m:h',
+                               ['file-prefix=', 'prefix=', 'module=', 'help'])
+    fileprefix = None
+    prefix = None
+    module = None
+    for opt, arg in opts:
+        if opt in ('-f', '--file-prefix'):
+            fileprefix = arg
+        elif opt in ('-p', '--prefix'):
+            prefix = arg
+        elif opt in ('-m', '--module'):
+            module = arg
+        elif opt in ('-h', '--help'):
+            print 'usage: mkskel.py -f fileprefix -p prefix -m module'
+            sys.exit(0)
+    if not fileprefix or not prefix or not module:
+        print 'usage: mkskel.py -f fileprefix -p prefix -m module'
+        sys.exit(1)
+    write_skels(fileprefix, prefix, module)


Property changes on: trunk/src/host/pye17/codegen/mkskel.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/host/pye17/codegen/override.py
===================================================================
--- trunk/src/host/pye17/codegen/override.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/override.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,281 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+
+# this file contains code for loading up an override file.  The override file
+# provides implementations of functions where the code generator could not
+# do its job correctly.
+
+import fnmatch
+import os
+import re
+import string
+import sys
+
+def class2cname(klass, method):
+    c_name = ''
+    for c in klass:
+        if c.isupper():
+            c_name += '_' + c.lower()
+        else:
+            c_name += c
+    return c_name[1:] + '_'  + method
+
+import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)')
+
+class Overrides:
+    def __init__(self, filename=None):
+        self.modulename = None
+        self.ignores = {}
+        self.glob_ignores = []
+        self.type_ignores = {}
+        self.overrides = {}
+        self.overridden = {}
+        self.kwargs = {}
+        self.noargs = {}
+        self.onearg = {}
+        self.staticmethod = {}
+        self.classmethod = {}
+        self.startlines = {}
+        self.override_attrs = {}
+        self.override_slots = {}
+        self.headers = ''
+        self.body = ''
+        self.init = ''
+        self.imports = []
+        self.defines = {}
+        self.functions = {}
+        self.newstyle_constructors = {}
+        self.dynamicnamespace = False
+        if filename:
+            self.handle_file(filename)
+
+    def handle_file(self, filename):
+        oldpath = os.getcwd()
+
+        fp = open(filename, 'r')
+        dirname = os.path.dirname(os.path.abspath(filename))
+
+        if dirname != oldpath:
+            os.chdir(dirname)
+
+        # read all the components of the file ...
+        bufs = []
+        startline = 1
+        lines = []
+        line = fp.readline()
+        linenum = 1
+        while line:
+            if line == '%%\n' or line == '%%':
+                if lines:
+                    bufs.append((string.join(lines, ''), startline))
+                startline = linenum + 1
+                lines = []
+            else:
+                lines.append(line)
+            line = fp.readline()
+            linenum = linenum + 1
+        if lines:
+            bufs.append((string.join(lines, ''), startline))
+        if not bufs: return
+
+        for buf, startline in bufs:
+            self.__parse_override(buf, startline, filename)
+
+        os.chdir(oldpath)
+
+    def __parse_override(self, buffer, startline, filename):
+        pos = string.find(buffer, '\n')
+        if pos >= 0:
+            line = buffer[:pos]
+            rest = buffer[pos+1:]
+        else:
+            line = buffer ; rest = ''
+        words = string.split(line)
+        command = words[0]
+        if (command == 'ignore' or
+            command == 'ignore-' + sys.platform):
+            "ignore/ignore-platform [functions..]"
+            for func in words[1:]:
+                self.ignores[func] = 1
+            for func in string.split(rest):
+                self.ignores[func] = 1
+        elif (command == 'ignore-glob' or
+              command == 'ignore-glob-' + sys.platform):
+            "ignore-glob/ignore-glob-platform [globs..]"
+            for func in words[1:]:
+                self.glob_ignores.append(func)
+            for func in string.split(rest):
+                self.glob_ignores.append(func)
+        elif (command == 'ignore-type' or
+              command == 'ignore-type-' + sys.platform):
+            "ignore-type/ignore-type-platform [typenames..]"
+            for typename in words[1:]:
+                self.type_ignores[typename] = 1
+            for typename in string.split(rest):
+                self.type_ignores[typename] = 1
+        elif command == 'override':
+            "override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
+            func = words[1]
+            if 'kwargs' in words[1:]:
+                self.kwargs[func] = 1
+            elif 'noargs' in words[1:]:
+                self.noargs[func] = 1
+            elif 'onearg' in words[1:]:
+                self.onearg[func] = True
+
+            if 'staticmethod' in words[1:]:
+                self.staticmethod[func] = True
+            elif 'classmethod' in words[1:]:
+                self.classmethod[func] = True
+            if func in self.overrides:
+                raise RuntimeError("Function %s is being overridden more than once" % (func,))
+            self.overrides[func] = rest
+            self.startlines[func] = (startline + 1, filename)
+        elif command == 'override-attr':
+            "override-slot Class.attr"
+            attr = words[1]
+            self.override_attrs[attr] = rest
+            self.startlines[attr] = (startline + 1, filename)
+        elif command == 'override-slot':
+            "override-slot Class.slot"
+            slot = words[1]
+            self.override_slots[slot] = rest
+            self.startlines[slot] = (startline + 1, filename)
+        elif command == 'headers':
+            "headers"
+            self.headers = '%s\n#line %d "%s"\n%s' % \
+                           (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':
+            "init"
+            self.init = '%s\n#line %d "%s"\n%s' % \
+                        (self.init, startline + 1, filename, rest)
+        elif command == 'modulename':
+            "modulename name"
+            self.modulename = words[1]
+        elif command == 'include':
+            "include filename"
+            for filename in words[1:]:
+                self.handle_file(filename)
+            for filename in string.split(rest):
+                self.handle_file(filename)
+        elif command == 'import':
+            "import module1 [\n module2, \n module3 ...]"
+            for line in string.split(buffer, '\n'):
+                match = import_pat.match(line)
+                if match:
+                    self.imports.append(match.groups())
+        elif command == 'define':
+            "define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
+            "define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
+            func = words[1]
+            klass = None
+            if func.find('.') != -1:
+                klass, func = func.split('.', 1)
+
+                if not self.defines.has_key(klass):
+                    self.defines[klass] = {}
+                self.defines[klass][func] = rest
+            else:
+                self.functions[func] = rest
+
+            if 'kwargs' in words[1:]:
+                self.kwargs[func] = 1
+            elif 'noargs' in words[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)
+
+        elif command == 'new-constructor':
+            "new-constructor GType"
+            gtype, = words[1:]
+            self.newstyle_constructors[gtype] = True
+        elif command == 'options':
+            for option in words[1:]:
+                if option == 'dynamicnamespace':
+                    self.dynamicnamespace = True
+
+    def is_ignored(self, name):
+        if self.ignores.has_key(name):
+            return 1
+        for glob in self.glob_ignores:
+            if fnmatch.fnmatchcase(name, glob):
+                return 1
+        return 0
+
+    def is_type_ignored(self, name):
+        return name in self.type_ignores
+
+    def is_overriden(self, name):
+        return self.overrides.has_key(name)
+
+    def is_already_included(self, name):
+        return self.overridden.has_key(name)
+
+    def override(self, name):
+        self.overridden[name] = 1
+        return self.overrides[name]
+
+    def define(self, klass, name):
+        self.overridden[class2cname(klass, name)] = 1
+        return self.defines[klass][name]
+
+    def function(self, name):
+        return self.functions[name]
+
+    def getstartline(self, name):
+        return self.startlines[name]
+
+    def wants_kwargs(self, name):
+        return self.kwargs.has_key(name)
+
+    def wants_noargs(self, 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):
+        return self.override_attrs.has_key(attr)
+
+    def attr_override(self, attr):
+        return self.override_attrs[attr]
+
+    def slot_is_overriden(self, slot):
+        return self.override_slots.has_key(slot)
+
+    def slot_override(self, slot):
+        return self.override_slots[slot]
+
+    def get_headers(self):
+        return self.headers
+
+    def get_body(self):
+        return self.body
+
+    def get_init(self):
+        return self.init
+
+    def get_imports(self):
+        return self.imports
+
+    def get_defines_for(self, klass):
+        return self.defines.get(klass, {})
+
+    def get_functions(self):
+        return self.functions

Added: trunk/src/host/pye17/codegen/reversewrapper.py
===================================================================
--- trunk/src/host/pye17/codegen/reversewrapper.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/reversewrapper.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,882 @@
+### -*- python -*-
+### Code to generate "Reverse Wrappers", i.e. C->Python wrappers
+### (C) 2004 Gustavo Carneiro <gjc at gnome.org>
+import argtypes
+import os
+
+DEBUG_MODE = ('PYGTK_CODEGEN_DEBUG' in os.environ)
+
+def join_ctype_name(ctype, name):
+    '''Joins a C type and a variable name into a single string'''
+    if ctype[-1] != '*':
+        return " ".join((ctype, name))
+    else:
+        return "".join((ctype, name))
+
+
+class CodeSink(object):
+    def __init__(self):
+        self.indent_level = 0 # current indent level
+        self.indent_stack = [] # previous indent levels
+
+    def _format_code(self, code):
+        assert isinstance(code, str)
+        l = []
+        for line in code.split('\n'):
+            l.append(' '*self.indent_level + line)
+        if l[-1]:
+            l.append('')
+        return '\n'.join(l)
+
+    def writeln(self, line=''):
+        raise NotImplementedError
+
+    def indent(self, level=4):
+        '''Add a certain ammount of indentation to all lines written
+        from now on and until unindent() is called'''
+        self.indent_stack.append(self.indent_level)
+        self.indent_level += level
+
+    def unindent(self):
+        '''Revert indentation level to the value before last indent() call'''
+        self.indent_level = self.indent_stack.pop()
+
+
+class FileCodeSink(CodeSink):
+    def __init__(self, fp):
+        CodeSink.__init__(self)
+        assert isinstance(fp, file)
+        self.fp = fp
+
+    def writeln(self, line=''):
+        self.fp.write(self._format_code(line))
+
+class MemoryCodeSink(CodeSink):
+    def __init__(self):
+        CodeSink.__init__(self)
+        self.lines = []
+
+    def writeln(self, line=''):
+        self.lines.append(self._format_code(line))
+
+    def flush_to(self, sink):
+        assert isinstance(sink, CodeSink)
+        for line in self.lines:
+            sink.writeln(line.rstrip())
+        self.lines = []
+
+    def flush(self):
+        l = []
+        for line in self.lines:
+            l.append(self._format_code(line))
+        self.lines = []
+        return "".join(l)
+
+class ReverseWrapper(object):
+    '''Object that generates a C->Python wrapper'''
+    def __init__(self, cname, is_static=True):
+        assert isinstance(cname, str)
+
+        self.cname = cname
+        ## function object we will call, or object whose method we will call
+        self.called_pyobj = None
+        ## name of method of self.called_pyobj we will call
+        self.method_name = None
+        self.is_static = is_static
+
+        self.parameters = []
+        self.declarations = MemoryCodeSink()
+        self.post_return_code = MemoryCodeSink()
+        self.body = MemoryCodeSink()
+        self.check_exception_code = MemoryCodeSink()
+        self.cleanup_actions = []
+        self.pyargv_items = []
+        self.pyargv_optional_items = []
+        self.pyret_parse_items = [] # list of (format_spec, parameter)
+        self.code_sinks_stack = [self.body]
+
+    def set_call_target(self, called_pyobj, method_name=None):
+        assert called_pyobj is not None
+        assert self.called_pyobj is None
+        self.called_pyobj = called_pyobj
+        self.method_name = method_name
+
+    def set_return_type(self, return_type):
+        assert isinstance(return_type, ReturnType)
+        self.return_type = return_type
+
+    def add_parameter(self, param):
+        assert isinstance(param, Parameter)
+        self.parameters.append(param)
+
+    def add_declaration(self, decl_code):
+        self.declarations.writeln(decl_code)
+
+    def add_pyargv_item(self, variable, optional=False):
+        if optional:
+            self.pyargv_optional_items.append(variable)
+        else:
+            self.pyargv_items.append(variable)
+
+    def 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 push_code_sink(self, code_sink):
+        self.code_sinks_stack.insert(0, code_sink)
+
+    def pop_code_sink(self):
+        return self.code_sinks_stack.pop(0)
+
+
+    def write_code(self, code,
+                   cleanup=None,
+                   failure_expression=None,
+                   failure_cleanup=None,
+                   failure_exception=None,
+                   code_sink=None):
+        '''Add a chunk of code with cleanup and error handling
+
+        This method is to be used by TypeHandlers when generating code
+
+        Keywork arguments:
+        code -- code to add
+        cleanup -- code to cleanup any dynamic resources created by @code
+                   (except in case of failure) (default None)
+        failure_expression -- C boolean expression to indicate
+                              if anything failed (default None)
+        failure_cleanup -- code to cleanup any dynamic resources
+                           created by @code in case of failure (default None)
+        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.code_sinks_stack[0]
+        if code is not None:
+            code_sink.writeln(code)
+        if failure_expression is not None:
+            code_sink.writeln("if (%s) {" % (failure_expression,))
+            code_sink.indent()
+            if failure_exception is None:
+                code_sink.writeln("if (PyErr_Occurred())")
+                code_sink.indent()
+                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:
+                code_sink.writeln(failure_cleanup)
+            for cleanup_action in self.cleanup_actions:
+                code_sink.writeln(cleanup_action)
+
+            self.push_code_sink(code_sink)
+            try:
+                self.return_type.write_error_return()
+            finally:
+                self.pop_code_sink()
+
+            code_sink.unindent()
+            code_sink.writeln("}")
+        if cleanup is not None:
+            self.cleanup_actions.insert(0, cleanup)
+
+    def generate(self, sink):
+        '''Generate the code into a CodeSink object'''
+        assert isinstance(sink, CodeSink)
+
+        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.write_code(code="__py_state = pyg_gil_state_ensure();",
+                        cleanup="pyg_gil_state_release(__py_state);")
+
+        for param in self.parameters:
+            param.convert_c2py()
+
+        assert self.called_pyobj is not None,\
+               "Parameters failed to provide a target function or method."
+
+        if self.is_static:
+            sink.writeln('static %s' % self.return_type.get_c_type())
+        else:
+            sink.writeln(self.return_type.get_c_type())
+        c_proto_params = map(Parameter.format_for_c_proto, self.parameters)
+        sink.writeln("%s(%s)\n{" % (self.cname, ", ".join(c_proto_params)))
+
+        self.return_type.write_decl()
+        self.add_declaration("PyObject *py_retval;")
+
+        ## Handle number of arguments
+        if self.pyargv_items:
+            self.add_declaration("PyObject *py_args;")
+            py_args = "py_args"
+            if self.pyargv_optional_items:
+                self.add_declaration("int argc = %i;" % len(self.pyargv_items))
+                argc = "argc"
+                for arg in self.pyargv_optional_items:
+                    self.body.writeln("if (%s)" % arg)
+                    self.body.indent()
+                    self.body.writeln("++argc;")
+                    self.body.unindent()
+            else:
+                argc = str(len(self.pyargv_items))
+        else:
+            if self.pyargv_optional_items:
+                self.add_declaration("PyObject *py_args;")
+                py_args = "py_args"
+                self.add_declaration("int argc = 0;")
+                argc = "argc"
+                for arg in self.pyargv_optional_items:
+                    self.body.writeln("if (%s)" % arg)
+                    self.body.indent()
+                    self.body.writeln("++argc;")
+                    self.body.unindent()
+            else:
+                py_args = "NULL"
+                argc = None
+
+        self.body.writeln()
+
+        if py_args != "NULL":
+            self.write_code("py_args = PyTuple_New(%s);" % argc,
+                            cleanup="Py_DECREF(py_args);")
+            pos = 0
+            for arg in self.pyargv_items:
+                try: # try to remove the Py_DECREF cleanup action, if we can
+                    self.cleanup_actions.remove("Py_DECREF(%s);" % arg)
+                except ValueError: # otherwise we have to Py_INCREF..
+                    self.body.writeln("Py_INCREF(%s);" % arg)
+                self.body.writeln("PyTuple_SET_ITEM(%s, %i, %s);" % (py_args, pos, arg))
+                pos += 1
+            for arg in self.pyargv_optional_items:
+                self.body.writeln("if (%s) {" % arg)
+                self.body.indent()
+                try: # try to remove the Py_DECREF cleanup action, if we can
+                    self.cleanup_actions.remove("Py_XDECREF(%s);" % arg)
+                except ValueError: # otherwise we have to Py_INCREF..
+                    self.body.writeln("Py_INCREF(%s);" % arg)
+                self.body.writeln("PyTuple_SET_ITEM(%s, %i, %s);" % (py_args, pos, arg))
+                self.body.unindent()
+                self.body.writeln("}")
+                pos += 1
+
+        self.body.writeln()
+
+        ## Call the python method
+        if self.method_name is None:
+            self.write_code("py_retval = PyObject_Call(%s, %s);"
+                            % (self.called_pyobj, py_args),
+                            cleanup="Py_XDECREF(py_retval);")
+            self.check_exception_code.flush_to(self.body)
+            self.write_code(None, failure_expression="!py_retval")
+
+        else:
+            self.add_declaration("PyObject *py_method;")
+            self.write_code("py_method = PyObject_GetAttrString(%s, \"%s\");"
+                            % (self.called_pyobj, self.method_name),
+                            cleanup="Py_DECREF(py_method);",
+                            failure_expression="!py_method")
+            self.write_code("py_retval = PyObject_CallObject(py_method, %s);"
+                            % (py_args,),
+                            cleanup="Py_XDECREF(py_retval);")
+            self.check_exception_code.flush_to(self.body)
+            self.write_code(None, 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()
+        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()
+
+        if self.pyret_parse_items == [("", "")]:
+            ## special case when there are no return parameters
+            self.write_code(
+                code=None,
+                failure_expression='py_retval != Py_None',
+                failure_exception=('PyErr_SetString(PyExc_TypeError, '
+                                   '"virtual method should return None");'))
+        else:    
+            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
+                params = ["py_retval",
+                          '"%s"' % "".join([format for format, param in self.pyret_parse_items])]
+                params.extend([param for format, param in self.pyret_parse_items if param])
+                self.write_code(code=None, failure_expression=(
+                    '!PyArg_ParseTuple(%s)' % (', '.join(params),)))
+
+        if DEBUG_MODE:
+            self.declarations.writeln("/* end declarations */")
+        self.declarations.flush_to(sink)
+        sink.writeln()
+        if DEBUG_MODE:
+            self.body.writeln("/* end main body */")
+        self.body.flush_to(sink)
+        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:
+            sink.writeln(cleanup_action)
+        if self.return_type.get_c_type() != 'void':
+            sink.writeln()
+            sink.writeln("return retval;")
+        sink.unindent()
+        sink.writeln("}")
+
+class TypeHandler(object):
+    def __init__(self, wrapper, **props):
+        assert isinstance(wrapper, ReverseWrapper)
+        self.wrapper = wrapper
+        self.props = props
+
+class ReturnType(TypeHandler):
+
+    def get_c_type(self):
+        raise NotImplementedError
+
+    def write_decl(self):
+        raise NotImplementedError
+
+    def write_error_return(self):
+        '''Write "return <value>" code in case of error'''
+        raise NotImplementedError
+
+    def write_conversion(self):
+        '''Writes code to convert Python return value in 'py_retval'
+        into C 'retval'.  Returns a string with C boolean expression
+        that determines if anything went wrong. '''
+        raise NotImplementedError
+
+class Parameter(TypeHandler):
+
+    def __init__(self, wrapper, name, **props):
+        TypeHandler.__init__(self, wrapper, **props)
+        self.name = name
+
+    def get_c_type(self):
+        raise NotImplementedError
+
+    def convert_c2py(self):
+        '''Write some code before calling the Python method.'''
+        pass
+
+    def format_for_c_proto(self):
+        return join_ctype_name(self.get_c_type(), self.name)
+
+
+###---
+class StringParam(Parameter):
+
+    def get_c_type(self):
+        return self.props.get('c_type', 'char *').replace('const-', 'const ')
+
+    def convert_c2py(self):
+        if self.props.get('optional', False):
+            self.wrapper.add_declaration("PyObject *py_%s = NULL;" % self.name)
+            self.wrapper.write_code(code=("if (%s)\n"
+                                          "    py_%s = PyString_FromString(%s);\n"
+                                          % (self.name, self.name, self.name)),
+                                    cleanup=("Py_XDECREF(py_%s);" % self.name))
+            self.wrapper.add_pyargv_item("py_%s" % self.name, optional=True)
+        else:
+            self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+            self.wrapper.write_code(code=("py_%s = PyString_FromString(%s);" %
+                                          (self.name, self.name)),
+                                    cleanup=("Py_DECREF(py_%s);" % self.name),
+                                    failure_expression=("!py_%s" % self.name))
+            self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+for ctype in ('char*', 'gchar*', 'const-char*', 'char-const*', 'const-gchar*',
+              'gchar-const*', 'string', 'static_string'):
+    argtypes.matcher.register_reverse(ctype, StringParam)
+del ctype
+
+class StringReturn(ReturnType):
+
+    def get_c_type(self):
+        return self.props.get('c_type', 'char *').replace('const-', 'const ')
+    #return "char *"
+
+    def write_decl(self):
+        self.wrapper.add_declaration("%s retval;" % self.get_c_type())
+        #self.wrapper.add_declaration("char *retval;")
+
+    def write_error_return(self):
+        self.wrapper.write_code("return NULL;")
+
+    def write_conversion(self):
+        self.wrapper.add_pyret_parse_item("s", "&retval", prepend=True)
+        self.wrapper.write_code("retval = g_strdup(retval);", code_sink=self.wrapper.post_return_code)
+
+for ctype in ('char*', 'gchar*', 'const-gchar*'):
+    argtypes.matcher.register_reverse_ret(ctype, StringReturn)
+del ctype
+
+
+class VoidReturn(ReturnType):
+
+    def get_c_type(self):
+        return "void"
+
+    def write_decl(self):
+        pass
+
+    def write_error_return(self):
+        self.wrapper.write_code("return;")
+
+    def write_conversion(self):
+        self.wrapper.add_pyret_parse_item("", "", prepend=True)
+
+argtypes.matcher.register_reverse_ret('void', VoidReturn)
+argtypes.matcher.register_reverse_ret('none', VoidReturn)
+
+class GObjectParam(Parameter):
+
+    def get_c_type(self):
+        return self.props.get('c_type', 'GObject *')
+
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s = NULL;" % self.name)
+        self.wrapper.write_code(code=("if (%s)\n"
+                                      "    py_%s = pygobject_new((GObject *) %s);\n"
+                                      "else {\n"
+                                      "    Py_INCREF(Py_None);\n"
+                                      "    py_%s = Py_None;\n"
+                                      "}"
+                                      % (self.name, self.name, self.name, self.name)),
+                                cleanup=("Py_DECREF(py_%s);" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+argtypes.matcher.register_reverse('GObject*', GObjectParam)
+
+class GObjectReturn(ReturnType):
+
+    def get_c_type(self):
+        return self.props.get('c_type', 'GObject *')
+
+    def write_decl(self):
+        self.wrapper.add_declaration("%s retval;" % self.get_c_type())
+
+    def write_error_return(self):
+        self.wrapper.write_code("return NULL;")
+
+    def write_conversion(self):
+        self.wrapper.write_code(
+            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.get_c_type())
+        self.wrapper.write_code("g_object_ref((GObject *) retval);")
+
+argtypes.matcher.register_reverse_ret('GObject*', GObjectReturn)
+
+
+
+class IntParam(Parameter):
+
+    def get_c_type(self):
+        return self.props.get('c_type', 'int')
+
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code(code=("py_%s = PyInt_FromLong(%s);" %
+                                      (self.name, self.name)),
+                                cleanup=("Py_DECREF(py_%s);" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+class IntReturn(ReturnType):
+    def get_c_type(self):
+        return self.props.get('c_type', 'int')
+    def write_decl(self):
+        self.wrapper.add_declaration("%s retval;" % self.get_c_type())
+    def write_error_return(self):
+        self.wrapper.write_code("return -G_MAXINT;")
+    def write_conversion(self):
+        self.wrapper.add_pyret_parse_item("i", "&retval", prepend=True)
+
+for argtype in ('int', 'gint', 'guint', 'short', 'gshort', 'gushort', 'long',
+                'glong', 'gsize', 'gssize', 'guint8', 'gint8', 'guint16',
+                'gint16', 'gint32', 'GTime'):
+    argtypes.matcher.register_reverse(argtype, IntParam)
+    argtypes.matcher.register_reverse_ret(argtype, IntReturn)
+del argtype
+
+class IntPtrParam(Parameter):
+    def __init__(self, wrapper, name, **props):
+        if "direction" not in props:
+            raise argtypes.ArgTypeConfigurationError(
+                "cannot use int* parameter without direction")
+        if props["direction"] not in ("out", "inout"):
+            raise argtypes.ArgTypeConfigurationError(
+                "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):
+    def write_conversion(self):
+        self.wrapper.write_code(
+            code=None,
+            failure_expression=(
+            "pyg_enum_get_value(%s, py_retval, (gint *)&retval)"
+            % (self.props['typecode'],)))
+
+argtypes.matcher.register_reverse_ret("GEnum", GEnumReturn)
+
+class GEnumParam(IntParam):
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code(code=("py_%s = pyg_enum_from_gtype(%s, %s);" %
+                                (self.name, self.props['typecode'], self.name)),
+                        cleanup=("Py_DECREF(py_%s);" % self.name),
+                        failure_expression=("!py_%s" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+argtypes.matcher.register_reverse("GEnum", GEnumParam)
+
+class GFlagsReturn(IntReturn):
+    def write_conversion(self):
+        self.wrapper.write_code(
+            code=None,
+            failure_expression=(
+            "pyg_flags_get_value(%s, py_retval, (gint *)&retval)" %
+            self.props['typecode']))
+
+argtypes.matcher.register_reverse_ret("GFlags", GFlagsReturn)
+
+class GFlagsParam(IntParam):
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code(code=(
+            "py_%s = pyg_flags_from_gtype(%s, %s);" %
+            (self.name, self.props['typecode'], self.name)),
+                                cleanup=("Py_DECREF(py_%s);" % self.name),
+                                failure_expression=("!py_%s" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+argtypes.matcher.register_reverse("GFlags", GFlagsParam)
+
+
+class GtkTreePathParam(IntParam):
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code(code=(
+            "py_%s = pygtk_tree_path_to_pyobject(%s);" %
+            (self.name, self.name)),
+                                cleanup=("Py_DECREF(py_%s);" % self.name),
+                                failure_expression=("!py_%s" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+argtypes.matcher.register_reverse("GtkTreePath*", GtkTreePathParam)
+
+
+class GtkTreePathReturn(ReturnType):
+    def get_c_type(self):
+        return self.props.get('c_type', 'GtkTreePath *')
+    def write_decl(self):
+        self.wrapper.add_declaration("GtkTreePath * retval;")
+    def write_error_return(self):
+        self.wrapper.write_code("return NULL;")
+    def write_conversion(self):
+        self.wrapper.write_code(
+            "retval = pygtk_tree_path_from_pyobject(py_retval);\n",
+            failure_expression=('!retval'),
+            failure_exception=(
+    'PyErr_SetString(PyExc_TypeError, "retval should be a GtkTreePath");'))
+
+argtypes.matcher.register_reverse_ret("GtkTreePath*", GtkTreePathReturn)
+
+
+class BooleanReturn(ReturnType):
+    def get_c_type(self):
+        return "gboolean"
+    def write_decl(self):
+        self.wrapper.add_declaration("gboolean retval;")
+        self.wrapper.add_declaration("PyObject *py_main_retval;")
+    def write_error_return(self):
+        self.wrapper.write_code("return FALSE;")
+    def write_conversion(self):
+        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)
+
+class BooleanParam(Parameter):
+    def get_c_type(self):
+        return "gboolean"
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code("py_%s = %s? Py_True : Py_False;"
+                                % (self.name, self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+argtypes.matcher.register_reverse("gboolean", BooleanParam)
+
+
+class DoubleParam(Parameter):
+    def get_c_type(self):
+        return self.props.get('c_type', 'gdouble')
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code(code=("py_%s = PyFloat_FromDouble(%s);" %
+                                      (self.name, self.name)),
+                                cleanup=("Py_DECREF(py_%s);" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+class DoublePtrParam(Parameter):
+    def __init__(self, wrapper, name, **props):
+        if "direction" not in props:
+            raise argtypes.ArgTypeConfigurationError(
+                "cannot use double* parameter without direction")
+        if props["direction"] not in ("out", ): # inout not yet implemented
+            raise argtypes.ArgTypeConfigurationError(
+                "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):
+    def get_c_type(self):
+        return self.props.get('c_type', 'gdouble')
+    def write_decl(self):
+        self.wrapper.add_declaration("%s retval;" % self.get_c_type())
+    def write_error_return(self):
+        self.wrapper.write_code("return -G_MAXFLOAT;")
+    def write_conversion(self):
+        self.wrapper.add_pyret_parse_item("d", "&retval", prepend=True)
+
+for argtype in ('float', 'double', 'gfloat', 'gdouble'):
+    argtypes.matcher.register_reverse(argtype, DoubleParam)
+    argtypes.matcher.register_reverse_ret(argtype, DoubleReturn)
+
+
+class GBoxedParam(Parameter):
+    def get_c_type(self):
+        return self.props.get('c_type').replace('const-', 'const ')
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        ctype = self.get_c_type()
+        if ctype.startswith('const '):
+            ctype_no_const = ctype[len('const '):]
+            self.wrapper.write_code(
+                code=('py_%s = pyg_boxed_new(%s, (%s) %s, TRUE, TRUE);' %
+                      (self.name, self.props['typecode'],
+                       ctype_no_const, self.name)),
+                cleanup=("Py_DECREF(py_%s);" % self.name))
+        else:
+            self.wrapper.write_code(
+                code=('py_%s = pyg_boxed_new(%s, %s, FALSE, FALSE);' %
+                      (self.name, self.props['typecode'], self.name)),
+                cleanup=("Py_DECREF(py_%s);" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+argtypes.matcher.register_reverse("GBoxed", GBoxedParam)
+
+
+class GBoxedReturn(ReturnType):
+    def get_c_type(self):
+        return self.props.get('c_type')
+    def write_decl(self):
+        self.wrapper.add_declaration("%s retval;" % self.get_c_type())
+    def write_error_return(self):
+        self.wrapper.write_code("return retval;")
+    def write_conversion(self):
+        self.wrapper.write_code(code = None,
+            failure_expression=("!pyg_boxed_check(py_retval, %s)" %
+                                (self.props['typecode'],)),
+            failure_exception=(
+            'PyErr_SetString(PyExc_TypeError, "retval should be a %s");'
+            % (self.props['typename'],)))
+        self.wrapper.write_code('retval = pyg_boxed_get(py_retval, %s);' %
+                                self.props['typename'])
+
+argtypes.matcher.register_reverse_ret("GBoxed", GBoxedReturn)
+
+
+class GdkRegionPtrReturn(GBoxedReturn):
+    def write_error_return(self):
+        self.wrapper.write_code("return gdk_region_new();")
+    def write_conversion(self):
+        self.props['typecode'] = 'PYGDK_TYPE_REGION'
+        self.props['typename'] = 'GdkRegion'
+        super(GdkRegionPtrReturn, self).write_conversion()
+
+argtypes.matcher.register_reverse_ret("GdkRegion*", GdkRegionPtrReturn)
+
+
+class PangoFontDescriptionReturn(GBoxedReturn):
+    def write_error_return(self):
+        self.wrapper.write_code("return pango_font_description_new();")
+    def write_conversion(self):
+        self.props['typecode'] = 'PANGO_TYPE_FONT_DESCRIPTION'
+        self.props['typename'] = 'PangoFontDescription'
+        super(PangoFontDescriptionReturn, self).write_conversion()
+
+argtypes.matcher.register_reverse_ret("PangoFontDescription*",
+                                      PangoFontDescriptionReturn)
+
+
+class PangoFontMetricsReturn(GBoxedReturn):
+    def write_error_return(self):
+        self.wrapper.write_code("return pango_font_metrics_new();")
+    def write_conversion(self):
+        self.props['typecode'] = 'PANGO_TYPE_FONT_METRICS'
+        self.props['typename'] = 'PangoFontMetrics'
+        super(PangoFontMetricsReturn, self).write_conversion()
+
+argtypes.matcher.register_reverse_ret("PangoFontMetrics*",
+                                      PangoFontMetricsReturn)
+
+
+class PangoLanguageReturn(GBoxedReturn):
+    def write_error_return(self):
+        self.wrapper.write_code("return pango_language_from_string(\"\");")
+    def write_conversion(self):
+        self.props['typecode'] = 'PANGO_TYPE_LANGUAGE'
+        self.props['typename'] = 'PangoLanguage'
+        super(PangoLanguageReturn, self).write_conversion()
+
+argtypes.matcher.register_reverse_ret("PangoLanguage*", PangoLanguageReturn)
+
+
+class GdkRectanglePtrParam(Parameter):
+    def get_c_type(self):
+        return self.props.get('c_type').replace('const-', 'const ')
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code(
+            code=('py_%s = pyg_boxed_new(GDK_TYPE_RECTANGLE, %s, TRUE, TRUE);' %
+                  (self.name, self.name)),
+            cleanup=("Py_DECREF(py_%s);" % self.name))
+        self.wrapper.add_pyargv_item("py_%s" % self.name)
+
+argtypes.matcher.register_reverse("GdkRectangle*", GdkRectanglePtrParam)
+argtypes.matcher.register_reverse('GtkAllocation*', GdkRectanglePtrParam)
+
+
+class GErrorParam(Parameter):
+    def get_c_type(self):
+        return self.props.get('c_type').replace('**', ' **')
+    def convert_c2py(self):
+        self.wrapper.write_code(code=None,
+            failure_expression=("pyg_gerror_exception_check(%s)" % self.name),
+                                code_sink=self.wrapper.check_exception_code)
+
+argtypes.matcher.register_reverse('GError**', GErrorParam)
+
+
+class PyGObjectMethodParam(Parameter):
+    def __init__(self, wrapper, name, method_name, **props):
+        Parameter.__init__(self, wrapper, name, **props)
+        self.method_name = method_name
+
+    def get_c_type(self):
+        return self.props.get('c_type', 'GObject *')
+
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+        self.wrapper.write_code(code=("py_%s = pygobject_new((GObject *) %s);" %
+                                      (self.name, self.name)),
+                                cleanup=("Py_DECREF(py_%s);" % self.name),
+                                failure_expression=("!py_%s" % self.name))
+        self.wrapper.set_call_target("py_%s" % self.name, self.method_name)
+
+
+class CallbackInUserDataParam(Parameter):
+    def __init__(self, wrapper, name, free_it, **props):
+        Parameter.__init__(self, wrapper, name, **props)
+        self.free_it = free_it
+
+    def get_c_type(self):
+        return "gpointer"
+
+    def convert_c2py(self):
+        self.wrapper.add_declaration("PyObject **_user_data;")
+        cleanup = self.free_it and ("g_free(%s);" % self.name) or None
+        self.wrapper.write_code(code=("_real_user_data = (PyObject **) %s;"
+                                      % self.name),
+                                cleanup=cleanup)
+
+        self.wrapper.add_declaration("PyObject *py_func;")
+        cleanup = self.free_it and "Py_DECREF(py_func);" or None
+        self.wrapper.write_code(code="py_func = _user_data[0];",
+                                cleanup=cleanup)
+        self.wrapper.set_call_target("py_func")
+
+        self.wrapper.add_declaration("PyObject *py_user_data;")
+        cleanup = self.free_it and "Py_XDECREF(py_user_data);" or None
+        self.wrapper.write_code(code="py_user_data = _user_data[1];",
+                                cleanup=cleanup)
+        self.wrapper.add_pyargv_item("py_user_data", optional=True)
+
+def _test():
+    import sys
+
+    if 1:
+        wrapper = ReverseWrapper("this_is_the_c_function_name", is_static=True)
+        wrapper.set_return_type(StringReturn(wrapper))
+        wrapper.add_parameter(PyGObjectMethodParam(wrapper, "self", method_name="do_xxx"))
+        wrapper.add_parameter(StringParam(wrapper, "param2", optional=True))
+        wrapper.add_parameter(GObjectParam(wrapper, "param3"))
+        #wrapper.add_parameter(InoutIntParam(wrapper, "param4"))
+        wrapper.generate(FileCodeSink(sys.stderr))
+
+    if 0:
+        wrapper = ReverseWrapper("this_a_callback_wrapper")
+        wrapper.set_return_type(VoidReturn(wrapper))
+        wrapper.add_parameter(StringParam(wrapper, "param1", optional=False))
+        wrapper.add_parameter(GObjectParam(wrapper, "param2"))
+        wrapper.add_parameter(CallbackInUserDataParam(wrapper, "data", free_it=True))
+        wrapper.generate(FileCodeSink(sys.stderr))
+
+if __name__ == '__main__':
+    _test()

Added: trunk/src/host/pye17/codegen/scmexpr.py
===================================================================
--- trunk/src/host/pye17/codegen/scmexpr.py	                        (rev 0)
+++ trunk/src/host/pye17/codegen/scmexpr.py	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+# -*- Mode: Python; py-indent-offset: 4 -*-
+from __future__ import generators
+
+import string
+from cStringIO import StringIO
+
+class error(Exception):
+    def __init__(self, filename, lineno, msg):
+        Exception.__init__(self, msg)
+        self.filename = filename
+        self.lineno = lineno
+        self.msg = msg
+    def __str__(self):
+        return '%s:%d: error: %s' % (self.filename, self.lineno, self.msg)
+
+trans = [' '] * 256
+for i in range(256):
+    if chr(i) in string.letters + string.digits + '_':
+        trans[i] = chr(i)
+    else:
+        trans[i] = '_'
+trans = string.join(trans, '')
+
+def parse(filename):
+    if isinstance(filename, str):
+        fp = open(filename, 'r')
+    else: # if not string, assume it is some kind of iterator
+        fp = filename
+        filename = getattr(fp, 'name', '<unknown>')
+    whitespace = ' \t\n\r\x0b\x0c'
+    nonsymbol = whitespace + '();\'"'
+    stack = []
+    openlines = []
+    lineno = 0
+    for line in fp:
+        pos = 0
+        lineno += 1
+        while pos < len(line):
+            if line[pos] in whitespace: # ignore whitespace
+                pass
+            elif line[pos] == ';': # comment
+                break
+            elif line[pos:pos+2] == "'(":
+                pass # the open parenthesis will be handled next iteration
+            elif line[pos] == '(':
+                stack.append(())
+                openlines.append(lineno)
+            elif line[pos] == ')':
+                if len(stack) == 0:
+                    raise error(filename, lineno, 'close parenthesis found when none open')
+                closed = stack[-1]
+                del stack[-1]
+                del openlines[-1]
+                if stack:
+                    stack[-1] += (closed,)
+                else:
+                    yield closed
+            elif line[pos] == '"': # quoted string
+                if not stack:
+                    raise error(filename, lineno,
+                                'string found outside of s-expression')
+                endpos = pos + 1
+                chars = []
+                while endpos < len(line):
+                    if endpos+1 < len(line) and line[endpos] == '\\':
+                        endpos += 1
+                        if line[endpos] == 'n':
+                            chars.append('\n')
+                        elif line[endpos] == 'r':
+                            chars.append('\r')
+                        elif line[endpos] == 't':
+                            chars.append('\t')
+                        else:
+                            chars.append('\\')
+                            chars.append(line[endpos])
+                    elif line[endpos] == '"':
+                        break
+                    else:
+                        chars.append(line[endpos])
+                    endpos += 1
+                if endpos >= len(line):
+                    raise error(filename, lineno, "unclosed quoted string")
+                pos = endpos
+                stack[-1] += (''.join(chars),)
+            else: # symbol/number
+                if not stack:
+                    raise error(filename, lineno,
+                                'identifier found outside of s-expression')
+                endpos = pos
+                while endpos < len(line) and line[endpos] not in nonsymbol:
+                    endpos += 1
+                symbol = line[pos:endpos]
+                pos = max(pos, endpos-1)
+                try: symbol = int(symbol)
+                except ValueError:
+                    try: symbol = float(symbol)
+                    except ValueError: pass
+                stack[-1] += (symbol,)
+            pos += 1
+    if len(stack) != 0:
+        msg = '%d unclosed parentheses found at end of ' \
+              'file (opened on line(s) %s)' % (len(stack),
+                                               ', '.join(map(str, openlines)))
+        raise error(filename, lineno, msg)
+
+class Parser:
+    def __init__(self, filename):
+        """Argument is either a string, a parse tree, or file object"""
+        self.filename = filename
+    def startParsing(self, filename=None):
+        statements = parse(filename or self.filename)
+        for statement in statements:
+            self.handle(statement)
+    def handle(self, tup):
+        cmd = string.translate(tup[0], trans)
+        if hasattr(self, cmd):
+            getattr(self, cmd)(*tup[1:])
+        else:
+            self.unknown(tup)
+    def unknown(self, tup):
+        pass
+
+_testString = """; a scheme file
+(define-func gdk_font_load    ; a comment at end of line
+  GdkFont
+  ((string name)))
+
+(define-boxed GdkEvent
+  gdk_event_copy
+  gdk_event_free
+  "sizeof(GdkEvent)")
+"""
+
+if __name__ == '__main__':
+    import sys
+    if sys.argv[1:]:
+        fp = open(sys.argv[1])
+    else:
+        fp = StringIO(_testString)
+    statements = parse(fp)
+    for s in statements:
+        print `s`


Property changes on: trunk/src/host/pye17/codegen/scmexpr.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/host/pye17/edje/Makefile
===================================================================
--- trunk/src/host/pye17/edje/Makefile	                        (rev 0)
+++ trunk/src/host/pye17/edje/Makefile	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,21 @@
+EDJE_PATH=$(E_PATH)/edje/src/lib
+
+CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include/ -I/usr/include/python2.5 -I/usr/include/pygtk-2.0/ -I$(E_PATH)/evas/src/lib/ -I$(EDJE_PATH) -I.
+
+.PHONY: all clean edje.so
+
+all: edje.so
+
+edje.so: edje.o edjemodule.o                             
+	$(CC) $(LDFLAGS) -shared $^ -o $@
+
+edje.c: edje.defs edje.override
+	pygtk-codegen-2.0 --prefix edje \
+	--override edje.override \
+	edje.defs > $@
+	
+edje.defs: $(H2DEF_PATH) $(EDJE_PATH)/Edje.h
+	$(H2DEF_PATH) $(EDJE_PATH)/Edje.h > edje.defs 
+
+clean:
+	rm -f *.o edje.defs edje.c

Added: trunk/src/host/pye17/edje/edje.override
===================================================================
--- trunk/src/host/pye17/edje/edje.override	                        (rev 0)
+++ trunk/src/host/pye17/edje/edje.override	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,14 @@
+%%
+headers
+#include <Python.h>               
+#include "pygobject.h"
+#include "Evas.h"
+#include "Edje.h"
+%%
+modulename edje                     
+%%
+import gtk.Plug as PyGtkPlug_Type       
+%%
+ignore-glob
+  *_get_type                            
+%%

Added: trunk/src/host/pye17/edje/edjemodule.c
===================================================================
--- trunk/src/host/pye17/edje/edjemodule.c	                        (rev 0)
+++ trunk/src/host/pye17/edje/edjemodule.c	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,22 @@
+#include <pygobject.h>
+ 
+void edje_register_classes (PyObject *d); 
+extern PyMethodDef edje_functions[];
+  
+DL_EXPORT(void)
+initedje(void)
+{
+  PyObject *m, *d;
+       
+  init_pygobject ();
+            
+  m = Py_InitModule ("edje", edje_functions);
+  d = PyModule_GetDict (m);
+                     
+  edje_register_classes (d);
+                          
+  if (PyErr_Occurred ()) {
+    Py_FatalError ("can't initialise module edje");
+  }
+}
+                                          
\ No newline at end of file

Added: trunk/src/host/pye17/evas/Makefile
===================================================================
--- trunk/src/host/pye17/evas/Makefile	                        (rev 0)
+++ trunk/src/host/pye17/evas/Makefile	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,24 @@
+EVAS_PATH=$(E_PATH)/evas/src/lib
+
+CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include/ -I/usr/include/python2.5 -I/usr/include/pygtk-2.0/ -I$(E_PATH)/evas/src/lib/ -I.
+
+.PHONY: all clean evas.so
+
+all: evas.so
+
+evas.so: evas.o evasmodule.o
+	$(CC) $(LDFLAGS) -shared $^ -o $@
+
+evas.c: evas_data.defs evas.defs evas.override
+	$(PYTHON) $(CODEGEN_PATH)/codegen.py --prefix evas \
+	--override evas.override --register evas_data.defs \
+	evas.defs > $@
+
+evas_data.defs: $(CODEGEN_PATH)/h2def.py $(EVAS_PATH)/Evas.h $(EVAS_PATH)/Evas_Data.h
+	$(CODEGEN_PATH)/h2def.py $(EVAS_PATH)/Evas_Data.h > $@
+
+evas.defs: $(CODEGEN_PATH)/h2def.py $(EVAS_PATH)/Evas.h $(EVAS_PATH)/Evas_Data.h
+	$(CODEGEN_PATH)/h2def.py $(EVAS_PATH)/Evas.h > $@
+
+clean:
+	rm -f *.o evas.c evas.defs

Added: trunk/src/host/pye17/evas/evas.override
===================================================================
--- trunk/src/host/pye17/evas/evas.override	                        (rev 0)
+++ trunk/src/host/pye17/evas/evas.override	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,13 @@
+%%
+headers
+#include <pygobject.h>
+#include <Evas_Data.h>
+#include <Evas.h>
+%%
+modulename evas                     
+%%
+import gtk.Plug as PyGtkPlug_Type       
+%%
+ignore-glob
+  *_get_type                            
+%%

Added: trunk/src/host/pye17/evas/evas_data.defs
===================================================================
--- trunk/src/host/pye17/evas/evas_data.defs	                        (rev 0)
+++ trunk/src/host/pye17/evas/evas_data.defs	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,485 @@
+;; -*- scheme -*-
+; object definitions ...
+(define-object Evas_Array
+  (c-name "Evas_Array")
+  (gtype-id "Evas_Array")
+)
+
+(define-object Evas_Hash
+  (c-name "Evas_Hash")
+  (gtype-id "Evas_Hash")
+)
+
+(define-object Evas_List
+  (c-name "Evas_List")
+  (gtype-id "Evas_List")
+)
+
+(define-object Evas_Object_List
+  (c-name "Evas_Object_List")
+  (gtype-id "Evas_Object_List")
+)
+
+;; Enumerations and flags ...
+
+
+;; From Evas_Data.h
+
+(define-function evas_array_new
+  (c-name "evas_array_new")
+  (is-constructor-of "EvasArray")
+  (return-type "Evas_Array*")
+  (parameters
+    '("unsigned-int" "step")
+  )
+)
+
+(define-function evas_array_setup
+  (c-name "evas_array_setup")
+  (return-type "none")
+  (parameters
+    '("Evas_Array*" "array")
+    '("unsigned-int" "step")
+  )
+)
+
+(define-function evas_array_free
+  (c-name "evas_array_free")
+  (return-type "none")
+  (parameters
+    '("Evas_Array*" "array")
+  )
+)
+
+(define-function evas_array_append
+  (c-name "evas_array_append")
+  (return-type "none")
+  (parameters
+    '("Evas_Array*" "array")
+    '("void*" "data")
+  )
+)
+
+(define-function evas_array_get
+  (c-name "evas_array_get")
+  (return-type "void*")
+  (parameters
+    '("Evas_Array*" "array")
+    '("unsigned-int" "index")
+  )
+)
+
+(define-function evas_array_clean
+  (c-name "evas_array_clean")
+  (return-type "none")
+  (parameters
+    '("Evas_Array*" "array")
+  )
+)
+
+(define-function evas_array_flush
+  (c-name "evas_array_flush")
+  (return-type "none")
+  (parameters
+    '("Evas_Array*" "array")
+  )
+)
+
+(define-function evas_array_remove
+  (c-name "evas_array_remove")
+  (return-type "none")
+  (parameters
+    '("Evas_Array*" "array")
+    '("void*" "callback")
+    '("void*" "gdata")
+  )
+)
+
+(define-function evas_array_hash_new
+  (c-name "evas_array_hash_new")
+  (is-constructor-of "EvasArrayHash")
+  (return-type "Evas_Array_Hash*")
+)
+
+(define-function evas_array_hash_free
+  (c-name "evas_array_hash_free")
+  (return-type "none")
+  (parameters
+    '("Evas_Array_Hash*" "hash")
+  )
+)
+
+(define-function evas_array_hash_add
+  (c-name "evas_array_hash_add")
+  (return-type "none")
+  (parameters
+    '("Evas_Array_Hash*" "hash")
+    '("int" "key")
+    '("int" "data")
+  )
+)
+
+(define-function evas_array_hash_search
+  (c-name "evas_array_hash_search")
+  (return-type "int")
+  (parameters
+    '("Evas_Array_Hash*" "hash")
+    '("int" "key")
+  )
+)
+
+(define-function evas_hash_add
+  (c-name "evas_hash_add")
+  (return-type "Evas_Hash*")
+  (parameters
+    '("Evas_Hash*" "hash")
+    '("const-char*" "key")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_hash_direct_add
+  (c-name "evas_hash_direct_add")
+  (return-type "Evas_Hash*")
+  (parameters
+    '("Evas_Hash*" "hash")
+    '("const-char*" "key")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_hash_del
+  (c-name "evas_hash_del")
+  (return-type "Evas_Hash*")
+  (parameters
+    '("Evas_Hash*" "hash")
+    '("const-char*" "key")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_hash_find
+  (c-name "evas_hash_find")
+  (return-type "void*")
+  (parameters
+    '("const-Evas_Hash*" "hash")
+    '("const-char*" "key")
+  )
+)
+
+(define-function evas_hash_modify
+  (c-name "evas_hash_modify")
+  (return-type "void*")
+  (parameters
+    '("Evas_Hash*" "hash")
+    '("const-char*" "key")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_hash_size
+  (c-name "evas_hash_size")
+  (return-type "int")
+  (parameters
+    '("const-Evas_Hash*" "hash")
+  )
+)
+
+(define-function evas_hash_free
+  (c-name "evas_hash_free")
+  (return-type "none")
+  (parameters
+    '("Evas_Hash*" "hash")
+  )
+)
+
+(define-function evas_hash_foreach
+  (c-name "evas_hash_foreach")
+  (return-type "none")
+  (parameters
+    '("const-Evas_Hash*" "hash")
+    '("void*" "callback")
+    '("const-void*" "fdata")
+  )
+)
+
+(define-function evas_hash_alloc_error
+  (c-name "evas_hash_alloc_error")
+  (return-type "int")
+)
+
+(define-function evas_list_append
+  (c-name "evas_list_append")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_list_prepend
+  (c-name "evas_list_prepend")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_list_append_relative
+  (c-name "evas_list_append_relative")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("const-void*" "data")
+    '("const-void*" "relative")
+  )
+)
+
+(define-function evas_list_append_relative_list
+  (c-name "evas_list_append_relative_list")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("const-void*" "data")
+    '("Evas_List*" "relative")
+  )
+)
+
+(define-function evas_list_prepend_relative
+  (c-name "evas_list_prepend_relative")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("const-void*" "data")
+    '("const-void*" "relative")
+  )
+)
+
+(define-function evas_list_prepend_relative_list
+  (c-name "evas_list_prepend_relative_list")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("const-void*" "data")
+    '("Evas_List*" "relative")
+  )
+)
+
+(define-function evas_list_remove
+  (c-name "evas_list_remove")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_list_remove_list
+  (c-name "evas_list_remove_list")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("Evas_List*" "remove_list")
+  )
+)
+
+(define-function evas_list_promote_list
+  (c-name "evas_list_promote_list")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("Evas_List*" "move_list")
+  )
+)
+
+(define-function evas_list_find
+  (c-name "evas_list_find")
+  (return-type "void*")
+  (parameters
+    '("const-Evas_List*" "list")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_list_find_list
+  (c-name "evas_list_find_list")
+  (return-type "Evas_List*")
+  (parameters
+    '("const-Evas_List*" "list")
+    '("const-void*" "data")
+  )
+)
+
+(define-function evas_list_free
+  (c-name "evas_list_free")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+  )
+)
+
+(define-function evas_list_last
+  (c-name "evas_list_last")
+  (return-type "Evas_List*")
+  (parameters
+    '("const-Evas_List*" "list")
+  )
+)
+
+(define-function evas_list_next
+  (c-name "evas_list_next")
+  (return-type "Evas_List*")
+  (parameters
+    '("const-Evas_List*" "list")
+  )
+)
+
+(define-function evas_list_prev
+  (c-name "evas_list_prev")
+  (return-type "Evas_List*")
+  (parameters
+    '("const-Evas_List*" "list")
+  )
+)
+
+(define-function evas_list_data
+  (c-name "evas_list_data")
+  (return-type "void*")
+  (parameters
+    '("const-Evas_List*" "list")
+  )
+)
+
+(define-function evas_list_count
+  (c-name "evas_list_count")
+  (return-type "int")
+  (parameters
+    '("const-Evas_List*" "list")
+  )
+)
+
+(define-function evas_list_nth
+  (c-name "evas_list_nth")
+  (return-type "void*")
+  (parameters
+    '("const-Evas_List*" "list")
+    '("int" "n")
+  )
+)
+
+(define-function evas_list_nth_list
+  (c-name "evas_list_nth_list")
+  (return-type "Evas_List*")
+  (parameters
+    '("const-Evas_List*" "list")
+    '("int" "n")
+  )
+)
+
+(define-function evas_list_reverse
+  (c-name "evas_list_reverse")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+  )
+)
+
+(define-function evas_list_sort
+  (c-name "evas_list_sort")
+  (return-type "Evas_List*")
+  (parameters
+    '("Evas_List*" "list")
+    '("int" "size")
+    '("void*" "callback")
+  )
+)
+
+(define-function evas_list_alloc_error
+  (c-name "evas_list_alloc_error")
+  (return-type "int")
+)
+
+(define-function evas_object_list_append
+  (c-name "evas_object_list_append")
+  (return-type "void*")
+  (parameters
+    '("void*" "in_list")
+    '("void*" "in_item")
+  )
+)
+
+(define-function evas_object_list_prepend
+  (c-name "evas_object_list_prepend")
+  (return-type "void*")
+  (parameters
+    '("void*" "in_list")
+    '("void*" "in_item")
+  )
+)
+
+(define-function evas_object_list_append_relative
+  (c-name "evas_object_list_append_relative")
+  (return-type "void*")
+  (parameters
+    '("void*" "in_list")
+    '("void*" "in_item")
+    '("void*" "in_relative")
+  )
+)
+
+(define-function evas_object_list_prepend_relative
+  (c-name "evas_object_list_prepend_relative")
+  (return-type "void*")
+  (parameters
+    '("void*" "in_list")
+    '("void*" "in_item")
+    '("void*" "in_relative")
+  )
+)
+
+(define-function evas_object_list_remove
+  (c-name "evas_object_list_remove")
+  (return-type "void*")
+  (parameters
+    '("void*" "in_list")
+    '("void*" "in_item")
+  )
+)
+
+(define-function evas_object_list_find
+  (c-name "evas_object_list_find")
+  (return-type "void*")
+  (parameters
+    '("void*" "in_list")
+    '("void*" "in_item")
+  )
+)
+
+(define-function evas_stringshare_init
+  (c-name "evas_stringshare_init")
+  (return-type "none")
+)
+
+(define-function evas_stringshare_shutdown
+  (c-name "evas_stringshare_shutdown")
+  (return-type "none")
+)
+
+(define-function evas_stringshare_add
+  (c-name "evas_stringshare_add")
+  (return-type "const-char*")
+  (parameters
+    '("const-char*" "str")
+  )
+)
+
+(define-function evas_stringshare_del
+  (c-name "evas_stringshare_del")
+  (return-type "none")
+  (parameters
+    '("const-char*" "str")
+  )
+)
+
+

Added: trunk/src/host/pye17/evas/evasmodule.c
===================================================================
--- trunk/src/host/pye17/evas/evasmodule.c	                        (rev 0)
+++ trunk/src/host/pye17/evas/evasmodule.c	2008-09-20 16:37:19 UTC (rev 4658)
@@ -0,0 +1,22 @@
+#include <pygobject.h>
+ 
+void evas_register_classes (PyObject *d); 
+extern PyMethodDef evas_functions[];
+  
+DL_EXPORT(void)
+initevas(void)
+{
+  PyObject *m, *d;
+       
+  init_pygobject ();
+            
+  m = Py_InitModule ("evas", evas_functions);
+  d = PyModule_GetDict (m);
+                     
+  evas_register_classes (d);
+                          
+  if (PyErr_Occurred ()) {
+    Py_FatalError ("can't initialise module evas");
+  }
+}
+                                          
\ No newline at end of file




More information about the commitlog mailing list