13 class Coverage(object):
14 def __init__(self, name):
19 def declare_wrapped(self):
22 def declare_not_wrapped(self):
26 total = self.wrapped + self.not_wrapped
29 fd.write("***INFO*** The coverage of %s is %.2f%% (%i/%i)\n" %
31 float(self.wrapped*100)/total,
35 fd.write("***INFO*** There are no declared %s." % self.name)
37 functions_coverage = Coverage("global functions")
38 methods_coverage = Coverage("methods")
39 vproxies_coverage = Coverage("virtual proxies")
40 vaccessors_coverage = Coverage("virtual accessors")
41 iproxies_coverage = Coverage("interface proxies")
44 #traceback.print_exc()
45 etype, value, tb = sys.exc_info()
50 ret = "No ArgType for %s" % (sval,)
58 if keyword.iskeyword(name):
63 '''Simple wrapper for file object, that makes writing #line
64 statements easier.''' # "
65 def __init__(self, fp, filename=None):
69 self.filename = filename
71 self.filename = self.fp.name
72 # handle writing to the file, and keep track of the line number ...
75 self.lineno = self.lineno + string.count(str, '\n')
76 def writelines(self, sequence):
84 def setline(self, linenum, filename):
85 '''writes out a #line statement, for use by the C
87 self.write('#line %d "%s"\n' % (linenum, filename))
89 '''resets line numbering to the original file'''
90 self.setline(self.lineno + 1, self.filename)
94 'PyTypeObject Py%(typename)s_Type = {\n'
95 ' PyObject_HEAD_INIT(NULL)\n'
97 ' "%(classname)s", /* tp_name */\n'
98 ' sizeof(%(tp_basicsize)s), /* tp_basicsize */\n'
99 ' 0, /* tp_itemsize */\n'
101 ' (destructor)%(tp_dealloc)s, /* tp_dealloc */\n'
102 ' (printfunc)0, /* tp_print */\n'
103 ' (getattrfunc)%(tp_getattr)s, /* tp_getattr */\n'
104 ' (setattrfunc)%(tp_setattr)s, /* tp_setattr */\n'
105 ' (cmpfunc)%(tp_compare)s, /* tp_compare */\n'
106 ' (reprfunc)%(tp_repr)s, /* tp_repr */\n'
107 ' (PyNumberMethods*)%(tp_as_number)s, /* tp_as_number */\n'
108 ' (PySequenceMethods*)%(tp_as_sequence)s, /* tp_as_sequence */\n'
109 ' (PyMappingMethods*)%(tp_as_mapping)s, /* tp_as_mapping */\n'
110 ' (hashfunc)%(tp_hash)s, /* tp_hash */\n'
111 ' (ternaryfunc)%(tp_call)s, /* tp_call */\n'
112 ' (reprfunc)%(tp_str)s, /* tp_str */\n'
113 ' (getattrofunc)%(tp_getattro)s, /* tp_getattro */\n'
114 ' (setattrofunc)%(tp_setattro)s, /* tp_setattro */\n'
115 ' (PyBufferProcs*)%(tp_as_buffer)s, /* tp_as_buffer */\n'
116 ' %(tp_flags)s, /* tp_flags */\n'
117 ' %(tp_doc)s, /* Documentation string */\n'
118 ' (traverseproc)%(tp_traverse)s, /* tp_traverse */\n'
119 ' (inquiry)%(tp_clear)s, /* tp_clear */\n'
120 ' (richcmpfunc)%(tp_richcompare)s, /* tp_richcompare */\n'
121 ' %(tp_weaklistoffset)s, /* tp_weaklistoffset */\n'
122 ' (getiterfunc)%(tp_iter)s, /* tp_iter */\n'
123 ' (iternextfunc)%(tp_iternext)s, /* tp_iternext */\n'
124 ' (struct PyMethodDef*)%(tp_methods)s, /* tp_methods */\n'
125 ' (struct PyMemberDef*)0, /* tp_members */\n'
126 ' (struct PyGetSetDef*)%(tp_getset)s, /* tp_getset */\n'
127 ' NULL, /* tp_base */\n'
128 ' NULL, /* tp_dict */\n'
129 ' (descrgetfunc)%(tp_descr_get)s, /* tp_descr_get */\n'
130 ' (descrsetfunc)%(tp_descr_set)s, /* tp_descr_set */\n'
131 ' %(tp_dictoffset)s, /* tp_dictoffset */\n'
132 ' (initproc)%(tp_init)s, /* tp_init */\n'
133 ' (allocfunc)%(tp_alloc)s, /* tp_alloc */\n'
134 ' (newfunc)%(tp_new)s, /* tp_new */\n'
135 ' (freefunc)%(tp_free)s, /* tp_free */\n'
136 ' (inquiry)%(tp_is_gc)s /* tp_is_gc */\n'
141 'tp_getattr', 'tp_setattr', 'tp_getattro', 'tp_setattro',
142 'tp_compare', 'tp_repr',
143 'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash',
144 'tp_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
145 'tp_iternext', 'tp_descr_get', 'tp_descr_set', 'tp_init',
146 'tp_alloc', 'tp_new', 'tp_free', 'tp_is_gc',
147 'tp_traverse', 'tp_clear', 'tp_dealloc', 'tp_flags', 'tp_doc'
151 'static PyObject *\n'
152 '%(funcname)s(PyObject *self, void *closure)\n'
155 ' ret = %(field)s;\n'
161 ' if (!PyArg_ParseTupleAndKeywords(args, kwargs,'
162 '"%(typecodes)s:%(name)s"%(parselist)s))\n'
163 ' return %(errorreturn)s;\n'
167 ' if (PyErr_Warn(PyExc_DeprecationWarning, '
168 '"%(deprecationmsg)s") < 0)\n'
169 ' return %(errorreturn)s;\n'
173 ' { "%(name)s", (PyCFunction)%(cname)s, %(flags)s,\n'
174 ' %(docstring)s },\n'
179 'pygobject_no_constructor(PyObject *self, PyObject *args, '
180 'PyObject *kwargs)\n'
184 ' g_snprintf(buf, sizeof(buf), "%s is an abstract widget", '
185 'self->ob_type->tp_name);\n'
186 ' PyErr_SetString(PyExc_NotImplementedError, buf);\n'
192 'static PyObject *\n'
193 '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
198 ' %(begin_allow_threads)s\n'
199 ' %(setreturn)s%(cname)s(%(arglist)s);\n'
200 ' %(end_allow_threads)s\n'
205 virtual_accessor_tmpl = (
206 'static PyObject *\n'
207 '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
213 ' klass = g_type_class_ref(pyg_type_from_object(cls));\n'
214 ' if (%(class_cast_macro)s(klass)->%(virtual)s) {\n'
215 ' pyg_begin_allow_threads;\n'
216 ' %(setreturn)s%(class_cast_macro)s(klass)->'
217 '%(virtual)s(%(arglist)s);\n'
218 ' pyg_end_allow_threads;\n'
220 ' PyErr_SetString(PyExc_NotImplementedError, '
221 '"virtual method %(name)s not implemented");\n'
222 ' g_type_class_unref(klass);\n'
225 ' g_type_class_unref(klass);\n'
230 # template for method calls
231 constructor_tmpl = None
234 def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
236 self.objinfo = objinfo
237 self.overrides = overrides
240 def get_lower_name(self):
241 return string.lower(string.replace(self.objinfo.typecode,
244 def get_field_accessor(self, fieldname):
245 raise NotImplementedError
247 def get_initial_class_substdict(self): return {}
249 def get_initial_constructor_substdict(self, constructor):
250 return { 'name': '%s.__init__' % self.objinfo.c_name,
251 'errorreturn': '-1' }
252 def get_initial_method_substdict(self, method):
253 substdict = { 'name': '%s.%s' % (self.objinfo.c_name, method.name) }
254 substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
255 substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
258 def write_class(self):
259 if self.overrides.is_type_ignored(self.objinfo.c_name):
261 self.fp.write('\n/* ----------- %s ----------- */\n\n' %
263 substdict = self.get_initial_class_substdict()
264 if not substdict.has_key('tp_flags'):
265 substdict['tp_flags'] = 'Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE'
266 substdict['typename'] = self.objinfo.c_name
267 if self.overrides.modulename:
268 substdict['classname'] = '%s.%s' % (self.overrides.modulename,
271 substdict['classname'] = self.objinfo.name
272 substdict['tp_doc'] = self.objinfo.docstring
274 # Maybe this could be done in a nicer way, but I'll leave it as it is
276 if not self.overrides.slot_is_overriden('%s.tp_init' %
277 self.objinfo.c_name):
278 substdict['tp_init'] = self.write_constructor()
279 substdict['tp_methods'] = self.write_methods()
280 substdict['tp_getset'] = self.write_getsets()
283 for slot in self.slots_list:
285 slotname = '%s.%s' % (self.objinfo.c_name, slot)
286 slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
287 if slot[:6] == 'tp_as_':
288 slotfunc = '&' + slotfunc
289 if self.overrides.slot_is_overriden(slotname):
290 data = self.overrides.slot_override(slotname)
291 self.write_function(slotname, data)
292 substdict[slot] = slotfunc
294 if not substdict.has_key(slot):
295 substdict[slot] = '0'
297 self.fp.write(self.type_tmpl % substdict)
299 self.write_virtuals()
301 def write_function_wrapper(self, function_obj, template,
302 handle_return=0, is_method=0, kwargs_needed=0,
304 '''This function is the guts of all functions that generate
305 wrappers for functions, methods and constructors.'''
306 if not substdict: substdict = {}
308 info = argtypes.WrapperInfo()
310 substdict.setdefault('errorreturn', 'NULL')
312 # for methods, we want the leading comma
314 info.arglist.append('')
316 if function_obj.varargs:
317 raise ValueError, "varargs functions not supported"
319 for param in function_obj.params:
320 if param.pdflt and '|' not in info.parsestr:
321 info.add_parselist('|', [], [])
322 handler = argtypes.matcher.get(param.ptype)
323 handler.write_param(param.ptype, param.pname, param.pdflt,
324 param.pnull, param.keeprefcount, info)
326 substdict['setreturn'] = ''
328 if function_obj.ret not in ('none', None):
329 substdict['setreturn'] = 'ret = '
330 handler = argtypes.matcher.get(function_obj.ret)
331 handler.write_return(function_obj.ret,
332 function_obj.caller_owns_return, info)
334 if function_obj.deprecated != None:
335 deprecated = self.deprecated_tmpl % {
336 'deprecationmsg': function_obj.deprecated,
337 'errorreturn': substdict['errorreturn'] }
341 # if name isn't set, set it to function_obj.name
342 substdict.setdefault('name', function_obj.name)
344 substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
345 substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
348 substdict['typename'] = self.objinfo.c_name
349 substdict.setdefault('cname', function_obj.c_name)
350 substdict['varlist'] = info.get_varlist()
351 substdict['typecodes'] = info.parsestr
352 substdict['parselist'] = info.get_parselist()
353 substdict['arglist'] = info.get_arglist()
354 substdict['codebefore'] = deprecated + (
355 string.replace(info.get_codebefore(),
356 'return NULL', 'return ' + substdict['errorreturn'])
358 substdict['codeafter'] = (
359 string.replace(info.get_codeafter(),
361 'return ' + substdict['errorreturn']))
363 if info.parsestr or kwargs_needed:
364 substdict['parseargs'] = self.parse_tmpl % substdict
365 substdict['extraparams'] = ', PyObject *args, PyObject *kwargs'
366 flags = 'METH_VARARGS|METH_KEYWORDS'
368 # prepend the keyword list to the variable list
369 substdict['varlist'] = info.get_kwlist() + substdict['varlist']
371 substdict['parseargs'] = ''
372 substdict['extraparams'] = ''
373 flags = 'METH_NOARGS'
375 return template % substdict, flags
377 def write_constructor(self):
379 constructor = self.parser.find_constructor(self.objinfo,self.overrides)
381 return self.write_default_constructor()
383 funcname = constructor.c_name
385 if self.overrides.is_overriden(funcname):
386 data = self.overrides.override(funcname)
387 self.write_function(funcname, data)
388 self.objinfo.has_new_constructor_api = (
389 self.objinfo.typecode in
390 self.overrides.newstyle_constructors)
392 # ok, a hack to determine if we should use
393 # new-style constructores :P
394 property_based = getattr(self,
395 'write_property_based_constructor',
398 if (len(constructor.params) == 0 or
399 isinstance(constructor.params[0],
400 definitions.Property)):
401 # write_property_based_constructor is only
402 # implemented in GObjectWrapper
403 return self.write_property_based_constructor(
407 "Warning: generating old-style constructor for:" +
408 constructor.c_name + '\n')
410 # write constructor from template ...
411 code = self.write_function_wrapper(constructor,
412 self.constructor_tmpl,
413 handle_return=0, is_method=0, kwargs_needed=1,
414 substdict=self.get_initial_constructor_substdict(
417 initfunc = '_wrap_' + funcname
419 sys.stderr.write('Could not write constructor for %s: %s\n'
420 % (self.objinfo.c_name, exc_info()))
422 initfunc = self.write_noconstructor()
425 def write_noconstructor(self):
427 if not hasattr(self.overrides, 'no_constructor_written'):
428 self.fp.write(self.noconstructor)
429 self.overrides.no_constructor_written = 1
430 initfunc = 'pygobject_no_constructor'
433 def write_default_constructor(self):
434 return self.write_noconstructor()
436 def get_methflags(self, funcname):
437 if self.overrides.wants_kwargs(funcname):
438 flags = 'METH_VARARGS|METH_KEYWORDS'
439 elif self.overrides.wants_noargs(funcname):
440 flags = 'METH_NOARGS'
441 elif self.overrides.wants_onearg(funcname):
444 flags = 'METH_VARARGS'
445 if self.overrides.is_staticmethod(funcname):
446 flags += '|METH_STATIC'
447 elif self.overrides.is_classmethod(funcname):
448 flags += '|METH_CLASS'
451 def write_function(self, funcname, data):
452 lineno, filename = self.overrides.getstartline(funcname)
453 self.fp.setline(lineno, filename)
456 self.fp.write('\n\n')
458 def _get_class_virtual_substdict(self, meth, cname, parent):
459 substdict = self.get_initial_method_substdict(meth)
460 substdict['virtual'] = substdict['name'].split('.')[1]
461 substdict['cname'] = cname
462 substdict['class_cast_macro'] = parent.typecode.replace(
463 '_TYPE_', '_', 1) + "_CLASS"
464 substdict['typecode'] = self.objinfo.typecode
465 substdict['cast'] = string.replace(parent.typecode, '_TYPE_', '_', 1)
468 def write_methods(self):
470 klass = self.objinfo.c_name
471 # First, get methods from the defs files
472 for meth in self.parser.find_methods(self.objinfo):
473 method_name = meth.c_name
474 if self.overrides.is_ignored(method_name):
477 if self.overrides.is_overriden(method_name):
478 if not self.overrides.is_already_included(method_name):
479 data = self.overrides.override(method_name)
480 self.write_function(method_name, data)
482 methflags = self.get_methflags(method_name)
484 # write constructor from template ...
485 code, methflags = self.write_function_wrapper(meth,
486 self.method_tmpl, handle_return=1, is_method=1,
487 substdict=self.get_initial_method_substdict(meth))
489 methods.append(self.methdef_tmpl %
490 { 'name': fixname(meth.name),
491 'cname': '_wrap_' + method_name,
493 'docstring': meth.docstring })
494 methods_coverage.declare_wrapped()
496 methods_coverage.declare_not_wrapped()
497 sys.stderr.write('Could not write method %s.%s: %s\n'
498 % (klass, meth.name, exc_info()))
500 # Now try to see if there are any defined in the override
501 for method_name in self.overrides.get_defines_for(klass):
502 c_name = override.class2cname(klass, method_name)
503 if self.overrides.is_already_included(method_name):
507 data = self.overrides.define(klass, method_name)
508 self.write_function(method_name, data)
509 methflags = self.get_methflags(method_name)
511 methods.append(self.methdef_tmpl %
512 { 'name': method_name,
513 'cname': '_wrap_' + c_name,
515 'docstring': meth.docstring })
516 methods_coverage.declare_wrapped()
518 methods_coverage.declare_not_wrapped()
519 sys.stderr.write('Could not write method %s.%s: %s\n'
520 % (klass, meth.name, exc_info()))
522 # Add GObject virtual method accessors, for chaining to parent
523 # virtuals from subclasses
524 methods += self.write_virtual_accessors()
527 methoddefs = '_Py%s_methods' % self.objinfo.c_name
528 # write the PyMethodDef structure
529 methods.append(' { NULL, NULL, 0, NULL }\n')
530 self.fp.write('static const PyMethodDef %s[] = {\n' % methoddefs)
531 self.fp.write(string.join(methods, ''))
532 self.fp.write('};\n\n')
537 def write_virtual_accessors(self):
538 klass = self.objinfo.c_name
540 for meth in self.parser.find_virtuals(self.objinfo):
541 method_name = self.objinfo.c_name + "__do_" + meth.name
542 if self.overrides.is_ignored(method_name):
545 if self.overrides.is_overriden(method_name):
546 if not self.overrides.is_already_included(method_name):
547 data = self.overrides.override(method_name)
548 self.write_function(method_name, data)
549 methflags = self.get_methflags(method_name)
551 # temporarily add a 'self' parameter as first argument
552 meth.params.insert(0, definitions.Parameter(
553 ptype=(self.objinfo.c_name + '*'),
554 pname='self', pdflt=None, pnull=None))
556 # write method from template ...
557 code, methflags = self.write_function_wrapper(
558 meth, self.virtual_accessor_tmpl,
559 handle_return=True, is_method=False,
560 substdict=self._get_class_virtual_substdict(
561 meth, method_name, self.objinfo))
565 methods.append(self.methdef_tmpl %
566 { 'name': "do_" + fixname(meth.name),
567 'cname': '_wrap_' + method_name,
568 'flags': methflags + '|METH_CLASS',
569 'docstring': 'NULL'})
570 vaccessors_coverage.declare_wrapped()
572 vaccessors_coverage.declare_not_wrapped()
574 'Could not write virtual accessor method %s.%s: %s\n'
575 % (klass, meth.name, exc_info()))
578 def write_virtuals(self):
580 Write _wrap_FooBar__proxy_do_zbr() reverse wrapers for
583 klass = self.objinfo.c_name
585 for meth in self.parser.find_virtuals(self.objinfo):
586 method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
587 if self.overrides.is_ignored(method_name):
590 if self.overrides.is_overriden(method_name):
591 if not self.overrides.is_already_included(method_name):
592 data = self.overrides.override(method_name)
593 self.write_function(method_name, data)
595 # write virtual proxy ...
596 ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
597 wrapper = reversewrapper.ReverseWrapper(
598 '_wrap_' + method_name, is_static=True)
599 wrapper.set_return_type(ret(wrapper, **props))
600 wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
601 wrapper, "self", method_name="do_" + meth.name,
602 c_type=(klass + ' *')))
603 for param in meth.params:
604 handler, props = argtypes.matcher.get_reverse(
606 props["direction"] = param.pdir
607 wrapper.add_parameter(handler(wrapper,
608 param.pname, **props))
609 buf = reversewrapper.MemoryCodeSink()
610 wrapper.generate(buf)
611 self.fp.write(buf.flush())
612 virtuals.append((fixname(meth.name), '_wrap_' + method_name))
613 vproxies_coverage.declare_wrapped()
614 except (KeyError, ValueError):
615 vproxies_coverage.declare_not_wrapped()
616 virtuals.append((fixname(meth.name), None))
617 sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
618 % (klass, meth.name, exc_info()))
620 # Write a 'pygtk class init' function for this object,
621 # except when the object type is explicitly ignored (like
622 # GtkPlug and GtkSocket on win32).
623 if self.overrides.is_ignored(self.objinfo.typecode):
625 class_cast_macro = self.objinfo.typecode.replace(
626 '_TYPE_', '_', 1) + "_CLASS"
627 cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1)
628 funcname = "__%s_class_init" % klass
629 self.objinfo.class_init_func = funcname
630 have_implemented_virtuals = not not [True
631 for name, cname in virtuals
632 if cname is not None]
635 '%(funcname)s(gpointer gclass, PyTypeObject *pyclass)\n'
638 if have_implemented_virtuals:
639 self.fp.write(' PyObject *o;\n')
641 ' %(klass)sClass *klass = '
642 '%(class_cast_macro)s(gclass);\n'
643 ' PyObject *gsignals = '
644 'PyDict_GetItemString(pyclass->tp_dict, "__gsignals__");\n'
647 for name, cname in virtuals:
648 do_name = 'do_' + name
650 self.fp.write('\n /* overriding %(do_name)s '
651 'is currently not supported */\n' % vars())
654 o = PyObject_GetAttrString((PyObject *) pyclass, "%(do_name)s");
658 if (!PyObject_TypeCheck(o, &PyCFunction_Type)
659 && !(gsignals && PyDict_GetItemString(gsignals, "%(name)s")))
660 klass->%(name)s = %(cname)s;
664 self.fp.write(' return 0;\n}\n')
666 def write_getsets(self):
667 lower_name = self.get_lower_name()
668 getsets_name = lower_name + '_getsets'
669 getterprefix = '_wrap_' + lower_name + '__get_'
670 setterprefix = '_wrap_' + lower_name + '__set_'
672 # no overrides for the whole function. If no fields,
674 if not self.objinfo.fields:
677 for ftype, cfname in self.objinfo.fields:
678 fname = cfname.replace('.', '_')
681 attrname = self.objinfo.c_name + '.' + fname
682 if self.overrides.attr_is_overriden(attrname):
683 code = self.overrides.attr_override(attrname)
684 self.write_function(attrname, code)
685 if string.find(code, getterprefix + fname) >= 0:
686 gettername = getterprefix + fname
687 if string.find(code, setterprefix + fname) >= 0:
688 settername = setterprefix + fname
689 if gettername == '0':
691 funcname = getterprefix + fname
692 info = argtypes.WrapperInfo()
693 handler = argtypes.matcher.get(ftype)
694 # for attributes, we don't own the "return value"
695 handler.write_return(ftype, 0, info)
696 self.fp.write(self.getter_tmpl %
697 { 'funcname': funcname,
698 'varlist': info.varlist,
699 'field': self.get_field_accessor(cfname),
700 'codeafter': info.get_codeafter() })
701 gettername = funcname
704 "Could not write getter for %s.%s: %s\n"
705 % (self.objinfo.c_name, fname, exc_info()))
706 if gettername != '0' or settername != '0':
707 getsets.append(' { "%s", (getter)%s, (setter)%s },\n' %
708 (fixname(fname), gettername, settername))
712 self.fp.write('static const PyGetSetDef %s[] = {\n' % getsets_name)
713 for getset in getsets:
714 self.fp.write(getset)
715 self.fp.write(' { NULL, (getter)0, (setter)0 },\n')
716 self.fp.write('};\n\n')
720 def write_functions(self, prefix):
721 self.fp.write('\n/* ----------- functions ----------- */\n\n')
724 # First, get methods from the defs files
725 for func in self.parser.find_functions():
726 funcname = func.c_name
727 if self.overrides.is_ignored(funcname):
730 if self.overrides.is_overriden(funcname):
731 data = self.overrides.override(funcname)
732 self.write_function(funcname, data)
734 methflags = self.get_methflags(funcname)
736 # write constructor from template ...
737 code, methflags = self.write_function_wrapper(func,
738 self.function_tmpl, handle_return=1, is_method=0)
740 functions.append(self.methdef_tmpl %
742 'cname': '_wrap_' + funcname,
744 'docstring': func.docstring })
745 functions_coverage.declare_wrapped()
747 functions_coverage.declare_not_wrapped()
748 sys.stderr.write('Could not write function %s: %s\n'
749 % (func.name, exc_info()))
751 # Now try to see if there are any defined in the override
752 for funcname in self.overrides.get_functions():
754 data = self.overrides.function(funcname)
755 self.write_function(funcname, data)
756 methflags = self.get_methflags(funcname)
757 functions.append(self.methdef_tmpl %
759 'cname': '_wrap_' + funcname,
761 'docstring': 'NULL'})
762 functions_coverage.declare_wrapped()
764 functions_coverage.declare_not_wrapped()
765 sys.stderr.write('Could not write function %s: %s\n'
766 % (funcname, exc_info()))
768 # write the PyMethodDef structure
769 functions.append(' { NULL, NULL, 0, NULL }\n')
771 self.fp.write('const PyMethodDef ' + prefix + '_functions[] = {\n')
772 self.fp.write(string.join(functions, ''))
773 self.fp.write('};\n\n')
775 class GObjectWrapper(Wrapper):
778 '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
783 ' self->obj = (GObject *)%(cname)s(%(arglist)s);\n'
785 ' if (!self->obj) {\n'
786 ' PyErr_SetString(PyExc_RuntimeError, '
787 '"could not create %(typename)s object");\n'
791 ' pygobject_register_wrapper((PyObject *)self);\n'
797 'static PyObject *\n'
798 '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
803 ' %(begin_allow_threads)s\n'
804 ' %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n'
805 ' %(end_allow_threads)s\n'
809 def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
810 Wrapper.__init__(self, parser, objinfo, overrides, fp)
812 self.castmacro = string.replace(self.objinfo.typecode,
815 def get_initial_class_substdict(self):
816 return { 'tp_basicsize' : 'PyGObject',
817 'tp_weaklistoffset' : 'offsetof(PyGObject, weakreflist)',
818 'tp_dictoffset' : 'offsetof(PyGObject, inst_dict)' }
820 def get_field_accessor(self, fieldname):
821 castmacro = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
822 return '%s(pygobject_get(self))->%s' % (castmacro, fieldname)
824 def get_initial_constructor_substdict(self, constructor):
825 substdict = Wrapper.get_initial_constructor_substdict(self,
827 if not constructor.caller_owns_return:
828 substdict['aftercreate'] = " g_object_ref(self->obj);\n"
830 substdict['aftercreate'] = ''
833 def get_initial_method_substdict(self, method):
834 substdict = Wrapper.get_initial_method_substdict(self, method)
835 substdict['cast'] = string.replace(self.objinfo.typecode,
839 def write_default_constructor(self):
841 parent = self.parser.find_object(self.objinfo.parent)
844 if parent is not None:
845 ## just like the constructor is inheritted, we should
846 # inherit the new API compatibility flag
847 self.objinfo.has_new_constructor_api = (
848 parent.has_new_constructor_api)
849 elif self.objinfo.parent == 'GObject':
850 self.objinfo.has_new_constructor_api = True
853 def write_property_based_constructor(self, constructor):
854 self.objinfo.has_new_constructor_api = True
856 print >> out, "static int"
857 print >> out, '_wrap_%s(PyGObject *self, PyObject *args,' \
858 ' PyObject *kwargs)\n{' % constructor.c_name
859 if constructor.params:
860 s = " GType obj_type = pyg_type_from_object((PyObject *) self);"
863 def py_str_list_to_c(arg):
865 return "{" + ", ".join(
866 map(lambda s: '"' + s + '"', arg)) + ", NULL }"
870 classname = '%s.%s' % (self.overrides.modulename,
873 if constructor.params:
874 mandatory_arguments = [param for param in constructor.params
875 if not param.optional]
876 optional_arguments = [param for param in constructor.params
878 arg_names = py_str_list_to_c(
880 for param in mandatory_arguments + optional_arguments])
882 prop_names = py_str_list_to_c(
884 for param in mandatory_arguments + optional_arguments])
886 print >> out, " GParameter params[%i];" % \
887 len(constructor.params)
888 print >> out, " PyObject *parsed_args[%i] = {NULL, };" % \
889 len(constructor.params)
890 print >> out, " char *arg_names[] = %s;" % arg_names
891 print >> out, " char *prop_names[] = %s;" % prop_names
892 print >> out, " guint nparams, i;"
894 if constructor.deprecated is not None:
896 ' if (PyErr_Warn(PyExc_DeprecationWarning, '
898 constructor.deprecated)
899 print >> out, ' return -1;'
901 out.write(" if (!PyArg_ParseTupleAndKeywords(args, kwargs, ")
903 if mandatory_arguments:
904 template += "O"*len(mandatory_arguments)
905 if optional_arguments:
906 template += "|" + "O"*len(optional_arguments)
907 template += ':%s.__init__"' % classname
908 print >> out, template, ", arg_names",
909 for i in range(len(constructor.params)):
910 print >> out, ", &parsed_args[%i]" % i,
916 " memset(params, 0, sizeof(GParameter)*%i);\n"
917 " if (!pyg_parse_constructor_args(obj_type, arg_names,\n"
918 " prop_names, params, \n"
919 " &nparams, parsed_args))\n"
921 " pygobject_constructv(self, nparams, params);\n"
922 " for (i = 0; i < nparams; ++i)\n"
923 " g_value_unset(¶ms[i].value);\n"
924 % len(constructor.params))
927 " static char* kwlist[] = { NULL };\n"
930 if constructor.deprecated is not None:
932 ' if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)\n'
934 '\n' % constructor.deprecated)
937 ' if (!PyArg_ParseTupleAndKeywords(args, kwargs,\n'
942 ' pygobject_constructv(self, 0, NULL);\n' % classname)
944 ' if (!self->obj) {\n'
945 ' PyErr_SetString(\n'
946 ' PyExc_RuntimeError, \n'
947 ' "could not create %s object");\n'
951 if not constructor.caller_owns_return:
952 print >> out, " g_object_ref(self->obj);\n"
958 return "_wrap_%s" % constructor.c_name
961 ## TODO : Add GstMiniObjectWrapper(Wrapper)
962 class GstMiniObjectWrapper(Wrapper):
965 '_wrap_%(cname)s(PyGstMiniObject *self%(extraparams)s)\n'
970 ' self->obj = (GstMiniObject *)%(cname)s(%(arglist)s);\n'
972 ' if (!self->obj) {\n'
973 ' PyErr_SetString(PyExc_RuntimeError, '
974 '"could not create %(typename)s miniobject");\n'
978 ' pygstminiobject_register_wrapper((PyObject *)self);\n'
983 'static PyObject *\n'
984 '_wrap_%(cname)s(PyGstMiniObject *self%(extraparams)s)\n'
989 ' %(begin_allow_threads)s\n'
990 ' %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n'
991 ' %(end_allow_threads)s\n'
995 def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
996 Wrapper.__init__(self, parser, objinfo, overrides, fp)
998 self.castmacro = string.replace(self.objinfo.typecode,
1001 def get_initial_class_substdict(self):
1002 return { 'tp_basicsize' : 'PyGstMiniObject',
1003 'tp_weaklistoffset' : 'offsetof(PyGstMiniObject, weakreflist)',
1004 'tp_dictoffset' : 'offsetof(PyGstMiniObject, inst_dict)' }
1006 def get_field_accessor(self, fieldname):
1007 castmacro = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
1008 return '%s(pygstminiobject_get(self))->%s' % (castmacro, fieldname)
1010 def get_initial_constructor_substdict(self, constructor):
1011 substdict = Wrapper.get_initial_constructor_substdict(self,
1013 if not constructor.caller_owns_return:
1014 substdict['aftercreate'] = " gst_mini_object_ref(self->obj);\n"
1016 substdict['aftercreate'] = ''
1019 def get_initial_method_substdict(self, method):
1020 substdict = Wrapper.get_initial_method_substdict(self, method)
1021 substdict['cast'] = string.replace(self.objinfo.typecode,
1027 class GInterfaceWrapper(GObjectWrapper):
1028 virtual_accessor_tmpl = (
1029 'static PyObject *\n'
1030 '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
1032 ' %(vtable)s *iface;\n'
1036 ' iface = g_type_interface_peek('
1037 'g_type_class_peek(pyg_type_from_object(cls)), %(typecode)s);\n'
1038 ' if (iface->%(virtual)s)\n'
1039 ' %(setreturn)siface->%(virtual)s(%(arglist)s);\n'
1041 ' PyErr_SetString(PyExc_NotImplementedError, '
1042 '"interface method %(name)s not implemented");\n'
1049 def get_initial_class_substdict(self):
1050 return { 'tp_basicsize' : 'PyObject',
1051 'tp_weaklistoffset' : '0',
1052 'tp_dictoffset' : '0'}
1054 def write_constructor(self):
1055 # interfaces have no constructors ...
1057 def write_getsets(self):
1058 # interfaces have no fields ...
1061 def _get_class_virtual_substdict(self, meth, cname, parent):
1062 substdict = self.get_initial_method_substdict(meth)
1063 substdict['virtual'] = substdict['name'].split('.')[1]
1064 substdict['cname'] = cname
1065 substdict['typecode'] = self.objinfo.typecode
1066 substdict['vtable'] = self.objinfo.vtable
1069 def write_virtuals(self):
1070 ## Now write reverse method wrappers, which let python code
1071 ## implement interface methods.
1072 # First, get methods from the defs files
1073 klass = self.objinfo.c_name
1075 for meth in self.parser.find_virtuals(self.objinfo):
1076 method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
1077 if self.overrides.is_ignored(method_name):
1080 if self.overrides.is_overriden(method_name):
1081 if not self.overrides.is_already_included(method_name):
1082 data = self.overrides.override(method_name)
1083 self.write_function(method_name, data)
1086 ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
1087 wrapper = reversewrapper.ReverseWrapper(
1088 '_wrap_' + method_name, is_static=True)
1089 wrapper.set_return_type(ret(wrapper, **props))
1090 wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
1091 wrapper, "self", method_name="do_" + meth.name,
1092 c_type=(klass + ' *')))
1093 for param in meth.params:
1094 handler, props = argtypes.matcher.get_reverse(
1096 props["direction"] = param.pdir
1097 wrapper.add_parameter(
1098 handler(wrapper, param.pname, **props))
1099 buf = reversewrapper.MemoryCodeSink()
1100 wrapper.generate(buf)
1101 self.fp.write(buf.flush())
1102 proxies.append((fixname(meth.name), '_wrap_' + method_name))
1103 iproxies_coverage.declare_wrapped()
1104 except (KeyError, ValueError):
1105 iproxies_coverage.declare_not_wrapped()
1106 proxies.append((fixname(meth.name), None))
1107 sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
1108 % (klass, meth.name, exc_info()))
1113 # Make sure we have at least one proxy function
1114 if not [cname for name,cname in proxies if not cname is None]:
1117 ## Write an interface init function for this object
1118 funcname = "__%s__interface_init" % klass
1119 vtable = self.objinfo.vtable
1122 '%(funcname)s(%(vtable)s *iface, PyTypeObject *pytype)\n'
1124 ' %(vtable)s *parent_iface = '
1125 'g_type_interface_peek_parent(iface);\n'
1126 ' PyObject *py_method;\n'
1130 for name, cname in proxies:
1131 do_name = 'do_' + name
1136 ' py_method = pytype? PyObject_GetAttrString('
1137 '(PyObject *) pytype, "%(do_name)s") : NULL;\n'
1138 ' if (py_method && !PyObject_TypeCheck(py_method, '
1139 '&PyCFunction_Type)) {\n'
1140 ' iface->%(name)s = %(cname)s;\n'
1143 ' if (parent_iface) {\n'
1144 ' iface->%(name)s = parent_iface->%(name)s;\n'
1146 ' Py_XDECREF(py_method);\n'
1149 self.fp.write('}\n\n')
1150 interface_info = "__%s__iinfo" % klass
1152 static const GInterfaceInfo %s = {
1153 (GInterfaceInitFunc) %s,
1157 ''' % (interface_info, funcname))
1158 self.objinfo.interface_info = interface_info
1160 class GBoxedWrapper(Wrapper):
1161 constructor_tmpl = (
1163 '_wrap_%(cname)s(PyGBoxed *self%(extraparams)s)\n'
1168 ' self->gtype = %(typecode)s;\n'
1169 ' self->free_on_dealloc = FALSE;\n'
1170 ' self->boxed = %(cname)s(%(arglist)s);\n'
1172 ' if (!self->boxed) {\n'
1173 ' PyErr_SetString(PyExc_RuntimeError, '
1174 '"could not create %(typename)s object");\n'
1177 ' self->free_on_dealloc = TRUE;\n'
1183 'static PyObject *\n'
1184 '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
1189 ' %(begin_allow_threads)s\n'
1190 ' %(setreturn)s%(cname)s(pyg_boxed_get(self, '
1191 '%(typename)s)%(arglist)s);\n'
1192 ' %(end_allow_threads)s\n'
1197 def get_initial_class_substdict(self):
1198 return { 'tp_basicsize' : 'PyGBoxed',
1199 'tp_weaklistoffset' : '0',
1200 'tp_dictoffset' : '0' }
1202 def get_field_accessor(self, fieldname):
1203 return 'pyg_boxed_get(self, %s)->%s' % (self.objinfo.c_name, fieldname)
1205 def get_initial_constructor_substdict(self, constructor):
1206 substdict = Wrapper.get_initial_constructor_substdict(
1208 substdict['typecode'] = self.objinfo.typecode
1211 class GPointerWrapper(GBoxedWrapper):
1212 constructor_tmpl = (
1214 '_wrap_%(cname)s(PyGPointer *self%(extraparams)s)\n'
1219 ' self->gtype = %(typecode)s;\n'
1220 ' self->pointer = %(cname)s(%(arglist)s);\n'
1222 ' if (!self->pointer) {\n'
1223 ' PyErr_SetString(PyExc_RuntimeError, '
1224 '"could not create %(typename)s object");\n'
1232 'static PyObject *\n'
1233 '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
1238 ' %(setreturn)s%(cname)s(pyg_pointer_get(self, '
1239 '%(typename)s)%(arglist)s);\n'
1244 def get_initial_class_substdict(self):
1245 return { 'tp_basicsize' : 'PyGPointer',
1246 'tp_weaklistoffset' : '0',
1247 'tp_dictoffset' : '0' }
1249 def get_field_accessor(self, fieldname):
1250 return 'pyg_pointer_get(self, %s)->%s' % (self.objinfo.c_name,
1253 def get_initial_constructor_substdict(self, constructor):
1254 substdict = Wrapper.get_initial_constructor_substdict(
1256 substdict['typecode'] = self.objinfo.typecode
1259 def write_headers(data, fp):
1260 fp.write('/* -- THIS FILE IS GENERATED - DO NOT EDIT */')
1261 fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
1262 fp.write('#include <Python.h>\n\n\n')
1267 def write_body(data, fp):
1272 def write_imports(overrides, fp):
1273 fp.write('/* ---------- types from other modules ---------- */\n')
1274 for module, pyname, cname in overrides.get_imports():
1275 fp.write('static PyTypeObject *_%s;\n' % cname)
1276 fp.write('#define %s (*_%s)\n' % (cname, cname))
1279 def write_type_declarations(parser, fp):
1280 fp.write('/* ---------- forward type declarations ---------- */\n')
1281 for obj in parser.boxes:
1282 fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n')
1283 for obj in parser.objects:
1284 fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n')
1285 for obj in parser.miniobjects:
1286 fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n')
1287 for interface in parser.interfaces:
1288 fp.write('PyTypeObject Py' + interface.c_name + '_Type;\n')
1292 def sort_parent_children(objects):
1293 objects = list(objects)
1299 for i, obj in enumerate(objects):
1300 if obj.parent == 'GObject':
1302 if obj.parent not in [info.c_name for info in objects[:i]]:
1303 for j, info in enumerate(objects[i+1:]):
1304 if info.c_name == obj.parent:
1305 parent_index = i + 1 + j
1311 if child_index is not None and parent_index is not None:
1312 if child_index != parent_index:
1313 objects.insert(child_index, objects.pop(parent_index))
1317 def write_classes(parser, overrides, fp):
1318 ## Sort the objects, so that we generate code for the parent types
1319 ## before their children.
1320 objects = sort_parent_children(parser.objects)
1321 for klass, items in ((GBoxedWrapper, parser.boxes),
1322 (GPointerWrapper, parser.pointers),
1323 (GObjectWrapper, objects),
1324 (GstMiniObjectWrapper, parser.miniobjects),
1325 (GInterfaceWrapper, parser.interfaces)):
1327 instance = klass(parser, item, overrides, fp)
1328 instance.write_class()
1331 def write_enums(parser, overrides, prefix, fp=sys.stdout):
1332 if not parser.enums:
1334 fp.write('\n/* ----------- enums and flags ----------- */\n\n')
1337 '_add_constants(PyObject *module, const gchar *strip_prefix)\n{\n')
1339 for enum in parser.enums:
1340 if overrides.is_type_ignored(enum.c_name):
1342 if enum.typecode is None:
1343 for nick, value in enum.values:
1345 ' PyModule_AddIntConstant(module, '
1346 '(char *) pyg_constant_strip_prefix("%s", strip_prefix), %s);\n'
1349 if enum.deftype == 'enum':
1350 fp.write(' pyg_enum_add(module, "%s", strip_prefix, %s);\n'
1351 % (enum.name, enum.typecode))
1353 fp.write(' pyg_flags_add(module, "%s", strip_prefix, %s);\n'
1354 % (enum.name, enum.typecode))
1357 fp.write(' if (PyErr_Occurred())\n')
1358 fp.write(' PyErr_Print();\n')
1361 def write_extension_init(overrides, prefix, fp):
1362 fp.write('/* initialise stuff extension classes */\n')
1363 fp.write('void\n' + prefix + '_register_classes(PyObject *d)\n{\n')
1364 imports = overrides.get_imports()[:]
1367 for module, pyname, cname in imports:
1368 bymod.setdefault(module, []).append((pyname, cname))
1369 fp.write(' PyObject *module;\n\n')
1370 for module in bymod:
1372 ' if ((module = PyImport_ImportModule("%s")) != NULL) {\n'
1375 ' PyObject *moddict = PyModule_GetDict(module);\n\n')
1376 for pyname, cname in bymod[module]:
1378 ' _%s = (PyTypeObject *)PyDict_GetItemString('
1379 'moddict, "%s");\n' % (cname, pyname))
1380 fp.write(' if (_%s == NULL) {\n' % cname)
1381 fp.write(' PyErr_SetString(PyExc_ImportError,\n')
1382 fp.write(' "cannot import name %s from %s");\n'
1384 fp.write(' return;\n')
1386 fp.write(' } else {\n')
1387 fp.write(' PyErr_SetString(PyExc_ImportError,\n')
1388 fp.write(' "could not import %s");\n' % module)
1389 fp.write(' return;\n')
1392 fp.write(overrides.get_init() + '\n')
1395 def write_registers(parser, overrides, fp):
1396 for boxed in parser.boxes:
1397 if overrides.is_type_ignored(boxed.c_name):
1399 fp.write(' pyg_register_boxed(d, "' + boxed.name +
1400 '", ' + boxed.typecode +
1401 ', &Py' + boxed.c_name +
1403 for pointer in parser.pointers:
1404 if overrides.is_type_ignored(pointer.c_name):
1406 fp.write(' pyg_register_pointer(d, "' + pointer.name +
1407 '", ' + pointer.typecode +
1408 ', &Py' + pointer.c_name + '_Type);\n')
1409 for interface in parser.interfaces:
1410 if overrides.is_type_ignored(interface.c_name):
1412 fp.write(' pyg_register_interface(d, "' + interface.name +
1413 '", '+ interface.typecode + ', &Py' + interface.c_name +
1415 if interface.interface_info is not None:
1416 fp.write(' pyg_register_interface_info(%s, &%s);\n' %
1417 (interface.typecode, interface.interface_info))
1419 objects = parser.objects[:]
1421 while pos < len(objects):
1422 parent = objects[pos].parent
1423 for i in range(pos+1, len(objects)):
1424 if objects[i].c_name == parent:
1425 objects.insert(i+1, objects[pos])
1431 if overrides.is_type_ignored(obj.c_name):
1434 if obj.parent != None:
1435 bases.append(obj.parent)
1436 bases = bases + obj.implements
1438 fp.write(' pygobject_register_class(d, "' + obj.c_name +
1439 '", ' + obj.typecode + ', &Py' + obj.c_name +
1440 '_Type, Py_BuildValue("(' + 'O' * len(bases) + ')", ' +
1441 string.join(map(lambda s: '&Py'+s+'_Type', bases), ', ') +
1444 fp.write(' pygobject_register_class(d, "' + obj.c_name +
1445 '", ' + obj.typecode + ', &Py' + obj.c_name +
1447 if obj.has_new_constructor_api:
1448 fp.write(' pyg_set_object_has_new_constructor(%s);\n' %
1451 print >> sys.stderr, (
1452 "Warning: Constructor for %s needs to be updated to new API\n"
1453 " See http://live.gnome.org/PyGTK_2fWhatsNew28"
1454 "#update-constructors") % obj.c_name
1455 if obj.class_init_func is not None:
1456 fp.write(' pyg_register_class_init(%s, %s);\n' %
1457 (obj.typecode, obj.class_init_func))
1458 #TODO: register mini-objects
1459 miniobjects = parser.miniobjects[:]
1460 for obj in miniobjects:
1462 if obj.parent != None:
1463 bases.append(obj.parent)
1464 bases = bases + obj.implements
1466 fp.write(' pygstminiobject_register_class(d, "' + obj.c_name +
1467 '", ' + obj.typecode + ', &Py' + obj.c_name +
1468 '_Type, Py_BuildValue("(' + 'O' * len(bases) + ')", ' +
1469 string.join(map(lambda s: '&Py'+s+'_Type', bases), ', ') +
1472 fp.write(' pygstminiobject_register_class(d, "' + obj.c_name +
1473 '", ' + obj.typecode + ', &Py' + obj.c_name +
1478 def write_source(parser, overrides, prefix, fp=FileOutput(sys.stdout)):
1479 write_headers(overrides.get_headers(), fp)
1480 write_imports(overrides, fp)
1481 write_type_declarations(parser, fp)
1482 write_body(overrides.get_body(), fp)
1483 write_classes(parser, overrides, fp)
1485 wrapper = Wrapper(parser, None, overrides, fp)
1486 wrapper.write_functions(prefix)
1488 write_enums(parser, overrides, prefix, fp)
1489 write_extension_init(overrides, prefix, fp)
1490 write_registers(parser, overrides, fp)
1492 def register_types(parser):
1493 for boxed in parser.boxes:
1494 argtypes.matcher.register_boxed(boxed.c_name, boxed.typecode)
1495 for pointer in parser.pointers:
1496 argtypes.matcher.register_pointer(pointer.c_name, pointer.typecode)
1497 for obj in parser.objects:
1498 argtypes.matcher.register_object(obj.c_name, obj.parent, obj.typecode)
1499 for obj in parser.miniobjects:
1500 argtypes.matcher.register_miniobject(obj.c_name, obj.parent, obj.typecode)
1501 for obj in parser.interfaces:
1502 argtypes.matcher.register_object(obj.c_name, None, obj.typecode)
1503 for enum in parser.enums:
1504 if enum.deftype == 'flags':
1505 argtypes.matcher.register_flag(enum.c_name, enum.typecode)
1507 argtypes.matcher.register_enum(enum.c_name, enum.typecode)
1509 usage = 'usage: codegen.py [-o overridesfile] [-p prefix] defsfile'
1511 o = override.Overrides()
1514 errorfilename = None
1516 opts, args = getopt.getopt(argv[1:], "o:p:r:t:D:x",
1517 ["override=", "prefix=", "register=", "outfilename=",
1518 "load-types=", "errorfilename=", "extendpath="])
1519 defines = {} # -Dkey[=val] options
1521 for opt, arg in opts:
1522 if opt in ('-x', '--extendpath'):
1523 extendpath.append(arg)
1524 extendpath.insert(0, os.getcwd())
1525 o = override.Overrides(path=extendpath)
1527 for opt, arg in opts:
1528 if opt in ('-o', '--override'):
1529 o = override.Overrides(arg, path=extendpath)
1530 elif opt in ('-p', '--prefix'):
1532 elif opt in ('-r', '--register'):
1533 # Warning: user has to make sure all -D options appear before -r
1534 p = defsparser.DefsParser(arg, defines)
1538 elif opt == '--outfilename':
1540 elif opt == '--errorfilename':
1542 elif opt in ('-t', '--load-types'):
1544 execfile(arg, globals)
1546 nameval = arg.split('=')
1548 defines[nameval[0]] = nameval[1]
1550 defines[nameval[0]] = None
1552 print >> sys.stderr, usage
1555 sys.stderr = open(errorfilename, "w")
1556 p = defsparser.DefsParser(args[0], defines)
1558 outfilename = os.path.splitext(args[0])[0] + '.c'
1563 write_source(p, o, prefix, FileOutput(sys.stdout, outfilename))
1565 functions_coverage.printstats()
1566 methods_coverage.printstats()
1567 vproxies_coverage.printstats()
1568 vaccessors_coverage.printstats()
1569 iproxies_coverage.printstats()
1571 if __name__ == '__main__':
1572 sys.exit(main(sys.argv))