codegen/: Updated codegenerator to current pygtk one.
authorEdward Hervey <bilboed@bilboed.com>
Fri, 9 Jun 2006 10:50:21 +0000 (10:50 +0000)
committerEdward Hervey <bilboed@bilboed.com>
Fri, 9 Jun 2006 10:50:21 +0000 (10:50 +0000)
Original commit message from CVS:
* codegen/Makefile.am:
* codegen/argtypes.py:
* codegen/codegen.py:
* codegen/definitions.py:
* codegen/defsconvert.py:
* codegen/defsparser.py:
* codegen/docextract.py:
* codegen/docextract_to_xml.py:
* codegen/docgen.py:
* codegen/h2def.py:
* codegen/mergedefs.py:
* codegen/missingdefs.py:
* codegen/mkskel.py:
* codegen/override.py:
* codegen/reversewrapper.py:
Updated codegenerator to current pygtk one.
* gst/gst.defs:
* gst/gst.override:
* gst/gstpad.override:
Update defs for new constructor definition.
* testsuite/test_bin.py:
With new constructors, pygobject will try to convert the argument to the
proper GType (here a string).

20 files changed:
ChangeLog
codegen/Makefile.am
codegen/argtypes.py
codegen/codegen.py
codegen/definitions.py
codegen/defsconvert.py [deleted file]
codegen/defsparser.py
codegen/docextract.py
codegen/docextract_to_xml.py [deleted file]
codegen/docgen.py
codegen/h2def.py
codegen/mergedefs.py
codegen/missingdefs.py [deleted file]
codegen/mkskel.py
codegen/override.py
codegen/reversewrapper.py
gst/gst.defs
gst/gst.override
gst/gstpad.override
testsuite/test_bin.py

index 7fce9d3..f769379 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
 2006-06-09  Edward Hervey  <edward@fluendo.com>
 
+       * codegen/Makefile.am:
+       * codegen/argtypes.py:
+       * codegen/codegen.py:
+       * codegen/definitions.py:
+       * codegen/defsconvert.py:
+       * codegen/defsparser.py:
+       * codegen/docextract.py:
+       * codegen/docextract_to_xml.py:
+       * codegen/docgen.py:
+       * codegen/h2def.py:
+       * codegen/mergedefs.py:
+       * codegen/missingdefs.py:
+       * codegen/mkskel.py:
+       * codegen/override.py:
+       * codegen/reversewrapper.py:
+       Updated codegenerator to current pygtk one.
+       * gst/gst.defs:
+       * gst/gst.override:
+       * gst/gstpad.override:
+       Update defs for new constructor definition.
+       * testsuite/test_bin.py:
+       With new constructors, pygobject will try to convert the argument to the
+       proper GType (here a string).
+
+2006-06-09  Edward Hervey  <edward@fluendo.com>
+
        * gst/base.defs:
        * gst/gst-0.10.7.ignore:
        * gst/gst-types.defs:
index 45d232f..dd3eea0 100644 (file)
@@ -3,15 +3,12 @@ EXTRA_DIST = \
        code-coverage.py \
        codegen.py \
        definitions.py \
-       defsconvert.py \
        defsparser.py \
        docextract.py \
-       docextract_to_xml.py \
        docgen.py \
        h2def.py \
        __init__.py \
        mergedefs.py \
-       missingdefs.py \
        mkskel.py \
        override.py \
        reversewrapper.py \
index 6fd445c..300400f 100644 (file)
@@ -1,31 +1,29 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
-import sys
 import string
-import traceback
 import keyword
 import struct
 
 class VarList:
     """Nicely format a C variable list"""
     def __init__(self):
-       self.vars = {}
+        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,)
+        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 = []
+        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 ''
+        return ''
 
 class WrapperInfo:
     """A class that holds information about variable defs, code
@@ -66,16 +64,16 @@ class WrapperInfo:
             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" % \
+    def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, 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" % \
+        """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):
@@ -85,20 +83,20 @@ class NoneArg(ArgType):
 
 class StringArg(ArgType):
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
+        if pdflt:
             if pdflt != 'NULL': pdflt = '"' + pdflt + '"'
-           info.varlist.add('char', '*' + pname + ' = ' + pdflt)
-       else:
-           info.varlist.add('char', '*' + pname)
-       info.arglist.append(pname)
-       if pnull:
+            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:
+        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')
+            # 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' +
@@ -106,8 +104,8 @@ class StringArg(ArgType):
                                   '    }\n' +
                                   '    Py_INCREF(Py_None);\n' +
                                   '    return Py_None;')
-       else:
-           info.varlist.add('const gchar', '*ret')
+        else:
+            info.varlist.add('const gchar', '*ret')
             info.codeafter.append('    if (ret)\n' +
                                   '        return PyString_FromString(ret);\n'+
                                   '    Py_INCREF(Py_None);\n' +
@@ -116,29 +114,29 @@ class StringArg(ArgType):
 class UCharArg(ArgType):
     # allows strings with embedded NULLs.
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('guchar', '*' + pname + ' = "' + pdflt + '"')
-       else:
-           info.varlist.add('guchar', '*' + pname)
+        if pdflt:
+            info.varlist.add('guchar', '*' + pname + ' = "' + pdflt + '"')
+        else:
+            info.varlist.add('guchar', '*' + pname)
         info.varlist.add('int', pname + '_len')
-       info.arglist.append(pname)
-       if pnull:
+        info.arglist.append(pname)
+        if pnull:
             info.add_parselist('z#', ['&' + pname, '&' + pname + '_len'],
                                [pname])
-       else:
+        else:
             info.add_parselist('s#', ['&' + pname, '&' + pname + '_len'],
                                [pname])
 
 class CharArg(ArgType):
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('char', pname + " = '" + pdflt + "'")
-       else:
-           info.varlist.add('char', pname)
-       info.arglist.append(pname)
+        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.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'
@@ -150,25 +148,25 @@ class GUniCharArg(ArgType):
                 '    py_ret = (Py_UNICODE)ret;\n'
                 '    return PyUnicode_FromUnicode(&py_ret, 1);\n')
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('gunichar', pname + " = '" + pdflt + "'")
-       else:
-           info.varlist.add('gunichar', pname)
-       info.arglist.append(pname)
+        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, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('int', pname + ' = ' + pdflt)
-       else:
-           info.varlist.add('int', pname)
-       info.arglist.append(pname)
+        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')
@@ -212,13 +210,13 @@ class SizeArg(ArgType):
         llp64 = True
     else:
         llp64 = False
-    
+
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add(ptype, pname + ' = ' + pdflt)
-       else:
-           info.varlist.add(ptype, pname)
-       info.arglist.append(pname)
+        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:
@@ -236,13 +234,13 @@ class SSizeArg(ArgType):
         llp64 = True
     else:
         llp64 = False
-    
+
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add(ptype, pname + ' = ' + pdflt)
-       else:
-           info.varlist.add(ptype, pname)
-       info.arglist.append(pname)
+        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:
@@ -256,11 +254,11 @@ class SSizeArg(ArgType):
 
 class LongArg(ArgType):
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add(ptype, pname + ' = ' + pdflt)
-       else:
-           info.varlist.add(ptype, pname)
-       info.arglist.append(pname)
+        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')
@@ -273,66 +271,80 @@ class BoolArg(IntArg):
 
 class TimeTArg(ArgType):
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('time_t', pname + ' = ' + pdflt)
-       else:
-           info.varlist.add('time_t', pname)
-       info.arglist.append(pname)
+        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):
-    dflt = '    if (py_%(name)s)\n' \
-           '        %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
-    before = '    %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
         if pdflt:
-            info.varlist.add('gulong', pname + ' = ' + pdflt)
-            info.codebefore.append(self.dflt % {'name':pname})            
+            info.varlist.add('unsigned long', pname + ' = ' + pdflt)
         else:
-            info.varlist.add('gulong', pname)
-            info.codebefore.append(self.before % {'name':pname})            
-        info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
+            info.varlist.add('unsigned long', pname)
         info.arglist.append(pname)
-        info.add_parselist('O!', ['&PyLong_Type', '&py_' + pname], [pname])
+        info.add_parselist('k', ['&' + pname], [pname])
     def write_return(self, ptype, ownsreturn, info):
-        info.varlist.add('gulong', 'ret')
-        info.codeafter.append('    return PyLong_FromUnsignedLong(ret);')
+        info.varlist.add(ptype, 'ret')
+        info.codeafter.append('    return PyLong_FromUnsignedLong(ret);\n')
+
+class UInt32Arg(ULongArg):
+    def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
+        ULongArg.write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info)
+        ## if sizeof(unsigned long) > sizeof(unsigned int), we need to
+        ## check the value is within guint32 range
+        if struct.calcsize('L') > struct.calcsize('I'):
+            info.codebefore.append((
+                '    if (%(pname)s > G_MAXUINT32) {\n'
+                '        PyErr_SetString(PyExc_ValueError,\n'
+                '                        "Value out of range in conversion of"\n'
+                '                        " %(pname)s parameter to unsigned 32 bit integer");\n'
+                '        return NULL;\n'
+                '    }\n') % vars())
 
 class Int64Arg(ArgType):
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('gint64', pname + ' = ' + pdflt)
-       else:
-           info.varlist.add('gint64', pname)
-       info.arglist.append(pname)
+        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, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('guint64', pname + ' = ' + pdflt)
-       else:
-           info.varlist.add('guint64', pname)
-       info.arglist.append(pname)
-        info.add_parselist('K', ['&' + pname], [pname])
+        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, keeprefcount, info):
-       if pdflt:
-           info.varlist.add('double', pname + ' = ' + pdflt)
-       else:
-           info.varlist.add('double', pname)
-       info.arglist.append(pname)
+        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')
@@ -345,7 +357,7 @@ class FileArg(ArgType):
                 '        %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' 
+                '        return NULL;\n'
                 '    }')
     null = ('    if (py_%(name)s && PyFile_Check(py_%(name)s)\n'
             '        %(name)s = PyFile_AsFile(py_%(name)s);\n'
@@ -356,29 +368,29 @@ class FileArg(ArgType):
     dflt = ('    if (py_%(name)s)\n'
             '        %(name)s = PyFile_AsFile(py_%(name)s);\n')
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, 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})
+        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 + ')')
+        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.varlist.add('FILE', '*ret')
         info.codeafter.append('    if (ret)\n' +
                               '        return PyFile_FromFile(ret, "", "", fclose);\n' +
                               '    Py_INCREF(Py_None);\n' +
@@ -388,17 +400,17 @@ class EnumArg(ArgType):
     enum = ('    if (pyg_enum_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
             '        return NULL;\n')
     def __init__(self, enumname, typecode):
-       self.enumname = enumname
-       self.typecode = typecode
+        self.enumname = enumname
+        self.typecode = typecode
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, 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,
+        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.arglist.append(pname)
         info.add_parselist('O', ['&py_' + pname], [pname]);
     def write_return(self, ptype, ownsreturn, info):
         info.varlist.add('gint', 'ret')
@@ -408,20 +420,20 @@ class FlagsArg(ArgType):
     flag = ('    if (%(default)spyg_flags_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
             '        return NULL;\n')
     def __init__(self, flagname, typecode):
-       self.flagname = flagname
-       self.typecode = typecode
+        self.flagname = flagname
+        self.typecode = typecode
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pdflt:
-           info.varlist.add(self.flagname, pname + ' = ' + pdflt)
+        if pdflt:
+            info.varlist.add(self.flagname, pname + ' = ' + pdflt)
             default = "py_%s && " % (pname,)
-       else:
-           info.varlist.add(self.flagname, pname)
+        else:
+            info.varlist.add(self.flagname, pname)
             default = ""
-       info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
+        info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
         info.codebefore.append(self.flag % {'default':default,
                                             'typecode':self.typecode,
                                             'name':pname})
-       info.arglist.append(pname)
+        info.arglist.append(pname)
         info.add_parselist('O', ['&py_' + pname], [pname])
     def write_return(self, ptype, ownsreturn, info):
         info.varlist.add('guint', 'ret')
@@ -447,42 +459,57 @@ class ObjectArg(ArgType):
     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.objname = objname
+        self.cast = string.replace(typecode, '_TYPE_', '_', 1)
         self.parent = parent
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, 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,
+        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,
+                                                        '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}) 
-            info.arglist.append(pname)
+                                                    'type':self.objname})
+            if ptype.endswith('*'):
+                typename = ptype[:-1]
+                try:
+                    const, typename = typename.split('const-')
+                except ValueError:
+                    const = ''
+                if typename != ptype:
+                    info.arglist.append('(%s *) %s' % (ptype[:-1], pname))
+                else:
+                    info.arglist.append(pname)
+
             info.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)
+        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))
+            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[-1] == '*': ptype = ptype[:-1]
-        info.varlist.add(ptype, '*ret')
+        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')
             # < GLib 2.8: using our custom _new and _unref functions
@@ -532,7 +559,17 @@ class MiniObjectArg(ArgType):
                info.codebefore.append(self.null % {'name':pname,
                                                     'cast':self.cast,
                                                     'type':self.objname}) 
-            info.arglist.append(pname)
+            if ptype.endswith('*'):
+                typename = ptype[:-1]
+                try:
+                    const, typename = typename.split('const-')
+                except ValueError:
+                    const = ''
+                if typename != ptype:
+                    info.arglist.append('(%s *) %s' % (ptype[:-1], pname))
+                else:
+                    info.arglist.append(pname)
+                    
             info.add_parselist('O', ['&py_' + pname], [pname])
        else:
            if pdflt:
@@ -551,8 +588,13 @@ class MiniObjectArg(ArgType):
         if keeprefcount:
             info.codebefore.append('    gst_mini_object_ref(GST_MINI_OBJECT(%s->obj));\n' % pname)
     def write_return(self, ptype, ownsreturn, info):
-        if ptype[-1] == '*': ptype = ptype[:-1]
-        info.varlist.add(ptype, '*ret')
+        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 = pygstminiobject_new((GstMiniObject *)ret);\n'
@@ -578,19 +620,19 @@ class BoxedArg(ArgType):
             '        return NULL;\n'
             '    }\n')
     def __init__(self, ptype, typecode):
-       self.typename = ptype
-       self.typecode = typecode
+        self.typename = ptype
+        self.typecode = typecode
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pnull:
+        if pnull:
             info.varlist.add(self.typename, '*' + pname + ' = NULL')
-           info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
-           info.codebefore.append(self.null % {'name':  pname,
+            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
+            info.codebefore.append(self.null % {'name':  pname,
                                                 'typename': self.typename,
                                                 'typecode': self.typecode})
-       else:
+        else:
             info.varlist.add(self.typename, '*' + pname + ' = NULL')
-           info.varlist.add('PyObject', '*py_' + pname)
-           info.codebefore.append(self.check % {'name':  pname,
+            info.varlist.add('PyObject', '*py_' + pname)
+            info.codebefore.append(self.check % {'name':  pname,
                                                  'typename': self.typename,
                                                  'typecode': self.typecode})
         if ptype[-1] == '*':
@@ -627,23 +669,23 @@ class CustomBoxedArg(ArgType):
             '        return NULL;\n'
             '    }\n')
     def __init__(self, ptype, pytype, getter, new):
-       self.pytype = pytype
-       self.getter = getter
+        self.pytype = pytype
+        self.getter = getter
         self.checker = 'Py' + ptype + '_Check'
-       self.new = new
+        self.new = new
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pnull:
+        if pnull:
             info.varlist.add(ptype[:-1], '*' + pname + ' = NULL')
-           info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
-           info.codebefore.append(self.null % {'name':  pname,
+            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.arglist.append(pname)
             info.add_parselist('O', ['&py_' + pname], [pname])
-       else:
-           info.varlist.add('PyObject', '*' + pname)
-           info.arglist.append(self.getter + '(' + 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')
@@ -667,19 +709,19 @@ class PointerArg(ArgType):
             '        return NULL;\n'
             '    }\n')
     def __init__(self, ptype, typecode):
-       self.typename = ptype
-       self.typecode = typecode
+        self.typename = ptype
+        self.typecode = typecode
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pnull:
+        if pnull:
             info.varlist.add(self.typename, '*' + pname + ' = NULL')
-           info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
-           info.codebefore.append(self.null % {'name':  pname,
+            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
+            info.codebefore.append(self.null % {'name':  pname,
                                                 'typename': self.typename,
                                                 'typecode': self.typecode})
-       else:
+        else:
             info.varlist.add(self.typename, '*' + pname + ' = NULL')
-           info.varlist.add('PyObject', '*py_' + pname)
-           info.codebefore.append(self.check % {'name':  pname,
+            info.varlist.add('PyObject', '*py_' + pname)
+            info.codebefore.append(self.check % {'name':  pname,
                                                  'typename': self.typename,
                                                  'typecode': self.typecode})
         info.arglist.append(pname)
@@ -716,16 +758,21 @@ class AtomArg(IntArg):
         info.add_parselist('O', ['&py_' + pname], [pname])
     def write_return(self, ptype, ownsreturn, info):
         info.varlist.add('GdkAtom', 'ret')
-        info.codeafter.append('    return PyString_FromString(gdk_atom_name(ret));')
+        info.varlist.add('PyObject *', 'py_ret')
+        info.varlist.add('gchar *', 'name')
+        info.codeafter.append('    name = gdk_atom_name(ret);\n'
+                              '    py_ret = PyString_FromString(name);\n'
+                              '    g_free(name);\n'
+                              '    return py_ret;')
 
 class GTypeArg(ArgType):
     gtype = ('    if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n'
              '        return NULL;\n')
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, 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.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')
@@ -759,17 +806,17 @@ class GtkTreePathArg(ArgType):
     def __init__(self):
         pass
     def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
-       if pnull:
+        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.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:
+        else:
             info.varlist.add('GtkTreePath', '*' + pname)
-           info.varlist.add('PyObject', '*py_' + pname)
+            info.varlist.add('PyObject', '*py_' + pname)
             info.codebefore.append(self.normal % {'name': pname})
-           info.arglist.append(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):
@@ -789,7 +836,7 @@ class GtkTreePathArg(ArgType):
                                   '    }\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')
@@ -816,8 +863,8 @@ class GdkRectanglePtrArg(ArgType):
 
 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);')
+        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, keeprefcount, info):
@@ -839,17 +886,17 @@ class PyObjectArg(ArgType):
 
 class ArgMatcher:
     def __init__(self):
-       self.argtypes = {}
-       self.reverse_argtypes = {}
-       self.reverse_rettypes = {}
+        self.argtypes = {}
+        self.reverse_argtypes = {}
+        self.reverse_rettypes = {}
 
     def register(self, ptype, handler):
-       self.argtypes[ptype] = handler
+        self.argtypes[ptype] = handler
     def register_reverse(self, ptype, handler):
-       self.reverse_argtypes[ptype] = handler
+        self.reverse_argtypes[ptype] = handler
     def register_reverse_ret(self, ptype, handler):
-       self.reverse_rettypes[ptype] = handler
-        
+        self.reverse_rettypes[ptype] = handler
+
     def register_enum(self, ptype, typecode):
         if typecode is None:
             typecode = "G_TYPE_NONE"
@@ -857,11 +904,12 @@ class ArgMatcher:
     def register_flag(self, ptype, typecode):
         if typecode is None:
             typecode = "G_TYPE_NONE"
-       self.register(ptype, FlagsArg(ptype, typecode))
+        self.register(ptype, FlagsArg(ptype, typecode))
     def register_object(self, ptype, parent, typecode):
         oa = ObjectArg(ptype, parent, typecode)
         self.register(ptype, oa)  # in case I forget the * in the .defs
-       self.register(ptype+'*', oa)
+        self.register(ptype+'*', oa)
+        self.register('const-'+ptype+'*', oa)
         if ptype == 'GdkPixmap':
             # hack to handle GdkBitmap synonym.
             self.register('GdkBitmap', oa)
@@ -874,16 +922,16 @@ class ArgMatcher:
         if self.argtypes.has_key(ptype): return
         arg = BoxedArg(ptype, typecode)
         self.register(ptype, arg)
-       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(ptype+'*', arg)
         self.register('const-'+ptype+'*', arg)
     def register_pointer(self, ptype, typecode):
         arg = PointerArg(ptype, typecode)
         self.register(ptype, arg)
-       self.register(ptype+'*', arg)
+        self.register(ptype+'*', arg)
         self.register('const-'+ptype+'*', arg)
 
     def get(self, ptype):
@@ -994,13 +1042,7 @@ matcher.register('gboolean', arg)
 arg = TimeTArg()
 matcher.register('time_t', arg)
 
-# If the system maxint is smaller than unsigned int, we need to use
-# Long objects with PyLong_AsUnsignedLong
-if sys.maxint >= (1L << 32):
-    matcher.register('guint32', arg)
-else:
-    arg = ULongArg()
-    matcher.register('guint32', arg)
+matcher.register('guint32', UInt32Arg())
 
 arg = ULongArg()
 matcher.register('gulong', arg)
index 7cc5bb4..dd8ac80 100644 (file)
@@ -1,7 +1,13 @@
-import sys, os, string
-import getopt, traceback, keyword
-import defsparser, argtypes, override
+import getopt
+import keyword
+import os
+import string
+import sys
+
+import argtypes
 import definitions
+import defsparser
+import override
 import reversewrapper
 
 class Coverage(object):
@@ -9,18 +15,24 @@ class Coverage(object):
         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)
+        total = self.wrapped + self.not_wrapped
+        fd = sys.stderr
         if total:
-            print >> sys.stderr, "***INFO*** The coverage of %s is %.2f%% (%i/%i)" %\
-                  (self.name, float(self.wrapped*100)/total, self.wrapped, total)
+            fd.write("***INFO*** The coverage of %s is %.2f%% (%i/%i)\n" %
+                     (self.name,
+                      float(self.wrapped*100)/total,
+                      self.wrapped,
+                      total))
         else:
-            print >> sys.stderr, "***INFO*** There are no declared %s." %\
-                  (self.name, )
+            fd.write("***INFO*** There are no declared %s." % self.name)
 
 functions_coverage = Coverage("global functions")
 methods_coverage = Coverage("methods")
@@ -44,7 +56,7 @@ def exc_info():
 
 def fixname(name):
     if keyword.iskeyword(name):
-       return name + '_'
+        return name + '_'
     return name
 
 class FileOutput:
@@ -78,121 +90,140 @@ class FileOutput:
         self.setline(self.lineno + 1, self.filename)
 
 class Wrapper:
-    type_tmpl = \
-        'PyTypeObject 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' \
-        '    NULL,                             /* 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' \
-        '    %(tp_methods)s,                   /* tp_methods */\n' \
-        '    0,                                        /* tp_members */\n' \
-        '    %(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' \
+    type_tmpl = (
+        'PyTypeObject 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']
-
-    getter_tmpl = \
-        'static PyObject *\n' \
-        '%(funcname)s(PyObject *self, void *closure)\n' \
-        '{\n' \
-        '%(varlist)s' \
-        '    ret = %(field)s;\n' \
-        '%(codeafter)s\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' \
+    parse_tmpl = (
+        '    if (!PyArg_ParseTupleAndKeywords(args, kwargs,'
+        '"%(typecodes)s:%(name)s"%(parselist)s))\n'
         '        return %(errorreturn)s;\n'
+        )
 
-    methdef_tmpl = '    { "%(name)s", (PyCFunction)%(cname)s, %(flags)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' \
+    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' \
-        '    %(setreturn)s%(cname)s(%(arglist)s);\n' \
-        '%(codeafter)s\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' \
+        )
+
+    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
@@ -217,12 +248,20 @@ class Wrapper:
         return { 'name': '%s.__init__' % self.objinfo.c_name,
                  'errorreturn': '-1' }
     def get_initial_method_substdict(self, method):
-        return { 'name': '%s.%s' % (self.objinfo.c_name, method.name) }
+        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/* ----------- ' + self.objinfo.c_name + ' ----------- */\n\n')
+        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'
@@ -232,17 +271,19 @@ class Wrapper:
                                            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):
+        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_':
@@ -254,7 +295,7 @@ class Wrapper:
             else:
                 if not substdict.has_key(slot):
                     substdict[slot] = '0'
-    
+
         self.fp.write(self.type_tmpl % substdict)
 
         self.write_virtuals()
@@ -265,7 +306,7 @@ class Wrapper:
         '''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')
@@ -302,6 +343,13 @@ class Wrapper:
         # 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)
@@ -309,11 +357,14 @@ class Wrapper:
         substdict['typecodes'] = info.parsestr
         substdict['parselist'] = info.get_parselist()
         substdict['arglist'] = info.get_arglist()
-        substdict['codebefore'] = deprecated + \
+        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'])
+            )
+        substdict['codeafter'] = (
+            string.replace(info.get_codeafter(),
+                           'return NULL',
+                           'return ' + substdict['errorreturn']))
 
         if info.parsestr or kwargs_needed:
             substdict['parseargs'] = self.parse_tmpl % substdict
@@ -326,41 +377,55 @@ class Wrapper:
             substdict['parseargs'] = ''
             substdict['extraparams'] = ''
             flags = 'METH_NOARGS'
+
         return template % substdict, flags
 
     def write_constructor(self):
         initfunc = '0'
         constructor = self.parser.find_constructor(self.objinfo,self.overrides)
-        if constructor:
-            funcname = constructor.c_name
-            try:
-                if self.overrides.is_overriden(funcname):
-                    data = self.overrides.override(funcname)
-                    self.write_function(funcname, data)
-                else:
-                    # ok, a hack to determine if we should use new-style constructores :P
-                    if getattr(self, 'write_property_based_constructor', None) is not None:
-                        if (len(constructor.params) == 0 or
-                            isinstance(constructor.params[0], definitions.Property)):
-                            # write_property_based_constructor is only
-                            # implemented in GObjectWrapper
-                            return self.write_property_based_constructor(constructor)
-                        else:
-                            print >> sys.stderr, "Warning: generating old-style constructor for",\
-                                  constructor.c_name
-                    # write constructor from template ...
-                    code = self.write_function_wrapper(constructor,
-                        self.constructor_tmpl,
-                        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:
-                sys.stderr.write('Could not write constructor for %s: %s\n' 
-                                 % (self.objinfo.c_name, exc_info()))
-                initfunc = self.write_noconstructor()
-        else:
-            initfunc = self.write_default_constructor()
+        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:
+            sys.stderr.write('Could not write constructor for %s: %s\n'
+                             % (self.objinfo.c_name, exc_info()))
+
+            initfunc = self.write_noconstructor()
         return initfunc
 
     def write_noconstructor(self):
@@ -376,11 +441,18 @@ class Wrapper:
 
     def get_methflags(self, funcname):
         if self.overrides.wants_kwargs(funcname):
-            return 'METH_VARARGS|METH_KEYWORDS'
+            flags = 'METH_VARARGS|METH_KEYWORDS'
         elif self.overrides.wants_noargs(funcname):
-            return 'METH_NOARGS'
+            flags = 'METH_NOARGS'
+        elif self.overrides.wants_onearg(funcname):
+            flags = 'METH_O'
         else:
-            return 'METH_VARARGS'
+            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)
@@ -393,7 +465,8 @@ class Wrapper:
         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['class_cast_macro'] = parent.typecode.replace(
+            '_TYPE_', '_', 1) + "_CLASS"
         substdict['typecode'] = self.objinfo.typecode
         substdict['cast'] = string.replace(parent.typecode, '_TYPE_', '_', 1)
         return substdict
@@ -410,7 +483,7 @@ class Wrapper:
                 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) 
+                        self.write_function(method_name, data)
 
                     methflags = self.get_methflags(method_name)
                 else:
@@ -422,7 +495,8 @@ class Wrapper:
                 methods.append(self.methdef_tmpl %
                                { 'name':  fixname(meth.name),
                                  'cname': '_wrap_' + method_name,
-                                 'flags': methflags})
+                                 'flags': methflags,
+                                 'docstring': meth.docstring })
                 methods_coverage.declare_wrapped()
             except:
                 methods_coverage.declare_not_wrapped()
@@ -437,13 +511,14 @@ class Wrapper:
 
             try:
                 data = self.overrides.define(klass, method_name)
-                self.write_function(method_name, data) 
+                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})
+                                 'flags': methflags,
+                                 'docstring': meth.docstring })
                 methods_coverage.declare_wrapped()
             except:
                 methods_coverage.declare_not_wrapped()
@@ -453,12 +528,12 @@ class Wrapper:
         # 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 }\n')
-            self.fp.write('static PyMethodDef %s[] = {\n' % methoddefs)
+            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:
@@ -485,25 +560,32 @@ class Wrapper:
                         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))
+                        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'})
+                                 'flags': methflags + '|METH_CLASS',
+                                 'docstring': 'NULL'})
                 vaccessors_coverage.declare_wrapped()
             except:
                 vaccessors_coverage.declare_not_wrapped()
-                sys.stderr.write('Could not write virtual accessor method %s.%s: %s\n'
-                                % (klass, meth.name, exc_info()))
+                sys.stderr.write(
+                    'Could not write virtual accessor method %s.%s: %s\n'
+                    % (klass, meth.name, exc_info()))
         return methods
 
     def write_virtuals(self):
-        '''Write _wrap_FooBar__proxy_do_zbr() reverse wrapers for GObject virtuals'''
+        '''
+        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):
@@ -525,14 +607,17 @@ class Wrapper:
                         wrapper, "self", method_name="do_" + meth.name,
                         c_type=(klass + ' *')))
                     for param in meth.params:
-                        handler, props = argtypes.matcher.get_reverse(param.ptype)
-                        wrapper.add_parameter(handler(wrapper, param.pname, **props))
+                        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 KeyError:
+            except (KeyError, ValueError):
                 vproxies_coverage.declare_not_wrapped()
                 virtuals.append((fixname(meth.name), None))
                 sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
@@ -543,22 +628,28 @@ class Wrapper:
             # GtkPlug and GtkSocket on win32).
             if self.overrides.is_ignored(self.objinfo.typecode):
                 return
-            class_cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1) + "_CLASS"
+            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())
+            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'
+                    '    %(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:
@@ -566,26 +657,35 @@ class Wrapper:
                                   'is currently not supported */\n' % vars())
                 else:
                     self.fp.write('''
-    if ((o = PyDict_GetItemString(pyclass->tp_dict, "%(do_name)s"))
-        && !PyObject_TypeCheck(o, &PyCFunction_Type))
-        klass->%(name)s = %(cname)s;\n''' % vars())
+    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
+        # no overrides for the whole function.  If no fields,
+        # don't write a func
         if not self.objinfo.fields:
             return '0'
         getsets = []
-        for ftype, fname in self.objinfo.fields:
+        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): 
+            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:
@@ -602,30 +702,31 @@ class Wrapper:
                     self.fp.write(self.getter_tmpl %
                                   { 'funcname': funcname,
                                     'varlist': info.varlist,
-                                    'field': self.get_field_accessor(fname),
+                                    'field': self.get_field_accessor(cfname),
                                     'codeafter': info.get_codeafter() })
                     gettername = funcname
                 except:
-                    sys.stderr.write("Could not write getter for %s.%s: %s\n"
-                                     % (self.objinfo.c_name, fname, exc_info()))
+                    sys.stderr.write(
+                        "Could not write getter for %s.%s: %s\n"
+                        % (self.objinfo.c_name, fname, exc_info()))
             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 PyGetSetDef %s[] = {\n' % getsets_name)
+        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_functions(self, prefix):
         self.fp.write('\n/* ----------- functions ----------- */\n\n')
         functions = []
-            
+
         # First, get methods from the defs files
         for func in self.parser.find_functions():
             funcname = func.c_name
@@ -645,7 +746,8 @@ class Wrapper:
                 functions.append(self.methdef_tmpl %
                                  { 'name':  func.name,
                                    'cname': '_wrap_' + funcname,
-                                   'flags': methflags })
+                                   'flags': methflags,
+                                   'docstring': func.docstring })
                 functions_coverage.declare_wrapped()
             except:
                 functions_coverage.declare_not_wrapped()
@@ -656,56 +758,60 @@ class Wrapper:
         for funcname in self.overrides.get_functions():
             try:
                 data = self.overrides.function(funcname)
-                self.write_function(funcname)
+                self.write_function(funcname, data)
                 methflags = self.get_methflags(funcname)
                 functions.append(self.methdef_tmpl %
                                  { 'name':  funcname,
                                    'cname': '_wrap_' + funcname,
-                                   'flags': methflags })
+                                   'flags': methflags,
+                                   'docstring': 'NULL'})
                 functions_coverage.declare_wrapped()
             except:
                 functions_coverage.declare_not_wrapped()
                 sys.stderr.write('Could not write function %s: %s\n'
                                  % (funcname, exc_info()))
-                
+
         # write the PyMethodDef structure
-        functions.append('    { NULL, NULL, 0 }\n')
-        
-        self.fp.write('PyMethodDef ' + prefix + '_functions[] = {\n')
+        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' \
+    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' \
-        '    pyg_begin_allow_threads;\n' \
-        '    %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n' \
-        '    pyg_end_allow_threads;\n' \
-        '%(codeafter)s\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:
@@ -716,13 +822,14 @@ class GObjectWrapper(Wrapper):
         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)
+        substdict = Wrapper.get_initial_constructor_substdict(self,
+                                                              constructor)
         if not constructor.caller_owns_return:
             substdict['aftercreate'] = "    g_object_ref(self->obj);\n"
         else:
@@ -731,47 +838,73 @@ class GObjectWrapper(Wrapper):
 
     def get_initial_method_substdict(self, method):
         substdict = Wrapper.get_initial_method_substdict(self, method)
-        substdict['cast'] = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
+        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,'\
+        print >> out, '_wrap_%s(PyGObject *self, PyObject *args,' \
               ' PyObject *kwargs)\n{' % constructor.c_name
-        print >> out, "    GType obj_type = pyg_type_from_object((PyObject *) self);"
+        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 }"
+                return "{" + ", ".join(
+                    map(lambda s: '"' + s + '"', arg)) + ", NULL }"
             else:
                 return "{ NULL }"
 
-        classname = '%s.%s' % (self.overrides.modulename, self.objinfo.name)
+        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)
+            mandatory_arguments = [param for param in constructor.params
+                                             if not param.optional]
+            optional_arguments = [param for param in constructor.params
+                                            if param.optional]
+            arg_names = py_str_list_to_c(
+            [param.argname
+             for param in mandatory_arguments + optional_arguments])
+
+            prop_names = py_str_list_to_c(
+            [param.pname
+             for param in mandatory_arguments + optional_arguments])
+
+            print >> out, "    GParameter params[%i];" % \
+                  len(constructor.params)
+            print >> out, "    PyObject *parsed_args[%i] = {NULL, };" % \
+                  len(constructor.params)
             print >> out, "    char *arg_names[] = %s;" % arg_names
             print >> out, "    char *prop_names[] = %s;" % prop_names
             print >> out, "    guint nparams, i;"
             print >> out
             if constructor.deprecated is not None:
-                print >> out, '    if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)' %\
-                      constructor.deprecated
+                out.write(
+                    '    if (PyErr_Warn(PyExc_DeprecationWarning, '
+                    '"%s") < 0)\n' %
+                    constructor.deprecated)
                 print >> out, '        return -1;'
                 print >> out
-            print >> out, "    if (!PyArg_ParseTupleAndKeywords(args, kwargs, ",
+            out.write("    if (!PyArg_ParseTupleAndKeywords(args, kwargs, ")
             template = '"'
             if mandatory_arguments:
                 template += "O"*len(mandatory_arguments)
@@ -781,78 +914,90 @@ class GObjectWrapper(Wrapper):
             print >> out, template, ", arg_names",
             for i in range(len(constructor.params)):
                 print >> out, ", &parsed_args[%i]" % i,
-            print >> out, "))"
-            print >> out, "        return -1;"
-            print >> out
-            print >> out, "    memset(params, 0, sizeof(GParameter)*%i);" % len(constructor.params)
-            print >> out, "    if (!pyg_parse_constructor_args(obj_type, arg_names, prop_names,"
-            print >> out, "                                    params, &nparams, parsed_args))"
-            print >> out, "        return -1;"
-            print >> out, "    self->obj = g_object_newv(obj_type, nparams, params);"
-            print >> out, "    for (i = 0; i < nparams; ++i)"
-            print >> out, "        g_value_unset(&params[i].value);"
+
+            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:
-            print >> out, "    static char* kwlist[] = { NULL };";
-            print >> out
-            if constructor.deprecated is not None:
-                print >> out, '    if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)' %\
-                      constructor.deprecated
-                print >> out, '        return -1;'
-                print >> out
-            print >> out, '    if (!PyArg_ParseTupleAndKeywords(args, kwargs, ":%s.__init__", kwlist))' % classname
-            print >> out, "        return -1;"
-            print >> out
-            print >> out, "    self->obj = g_object_newv(obj_type, 0, NULL);"
+            out.write(
+                "    static char* kwlist[] = { NULL };\n"
+                "\n")
 
-        print >> out, \
-              '    if (!self->obj) {\n' \
-              '        PyErr_SetString(PyExc_RuntimeError, "could not create %(typename)s object");\n' \
-              '        return -1;\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"
 
-        print >> out, \
-              '    pygobject_register_wrapper((PyObject *)self);\n' \
-              '    return 0;\n' \
-              '}\n\n' % { 'typename': classname }
+        out.write(
+            '    return 0;\n'
+            '}\n\n')
+
         return "_wrap_%s" % constructor.c_name
 
 
 ## TODO : Add GstMiniObjectWrapper(Wrapper)
 class GstMiniObjectWrapper(Wrapper):
-    constructor_tmpl = \
-        'static int\n' \
-        '_wrap_%(cname)s(PyGstMiniObject *self%(extraparams)s)\n' \
-        '{\n' \
-        '%(varlist)s' \
-        '%(parseargs)s' \
-        '%(codebefore)s' \
-        '    self->obj = (GstMiniObject *)%(cname)s(%(arglist)s);\n' \
-        '%(codeafter)s\n' \
-        '    if (!self->obj) {\n' \
-        '        PyErr_SetString(PyExc_RuntimeError, "could not create %(typename)s miniobject");\n' \
-        '        return -1;\n' \
-        '    }\n' \
-        '%(aftercreate)s' \
-        '    pygstminiobject_register_wrapper((PyObject *)self);\n' \
-        '    return 0;\n' \
+    constructor_tmpl = (
+        'static int\n'
+        '_wrap_%(cname)s(PyGstMiniObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    self->obj = (GstMiniObject *)%(cname)s(%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '    if (!self->obj) {\n'
+        '        PyErr_SetString(PyExc_RuntimeError, '
+        '"could not create %(typename)s miniobject");\n'
+        '        return -1;\n'
+        '    }\n'
+        '%(aftercreate)s'
+        '    pygstminiobject_register_wrapper((PyObject *)self);\n'
+        '    return 0;\n'
         '}\n\n'
-    method_tmpl = \
-        'static PyObject *\n' \
-        '_wrap_%(cname)s(PyGstMiniObject *self%(extraparams)s)\n' \
-        '{\n' \
-        '%(varlist)s' \
-        '%(parseargs)s' \
-        '%(codebefore)s' \
-        '    pyg_begin_allow_threads;\n' \
-        '    %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n' \
-        '    pyg_end_allow_threads;\n' \
-        '%(codeafter)s\n' \
+        )
+    method_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyGstMiniObject *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:
@@ -869,7 +1014,8 @@ class GstMiniObjectWrapper(Wrapper):
         return '%s(pygstminiobject_get(self))->%s' % (castmacro, fieldname)
 
     def get_initial_constructor_substdict(self, constructor):
-        substdict = Wrapper.get_initial_constructor_substdict(self, constructor)
+        substdict = Wrapper.get_initial_constructor_substdict(self,
+                                                              constructor)
         if not constructor.caller_owns_return:
             substdict['aftercreate'] = "    gst_mini_object_ref(self->obj);\n"
         else:
@@ -878,11 +1024,34 @@ class GstMiniObjectWrapper(Wrapper):
 
     def get_initial_method_substdict(self, method):
         substdict = Wrapper.get_initial_method_substdict(self, method)
-        substdict['cast'] = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
+        substdict['cast'] = string.replace(self.objinfo.typecode,
+                                           '_TYPE_', '_', 1)
         return substdict
     
 
+
 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',
@@ -895,9 +1064,13 @@ class GInterfaceWrapper(GObjectWrapper):
         # interfaces have no fields ...
         return '0'
 
-    def write_virtual_accessors(self):
-        ## we don't want the 'chaining' functions for interfaces
-        return []
+    def _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
@@ -924,71 +1097,108 @@ class GInterfaceWrapper(GObjectWrapper):
                         wrapper, "self", method_name="do_" + meth.name,
                         c_type=(klass + ' *')))
                     for param in meth.params:
-                        handler, props = argtypes.matcher.get_reverse(param.ptype)
-                        wrapper.add_parameter(handler(wrapper, param.pname, **props))
+                        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 KeyError:
+            except (KeyError, ValueError):
                 iproxies_coverage.declare_not_wrapped()
                 proxies.append((fixname(meth.name), None))
                 sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
                                 % (klass, meth.name, exc_info()))
-        if proxies:
-            ## Write an interface init function for this object
-            funcname = "__%s__interface_init" % klass
-            vtable = self.objinfo.vtable
-            self.fp.write(('\nstatic void\n'
-                           '%(funcname)s(%(vtable)s *iface)\n'
-                           '{\n') % vars())
-            for name, cname in proxies:
-                do_name = 'do_' + name
-                if cname is not None:
-                    self.fp.write('    iface->%s = %s;\n' % (name, cname))
-            self.fp.write('}\n\n')
-            interface_info = "__%s__iinfo" % klass
-            self.fp.write('''
+
+        if not proxies:
+            return
+
+        # Make sure we have at least one proxy function
+        if not [cname for name,cname in proxies if not cname is None]:
+            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
-            
+        self.objinfo.interface_info = interface_info
 
 class GBoxedWrapper(Wrapper):
-    constructor_tmpl = \
-        'static int\n' \
-        '_wrap_%(cname)s(PyGBoxed *self%(extraparams)s)\n' \
+    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' \
+        '%(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' \
-        '    %(setreturn)s%(cname)s(pyg_boxed_get(self, %(typename)s)%(arglist)s);\n' \
-        '%(codeafter)s\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',
@@ -999,38 +1209,43 @@ class GBoxedWrapper(Wrapper):
         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 = 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' \
+    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' \
+        )
+
+    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',
@@ -1038,10 +1253,12 @@ class GPointerWrapper(GBoxedWrapper):
                  'tp_dictoffset'     : '0' }
 
     def get_field_accessor(self, fieldname):
-        return 'pyg_pointer_get(self, %s)->%s' % (self.objinfo.c_name, 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 = Wrapper.get_initial_constructor_substdict(
+            self, constructor)
         substdict['typecode'] = self.objinfo.typecode
         return substdict
 
@@ -1052,14 +1269,19 @@ def write_headers(data, fp):
     fp.write(data)
     fp.resetline()
     fp.write('\n\n')
-    
+
+def write_body(data, fp):
+    fp.write(data)
+    fp.resetline()
+    fp.write('\n\n')
+
 def write_imports(overrides, fp):
     fp.write('/* ---------- types from other modules ---------- */\n')
     for module, pyname, cname in overrides.get_imports():
         fp.write('static PyTypeObject *_%s;\n' % cname)
         fp.write('#define %s (*_%s)\n' % (cname, cname))
     fp.write('\n\n')
-    
+
 def write_type_declarations(parser, fp):
     fp.write('/* ---------- forward type declarations ---------- */\n')
     for obj in parser.boxes:
@@ -1072,10 +1294,39 @@ def write_type_declarations(parser, fp):
         fp.write('PyTypeObject Py' + interface.c_name + '_Type;\n')
     fp.write('\n')
 
+
+def sort_parent_children(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(parser, overrides, fp):
+    ## Sort the objects, so that we generate code for the parent types
+    ## before their children.
+    objects = sort_parent_children(parser.objects)
     for klass, items in ((GBoxedWrapper, parser.boxes),
                          (GPointerWrapper, parser.pointers),
-                         (GObjectWrapper, parser.objects),
+                         (GObjectWrapper, objects),
                          (GstMiniObjectWrapper, parser.miniobjects),
                          (GInterfaceWrapper, parser.interfaces)):
         for item in items:
@@ -1087,26 +1338,33 @@ def write_enums(parser, overrides, prefix, fp=sys.stdout):
     if not parser.enums:
         return
     fp.write('\n/* ----------- enums and flags ----------- */\n\n')
-    fp.write('void\n' + prefix + '_add_constants(PyObject *module, const gchar *strip_prefix)\n{\n')
+    fp.write(
+        'void\n' + prefix +
+        '_add_constants(PyObject *module, const gchar *strip_prefix)\n{\n')
+
     for enum in parser.enums:
         if overrides.is_type_ignored(enum.c_name):
             continue
         if enum.typecode is None:
             for nick, value in enum.values:
-                fp.write('    PyModule_AddIntConstant(module, pyg_constant_strip_prefix("%s", strip_prefix), %s);\n'
-                         % (value, value))
+                fp.write(
+                    '    PyModule_AddIntConstant(module, '
+                    'pyg_constant_strip_prefix("%s", strip_prefix), %s);\n'
+                    % (value, value))
         else:
             if enum.deftype == 'enum':
-                fp.write('  pyg_enum_add(module, "%s", strip_prefix, %s);\n' % (enum.name, enum.typecode))
+                fp.write('  pyg_enum_add(module, "%s", strip_prefix, %s);\n'
+                         % (enum.name, enum.typecode))
             else:
-                fp.write('  pyg_flags_add(module, "%s", strip_prefix, %s);\n' % (enum.name, enum.typecode))
-            
+                fp.write('  pyg_flags_add(module, "%s", strip_prefix, %s);\n'
+                         % (enum.name, enum.typecode))
+
     fp.write('\n')
     fp.write('  if (PyErr_Occurred())\n')
-    fp.write('    PyErr_Print();\n') 
+    fp.write('    PyErr_Print();\n')
     fp.write('}\n\n')
 
-def write_extension_init(overrides, prefix, fp): 
+def write_extension_init(overrides, prefix, fp):
     fp.write('/* initialise stuff extension classes */\n')
     fp.write('void\n' + prefix + '_register_classes(PyObject *d)\n{\n')
     imports = overrides.get_imports()[:]
@@ -1116,10 +1374,15 @@ def write_extension_init(overrides, prefix, fp):
             bymod.setdefault(module, []).append((pyname, cname))
         fp.write('    PyObject *module;\n\n')
         for module in bymod:
-            fp.write('    if ((module = PyImport_ImportModule("%s")) != NULL) {\n' % module)
-            fp.write('        PyObject *moddict = PyModule_GetDict(module);\n\n')
+            fp.write(
+                '    if ((module = PyImport_ImportModule("%s")) != NULL) {\n'
+                % module)
+            fp.write(
+                '        PyObject *moddict = PyModule_GetDict(module);\n\n')
             for pyname, cname in bymod[module]:
-                fp.write('        _%s = (PyTypeObject *)PyDict_GetItemString(moddict, "%s");\n' % (cname, pyname))
+                fp.write(
+                    '        _%s = (PyTypeObject *)PyDict_GetItemString('
+                    'moddict, "%s");\n' % (cname, pyname))
                 fp.write('        if (_%s == NULL) {\n' % cname)
                 fp.write('            PyErr_SetString(PyExc_ImportError,\n')
                 fp.write('                "cannot import name %s from %s");\n'
@@ -1138,10 +1401,13 @@ def write_extension_init(overrides, prefix, fp):
 def write_registers(parser, overrides, fp):
     for boxed in parser.boxes:
         fp.write('    pyg_register_boxed(d, "' + boxed.name +
-                 '", ' + boxed.typecode + ', &Py' + boxed.c_name + '_Type);\n')
+                 '", ' + boxed.typecode +
+                 ', &Py' + boxed.c_name +
+                 '_Type);\n')
     for pointer in parser.pointers:
         fp.write('    pyg_register_pointer(d, "' + pointer.name +
-                 '", ' + pointer.typecode + ', &Py' + pointer.c_name + '_Type);\n')
+                 '", ' + pointer.typecode +
+                 ', &Py' + pointer.c_name + '_Type);\n')
     for interface in parser.interfaces:
         fp.write('    pyg_register_interface(d, "' + interface.name +
                  '", '+ interface.typecode + ', &Py' + interface.c_name +
@@ -1178,6 +1444,14 @@ def write_registers(parser, overrides, fp):
             fp.write('    pygobject_register_class(d, "' + obj.c_name +
                      '", ' + obj.typecode + ', &Py' + obj.c_name +
                      '_Type, NULL);\n')
+        if obj.has_new_constructor_api:
+            fp.write('    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:
             fp.write('    pyg_register_class_init(%s, %s);\n' %
                      (obj.typecode, obj.class_init_func))
@@ -1205,6 +1479,7 @@ def write_source(parser, overrides, prefix, fp=FileOutput(sys.stdout)):
     write_headers(overrides.get_headers(), fp)
     write_imports(overrides, fp)
     write_type_declarations(parser, fp)
+    write_body(overrides.get_body(), fp)
     write_classes(parser, overrides, fp)
 
     wrapper = Wrapper(parser, None, overrides, fp)
@@ -1226,13 +1501,14 @@ def register_types(parser):
     for obj in parser.interfaces:
         argtypes.matcher.register_object(obj.c_name, None, obj.typecode)
     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)
+        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
@@ -1254,7 +1530,7 @@ def main(argv):
         elif opt in ('-p', '--prefix'):
             prefix = arg
         elif opt in ('-r', '--register'):
-           # Warning: user has to make sure all -D options appear before -r
+            # Warning: user has to make sure all -D options appear before -r
             p = defsparser.DefsParser(arg, defines)
             p.startParsing()
             register_types(p)
@@ -1266,12 +1542,12 @@ def main(argv):
         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 == '-D':
+            nameval = arg.split('=')
+            try:
+                defines[nameval[0]] = nameval[1]
+            except IndexError:
+                defines[nameval[0]] = None
     if len(args) < 1:
         print >> sys.stderr, usage
         return 1
@@ -1280,9 +1556,9 @@ def main(argv):
     p = defsparser.DefsParser(args[0], defines)
     if not outfilename:
         outfilename = os.path.splitext(args[0])[0] + '.c'
-        
+
     p.startParsing()
-    
+
     register_types(p)
     write_source(p, o, prefix, FileOutput(sys.stdout, outfilename))
 
index c5c06c2..911c8dd 100644 (file)
@@ -1,17 +1,25 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
+import copy
 import sys
-from copy import *
 
 def get_valid_scheme_definitions(defs):
     return [x for x in defs if isinstance(x, tuple) and len(x) >= 2]
 
+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, prop=None, keeprefcount=False):
+    def __init__(self, ptype, pname, pdflt, pnull, pdir=None, keeprefcount = False):
         self.ptype = ptype
         self.pname = pname
         self.pdflt = pdflt
         self.pnull = pnull
+       self.pdir = pdir
         self.keeprefcount = keeprefcount
         
     def __len__(self): return 4
@@ -39,16 +47,17 @@ class Property(object):
 
 
 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"
+        """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"
+        """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"
+        """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"
@@ -62,46 +71,49 @@ class Definition:
 
 class ObjectDef(Definition):
     def __init__(self, name, *args):
-       self.name = name
-       self.module = None
-       self.parent = None
-       self.c_name = None
+        self.name = name
+        self.module = None
+        self.parent = None
+        self.c_name = None
         self.typecode = None
-       self.fields = []
+        self.fields = []
         self.implements = []
         self.class_init_func = None
-       for arg in get_valid_scheme_definitions(args):
-           if arg[0] == 'in-module':
-               self.module = arg[1]
-           elif arg[0] == 'parent':
+        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':
+            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
+        # 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')
+        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.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:
@@ -162,108 +174,110 @@ class MiniObjectDef(Definition):
 
 class InterfaceDef(Definition):
     def __init__(self, name, *args):
-       self.name = name
-       self.module = None
-       self.c_name = None
+        self.name = name
+        self.module = None
+        self.c_name = None
         self.typecode = None
         self.vtable = None
-       self.fields = []
+        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] == 'c-name':
-               self.c_name = arg[1]
-           elif arg[0] == 'gtype-id':
-               self.typecode = arg[1]
-           elif arg[0] == 'vtable':
-               self.vtable = arg[1]
+        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')
+        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.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':
+        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
+        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')
+        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')
+        fp.write(')\n\n')
 
 class FlagsDef(EnumDef):
     def __init__(self, *args):
-       apply(EnumDef.__init__, (self,) + args)
-       self.deftype = 'flags'
+        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.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]
+        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':
+            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
+        # 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')
+        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:
@@ -273,74 +287,80 @@ class BoxedDef(Definition):
             for (ftype, fname) in self.fields:
                 fp.write('    \'("' + ftype + '" "' + fname + '")\n')
             fp.write('  )\n')
-       fp.write(')\n\n')
+        fp.write(')\n\n')
 
 class PointerDef(Definition):
     def __init__(self, name, *args):
-       self.name = name
-       self.module = None
-       self.c_name = None
+        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':
+        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
+        # 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')
+        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')
+        fp.write(')\n\n')
 
 class MethodDefBase(Definition):
     def __init__(self, name, *args):
         dump = 0
-       self.name = name
-       self.ret = None
+        self.name = name
+        self.ret = None
         self.caller_owns_return = None
-       self.c_name = 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.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':
+        for arg in get_valid_scheme_definitions(args):
+            if arg[0] == 'of-object':
                 self.of_object = 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] == '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] == 'parameters':
+            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
                     keeprefcount = False
                     for farg in parg[2:]:
                         assert isinstance(farg, tuple)
@@ -348,16 +368,18 @@ class MethodDefBase(Definition):
                             pdflt = farg[1]
                         elif farg[0] == 'null-ok':
                             pnull = 1
+                        elif farg[0] == 'direction':
+                            pdir = farg[1]
                         elif farg[0] == 'keep-refcount':
                             keeprefcount = True
-                    self.params.append(Parameter(ptype, pname, pdflt, pnull,
+                    self.params.append(Parameter(ptype, pname, pdflt, pnull, pdir,
                                                  keeprefcount=keeprefcount))
             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" 
+                sys.stderr.write("Warning: %s argument unsupported.\n"
                                  % (arg[0]))
                 dump = 1
         if dump:
@@ -365,33 +387,35 @@ class MethodDefBase(Definition):
 
         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.
+        # here we merge extra parameter flags accross to the new object.
         if not parmerge:
-            self.params = deepcopy(old.params)
+            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
+        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.of_object != (None, None):
+            fp.write('  (of-object "' + self.of_object + '")\n')
+        if self.c_name:
+            fp.write('  (c-name "' + self.c_name + '")\n')
+        if self.typecode:
+            fp.write('  (gtype-id "' + self.typecode + '")\n')
         if self.caller_owns_return:
-           fp.write('  (caller-owns-return #t)\n')
-       if self.ret:
-           fp.write('  (return-type "' + self.ret + '")\n')
-       if self.deprecated:
-           fp.write('  (deprecated "' + self.deprecated + '")\n')
+            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:
@@ -400,9 +424,10 @@ class MethodDefBase(Definition):
                 if pnull: fp.write(' (null-ok)')
                 fp.write(')\n')
             fp.write('  )\n')
-       if self.varargs:
-           fp.write('  (varargs #t)\n')
-       fp.write(')\n\n')
+        if self.varargs:
+            fp.write('  (varargs #t)\n')
+        fp.write(')\n\n')
+
 
 class MethodDef(MethodDefBase):
     def __init__(self, name, *args):
@@ -411,43 +436,48 @@ class MethodDef(MethodDefBase):
             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')
+        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')
+        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.name = name
+        self.in_module = None
+        self.is_constructor_of = None
+        self.ret = None
         self.caller_owns_return = None
-       self.c_name = None
+        self.unblock_threads = None
+        self.c_name = None
         self.typecode = None
-       self.params = [] # of form (type, name, default, nullok)
+        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] == '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]
+        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] == 'parameters':
+            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]
@@ -501,17 +531,17 @@ class FunctionDef(Definition):
         self.caller_owns_return = old.caller_owns_return
         self.varargs = old.varargs
         if not parmerge:
-            self.params = deepcopy(old.params)
+            self.params = copy.deepcopy(old.params)
             return
-       # here we merge extra parameter flags accross to the new object.
+        # here we merge extra parameter flags accross to the new object.
         def merge_param(param):
-           for old_param in old.params:
-               if old_param.pname == param.pname:
+            for old_param in old.params:
+                if old_param.pname == param.pname:
                     if isinstance(old_param, Property):
                         # h2def never scans Property's, therefore if
                         # we have one it was manually written, so we
                         # keep it.
-                        return deepcopy(old_param)
+                        return copy.deepcopy(old_param)
                     else:
                         param.merge(old_param)
                         return param
@@ -522,35 +552,37 @@ class FunctionDef(Definition):
         except RuntimeError:
             # parameter names changed and we can't find a match; it's
             # safer to keep the old parameter list untouched.
-            self.params = deepcopy(old.params)
-        
-       if not self.is_constructor_of:
+            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]
+        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')
+        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.ret:
-           fp.write('  (return-type "' + self.ret + '")\n')
-       if self.deprecated:
-           fp.write('  (deprecated "' + self.deprecated + '")\n')
+            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')
@@ -569,7 +601,7 @@ class FunctionDef(Definition):
                 fp.write('  )\n')
             else:
                 assert False, "strange parameter list %r" % self.params[0]
-       if self.varargs:
-           fp.write('  (varargs #t)\n')
+        if self.varargs:
+            fp.write('  (varargs #t)\n')
 
-       fp.write(')\n\n')
+        fp.write(')\n\n')
diff --git a/codegen/defsconvert.py b/codegen/defsconvert.py
deleted file mode 100644 (file)
index c25dcfb..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-import sys
-import string, re
-
-# ------------------ Create typecodes from typenames ---------
-
-_upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])')
-_upperstr_pat2 = re.compile(r'([A-Z][A-Z])([A-Z][0-9a-z])')
-_upperstr_pat3 = re.compile(r'^([A-Z])([A-Z])')
-
-def to_upper_str(name):
-    """Converts a typename to the equivalent upercase and underscores
-    name.  This is used to form the type conversion macros and enum/flag
-    name variables"""
-    name = _upperstr_pat1.sub(r'\1_\2', name)
-    name = _upperstr_pat2.sub(r'\1_\2', name)
-    name = _upperstr_pat3.sub(r'\1_\2', name, count=1)
-    return string.upper(name)
-
-def typecode(typename):
-    """create a typecode (eg. GTK_TYPE_WIDGET) from a typename"""
-    return string.replace(to_upper_str(typename), '_', '_TYPE_', 1)
-
-
-STATE_START = 0
-STATE_OBJECT = 1
-STATE_INTERFACE = 2
-STATE_BOXED = 3
-STATE_ENUM = 4
-STATE_FLAGS = 5
-STATE_METHOD = 6
-STATE_FUNCTION = 7
-STATE_MINIOBJECT = 8
-
-def convert(infp=sys.stdin, outfp=sys.stdout):
-    state = STATE_START
-    seen_params = 0
-
-    line = infp.readline()
-    while line:
-       if line[:8] == '(object ':
-           state = STATE_OBJECT
-           seen_params = 0
-           outfp.write('(define-object ' + line[8:])
-        elif line[:13] == '(mini-object ':
-            state = STATE_MINI_OBJECT
-            seen_params = 0
-            outfp.write('(define mini-object ' + line[13:])
-       elif line[:11] == '(interface ':
-           state = STATE_INTERFACE
-           seen_params = 0
-           outfp.write('(define-interface ' + line[11:])
-       elif line[:7] == '(boxed ':
-           state = STATE_BOXED
-           seen_params = 0
-           outfp.write('(define-boxed ' + line[7:])
-       elif line[:6] == '(enum ':
-           state = STATE_ENUM
-           seen_params = 0
-           outfp.write('(define-enum ' + line[6:])
-       elif line[:7] == '(flags ':
-           state = STATE_FLAGS
-           seen_params = 0
-           outfp.write('(define-flags ' + line[7:])
-       elif line[:8] == '(method ':
-           state = STATE_METHOD
-           seen_params = 0
-           outfp.write('(define-method ' + line[8:])
-       elif line[:10] == '(function ':
-           state = STATE_FUNCTION
-           seen_params = 0
-           outfp.write('(define-function ' + line[10:])
-       elif line[:13] == '  (in-module ':
-           outfp.write(re.sub(r'^(\s+\(in-module\s+)(\w+)(.*)$',
-                              r'\1"\2"\3', line))
-       elif line[:10] == '  (parent ':
-           outfp.write(re.sub(r'^(\s+\(parent\s+)(\w+)(\s+\((\w+)\))?(.*)$',
-                              r'\1"\4\2"\5', line))
-       elif line[:14] == '  (implements ':
-           outfp.write(re.sub(r'^(\s+\(implements\s+)([^\s]+)(\s*\))$',
-                              r'\1"\2"\3', line))
-       elif line[:13] == '  (of-object ':
-           outfp.write(re.sub(r'^(\s+\(of-object\s+)(\w+)(\s+\((\w+)\))?(.*)$',
-                              r'\1"\4\2"\5', line))
-       elif line[:10] == '  (c-name ':
-           outfp.write(re.sub(r'^(\s+\(c-name\s+)([^\s]+)(\s*\))$',
-                              r'\1"\2"\3', line))
-           if state in (STATE_OBJECT, STATE_INTERFACE, STATE_BOXED,
-                        STATE_ENUM, STATE_FLAGS):
-               c_name = re.match(r'^\s+\(c-name\s+([^\s]+)\s*\)$',
-                                 line).group(1)
-               outfp.write('  (gtype-id "%s")\n' % typecode(c_name))
-       elif line[:15] == '  (return-type ':
-           outfp.write(re.sub(r'^(\s+\(return-type\s+)([^\s]+)(\s*\))$',
-                              r'\1"\2"\3', line))
-       elif line[:13] == '  (copy-func ':
-           outfp.write(re.sub(r'^(\s+\(copy-func\s+)(\w+)(.*)$',
-                              r'\1"\2"\3', line))
-       elif line[:16] == '  (release-func ':
-           outfp.write(re.sub(r'^(\s+\(release-func\s+)(\w+)(.*)$',
-                              r'\1"\2"\3', line))
-       elif line[:9] == '  (field ':
-           if not seen_params:
-               outfp.write('  (fields\n')
-           seen_params = 1
-           outfp.write(re.sub(r'^\s+\(field\s+\(type-and-name\s+([^\s]+)\s+([^\s]+)\s*\)\s*\)$',
-                              '    \'("\\1" "\\2")', line))
-       elif line[:9] == '  (value ':
-           if not seen_params:
-               outfp.write('  (values\n')
-           seen_params = 1
-           outfp.write(re.sub(r'^\s+\(value\s+\(name\s+([^\s]+)\)\s+\(c-name\s+([^\s]+)\s*\)\s*\)$',
-                              '    \'("\\1" "\\2")', line))
-       elif line[:13] == '  (parameter ':
-           if not seen_params:
-               outfp.write('  (parameters\n')
-           seen_params = 1
-           outfp.write(re.sub(r'^\s+\(parameter\s+\(type-and-name\s+([^\s]+)\s+([^\s]+)\s*\)(\s*.*)\)$',
-                              '    \'("\\1" "\\2"\\3)', line))
-       elif line[:11] == '  (varargs ':
-           if seen_params:
-               outfp.write('  )\n')
-           seen_params = 0
-           outfp.write('  (varargs #t)\n')
-       elif line[0] == ')':
-           if seen_params:
-               outfp.write('  )\n')
-           seen_params = 0
-           state = STATE_START
-           outfp.write(line)
-       else:
-           outfp.write(line)
-       line = infp.readline()
-
-if __name__ == '__main__':
-    convert()
index 9f58f1a..e24a969 100644 (file)
@@ -1,7 +1,9 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
 import os, sys
 import scmexpr
-from definitions import *
+from definitions import BoxedDef, EnumDef, FlagsDef, FunctionDef, \
+     InterfaceDef, MethodDef, ObjectDef, MiniObjectDef, PointerDef, \
+     VirtualDef
 
 class IncludeParser(scmexpr.Parser):
     """A simple parser that follows include statements automatically"""
@@ -21,14 +23,14 @@ class DefsParser(IncludeParser):
        self.objects = []
         self.miniobjects = []
         self.interfaces = []
-       self.enums = []      # enums and flags
+        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
+        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)
@@ -60,16 +62,16 @@ class DefsParser(IncludeParser):
         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
+        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
+        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)
+        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):
@@ -79,12 +81,12 @@ class DefsParser(IncludeParser):
                 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):
+        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()
+        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:
@@ -92,14 +94,14 @@ class DefsParser(IncludeParser):
         # TODO: Add miniobject
         for obj in self.miniobjects:
             obj.write_defs(fp)
-       for enum in self.enums:
-           enum.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)
+        for func in self.functions:
+            func.write_defs(fp)
 
     def find_object(self, c_name):
         for obj in self.objects:
@@ -131,12 +133,11 @@ class DefsParser(IncludeParser):
                       not func.is_constructor_of, self.functions)
 
     def ifdef(self, *args):
-       if args[0] in self.defines:
-           for arg in args[1:]:
-               self.handle(arg)
+        if args[0] in self.defines:
+            for arg in args[1:]:
+                self.handle(arg)
 
     def ifndef(self, *args):
-       if args[0] not in self.defines:
-           for arg in args[1:]:
-               self.handle(arg)
-
+        if args[0] not in self.defines:
+            for arg in args[1:]:
+                self.handle(arg)
index 1de4567..e6c6505 100644 (file)
@@ -8,18 +8,18 @@ __all__ = ['extract']
 
 class FunctionDoc:
     def __init__(self):
-       self.name = None
-       self.params = []
-       self.description = ''
-       self.ret = ''
+        self.name = None
+        self.params = []
+        self.description = ''
+        self.ret = ''
     def set_name(self, name):
-       self.name = name
+        self.name = name
     def add_param(self, name, description):
-       if name == '...':
-           name = 'Varargs'
-       self.params.append((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)
+        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:
@@ -28,9 +28,9 @@ class FunctionDoc:
         # fall through to adding extra parameter ...
         self.add_param(name, extra)
     def append_description(self, extra):
-       self.description = self.description + extra
+        self.description = self.description + extra
     def append_return(self, extra):
-       self.ret = self.ret + extra
+        self.ret = self.ret + extra
 
     def get_param_description(self, name):
         for param, description in self.params:
@@ -44,97 +44,97 @@ comment_end_pat = re.compile(r'^\s*\*+/')
 comment_line_lead = re.compile(r'^\s*\*\s*')
 funcname_pat = re.compile(r'^(\w+)\s*:?')
 return_pat = re.compile(r'^(returns:|return\s+value:|returns\s*)(.*\n?)$',
-                       re.IGNORECASE)
+                        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
-               cur_doc.description = cur_doc.description + return_start + \
-                                     cur_doc.ret
-               return_start = match.group(1)
-               cur_doc.ret = match.group(2)
-           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 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:
+            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()
+                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)
+        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)
+        parse_dir(dir, doc_dict)
     return doc_dict
 
 tmpl_section_pat = re.compile(r'^<!-- ##### (\w+) (\w+) ##### -->$')
diff --git a/codegen/docextract_to_xml.py b/codegen/docextract_to_xml.py
deleted file mode 100755 (executable)
index 38d6722..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: Python; py-indent-offset: 4 -*-
-#
-# This litte script outputs the C doc comments to an XML format.
-# So far it's only used by gtkmm (The C++ bindings). Murray Cumming.
-# Usage example:
-# # ./docextract_to_xml.py -s /gnome/head/cvs/gtk+/gtk/ -s /gnome/head/cvs/gtk+/docs/reference/gtk/tmpl/ > gtk_docs.xml
-
-import sys, os, string, re, getopt
-
-import docextract
-import string
-
-def escape_text(unescaped_text):
-    escaped_text = unescaped_text
-    escaped_text = string.replace(escaped_text, '<', '&lt;')
-    escaped_text = string.replace(escaped_text, '>', '&gt;')
-    escaped_text = string.replace(escaped_text, '&', '&amp;')
-    escaped_text = string.replace(escaped_text, '\'', '&apos;')
-    escaped_text = string.replace(escaped_text, '\"', '&quot;')
-
-    #Apparently this is an undefined symbol:
-    escaped_text = string.replace(escaped_text, '&mdash;', ' mdash ')
-    
-    return escaped_text
-
-if __name__ == '__main__':
-    try:
-        opts, args = getopt.getopt(sys.argv[1:], "d:s:o:",
-                                   ["source-dir="])
-    except getopt.error, e:
-        sys.stderr.write('docgen.py: %s\n' % e)
-       sys.stderr.write(
-           'usage: docgen.py [-s /src/dir]\n')
-        sys.exit(1)
-    source_dirs = []
-    for opt, arg in opts:
-       if opt in ('-s', '--source-dir'):
-           source_dirs.append(arg)
-    if len(args) != 0:
-       sys.stderr.write(
-           'usage: docgen.py  [-s /src/dir]\n')
-        sys.exit(1)
-
-    docs = docextract.extract(source_dirs);
-    docextract.extract_tmpl(source_dirs, docs); #Try the tmpl sgml files too.
-
-    # print d.docs
-    
-    if docs:
-
-        print "<root>"
-        
-        for name, value in docs.items():
-            print "<function name=\"" + escape_text(name) + "\">"
-
-            print "<description>"
-            #The value is a docextract.FunctionDoc
-            print escape_text(value.description)
-            print "</description>"
-
-             # Loop through the parameters:
-            print "<parameters>"
-            for name, description in value.params:
-                print "<parameter name=\"" + escape_text(name) + "\">"
-                print "<parameter_description>" + escape_text(description) + "</parameter_description>"
-                print "</parameter>"
-            
-            print "</parameters>"
-
-            # Show the return-type:
-            print "<return>" + escape_text(value.ret) + "</return>"
-            
-            print "</function>\n"
-
-        print "</root>"
-    
-
index 5c7cde7..6905a14 100644 (file)
@@ -32,13 +32,12 @@ def build_object_tree(parser):
     root = Node(None)
     nodes = { None: root }
     for obj_def in objects:
+        print obj_def.name
         parent_node = nodes[obj_def.parent]
         node = Node(obj_def.c_name, obj_def.implements)
         parent_node.add_child(node)
         nodes[node.name] = node
 
-    # TODO: Add mini-object
-
     if parser.interfaces:
         interfaces = Node('gobject.GInterface')
         root.add_child(interfaces)
@@ -70,7 +69,7 @@ def build_object_tree(parser):
 
 class DocWriter:
     def __init__(self):
-       # parse the defs file
+        # parse the defs file
         self.parser = defsparser.DefsParser(())
         self.overrides = override.Overrides()
         self.classmap = {}
@@ -116,12 +115,12 @@ class DocWriter:
         self.write_full_hierarchy(hierarchy, fp)
         fp.close()
 
-       obj_defs = self.parser.objects + self.parser.interfaces + \
+        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:
+        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')
+            fp = open(filename, 'w')
             if isinstance(obj_def, definitions.ObjectDef):
                 self.output_object_docs(obj_def, fp)
             elif isinstance(obj_def, definitions.InterfaceDef):
@@ -130,24 +129,24 @@ class DocWriter:
                 self.output_boxed_docs(obj_def, fp)
             elif isinstance(obj_def, definitions.PointerDef):
                 self.output_boxed_docs(obj_def, fp)
-           fp.close()
+            fp.close()
             files.append((os.path.basename(filename), obj_def))
 
         if files:
             filename = self.create_toc_filename(output_prefix)
-           fp = open(filename, 'w')
+            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_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) ]
+        # construct the inheritence hierarchy ...
+        ancestry = [ (obj_def.c_name, obj_def.implements) ]
         try:
             parent = obj_def.parent
             while parent != None:
@@ -185,7 +184,7 @@ class DocWriter:
         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_class_header(int_def.c_name, fp)
 
         self.write_heading('Synopsis', fp)
         self.write_synopsis(int_def, fp)
@@ -203,7 +202,7 @@ class DocWriter:
         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_class_header(box_def.c_name, fp)
 
         self.write_heading('Synopsis', fp)
         self.write_synopsis(box_def, fp)
@@ -235,8 +234,8 @@ class DocWriter:
 
     # 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'
+        '''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)
 
@@ -269,8 +268,8 @@ class DocWriter:
                ')'
 
     def write_class_header(self, obj_name, fp):
-       fp.write('Class %s\n' % obj_name)
-       fp.write('======%s\n\n' % ('=' * len(obj_name)))
+        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):
@@ -352,9 +351,9 @@ 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'''
+        '''Create output filename for this particular object'''
         stem = output_prefix + '-' + string.lower(obj_name)
         if self.use_xml:
             return stem + '.xml'
@@ -429,7 +428,7 @@ class DocbookDocWriter(DocWriter):
                        '</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)
@@ -439,7 +438,7 @@ class DocbookDocWriter(DocWriter):
 
         # 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]) == '':
@@ -538,7 +537,7 @@ class DocbookDocWriter(DocWriter):
             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')
@@ -680,7 +679,7 @@ class DocbookDocWriter(DocWriter):
             #    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:
@@ -726,25 +725,25 @@ if __name__ == '__main__':
                                     "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.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 ('-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
+        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.stderr.write(
+            'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
         sys.exit(1)
 
     d = DocbookDocWriter()
index 517ed5c..d4b2135 100755 (executable)
@@ -4,13 +4,19 @@
 # For each prototype, generate a scheme style definition.
 # GPL'ed
 # Toby D. Reeves <toby@max.rl.plh.af.mil>
-
+#
 # Modified by James Henstridge <james@daa.com.au> to output stuff in
 # Havoc's new defs format.  Info on this format can be seen at:
 #   http://www.gnome.org/mailing-lists/archives/gtk-devel-list/2000-January/0085.shtml
+# Updated to be PEP-8 compatible and refactored to use OOP
 
+import getopt
+import os
+import re
+import string
+import sys
 
-import string, sys, re, types
+import defsparser
 
 # ------------------ Create typecodes from typenames ---------
 
@@ -114,7 +120,8 @@ def find_obj_defs(buf, objdefs=[]):
             objdefs.append(t)
         pos = m.end()
 
-    # now find all structures that look like they might represent a class inherited from GTypeInterface:
+    # now find all structures that look like they might represent
+    # a class inherited from GTypeInterface:
     pat = re.compile("struct _(" + obj_name_pat + ")Class\s*{\s*" +
                      "GTypeInterface\s+", re.MULTILINE)
     pos = 0
@@ -129,7 +136,8 @@ def find_obj_defs(buf, objdefs=[]):
             objdefs.append(t)
         pos = m.end()
 
-    # now find all structures that look like they might represent an Iface inherited from GTypeInterface:
+    # now find all structures that look like they might represent
+    # an Iface inherited from GTypeInterface:
     pat = re.compile("struct _(" + obj_name_pat + ")Iface\s*{\s*" +
                      "GTypeInterface\s+", re.MULTILINE)
     pos = 0
@@ -159,35 +167,6 @@ def sort_obj_defs(objdefs):
             pos = pos + 1
     return objdefs
 
-def write_obj_defs(objdefs, output):
-    if type(output)==types.StringType:
-        fp=open(output,'w')
-    elif type(output)==types.FileType:
-        fp=output
-    else:
-        fp=sys.stdout
-
-    fp.write(';; -*- scheme -*-\n')
-    fp.write('; object definitions ...\n')
-
-    for klass, parent in objdefs:
-        m = split_prefix_pat.match(klass)
-        cmodule = None
-        cname = klass
-        if m:
-            cmodule = m.group(1)
-            cname = m.group(2)
-
-        fp.write('(define-object ' + cname + '\n')
-        if cmodule:
-            fp.write('  (in-module "' + cmodule + '")\n')
-        if parent:
-            fp.write('  (parent "' + parent + '")\n')
-        fp.write('  (c-name "' + klass + '")\n')
-        fp.write('  (gtype-id "' + typecode(klass) + '")\n')
-        # should do something about accessible fields
-        fp.write(')\n\n')
-
 # ------------------ Find enum definitions -----------------
 
 def find_enum_defs(buf, enums=[]):
@@ -196,7 +175,7 @@ def find_enum_defs(buf, enums=[]):
     buf = strip_comments(buf)
 
     buf = re.sub('\n', ' ', buf)
-    
+
     enum_pat = re.compile(r'enum\s*{([^}]*)}\s*([A-Z][A-Za-z]*)(\s|;)')
     splitter = re.compile(r'\s*,\s', re.MULTILINE)
     pos = 0
@@ -213,47 +192,8 @@ def find_enum_defs(buf, enums=[]):
             entries.append(string.split(val)[0])
         if name != 'GdkCursorType':
             enums.append((name, isflags, entries))
-        
-        pos = m.end()
 
-def write_enum_defs(enums, output=None):
-    if type(output)==types.StringType:
-        fp=open(output,'w')
-    elif type(output)==types.FileType:
-        fp=output
-    else:
-        fp=sys.stdout
-
-    fp.write(';; Enumerations and flags ...\n\n')
-    trans = string.maketrans(string.uppercase + '_', string.lowercase + '-')
-    for cname, isflags, entries in enums:
-        name = cname
-        module = None
-        m = split_prefix_pat.match(cname)
-        if m:
-            module = m.group(1)
-            name = m.group(2)
-        if isflags:
-            fp.write('(define-flags ' + name + '\n')
-        else:
-            fp.write('(define-enum ' + name + '\n')
-        if module:
-            fp.write('  (in-module "' + module + '")\n')
-        fp.write('  (c-name "' + cname + '")\n')
-        fp.write('  (gtype-id "' + typecode(cname) + '")\n')
-        prefix = entries[0]
-        for ent in entries:
-            # shorten prefix til we get a match ...
-            # and handle GDK_FONT_FONT, GDK_FONT_FONTSET case
-            while ent[:len(prefix)] != prefix or len(prefix) >= len(ent):
-                prefix = prefix[:-1]
-        prefix_len = len(prefix)
-        fp.write('  (values\n')
-        for ent in entries:
-            fp.write('    \'("%s" "%s")\n' %
-                     (string.translate(ent[prefix_len:], trans), ent))
-        fp.write('  )\n')
-        fp.write(')\n\n')
+        pos = m.end()
 
 # ------------------ Find function definitions -----------------
 
@@ -267,40 +207,41 @@ def clean_func(buf):
     buf = strip_comments(buf)
 
     # compact continued lines
-    pat = re.compile(r"""\\\n""", re.MULTILINE) 
-    buf=pat.sub('',buf)
+    pat = re.compile(r"""\\\n""", re.MULTILINE)
+    buf = pat.sub('', buf)
 
     # Preprocess directives
-    pat = re.compile(r"""^[#].*?$""", re.MULTILINE) 
-    buf=pat.sub('',buf)
+    pat = re.compile(r"""^[#].*?$""", re.MULTILINE)
+    buf = pat.sub('', buf)
 
     #typedefs, stucts, and enums
-    pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re.MULTILINE) 
-    buf=pat.sub('',buf)
+    pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""",
+                     re.MULTILINE)
+    buf = pat.sub('', buf)
 
     #strip DECLS macros
-    pat = re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS""", re.MULTILINE) 
-    buf=pat.sub('',buf)
+    pat = re.compile(r"""G_BEGIN_DECLS|BEGIN_LIBGTOP_DECLS""", re.MULTILINE)
+    buf = pat.sub('', buf)
 
     #extern "C"
-    pat = re.compile(r"""^\s*(extern)\s+\"C\"\s+{""", re.MULTILINE) 
-    buf=pat.sub('',buf)
+    pat = re.compile(r"""^\s*(extern)\s+\"C\"\s+{""", re.MULTILINE)
+    buf = pat.sub('', buf)
 
     #multiple whitespace
-    pat = re.compile(r"""\s+""", re.MULTILINE) 
-    buf=pat.sub(' ',buf)
+    pat = re.compile(r"""\s+""", re.MULTILINE)
+    buf = pat.sub(' ', buf)
 
     #clean up line ends
-    pat = re.compile(r""";\s*""", re.MULTILINE) 
-    buf=pat.sub('\n',buf)
+    pat = re.compile(r""";\s*""", re.MULTILINE)
+    buf = pat.sub('\n', buf)
     buf = buf.lstrip()
 
     #associate *, &, and [] with type instead of variable
-    #pat=re.compile(r'\s+([*|&]+)\s*(\w+)')
-    pat=re.compile(r' \s* ([*|&]+) \s* (\w+)',re.VERBOSE)
-    buf=pat.sub(r'\1 \2', buf)
-    pat=re.compile(r'\s+ (\w+) \[ \s* \]',re.VERBOSE)
-    buf=pat.sub(r'[] \1', buf)
+    #pat = re.compile(r'\s+([*|&]+)\s*(\w+)')
+    pat = re.compile(r' \s* ([*|&]+) \s* (\w+)', re.VERBOSE)
+    buf = pat.sub(r'\1 \2', buf)
+    pat = re.compile(r'\s+ (\w+) \[ \s* \]', re.VERBOSE)
+    buf = pat.sub(r'[] \1', buf)
 
     # make return types that are const work.
     buf = string.replace(buf, 'G_CONST_RETURN ', 'const-')
@@ -312,165 +253,244 @@ proto_pat=re.compile(r"""
 (?P<ret>(-|\w|\&|\*)+\s*)  # return type
 \s+                   # skip whitespace
 (?P<func>\w+)\s*[(]   # match the function name until the opening (
-\s*(?P<args>.*?)[)]     # group the function arguments
+\s*(?P<args>.*?)\s*[)]     # group the function arguments
 """, re.IGNORECASE|re.VERBOSE)
 #"""
 arg_split_pat = re.compile("\s*,\s*")
 
-def define_func(buf,fp, prefix):
-    buf=clean_func(buf)
-    buf=string.split(buf,'\n')
-    for p in buf:
-        if len(p)==0: continue
-        m=proto_pat.match(p)
-        if m==None:
-            if verbose:
-                sys.stderr.write('No match:|%s|\n'%p)
-            continue
-        func = m.group('func')
-        if func[0] == '_':
-            continue
-        ret = m.group('ret')
-        args=m.group('args')
-        args=arg_split_pat.split(args)
-        for i in range(len(args)):
-            spaces = string.count(args[i], ' ')
-            if spaces > 1:
-                args[i] = string.replace(args[i], ' ', '-', spaces - 1)
-                
-        write_func(fp, func, ret, args, prefix)
-
 get_type_pat = re.compile(r'(const-)?([A-Za-z0-9]+)\*?\s+')
 pointer_pat = re.compile('.*\*$')
 func_new_pat = re.compile('(\w+)_new$')
 
-def write_func(fp, name, ret, args, prefix):
-    if len(args) >= 1:
-        # methods must have at least one argument
-        munged_name = string.replace(name, '_', '')
-        m = get_type_pat.match(args[0])
-        if m:
-            obj = m.group(2)
-            if munged_name[:len(obj)] == string.lower(obj):
-                regex = string.join(map(lambda x: x+'_?',string.lower(obj)),'')
-                mname = re.sub(regex, '', name, 1)
-                if prefix:
-                    l = len(prefix) + 1
-                    if mname[:l] == prefix and mname[l+1] == '_':
-                        mname = mname[l+1:]
-                fp.write('(define-method ' + mname + '\n')
-                fp.write('  (of-object "' + obj + '")\n')
-                fp.write('  (c-name "' + name + '")\n')
-                if ret != 'void':
-                    fp.write('  (return-type "' + ret + '")\n')
-                else:
-                    fp.write('  (return-type "none")\n')
-                is_varargs = 0
-                has_args = len(args) > 1
-                for arg in args[1:]:
-                    if arg == '...':
-                        is_varargs = 1
-                    elif arg in ('void', 'void '):
-                        has_args = 0
-                if has_args:
-                    fp.write('  (parameters\n')
-                    for arg in args[1:]:
-                        if arg != '...':
-                            tupleArg = tuple(string.split(arg))
-                            if len(tupleArg) == 2:
-                                fp.write('    \'("%s" "%s")\n' % tupleArg)
-                    fp.write('  )\n')
-                if is_varargs:
-                    fp.write('  (varargs #t)\n')
-                fp.write(')\n\n')
-                return
-    if prefix:
-        l = len(prefix)
-        if name[:l] == prefix and name[l] == '_':
-            fname = name[l+1:]
+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
+            m = proto_pat.match(p)
+            if m == None:
+                if self.verbose:
+                    sys.stderr.write('No match:|%s|\n' % p)
+                continue
+            func = m.group('func')
+            if func[0] == '_':
+                continue
+            if filter:
+                if func in filter:
+                    continue
+            ret = m.group('ret')
+            args = m.group('args')
+            args = arg_split_pat.split(args)
+            for i in range(len(args)):
+                spaces = string.count(args[i], ' ')
+                if spaces > 1:
+                    args[i] = string.replace(args[i], ' ', '-', spaces - 1)
+
+            self._write_func(func, ret, args)
+
+    def _write_func(self, name, ret, args):
+        if len(args) >= 1:
+            # methods must have at least one argument
+            munged_name = name.replace('_', '')
+            m = get_type_pat.match(args[0])
+            if m:
+                obj = m.group(2)
+                if munged_name[:len(obj)] == obj.lower():
+                    self._write_method(obj, name, ret, args)
+                    return
+
+        if self.prefix:
+            l = len(self.prefix)
+            if name[:l] == self.prefix and name[l] == '_':
+                fname = name[l+1:]
+            else:
+                fname = name
         else:
             fname = name
-    else:
-        fname = name
-    # it is either a constructor or normal function
-    fp.write('(define-function ' + fname + '\n')
-    fp.write('  (c-name "' + name + '")\n')
-
-    # Hmmm... Let's asume that a constructor function name
-    # 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 != '':
-           fp.write('  (is-constructor-of "' + cname + '")\n')
-
-    if ret != 'void':
-        fp.write('  (return-type "' + ret + '")\n')
-    else:
-        fp.write('  (return-type "none")\n')
-    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:
-        fp.write('  (parameters\n')
-        for arg in args:
-            if arg != '...':
-                tupleArg = tuple(string.split(arg))
-                if len(tupleArg) == 2:
-                    fp.write('    \'("%s" "%s")\n' % tupleArg)
-        fp.write('  )\n')
-    if is_varargs:
-        fp.write('  (varargs #t)\n')
-    fp.write(')\n\n')
-
-def write_def(input,output=None, prefix=None):
-    fp = open(input)
-    buf = fp.read()
-    fp.close()
-
-    if type(output) == types.StringType:
-        fp = open(output,'w')
-    elif type(output) == types.FileType:
-        fp = output
-    else:
-        fp = sys.stdout
 
-    fp.write('\n;; From %s\n\n' % input)
-    buf = define_func(buf, fp, prefix)
-    fp.write('\n')
+        # 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:
+                        self.fp.write('    \'("%s" "%s")\n' % tupleArg)
+            self.fp.write('  )\n')
+        if is_varargs:
+            self.fp.write('  (varargs #t)\n')
+        self.fp.write(')\n\n')
 
 # ------------------ Main function -----------------
 
-verbose=0
 def main(args):
-    import getopt
-    global verbose
-
-    onlyenums = 0
-    onlyobjdefs = 0
-    separate = 0
+    verbose = False
+    onlyenums = False
+    onlyobjdefs = False
+    separate = False
     modulename = None
-    opts, args = getopt.getopt(args[1:], 'vs:m:',
+    defsfilter = None
+    opts, args = getopt.getopt(args[1:], 'vs:m:f:',
                                ['onlyenums', 'onlyobjdefs',
-                                'modulename=', 'separate='])
+                                'modulename=', 'separate=',
+                                'defsfilter='])
     for o, v in opts:
         if o == '-v':
-            verbose = 1
+            verbose = True
         if o == '--onlyenums':
-            onlyenums = 1
+            onlyenums = True
         if o == '--onlyobjdefs':
-            onlyobjdefs = 1
+            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
@@ -485,29 +505,32 @@ def main(args):
     objdefs = sort_obj_defs(objdefs)
 
     if separate:
-        types = file(separate + '-types.defs', 'w')
         methods = file(separate + '.defs', 'w')
-        
-        write_obj_defs(objdefs,types)
-        write_enum_defs(enums,types)
-        types.close()
+        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:
-            write_def(filename,methods,prefix=modulename)
-        methods.close()
+            dw.write_def(filename)
         print "Wrote %s.defs" % separate
     else:
+        dw = DefsWriter(prefix=modulename, verbose=verbose,
+                        defsfilter=defsfilter)
+
         if onlyenums:
-            write_enum_defs(enums,None)
+            dw.write_enum_defs(enums)
         elif onlyobjdefs:
-            write_obj_defs(objdefs,None)
+            dw.write_obj_defs(objdefs)
         else:
-            write_obj_defs(objdefs,None)
-            write_enum_defs(enums,None)
+            dw.write_obj_defs(objdefs)
+            dw.write_enum_defs(enums)
 
             for filename in args:
-                write_def(filename,None,prefix=modulename)
-            
+                dw.write_def(filename)
+
 if __name__ == '__main__':
     sys.exit(main(sys.argv))
index 3e92f9c..773e499 100755 (executable)
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
 # -*- Mode: Python; py-indent-offset: 4 -*-
 
-import sys
+import optparse
+
 import defsparser
-from optparse import OptionParser
 
-parser = OptionParser(usage="usage: %prog [options] generated-defs old-defs")
+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)
diff --git a/codegen/missingdefs.py b/codegen/missingdefs.py
deleted file mode 100755 (executable)
index f0017e7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: Python; py-indent-offset: 4 -*-
-
-import sys
-import defsparser
-
-if len(sys.argv) < 3:
-    sys.stderr.write("Usage: missingdefs.py generated-defs old-defs\n")
-    sys.exit(1)
-
-newp = defsparser.DefsParser(sys.argv[1])
-oldp = defsparser.DefsParser(sys.argv[2])
-
-newp.startParsing()
-oldp.startParsing()
-
-newp.printMissing(oldp)
index 2a1e1c3..61f520b 100755 (executable)
@@ -52,11 +52,11 @@ override_template = \
 
 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
+        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):
@@ -69,21 +69,21 @@ def write_skels(fileprefix, prefix, module):
 
 if __name__ == '__main__':
     opts, args = getopt.getopt(sys.argv[1:], 'f:p:m:h',
-                              ['file-prefix=', 'prefix=', 'module=', 'help'])
+                               ['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 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)
+        print 'usage: mkskel.py -f fileprefix -p prefix -m module'
+        sys.exit(1)
     write_skels(fileprefix, prefix, module)
index 5b59632..4940876 100644 (file)
@@ -18,27 +18,32 @@ def class2cname(klass, method):
         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, path=[]):
         self.modulename = None
-       self.ignores = {}
-       self.glob_ignores = []
+        self.ignores = {}
+        self.glob_ignores = []
         self.type_ignores = {}
-       self.overrides = {}
+        self.overrides = {}
         self.overridden = {}
-       self.kwargs = {}
+        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.path = path
        if filename:
             self.handle_file(filename)
@@ -61,8 +66,8 @@ class Overrides:
 
         if dirname != oldpath:
             os.chdir(dirname)
-            
-       # read all the components of the file ...
+
+        # read all the components of the file ...
         bufs = []
         startline = 1
         lines = []
@@ -80,36 +85,36 @@ class Overrides:
             linenum = linenum + 1
         if lines:
             bufs.append((string.join(lines, ''), startline))
-       if not bufs: return
+        if not bufs: return
 
-       for buf, startline in bufs:
-           self.__parse_override(buf, startline, filename)
+        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)
+        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
+        if (command == 'ignore' or
             command == 'ignore-' + sys.platform):
             "ignore/ignore-platform [functions..]"
-           for func in words[1:]:
+            for func in words[1:]:
                 self.ignores[func] = 1
-           for func in string.split(rest):
+            for func in string.split(rest):
                 self.ignores[func] = 1
-       elif (command == 'ignore-glob' or
+        elif (command == 'ignore-glob' or
               command == 'ignore-glob-' + sys.platform):
-            "ignore-glob/ignore-glob-platform [globs..]"            
-           for func in words[1:]:
+            "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)
-           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..]"
@@ -117,14 +122,23 @@ class Overrides:
                 self.type_ignores[typename] = 1
             for typename in string.split(rest):
                 self.type_ignores[typename] = 1
-       elif command == 'override':
-            "override function/method [kwargs,noargs]"
-           func = words[1]
-           if 'kwargs' in words[1:]:
-               self.kwargs[func] = 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
-           self.overrides[func] = rest
+                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"
@@ -140,6 +154,10 @@ class Overrides:
             "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' % \
@@ -149,9 +167,9 @@ class Overrides:
             self.modulename = words[1]
         elif command == 'include':
             "include filename"
-           for filename in words[1:]:
+            for filename in words[1:]:
                 self.handle_file(filename)
-           for filename in string.split(rest):
+            for filename in string.split(rest):
                 self.handle_file(filename)
         elif command == 'import':
             "import module1 [\n module2, \n module3 ...]"
@@ -160,9 +178,9 @@ class Overrides:
                 if match:
                     self.imports.append(match.groups())
         elif command == 'define':
-            "define funcname [kwargs,noargs]"
-            "define Class.method [kwargs,noargs]"
-           func = words[1]
+            "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)
@@ -173,30 +191,42 @@ class Overrides:
             else:
                 self.functions[func] = rest
 
-           if 'kwargs' in words[1:]:
-               self.kwargs[func] = 1
+            if 'kwargs' in words[1:]:
+                self.kwargs[func] = 1
             elif 'noargs' in words[1:]:
-               self.noargs[func] = 1
+                self.noargs[func] = 1
+            elif 'onearg' in words[1:]:
+                self.onearg[func] = 1
+
+            if 'staticmethod' in words[1:]:
+                self.staticmethod[func] = True
+            elif 'classmethod' in words[1:]:
+                self.classmethod[func] = True
 
             self.startlines[func] = (startline + 1, filename)
-            
+
+        elif command == 'new-constructor':
+            "new-constructor GType"
+            gtype, = words[1:]
+            self.newstyle_constructors[gtype] = 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
-    
+        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)
-    
+        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]
@@ -207,39 +237,51 @@ class Overrides:
 
     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)
-    
+        return self.kwargs.has_key(name)
+
     def wants_noargs(self, name):
-       return self.noargs.has_key(name)
-    
+        return self.noargs.has_key(name)
+
+    def wants_onearg(self, name):
+        return self.onearg.has_key(name)
+
+    def is_staticmethod(self, name):
+        return self.staticmethod.has_key(name)
+
+    def is_classmethod(self, name):
+        return self.classmethod.has_key(name)
+
     def attr_is_overriden(self, attr):
         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
index 3f0fb4f..f528828 100644 (file)
@@ -2,6 +2,9 @@
 ### Code to generate "Reverse Wrappers", i.e. C->Python wrappers
 ### (C) 2004 Gustavo Carneiro <gjc@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'''
@@ -24,10 +27,10 @@ class CodeSink(object):
         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'''
@@ -75,18 +78,20 @@ class ReverseWrapper(object):
         assert isinstance(cname, str)
 
         self.cname = cname
-        ## function object we will call, or object whose method we will call 
+        ## function object we will call, or object whose method we will call
         self.called_pyobj = None
         ## name of method of self.called_pyobj we will call
-        self.method_name = None 
+        self.method_name = None
         self.is_static = is_static
 
         self.parameters = []
         self.declarations = MemoryCodeSink()
+        self.post_return_code = MemoryCodeSink()
         self.body = MemoryCodeSink()
         self.cleanup_actions = []
         self.pyargv_items = []
         self.pyargv_optional_items = []
+        self.pyret_parse_items = [] # list of (format_spec, parameter)
 
     def set_call_target(self, called_pyobj, method_name=None):
         assert called_pyobj is not None
@@ -111,10 +116,18 @@ class ReverseWrapper(object):
         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 write_code(self, code,
-                 cleanup=None,
-                 failure_expression=None,
-                 failure_cleanup=None):
+                   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
@@ -127,23 +140,39 @@ class ReverseWrapper(object):
                               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.body
         if code is not None:
-            self.body.writeln(code)
+            code_sink.writeln(code)
         if failure_expression is not None:
-            self.body.writeln("if (%s) {" % failure_expression)
-            self.body.indent()
-            self.body.writeln("if (PyErr_Occurred())")
-            self.body.indent()
-            self.body.writeln("PyErr_Print();")
-            self.body.unindent()
+            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:
-                self.body.writeln(failure_cleanup)
+                code_sink.writeln(failure_cleanup)
             for cleanup_action in self.cleanup_actions:
-                self.body.writeln(cleanup_action)
+                code_sink.writeln(cleanup_action)
             self.return_type.write_error_return()
-            self.body.unindent()
-            self.body.writeln("}")
+            code_sink.unindent()
+            code_sink.writeln("}")
         if cleanup is not None:
             self.cleanup_actions.insert(0, cleanup)
 
@@ -151,6 +180,11 @@ class ReverseWrapper(object):
         '''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);")
@@ -201,7 +235,7 @@ class ReverseWrapper(object):
                 argc = None
 
         self.body.writeln()
-        
+
         if py_args != "NULL":
             self.write_code("py_args = PyTuple_New(%s);" % argc,
                             cleanup="Py_DECREF(py_args);")
@@ -227,7 +261,7 @@ class ReverseWrapper(object):
 
         self.body.writeln()
 
-        # call it
+        ## Call the python method
         if self.method_name is None:
             self.write_code("py_retval = PyObject_Call(%s, %s);"
                             % (self.called_pyobj, py_args),
@@ -243,14 +277,44 @@ class ReverseWrapper(object):
                             % (py_args,),
                             cleanup="Py_DECREF(py_retval);",
                             failure_expression="!py_retval")
-        
+
+        ## -- Handle the return value --
+
+        ## we need to check if the return_type object is prepared to cooperate with multiple return values
+        len_before = len(self.pyret_parse_items)
         self.return_type.write_conversion()
+        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 len(self.pyret_parse_items) == 1:
+            ## if retval is one item only, pack it in a tuple so we
+            ## can use PyArg_ParseTuple as usual..
+            self.write_code('py_retval = Py_BuildValue("(N)", py_retval);')
+        if len(self.pyret_parse_items) > 0:
+            ## Parse return values using PyArg_ParseTuple
+            self.write_code(code=None, failure_expression=(
+                '!PyArg_ParseTuple(py_retval, "%s", %s)' % (
+                "".join([format for format, param in self.pyret_parse_items]),
+                ", ".join([param for format, param in self.pyret_parse_items]))))
+
+        if DEBUG_MODE:
+            self.declarations.writeln("/* end declarations */")
         self.declarations.flush_to(sink)
         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':
@@ -325,7 +389,7 @@ class StringParam(Parameter):
 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):
 
@@ -339,15 +403,12 @@ class StringReturn(ReturnType):
         self.wrapper.write_code("return NULL;")
 
     def write_conversion(self):
-        self.wrapper.write_code(
-            code=None,
-            failure_expression="!PyString_Check(py_retval)",
-            failure_cleanup='PyErr_SetString(PyExc_TypeError, "retval should be a string");')
-        self.wrapper.write_code("retval = g_strdup(PyString_AsString(py_retval));")
+        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*'):
-    argtypes.matcher.register_reverse(ctype, StringReturn)
-
+    argtypes.matcher.register_reverse_ret(ctype, StringReturn)
+del ctype
 
 
 class VoidReturn(ReturnType):
@@ -401,6 +462,10 @@ class GObjectReturn(ReturnType):
         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);")
@@ -429,17 +494,35 @@ class IntReturn(ReturnType):
     def write_error_return(self):
         self.wrapper.write_code("return -G_MAXINT;")
     def write_conversion(self):
-        self.wrapper.write_code(
-            code=None,
-            failure_expression="!PyInt_Check(py_retval)",
-            failure_cleanup='PyErr_SetString(PyExc_TypeError, "retval should be an int");')
-        self.wrapper.write_code("retval = PyInt_AsLong(py_retval);")
+        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 ValueError("cannot use int* parameter without direction")
+        if props["direction"] not in ("out", "inout"):
+            raise ValueError("cannot use int* parameter with direction '%s'" % (props["direction"],))
+        Parameter.__init__(self, wrapper, name, **props)
+    def get_c_type(self):
+        return self.props.get('c_type', 'int*')
+    def convert_c2py(self):
+        if self.props["direction"] == "inout":
+            self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
+            self.wrapper.write_code(code=("py_%s = PyInt_FromLong(*%s);" %
+                                          (self.name, self.name)),
+                                    cleanup=("Py_DECREF(py_%s);" % self.name))
+            self.wrapper.add_pyargv_item("py_%s" % self.name)
+        self.wrapper.add_pyret_parse_item("i", self.name)
+for argtype in ('int*', 'gint*'):
+    argtypes.matcher.register_reverse(argtype, IntPtrParam)
+del argtype
 
 
 class GEnumReturn(IntReturn):
@@ -500,10 +583,13 @@ class BooleanReturn(ReturnType):
         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.write_code("retval = PyObject_IsTrue(py_retval)? TRUE : FALSE;")
+        self.wrapper.add_pyret_parse_item("O", "&py_main_retval", prepend=True)
+        self.wrapper.write_code("retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE;",
+                                code_sink=self.wrapper.post_return_code)
 argtypes.matcher.register_reverse_ret("gboolean", BooleanReturn)
 
 class BooleanParam(Parameter):
@@ -528,6 +614,21 @@ class DoubleParam(Parameter):
                                 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 ValueError("cannot use double* parameter without direction")
+        if props["direction"] not in ("out", ): # inout not yet implemented
+            raise ValueError("cannot use double* parameter with direction '%s'" % (props["direction"],))
+        Parameter.__init__(self, wrapper, name, **props)
+    def get_c_type(self):
+        return self.props.get('c_type', 'double*')
+    def convert_c2py(self):
+        self.wrapper.add_pyret_parse_item("d", self.name)
+for argtype in ('double*', 'gdouble*'):
+    argtypes.matcher.register_reverse(argtype, DoublePtrParam)
+del argtype
+
 class DoubleReturn(ReturnType):
     def get_c_type(self):
         return self.props.get('c_type', 'gdouble')
@@ -594,13 +695,13 @@ class GdkRectanglePtrParam(Parameter):
     def convert_c2py(self):
         self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
         self.wrapper.write_code(
-            code=('py_%(name)s = Py_BuildValue("(ffff)", %(name)s->x, %(name)s->y,\n'
-                  '                            %(name)s->width, %(name)s->height);'
-                  % dict(name=self.name)),
+            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 PyGObjectMethodParam(Parameter):
@@ -649,19 +750,22 @@ class CallbackInUserDataParam(Parameter):
 def _test():
     import sys
 
-    wrapper = ReverseWrapper("this_is_the_c_function_name", is_static=True)
-    wrapper.set_return_type(StringReturn(wrapper))
-    wrapper.add_parameter(PyGObjectMethodParam(wrapper, "self", method_name="do_xxx"))
-    wrapper.add_parameter(StringParam(wrapper, "param2", optional=True))
-    wrapper.add_parameter(GObjectParam(wrapper, "param3"))
-    wrapper.generate(FileCodeSink(sys.stderr))
-
-    wrapper = ReverseWrapper("this_a_callback_wrapper")
-    wrapper.set_return_type(VoidReturn(wrapper))
-    wrapper.add_parameter(StringParam(wrapper, "param1", optional=False))
-    wrapper.add_parameter(GObjectParam(wrapper, "param2"))
-    wrapper.add_parameter(CallbackInUserDataParam(wrapper, "data", free_it=True))
-    wrapper.generate(FileCodeSink(sys.stderr))
+    if 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()
index a29dec1..a49e06c 100644 (file)
@@ -74,8 +74,8 @@
   (c-name "gst_bin_new")
   (is-constructor-of "GstBin")
   (return-type "GstElement*")
-  (parameters
-    '("const-gchar*" "name" (null-ok) (default "NULL"))
+  (properties
+    '("name" (argname "name") (optional))
   )
 )
 
   (c-name "gst_index_factory_new")
   (is-constructor-of "GstIndexFactory")
   (return-type "GstIndexFactory*")
-  (parameters
-    '("const-gchar*" "name")
-    '("const-gchar*" "longdesc")
-    '("GType" "type")
+  (properties
+    '("name" (argname "name"))
+    '("longdesc" (argname "longdesc"))
+    '("type" (argname "type"))
   )
 )
 
   (c-name "gst_pad_new")
   (is-constructor-of "GstPad")
   (return-type "GstPad*")
-  (parameters
-    '("const-gchar*" "name")
-    '("GstPadDirection" "direction")
+  (properties
+    '("name" (argname "name"))
+    '("direction" (argname "direction"))
   )
 )
 
   (c-name "gst_pipeline_new")
   (is-constructor-of "GstPipeline")
   (return-type "GstElement*")
-  (parameters
-    '("const-gchar*" "name" (null-ok) (default "NULL"))
+  (properties
+    '("name" (argname "name") (optional))
   )
 )
 
index 9803ffa..da96c98 100644 (file)
@@ -553,6 +553,8 @@ _wrap_gst_registry_get_feature_list_by_plugin (PyGObject *self, PyObject *args,
 }
 
 %%
+new-constructor GST_TYPE_XML
+%%
 override gst_xml_new noargs
 
 extern PyObject * libxml_xmlDocPtrWrap(xmlDocPtr doc);
index 406704a..d6cfc29 100644 (file)
@@ -506,6 +506,8 @@ _wrap_gst_pad_template_get_caps_by_name(PyGObject *self, PyObject *args, PyObjec
     return pyg_boxed_new(GST_TYPE_CAPS, ret, TRUE, TRUE);
 }
 %%
+new-constructor GST_TYPE_PAD
+%%
 override gst_pad_new kwargs
 static int
 _wrap_gst_pad_new(PyGObject *self, PyObject *args, PyObject *kwargs)
@@ -658,7 +660,7 @@ _wrap_gst_pad_template_tp_getattr(PyObject *self, char *attr)
   } else if (IS_ATTR ("caps")) {
     return pyg_boxed_new (GST_TYPE_CAPS, GST_PAD_TEMPLATE_CAPS(templ), TRUE, TRUE);
   }
-  return Py_FindMethod(_PyGstPadTemplate_methods, self, attr);
+  return Py_FindMethod((PyMethodDef*) _PyGstPadTemplate_methods, self, attr);
 }
 %%
 override gst_pad_query_position args
index 1857790..288201f 100644 (file)
@@ -186,8 +186,11 @@ class ConstructorTest(TestCase):
         bin = gst.Bin('myname')
         
     def testBad(self):
-        self.assertRaises(TypeError, gst.Bin, 0)
-        self.assertRaises(TypeError, gst.Bin, gst.Bin())
-
+        # these are now valid. pygobject will take care of converting
+        # the arguments to a string.
+        #self.assertRaises(TypeError, gst.Bin, 0)
+        #self.assertRaises(TypeError, gst.Bin, gst.Bin())
+        pass
+        
 if __name__ == "__main__":
     unittest.main()