summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2006-06-09 10:50:21 +0000
committerEdward Hervey <bilboed@bilboed.com>2006-06-09 10:50:21 +0000
commitbc17f73dcbde88042a175213dfeb98e45afafef3 (patch)
treea8e4e4d8a816b788b3db37771cd1350370518d91
parent6189051361a16f28279ab7d2c8c8ebab71a41a17 (diff)
codegen/: Updated codegenerator to current pygtk one.
Original commit message from CVS: * codegen/Makefile.am: * codegen/argtypes.py: * codegen/codegen.py: * codegen/definitions.py: * codegen/defsconvert.py: * codegen/defsparser.py: * codegen/docextract.py: * codegen/docextract_to_xml.py: * codegen/docgen.py: * codegen/h2def.py: * codegen/mergedefs.py: * codegen/missingdefs.py: * codegen/mkskel.py: * codegen/override.py: * codegen/reversewrapper.py: Updated codegenerator to current pygtk one. * gst/gst.defs: * gst/gst.override: * gst/gstpad.override: Update defs for new constructor definition. * testsuite/test_bin.py: With new constructors, pygobject will try to convert the argument to the proper GType (here a string).
-rw-r--r--ChangeLog26
-rw-r--r--codegen/Makefile.am3
-rw-r--r--codegen/argtypes.py510
-rw-r--r--codegen/codegen.py1112
-rw-r--r--codegen/definitions.py468
-rw-r--r--codegen/defsconvert.py135
-rw-r--r--codegen/defsparser.py63
-rw-r--r--codegen/docextract.py162
-rwxr-xr-xcodegen/docextract_to_xml.py78
-rw-r--r--codegen/docgen.py69
-rwxr-xr-xcodegen/h2def.py505
-rwxr-xr-xcodegen/mergedefs.py7
-rwxr-xr-xcodegen/missingdefs.py17
-rwxr-xr-xcodegen/mkskel.py34
-rw-r--r--codegen/override.py172
-rw-r--r--codegen/reversewrapper.py206
-rw-r--r--gst/gst.defs22
-rw-r--r--gst/gst.override2
-rw-r--r--gst/gstpad.override4
-rw-r--r--testsuite/test_bin.py9
20 files changed, 1962 insertions, 1642 deletions
diff --git a/ChangeLog b/ChangeLog
index 7fce9d3..f769379 100644
--- 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:
diff --git a/codegen/Makefile.am b/codegen/Makefile.am
index 45d232f..dd3eea0 100644
--- a/codegen/Makefile.am
+++ b/codegen/Makefile.am
@@ -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 \
diff --git a/codegen/argtypes.py b/codegen/argtypes.py
index 6fd445c..300400f 100644
--- a/codegen/argtypes.py
+++ b/codegen/argtypes.py
@@ -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)
diff --git a/codegen/codegen.py b/codegen/codegen.py
index 7cc5bb4..dd8ac80 100644
--- a/codegen/codegen.py
+++ b/codegen/codegen.py
@@ -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))
diff --git a/codegen/definitions.py b/codegen/definitions.py
index c5c06c2..911c8dd 100644
--- a/codegen/definitions.py
+++ b/codegen/definitions.py
@@ -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
index c25dcfb..0000000
--- a/codegen/defsconvert.py
+++ /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()
diff --git a/codegen/defsparser.py b/codegen/defsparser.py
index 9f58f1a..e24a969 100644
--- a/codegen/defsparser.py
+++ b/codegen/defsparser.py
@@ -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)
diff --git a/codegen/docextract.py b/codegen/docextract.py
index 1de4567..e6c6505 100644
--- a/codegen/docextract.py
+++ b/codegen/docextract.py
@@ -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
index 38d6722..0000000
--- a/codegen/docextract_to_xml.py
+++ /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>"
-
-
diff --git a/codegen/docgen.py b/codegen/docgen.py
index 5c7cde7..6905a14 100644
--- a/codegen/docgen.py
+++ b/codegen/docgen.py
@@ -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()
diff --git a/codegen/h2def.py b/codegen/h2def.py
index 517ed5c..d4b2135 100755
--- a/codegen/h2def.py
+++ b/codegen/h2def.py
@@ -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))
diff --git a/codegen/mergedefs.py b/codegen/mergedefs.py
index 3e92f9c..773e499 100755
--- a/codegen/mergedefs.py
+++ b/codegen/mergedefs.py
@@ -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
index f0017e7..0000000
--- a/codegen/missingdefs.py
+++ /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)
diff --git a/codegen/mkskel.py b/codegen/mkskel.py
index 2a1e1c3..61f520b 100755
--- a/codegen/mkskel.py
+++ b/codegen/mkskel.py
@@ -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)
diff --git a/codegen/override.py b/codegen/override.py
index 5b59632..4940876 100644
--- a/codegen/override.py
+++ b/codegen/override.py
@@ -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
diff --git a/codegen/reversewrapper.py b/codegen/reversewrapper.py
index 3f0fb4f..f528828 100644
--- a/codegen/reversewrapper.py
+++ b/codegen/reversewrapper.py
@@ -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()
diff --git a/gst/gst.defs b/gst/gst.defs
index a29dec1..a49e06c 100644
--- a/gst/gst.defs
+++ b/gst/gst.defs
@@ -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))
)
)
@@ -2342,10 +2342,10 @@
(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"))
)
)
@@ -3324,9 +3324,9 @@
(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"))
)
)
@@ -4043,8 +4043,8 @@
(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))
)
)
diff --git a/gst/gst.override b/gst/gst.override
index 9803ffa..da96c98 100644
--- a/gst/gst.override
+++ b/gst/gst.override
@@ -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);
diff --git a/gst/gstpad.override b/gst/gstpad.override
index 406704a..d6cfc29 100644
--- a/gst/gstpad.override
+++ b/gst/gstpad.override
@@ -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
diff --git a/testsuite/test_bin.py b/testsuite/test_bin.py
index 1857790..288201f 100644
--- a/testsuite/test_bin.py
+++ b/testsuite/test_bin.py
@@ -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()