Updated codegen to pygtk-2.8

master
Yevgen Muntyan 2006-04-29 11:10:57 -05:00
parent b617905ed7
commit b934ad8c18
11 changed files with 281 additions and 72 deletions

View File

@ -1,3 +1,37 @@
##############################################################################
# _MOO_AC_PYGTK_CODEGEN
#
AC_DEFUN([_MOO_AC_PYGTK_CODEGEN],[
AC_ARG_WITH([custom-codegen], AC_HELP_STRING([--with-custom-codegen], [whether to use custom copy of pygtk codegen (default = autodetect)]),[
if test x$with_custom_codegen = "xno"; then
MOO_USE_CUSTOM_CODEGEN="no"
AC_MSG_NOTICE([using installed codegen])
else
MOO_USE_CUSTOM_CODEGEN="yes"
AC_MSG_NOTICE([using patched codegen])
fi
],[
if $PKG_CONFIG "pygtk-2.0 >= 2.8"; then
AC_MSG_NOTICE([pygtk >= 2.8, using patched codegen])
MOO_USE_CUSTOM_CODEGEN=yes
else
AC_MSG_NOTICE([pygtk < 2.8, using installed codegen])
MOO_USE_CUSTOM_CODEGEN=no
fi
])
PYGTK_CODEGEN_DIR=`$PKG_CONFIG --variable=codegendir pygtk-2.0`
AC_SUBST(PYGTK_CODEGEN_DIR)
if test x$MOO_USE_CUSTOM_CODEGEN != xyes; then
AC_MSG_NOTICE([pygtk codegen dir: $PYGTK_CODEGEN_DIR])
fi
AM_CONDITIONAL(MOO_USE_CUSTOM_CODEGEN, test x$MOO_USE_CUSTOM_CODEGEN = "xyes")
])
############################################################################## ##############################################################################
# _MOO_AC_CHECK_PYGTK_MINGW(version,action-if-found,action-if-not-found) # _MOO_AC_CHECK_PYGTK_MINGW(version,action-if-found,action-if-not-found)
# checks pygtk stuff for mingw, it's broken # checks pygtk stuff for mingw, it's broken
@ -35,8 +69,11 @@ AC_DEFUN([_MOO_AC_CHECK_PYGTK_MINGW],[
AC_SUBST(PYGTK_CFLAGS) AC_SUBST(PYGTK_CFLAGS)
PYGTK_DEFS_DIR=$PYTHON_PREFIX/share/pygtk/2.0/defs PYGTK_DEFS_DIR=$PYTHON_PREFIX/share/pygtk/2.0/defs
AC_SUBST(PYGTK_DEFS_DIR) AC_SUBST(PYGTK_DEFS_DIR)
PYGTK_CODEGEN_DIR=`$PKG_CONFIG --variable=codegendir pygtk-2.0`
AC_SUBST(PYGTK_CODEGEN_DIR)
AC_MSG_NOTICE([pygtk defs dir: $PYGTK_DEFS_DIR]) AC_MSG_NOTICE([pygtk defs dir: $PYGTK_DEFS_DIR])
$2 $2
_MOO_AC_PYGTK_CODEGEN
],[ ],[
AC_MSG_RESULT([not found]) AC_MSG_RESULT([not found])
$3 $3
@ -76,6 +113,7 @@ AC_DEFUN([_MOO_AC_CHECK_PYGTK_UNIX],[
PYGTK_DEFS_DIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0` PYGTK_DEFS_DIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
AC_SUBST(PYGTK_DEFS_DIR) AC_SUBST(PYGTK_DEFS_DIR)
AC_MSG_NOTICE([pygtk defs dir: $PYGTK_DEFS_DIR]) AC_MSG_NOTICE([pygtk defs dir: $PYGTK_DEFS_DIR])
_MOO_AC_PYGTK_CODEGEN
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
$3 $3

View File

@ -802,7 +802,7 @@ moo_edit_action_class_init (MooEditActionClass *klass)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (MooEditActionClass, check_state), G_STRUCT_OFFSET (MooEditActionClass, check_state),
g_signal_accumulator_true_handled, NULL, g_signal_accumulator_true_handled, NULL,
_moo_marshal_VOID__VOID, _moo_marshal_BOOLEAN__VOID,
G_TYPE_BOOLEAN, 0); G_TYPE_BOOLEAN, 0);
} }

View File

@ -199,16 +199,36 @@ class IntArg(ArgType):
info.codeafter.append(' return PyInt_FromLong(ret);') info.codeafter.append(' return PyInt_FromLong(ret);')
class UIntArg(ArgType): class UIntArg(ArgType):
dflt = (' if (py_%(name)s) {\n'
' if (PyLong_Check(py_%(name)s))\n'
' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
' else if (PyInt_Check(py_%(name)s))\n'
' %(name)s = PyInt_AsLong(py_%(name)s);\n'
' else\n'
' PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
' if (PyErr_Occurred())\n'
' return NULL;\n'
' }\n')
before = (' if (PyLong_Check(py_%(name)s))\n'
' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
' else if (PyInt_Check(py_%(name)s))\n'
' %(name)s = PyInt_AsLong(py_%(name)s);\n'
' else\n'
' PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
' if (PyErr_Occurred())\n'
' return NULL;\n')
def write_param(self, ptype, pname, pdflt, pnull, info): def write_param(self, ptype, pname, pdflt, pnull, info):
if pdflt: if not pdflt:
info.varlist.add(ptype, pname + ' = ' + pdflt) pdflt = '0';
else:
info.varlist.add(ptype, pname) info.varlist.add(ptype, pname + ' = ' + pdflt)
info.arglist.append(pname) info.codebefore.append(self.dflt % {'name':pname})
info.add_parselist('I', ['&' + pname], [pname]) info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
info.arglist.append(pname)
info.add_parselist('O', ['&py_' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add(ptype, 'ret') info.varlist.add(ptype, 'ret')
info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n') info.codeafter.append(' return PyLong_FromUnsignedLong(ret);')
class SizeArg(ArgType): class SizeArg(ArgType):
@ -288,22 +308,30 @@ class TimeTArg(ArgType):
info.codeafter.append(' return PyInt_FromLong(ret);') info.codeafter.append(' return PyInt_FromLong(ret);')
class ULongArg(ArgType): class ULongArg(ArgType):
dflt = ' if (py_%(name)s)\n' \
' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
before = ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
def write_param(self, ptype, pname, pdflt, pnull, info): def write_param(self, ptype, pname, pdflt, pnull, info):
if pdflt: if pdflt:
info.varlist.add('gulong', pname + ' = ' + pdflt) info.varlist.add('unsigned long', pname + ' = ' + pdflt)
info.codebefore.append(self.dflt % {'name':pname}) else:
else: info.varlist.add('unsigned long', pname)
info.varlist.add('gulong', pname) info.arglist.append(pname)
info.codebefore.append(self.before % {'name':pname}) info.add_parselist('k', ['&' + pname], [pname])
info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
info.arglist.append(pname)
info.add_parselist('O!', ['&PyLong_Type', '&py_' + pname], [pname])
def write_return(self, ptype, ownsreturn, info): def write_return(self, ptype, ownsreturn, info):
info.varlist.add('gulong', 'ret') info.varlist.add(ptype, 'ret')
info.codeafter.append(' return PyLong_FromUnsignedLong(ret);') info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n')
class UInt32Arg(ULongArg):
def write_param(self, ptype, pname, pdflt, pnull, info):
ULongArg.write_param(self, ptype, pname, pdflt, pnull, info)
## if sizeof(unsigned long) > sizeof(unsigned int), we need to
## check the value is within guint32 range
if struct.calcsize('L') > struct.calcsize('I'):
info.codebefore.append((
' if (%(pname)s > G_MAXUINT32) {\n'
' PyErr_SetString(PyExc_ValueError,\n'
' "Value out of range in conversion of"\n'
' " %(pname)s parameter to unsigned 32 bit integer");\n'
' return NULL;\n'
' }\n') % vars())
class Int64Arg(ArgType): class Int64Arg(ArgType):
def write_param(self, ptype, pname, pdflt, pnull, info): def write_param(self, ptype, pname, pdflt, pnull, info):
@ -555,7 +583,7 @@ class BoxedArg(ArgType):
info.varlist.add('const ' + self.typename, '*ret') info.varlist.add('const ' + self.typename, '*ret')
else: else:
info.varlist.add(self.typename, '*ret') info.varlist.add(self.typename, '*ret')
ret = 'ret' ret = 'ret'
else: else:
info.varlist.add(self.typename, 'ret') info.varlist.add(self.typename, 'ret')
ret = '&ret' ret = '&ret'
@ -786,6 +814,20 @@ class PyObjectArg(ArgType):
' Py_INCREF(ret);\n' ' Py_INCREF(ret);\n'
' return ret;') ' return ret;')
class CairoArg(ArgType):
def write_param(self, ptype, pname, pdflt, pnull, info):
info.varlist.add('PycairoContext', '*' + pname)
info.add_parselist('O!', ['&PycairoContext_Type', '&' + pname], [pname])
info.arglist.append('%s->ctx' % pname)
def write_return(self, ptype, ownsreturn, info):
info.varlist.add("cairo_t", "*ret")
if ownsreturn:
info.codeafter.append(' return PycairoContext_FromContext(ret, NULL, NULL);')
else:
info.codeafter.append(' cairo_reference(ret);\n'
' return PycairoContext_FromContext(ret, NULL, NULL);')
class ArgMatcher: class ArgMatcher:
def __init__(self): def __init__(self):
self.argtypes = {} self.argtypes = {}
@ -937,13 +979,7 @@ matcher.register('gboolean', arg)
arg = TimeTArg() arg = TimeTArg()
matcher.register('time_t', arg) matcher.register('time_t', arg)
# If the system maxint is smaller than unsigned int, we need to use matcher.register('guint32', UInt32Arg())
# Long objects with PyLong_AsUnsignedLong
if sys.maxint >= (1L << 32):
matcher.register('guint32', arg)
else:
arg = ULongArg()
matcher.register('guint32', arg)
arg = ULongArg() arg = ULongArg()
matcher.register('gulong', arg) matcher.register('gulong', arg)
@ -984,3 +1020,5 @@ matcher.register('GdkNativeWindow', ULongArg())
matcher.register_object('GObject', None, 'G_TYPE_OBJECT') matcher.register_object('GObject', None, 'G_TYPE_OBJECT')
del arg del arg
matcher.register('cairo_t*', CairoArg())

View File

@ -340,6 +340,8 @@ class Wrapper:
if self.overrides.is_overriden(funcname): if self.overrides.is_overriden(funcname):
data = self.overrides.override(funcname) data = self.overrides.override(funcname)
self.write_function(funcname, data) self.write_function(funcname, data)
self.objinfo.has_new_constructor_api = (
self.objinfo.typecode in self.overrides.newstyle_constructors)
else: else:
# ok, a hack to determine if we should use new-style constructores :P # 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 getattr(self, 'write_property_based_constructor', None) is not None:
@ -379,11 +381,18 @@ class Wrapper:
def get_methflags(self, funcname): def get_methflags(self, funcname):
if self.overrides.wants_kwargs(funcname): if self.overrides.wants_kwargs(funcname):
return 'METH_VARARGS|METH_KEYWORDS' flags = 'METH_VARARGS|METH_KEYWORDS'
elif self.overrides.wants_noargs(funcname): elif self.overrides.wants_noargs(funcname):
return 'METH_NOARGS' flags = 'METH_NOARGS'
elif self.overrides.wants_onearg(funcname):
flags = 'METH_O'
else: 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): def write_function(self, funcname, data):
lineno, filename = self.overrides.getstartline(funcname) lineno, filename = self.overrides.getstartline(funcname)
@ -563,6 +572,7 @@ class Wrapper:
self.fp.write(' PyObject *o;\n') self.fp.write(' PyObject *o;\n')
self.fp.write( 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()) % vars())
for name, cname in virtuals: for name, cname in virtuals:
@ -572,8 +582,9 @@ class Wrapper:
'is currently not supported */\n' % vars()) 'is currently not supported */\n' % vars())
else: else:
self.fp.write(''' self.fp.write('''
if ((o = PyDict_GetItemString(pyclass->tp_dict, (char*)"%(do_name)s")) if ((o = PyDict_GetItemString(pyclass->tp_dict, "%(do_name)s"))
&& !PyObject_TypeCheck(o, &PyCFunction_Type)) && !PyObject_TypeCheck(o, &PyCFunction_Type)
&& !(gsignals && PyDict_GetItemString(gsignals, "%(name)s")))
klass->%(name)s = %(cname)s;\n''' % vars()) klass->%(name)s = %(cname)s;\n''' % vars())
self.fp.write(' return 0;\n}\n') self.fp.write(' return 0;\n}\n')
@ -587,7 +598,8 @@ class Wrapper:
if not self.objinfo.fields: if not self.objinfo.fields:
return '0' return '0'
getsets = [] getsets = []
for ftype, fname in self.objinfo.fields: for ftype, cfname in self.objinfo.fields:
fname = cfname.replace('.', '_')
gettername = '0' gettername = '0'
settername = '0' settername = '0'
attrname = self.objinfo.c_name + '.' + fname attrname = self.objinfo.c_name + '.' + fname
@ -608,7 +620,7 @@ class Wrapper:
self.fp.write(self.getter_tmpl % self.fp.write(self.getter_tmpl %
{ 'funcname': funcname, { 'funcname': funcname,
'varlist': info.varlist, 'varlist': info.varlist,
'field': self.get_field_accessor(fname), 'field': self.get_field_accessor(cfname),
'codeafter': info.get_codeafter() }) 'codeafter': info.get_codeafter() })
gettername = funcname gettername = funcname
except: except:
@ -741,14 +753,25 @@ class GObjectWrapper(Wrapper):
return substdict return substdict
def write_default_constructor(self): 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' return '0'
def write_property_based_constructor(self, constructor): def write_property_based_constructor(self, constructor):
self.objinfo.has_new_constructor_api = True
out = self.fp out = self.fp
print >> out, "static int" 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 ' PyObject *kwargs)\n{' % constructor.c_name
print >> out, " GType obj_type = pyg_type_from_object((PyObject *) self);" if constructor.params:
print >> out, " GType obj_type = pyg_type_from_object((PyObject *) self);"
def py_str_list_to_c(arg): def py_str_list_to_c(arg):
if arg: if arg:
@ -794,7 +817,7 @@ class GObjectWrapper(Wrapper):
print >> out, " if (!pyg_parse_constructor_args(obj_type, arg_names, prop_names," print >> out, " if (!pyg_parse_constructor_args(obj_type, arg_names, prop_names,"
print >> out, " params, &nparams, parsed_args))" print >> out, " params, &nparams, parsed_args))"
print >> out, " return -1;" print >> out, " return -1;"
print >> out, " self->obj = g_object_newv(obj_type, nparams, params);" print >> out, " pygobject_constructv(self, nparams, params);\n"
print >> out, " for (i = 0; i < nparams; ++i)" print >> out, " for (i = 0; i < nparams; ++i)"
print >> out, " g_value_unset(&params[i].value);" print >> out, " g_value_unset(&params[i].value);"
else: else:
@ -808,7 +831,7 @@ class GObjectWrapper(Wrapper):
print >> out, ' if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char*)":%s.__init__", kwlist))' % classname print >> out, ' if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char*)":%s.__init__", kwlist))' % classname
print >> out, " return -1;" print >> out, " return -1;"
print >> out print >> out
print >> out, " self->obj = g_object_newv(obj_type, 0, NULL);" print >> out, " pygobject_constructv(self, 0, NULL);\n"
print >> out, \ print >> out, \
' if (!self->obj) {\n' \ ' if (!self->obj) {\n' \
@ -820,7 +843,6 @@ class GObjectWrapper(Wrapper):
print >> out, " g_object_ref(self->obj);\n" print >> out, " g_object_ref(self->obj);\n"
print >> out, \ print >> out, \
' pygobject_register_wrapper((PyObject *)self);\n' \
' return 0;\n' \ ' return 0;\n' \
'}\n\n' % { 'typename': classname } '}\n\n' % { 'typename': classname }
return "_wrap_%s" % constructor.c_name return "_wrap_%s" % constructor.c_name
@ -997,6 +1019,11 @@ def write_headers(data, fp):
fp.resetline() fp.resetline()
fp.write('\n\n') fp.write('\n\n')
def write_body(data, fp):
fp.write(data)
fp.resetline()
fp.write('\n\n')
def write_imports(overrides, fp): def write_imports(overrides, fp):
fp.write('/* ---------- types from other modules ---------- */\n') fp.write('/* ---------- types from other modules ---------- */\n')
for module, pyname, cname in overrides.get_imports(): for module, pyname, cname in overrides.get_imports():
@ -1014,10 +1041,39 @@ def write_type_declarations(parser, fp):
fp.write('PyTypeObject Py' + interface.c_name + '_Type;\n') fp.write('PyTypeObject Py' + interface.c_name + '_Type;\n')
fp.write('\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): 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), for klass, items in ((GBoxedWrapper, parser.boxes),
(GPointerWrapper, parser.pointers), (GPointerWrapper, parser.pointers),
(GObjectWrapper, parser.objects), (GObjectWrapper, objects),
(GInterfaceWrapper, parser.interfaces)): (GInterfaceWrapper, parser.interfaces)):
for item in items: for item in items:
instance = klass(parser, item, overrides, fp) instance = klass(parser, item, overrides, fp)
@ -1116,6 +1172,12 @@ def write_registers(parser, fp):
fp.write(' pygobject_register_class(d, "' + obj.c_name + fp.write(' pygobject_register_class(d, "' + obj.c_name +
'", ' + obj.typecode + ', &Py' + obj.c_name + '", ' + obj.typecode + ', &Py' + obj.c_name +
'_Type, NULL);\n') '_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: if obj.class_init_func is not None:
fp.write(' pyg_register_class_init(%s, %s);\n' % fp.write(' pyg_register_class_init(%s, %s);\n' %
(obj.typecode, obj.class_init_func)) (obj.typecode, obj.class_init_func))
@ -1125,6 +1187,7 @@ def write_source(parser, overrides, prefix, fp=FileOutput(sys.stdout)):
write_headers(overrides.get_headers(), fp) write_headers(overrides.get_headers(), fp)
write_imports(overrides, fp) write_imports(overrides, fp)
write_type_declarations(parser, fp) write_type_declarations(parser, fp)
write_body(overrides.get_body(), fp)
write_classes(parser, overrides, fp) write_classes(parser, overrides, fp)
wrapper = Wrapper(parser, None, overrides, fp) wrapper = Wrapper(parser, None, overrides, fp)

View File

@ -19,7 +19,7 @@ class Parameter(object):
self.pname = pname self.pname = pname
self.pdflt = pdflt self.pdflt = pdflt
self.pnull = pnull self.pnull = pnull
def __len__(self): return 4 def __len__(self): return 4
def __getitem__(self, i): def __getitem__(self, i):
return (self.ptype, self.pname, self.pdflt, self.pnull)[i] return (self.ptype, self.pname, self.pdflt, self.pnull)[i]
@ -77,6 +77,7 @@ class ObjectDef(Definition):
self.fields = [] self.fields = []
self.implements = [] self.implements = []
self.class_init_func = None self.class_init_func = None
self.has_new_constructor_api = False
for arg in get_valid_scheme_definitions(args): for arg in get_valid_scheme_definitions(args):
if arg[0] == 'in-module': if arg[0] == 'in-module':
self.module = arg[1] self.module = arg[1]
@ -103,7 +104,7 @@ class ObjectDef(Definition):
fp.write('(define-object ' + self.name + '\n') fp.write('(define-object ' + self.name + '\n')
if self.module: if self.module:
fp.write(' (in-module "' + self.module + '")\n') fp.write(' (in-module "' + self.module + '")\n')
if self.parent != (None, None): if self.parent != (None, None):
fp.write(' (parent "' + self.parent + '")\n') fp.write(' (parent "' + self.parent + '")\n')
for interface in self.implements: for interface in self.implements:
fp.write(' (implements "' + interface + '")\n') fp.write(' (implements "' + interface + '")\n')
@ -315,7 +316,7 @@ class MethodDefBase(Definition):
elif arg[0] == 'deprecated': elif arg[0] == 'deprecated':
self.deprecated = arg[1] self.deprecated = arg[1]
else: else:
sys.stderr.write("Warning: %s argument unsupported.\n" sys.stderr.write("Warning: %s argument unsupported.\n"
% (arg[0])) % (arg[0]))
dump = 1 dump = 1
if dump: if dump:
@ -323,7 +324,7 @@ class MethodDefBase(Definition):
if self.caller_owns_return is None and self.ret is not None: if self.caller_owns_return is None and self.ret is not None:
self.guess_return_value_ownership() self.guess_return_value_ownership()
def merge(self, old, parmerge): def merge(self, old, parmerge):
self.caller_owns_return = old.caller_owns_return self.caller_owns_return = old.caller_owns_return
self.varargs = old.varargs self.varargs = old.varargs
@ -370,7 +371,7 @@ class MethodDef(MethodDefBase):
if self.__dict__[item] == None: if self.__dict__[item] == None:
self.write_defs(sys.stderr) self.write_defs(sys.stderr)
raise RuntimeError, "definition missing required %s" % (item,) raise RuntimeError, "definition missing required %s" % (item,)
def write_defs(self, fp=sys.stdout): def write_defs(self, fp=sys.stdout):
fp.write('(define-method ' + self.name + '\n') fp.write('(define-method ' + self.name + '\n')
self._write_defs(fp) self._write_defs(fp)
@ -480,7 +481,7 @@ class FunctionDef(Definition):
# parameter names changed and we can't find a match; it's # parameter names changed and we can't find a match; it's
# safer to keep the old parameter list untouched. # safer to keep the old parameter list untouched.
self.params = deepcopy(old.params) self.params = deepcopy(old.params)
if not self.is_constructor_of: if not self.is_constructor_of:
try: try:
self.is_constructor_of = old.is_constructor_of self.is_constructor_of = old.is_constructor_of

View File

@ -30,14 +30,19 @@ class Overrides:
self.overridden = {} self.overridden = {}
self.kwargs = {} self.kwargs = {}
self.noargs = {} self.noargs = {}
self.onearg = {}
self.staticmethod = {}
self.classmethod = {}
self.startlines = {} self.startlines = {}
self.override_attrs = {} self.override_attrs = {}
self.override_slots = {} self.override_slots = {}
self.headers = '' self.headers = ''
self.body = ''
self.init = '' self.init = ''
self.imports = [] self.imports = []
self.defines = {} self.defines = {}
self.functions = {} self.functions = {}
self.newstyle_constructors = {}
if filename: if filename:
self.handle_file(filename) self.handle_file(filename)
@ -99,12 +104,20 @@ class Overrides:
for func in string.split(rest): for func in string.split(rest):
self.glob_ignores.append(func) self.glob_ignores.append(func)
elif command == 'override': elif command == 'override':
"override function/method [kwargs,noargs]" "override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
func = words[1] func = words[1]
if 'kwargs' in words[1:]: if 'kwargs' in words[1:]:
self.kwargs[func] = 1 self.kwargs[func] = 1
elif 'noargs' in words[1:]: elif 'noargs' in words[1:]:
self.noargs[func] = 1 self.noargs[func] = 1
elif 'onearg' in words[1:]:
self.onearg[func] = True
if 'staticmethod' in words[1:]:
self.staticmethod[func] = True
elif 'classmethod' in words[1:]:
self.classmethod[func] = True
self.overrides[func] = rest self.overrides[func] = rest
self.startlines[func] = (startline + 1, filename) self.startlines[func] = (startline + 1, filename)
elif command == 'override-attr': elif command == 'override-attr':
@ -121,6 +134,10 @@ class Overrides:
"headers" "headers"
self.headers = '%s\n#line %d "%s"\n%s' % \ self.headers = '%s\n#line %d "%s"\n%s' % \
(self.headers, startline + 1, filename, rest) (self.headers, startline + 1, filename, rest)
elif command == 'body':
"body"
self.body = '%s\n#line %d "%s"\n%s' % \
(self.body, startline + 1, filename, rest)
elif command == 'init': elif command == 'init':
"init" "init"
self.init = '%s\n#line %d "%s"\n%s' % \ self.init = '%s\n#line %d "%s"\n%s' % \
@ -141,8 +158,8 @@ class Overrides:
if match: if match:
self.imports.append(match.groups()) self.imports.append(match.groups())
elif command == 'define': elif command == 'define':
"define funcname [kwargs,noargs]" "define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
"define Class.method [kwargs,noargs]" "define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
func = words[1] func = words[1]
klass = None klass = None
if func.find('.') != -1: if func.find('.') != -1:
@ -158,8 +175,20 @@ class Overrides:
self.kwargs[func] = 1 self.kwargs[func] = 1
elif 'noargs' in words[1:]: elif 'noargs' in words[1:]:
self.noargs[func] = 1 self.noargs[func] = 1
elif 'onearg' in words[1:]:
self.onearg[func] = 1
if 'staticmethod' in words[1:]:
self.staticmethod[func] = True
elif 'classmethod' in words[1:]:
self.classmethod[func] = True
self.startlines[func] = (startline + 1, filename) self.startlines[func] = (startline + 1, filename)
elif command == 'new-constructor':
"new-constructor GType"
gtype, = words[1:]
self.newstyle_constructors[gtype] = True
def is_ignored(self, name): def is_ignored(self, name):
if self.ignores.has_key(name): if self.ignores.has_key(name):
@ -194,7 +223,16 @@ class Overrides:
def wants_noargs(self, name): def wants_noargs(self, name):
return self.noargs.has_key(name) return self.noargs.has_key(name)
def wants_onearg(self, name):
return self.onearg.has_key(name)
def is_staticmethod(self, name):
return self.staticmethod.has_key(name)
def is_classmethod(self, name):
return self.classmethod.has_key(name)
def attr_is_overriden(self, attr): def attr_is_overriden(self, attr):
return self.override_attrs.has_key(attr) return self.override_attrs.has_key(attr)
@ -209,6 +247,9 @@ class Overrides:
def get_headers(self): def get_headers(self):
return self.headers return self.headers
def get_body(self):
return self.body
def get_init(self): def get_init(self):
return self.init return self.init

View File

@ -112,9 +112,10 @@ class ReverseWrapper(object):
self.pyargv_items.append(variable) self.pyargv_items.append(variable)
def write_code(self, code, def write_code(self, code,
cleanup=None, cleanup=None,
failure_expression=None, failure_expression=None,
failure_cleanup=None): failure_cleanup=None,
failure_exception=None):
'''Add a chunk of code with cleanup and error handling '''Add a chunk of code with cleanup and error handling
This method is to be used by TypeHandlers when generating code This method is to be used by TypeHandlers when generating code
@ -127,16 +128,23 @@ class ReverseWrapper(object):
if anything failed (default None) if anything failed (default None)
failure_cleanup -- code to cleanup any dynamic resources failure_cleanup -- code to cleanup any dynamic resources
created by @code in case of failure (default None) created by @code in case of failure (default None)
failure_exception -- code to raise an exception in case of
failure (which will be immediately
printed and cleared), (default None)
''' '''
if code is not None: if code is not None:
self.body.writeln(code) self.body.writeln(code)
if failure_expression is not None: if failure_expression is not None:
self.body.writeln("if (%s) {" % failure_expression) self.body.writeln("if (%s) {" % failure_expression)
self.body.indent() self.body.indent()
self.body.writeln("if (PyErr_Occurred())") if failure_exception is None:
self.body.indent() self.body.writeln("if (PyErr_Occurred())")
self.body.writeln("PyErr_Print();") self.body.indent()
self.body.unindent() self.body.writeln("PyErr_Print();")
self.body.unindent()
else:
self.body.writeln(failure_exception)
self.body.writeln("PyErr_Print();")
if failure_cleanup is not None: if failure_cleanup is not None:
self.body.writeln(failure_cleanup) self.body.writeln(failure_cleanup)
for cleanup_action in self.cleanup_actions: for cleanup_action in self.cleanup_actions:
@ -401,6 +409,10 @@ class GObjectReturn(ReturnType):
self.wrapper.write_code("return NULL;") self.wrapper.write_code("return NULL;")
def write_conversion(self): def write_conversion(self):
self.wrapper.write_code(
code=None,
failure_expression="!PyObject_TypeCheck(py_retval, &PyGObject_Type)",
failure_exception='PyErr_SetString(PyExc_TypeError, "retval should be a GObject");')
self.wrapper.write_code("retval = (%s) pygobject_get(py_retval);" self.wrapper.write_code("retval = (%s) pygobject_get(py_retval);"
% self.get_c_type()) % self.get_c_type())
self.wrapper.write_code("g_object_ref((GObject *) retval);") self.wrapper.write_code("g_object_ref((GObject *) retval);")
@ -594,13 +606,13 @@ class GdkRectanglePtrParam(Parameter):
def convert_c2py(self): def convert_c2py(self):
self.wrapper.add_declaration("PyObject *py_%s;" % self.name) self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
self.wrapper.write_code( self.wrapper.write_code(
code=('py_%(name)s = Py_BuildValue("(ffff)", %(name)s->x, %(name)s->y,\n' code=('py_%s = pyg_boxed_new(GDK_TYPE_RECTANGLE, %s, TRUE, TRUE);' %
' %(name)s->width, %(name)s->height);' (self.name, self.name)),
% dict(name=self.name)),
cleanup=("Py_DECREF(py_%s);" % self.name)) cleanup=("Py_DECREF(py_%s);" % self.name))
self.wrapper.add_pyargv_item("py_%s" % self.name) self.wrapper.add_pyargv_item("py_%s" % self.name)
argtypes.matcher.register_reverse("GdkRectangle*", GdkRectanglePtrParam) argtypes.matcher.register_reverse("GdkRectangle*", GdkRectanglePtrParam)
argtypes.matcher.register_reverse('GtkAllocation*', GdkRectanglePtrParam)
class PyGObjectMethodParam(Parameter): class PyGObjectMethodParam(Parameter):

View File

@ -1,15 +1,17 @@
import moo import moo
import gobject import gobject
UIInfo = moo.edit.Plugin.UIInfo
PLUGIN_ID = "TestPythonPlugin" PLUGIN_ID = "TestPythonPlugin"
class Action(moo.edit.Action): class Action(moo.edit.Action):
def __init__(self): def __init__(self):
moo.edit.Action.__init__(self) moo.edit.Action.__init__(self)
self.set_property("label", "AnAction")
print "__init__" print "__init__"
def do_check_state(self): def do_check_state(self):
self.set_property("label", "AnAction")
print "check_state" print "check_state"
return True return True
@ -29,7 +31,7 @@ class Plugin(moo.edit.Plugin):
} }
moo.edit.edit_class_add_action(moo.edit.Edit, "AnAction", Action) moo.edit.edit_class_add_action(moo.edit.Edit, "AnAction", Action)
self.ui.append(moo.edit.Plugin.UIInfo("Editor/Popup", "AnAction")) self.ui.append(UIInfo("Editor/Popup", "AnAction"))
def attach_doc(self, doc, window): def attach_doc(self, doc, window):
print "attaching to", doc print "attaching to", doc

View File

@ -87,10 +87,15 @@ if MOO_OS_MINGW
codegen_platform = --platform win32 codegen_platform = --platform win32
endif endif
if MOO_USE_CUSTOM_CODEGEN
codegen = $(PYTHON) $(moopython_srcdir)/codegen/codegen.py $(codegen_platform)
else
codegen = $(PYTHON) $(PYGTK_CODEGEN_DIR)/codegen.py $(codegen_platform)
endif
$(moopygtk)/mooutils-pygtk.c: $(moopygtk)/mooutils-pygtk.defs $(moopygtk)/mooutils-pygtk.override $(mooutils_override_files) $(moopygtk)/mooutils-pygtk.c: $(moopygtk)/mooutils-pygtk.defs $(moopygtk)/mooutils-pygtk.override $(mooutils_override_files)
mkdir -p $(moopygtk) mkdir -p $(moopygtk)
$(PYTHON) $(moopython_srcdir)/codegen/codegen.py \ $(codegen) --prefix _moo_utils \
--prefix _moo_utils $(codegen_platform) \
--register $(PYGTK_DEFS_DIR)/gtk-types.defs \ --register $(PYGTK_DEFS_DIR)/gtk-types.defs \
--register $(PYGTK_DEFS_DIR)/gdk-types.defs \ --register $(PYGTK_DEFS_DIR)/gdk-types.defs \
--override $(moopygtk_srcdir)/mooutils-pygtk.override \ --override $(moopygtk_srcdir)/mooutils-pygtk.override \
@ -99,8 +104,7 @@ $(moopygtk)/mooutils-pygtk.c: $(moopygtk)/mooutils-pygtk.defs $(moopygtk)/moouti
$(moopygtk)/mooterm-pygtk.c: $(moopygtk)/mooterm-pygtk.defs $(moopygtk)/mooterm-pygtk.override $(moopygtk)/mooterm-pygtk.c: $(moopygtk)/mooterm-pygtk.defs $(moopygtk)/mooterm-pygtk.override
mkdir -p $(moopygtk) mkdir -p $(moopygtk)
$(PYTHON) $(moopython_srcdir)/codegen/codegen.py \ $(codegen) --prefix _moo_term \
--prefix _moo_term $(codegen_platform) \
--register $(PYGTK_DEFS_DIR)/gtk-types.defs \ --register $(PYGTK_DEFS_DIR)/gtk-types.defs \
--register $(PYGTK_DEFS_DIR)/gdk-types.defs \ --register $(PYGTK_DEFS_DIR)/gdk-types.defs \
--register $(moopygtk_srcdir)/mooutils-pygtk.defs \ --register $(moopygtk_srcdir)/mooutils-pygtk.defs \
@ -110,8 +114,7 @@ $(moopygtk)/mooterm-pygtk.c: $(moopygtk)/mooterm-pygtk.defs $(moopygtk)/mooterm-
$(moopygtk)/mooedit-pygtk.c: $(moopygtk)/mooedit-pygtk.defs $(moopygtk)/mooedit-pygtk.override $(mooedit_defs_files) $(moopygtk)/mooedit-pygtk.c: $(moopygtk)/mooedit-pygtk.defs $(moopygtk)/mooedit-pygtk.override $(mooedit_defs_files)
mkdir -p $(moopygtk) mkdir -p $(moopygtk)
$(PYTHON) $(moopython_srcdir)/codegen/codegen.py \ $(codegen) --prefix _moo_edit \
--prefix _moo_edit $(codegen_platform) \
--register $(PYGTK_DEFS_DIR)/gtk-types.defs \ --register $(PYGTK_DEFS_DIR)/gtk-types.defs \
--register $(PYGTK_DEFS_DIR)/gdk-types.defs \ --register $(PYGTK_DEFS_DIR)/gdk-types.defs \
--register $(moopygtk_srcdir)/mooutils-pygtk.defs \ --register $(moopygtk_srcdir)/mooutils-pygtk.defs \
@ -121,8 +124,7 @@ $(moopygtk)/mooedit-pygtk.c: $(moopygtk)/mooedit-pygtk.defs $(moopygtk)/mooedit-
$(moopygtk)/mooapp-pygtk.c: $(moopygtk)/mooapp-pygtk.defs $(moopygtk)/mooapp-pygtk.override $(moopygtk)/mooapp-pygtk.c: $(moopygtk)/mooapp-pygtk.defs $(moopygtk)/mooapp-pygtk.override
mkdir -p $(moopygtk) mkdir -p $(moopygtk)
$(PYTHON) $(moopython_srcdir)/codegen/codegen.py \ $(codegen) --prefix _moo_app \
--prefix _moo_app $(codegen_platform) \
--register $(PYGTK_DEFS_DIR)/gtk-types.defs \ --register $(PYGTK_DEFS_DIR)/gtk-types.defs \
--register $(PYGTK_DEFS_DIR)/gdk-types.defs \ --register $(PYGTK_DEFS_DIR)/gdk-types.defs \
--register $(moopygtk_srcdir)/mooedit-pygtk.defs \ --register $(moopygtk_srcdir)/mooedit-pygtk.defs \

View File

@ -1398,6 +1398,12 @@
;; From moo/mooedit/mooedit-actions.h ;; From moo/mooedit/mooedit-actions.h
(define-function moo_edit_action_new
(c-name "moo_edit_action_new")
(is-constructor-of "MooEditAction")
(return-type "MooAction*")
)
(define-function _edit_class_add_action (define-function _edit_class_add_action
(c-name "moo_edit_class_add_action") (c-name "moo_edit_class_add_action")
(return-type "none") (return-type "none")

View File

@ -2194,6 +2194,12 @@
;; From ./ggap/moo/mooutils/mooaction.h ;; From ./ggap/moo/mooutils/mooaction.h
(define-function moo_action_new
(c-name "moo_action_new")
(is-constructor-of "MooAction")
(return-type "MooAction*")
)
(define-method activate (define-method activate
(of-object "MooAction") (of-object "MooAction")
(c-name "moo_action_activate") (c-name "moo_action_activate")