1 # -*- Mode: Python; py-indent-offset: 4 -*-
7 """Nicely format a C variable list"""
10 def add(self, ctype, name):
11 if self.vars.has_key(ctype):
12 self.vars[ctype] = self.vars[ctype] + (name,)
14 self.vars[ctype] = (name,)
17 for type in self.vars.keys():
21 ret.append(string.join(self.vars[type], ', '))
25 return string.join(ret, '')
29 """A class that holds information about variable defs, code
30 snippets, etcd for use in writing out the function/method
33 self.varlist = VarList()
35 self.parselist = ['', 'kwlist']
40 def get_parselist(self):
41 return string.join(self.parselist, ', ')
42 def get_codebefore(self):
43 return string.join(self.codebefore, '')
44 def get_codeafter(self):
45 return string.join(self.codeafter, '')
46 def get_arglist(self):
47 return string.join(self.arglist, ', ')
48 def get_varlist(self):
49 return str(self.varlist)
51 ret = ' static char *kwlist[] = { %s };\n' % \
52 string.join(self.kwlist + [ 'NULL' ], ', ')
53 if not self.get_varlist():
57 def add_parselist(self, codes, parseargs, keywords):
58 self.parsestr = self.parsestr + codes
60 self.parselist.append(arg)
62 if keyword.iskeyword(kw):
64 self.kwlist.append('"%s"' % kw)
67 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
68 """Add code to the WrapperInfo instance to handle
70 raise RuntimeError, "write_param not implemented for %s" % \
71 self.__class__.__name__
72 def write_return(self, ptype, ownsreturn, info):
73 """Adds a variable named ret of the return type to
74 info.varlist, and add any required code to info.codeafter to
75 convert the return value to a python object."""
76 raise RuntimeError, "write_return not implemented for %s" % \
77 self.__class__.__name__
79 class NoneArg(ArgType):
80 def write_return(self, ptype, ownsreturn, info):
81 info.codeafter.append(' Py_INCREF(Py_None);\n' +
84 class StringArg(ArgType):
85 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
87 if pdflt != 'NULL': pdflt = '"' + pdflt + '"'
88 info.varlist.add('char', '*' + pname + ' = ' + pdflt)
90 info.varlist.add('char', '*' + pname)
91 info.arglist.append(pname)
93 info.add_parselist('z', ['&' + pname], [pname])
95 info.add_parselist('s', ['&' + pname], [pname])
96 def write_return(self, ptype, ownsreturn, info):
98 # have to free result ...
99 info.varlist.add('gchar', '*ret')
100 info.codeafter.append(' if (ret) {\n' +
101 ' PyObject *py_ret = PyString_FromString(ret);\n' +
103 ' return py_ret;\n' +
105 ' Py_INCREF(Py_None);\n' +
108 info.varlist.add('const gchar', '*ret')
109 info.codeafter.append(' if (ret)\n' +
110 ' return PyString_FromString(ret);\n'+
111 ' Py_INCREF(Py_None);\n' +
114 class UCharArg(ArgType):
115 # allows strings with embedded NULLs.
116 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
118 info.varlist.add('guchar', '*' + pname + ' = "' + pdflt + '"')
120 info.varlist.add('guchar', '*' + pname)
121 info.varlist.add('int', pname + '_len')
122 info.arglist.append(pname)
124 info.add_parselist('z#', ['&' + pname, '&' + pname + '_len'],
127 info.add_parselist('s#', ['&' + pname, '&' + pname + '_len'],
130 class CharArg(ArgType):
131 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
133 info.varlist.add('char', pname + " = '" + pdflt + "'")
135 info.varlist.add('char', pname)
136 info.arglist.append(pname)
137 info.add_parselist('c', ['&' + pname], [pname])
138 def write_return(self, ptype, ownsreturn, info):
139 info.varlist.add('gchar', 'ret')
140 info.codeafter.append(' return PyString_FromStringAndSize(&ret, 1);')
141 class GUniCharArg(ArgType):
142 ret_tmpl = ('#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2\n'
143 ' if (ret > 0xffff) {\n'
144 ' PyErr_SetString(PyExc_RuntimeError, "returned character can not be represented in 16-bit unicode");\n'
148 ' py_ret = (Py_UNICODE)ret;\n'
149 ' return PyUnicode_FromUnicode(&py_ret, 1);\n')
150 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
152 info.varlist.add('gunichar', pname + " = '" + pdflt + "'")
154 info.varlist.add('gunichar', pname)
155 info.arglist.append(pname)
156 info.add_parselist('O&', ['pyg_pyobj_to_unichar_conv', '&' + pname], [pname])
157 def write_return(self, ptype, ownsreturn, info):
158 info.varlist.add('gunichar', 'ret')
159 info.varlist.add('Py_UNICODE', 'py_ret')
160 info.codeafter.append(self.ret_tmpl)
163 class IntArg(ArgType):
164 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
166 info.varlist.add('int', pname + ' = ' + pdflt)
168 info.varlist.add('int', pname)
169 info.arglist.append(pname)
170 info.add_parselist('i', ['&' + pname], [pname])
171 def write_return(self, ptype, ownsreturn, info):
172 info.varlist.add('int', 'ret')
173 info.codeafter.append(' return PyInt_FromLong(ret);')
175 class UIntArg(ArgType):
176 dflt = (' if (py_%(name)s) {\n'
177 ' if (PyLong_Check(py_%(name)s))\n'
178 ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
179 ' else if (PyInt_Check(py_%(name)s))\n'
180 ' %(name)s = PyInt_AsLong(py_%(name)s);\n'
182 ' PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
183 ' if (PyErr_Occurred())\n'
186 before = (' if (PyLong_Check(py_%(name)s))\n'
187 ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
188 ' else if (PyInt_Check(py_%(name)s))\n'
189 ' %(name)s = PyInt_AsLong(py_%(name)s);\n'
191 ' PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
192 ' if (PyErr_Occurred())\n'
194 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
198 info.varlist.add(ptype, pname + ' = ' + pdflt)
199 info.codebefore.append(self.dflt % {'name':pname})
200 info.varlist.add('PyObject', "*py_" + pname + ' = NULL')
201 info.arglist.append(pname)
202 info.add_parselist('O', ['&py_' + pname], [pname])
203 def write_return(self, ptype, ownsreturn, info):
204 info.varlist.add(ptype, 'ret')
205 info.codeafter.append(' return PyLong_FromUnsignedLong(ret);')
207 class SizeArg(ArgType):
209 if struct.calcsize('P') <= struct.calcsize('l'):
214 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
216 info.varlist.add(ptype, pname + ' = ' + pdflt)
218 info.varlist.add(ptype, pname)
219 info.arglist.append(pname)
221 info.add_parselist('k', ['&' + pname], [pname])
223 info.add_parselist('K', ['&' + pname], [pname])
224 def write_return(self, ptype, ownsreturn, info):
225 info.varlist.add(ptype, 'ret')
227 info.codeafter.append(' return PyLong_FromUnsignedLongLong(ret);\n')
229 info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n')
231 class SSizeArg(ArgType):
233 if struct.calcsize('P') <= struct.calcsize('l'):
238 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
240 info.varlist.add(ptype, pname + ' = ' + pdflt)
242 info.varlist.add(ptype, pname)
243 info.arglist.append(pname)
245 info.add_parselist('l', ['&' + pname], [pname])
247 info.add_parselist('L', ['&' + pname], [pname])
248 def write_return(self, ptype, ownsreturn, info):
249 info.varlist.add(ptype, 'ret')
251 info.codeafter.append(' return PyLong_FromLongLong(ret);\n')
253 info.codeafter.append(' return PyLong_FromLong(ret);\n')
255 class LongArg(ArgType):
256 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
258 info.varlist.add(ptype, pname + ' = ' + pdflt)
260 info.varlist.add(ptype, pname)
261 info.arglist.append(pname)
262 info.add_parselist('l', ['&' + pname], [pname])
263 def write_return(self, ptype, ownsreturn, info):
264 info.varlist.add(ptype, 'ret')
265 info.codeafter.append(' return PyInt_FromLong(ret);\n')
267 class BoolArg(IntArg):
268 def write_return(self, ptype, ownsreturn, info):
269 info.varlist.add('int', 'ret')
270 info.codeafter.append(' return PyBool_FromLong(ret);\n')
272 class TimeTArg(ArgType):
273 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
275 info.varlist.add('time_t', pname + ' = ' + pdflt)
277 info.varlist.add('time_t', pname)
278 info.arglist.append(pname)
279 info.add_parselist('i', ['&' + pname], [pname])
280 def write_return(self, ptype, ownsreturn, info):
281 info.varlist.add('time_t', 'ret')
282 info.codeafter.append(' return PyInt_FromLong(ret);')
284 class ULongArg(ArgType):
285 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
287 info.varlist.add('unsigned long', pname + ' = ' + pdflt)
289 info.varlist.add('unsigned long', pname)
290 info.arglist.append(pname)
291 info.add_parselist('k', ['&' + pname], [pname])
292 def write_return(self, ptype, ownsreturn, info):
293 info.varlist.add(ptype, 'ret')
294 info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n')
296 class UInt32Arg(ULongArg):
297 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
298 ULongArg.write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info)
299 ## if sizeof(unsigned long) > sizeof(unsigned int), we need to
300 ## check the value is within guint32 range
301 if struct.calcsize('L') > struct.calcsize('I'):
302 info.codebefore.append((
303 ' if (%(pname)s > G_MAXUINT32) {\n'
304 ' PyErr_SetString(PyExc_ValueError,\n'
305 ' "Value out of range in conversion of"\n'
306 ' " %(pname)s parameter to unsigned 32 bit integer");\n'
310 class Int64Arg(ArgType):
311 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
313 info.varlist.add('gint64', pname + ' = ' + pdflt)
315 info.varlist.add('gint64', pname)
316 info.arglist.append(pname)
317 info.add_parselist('L', ['&' + pname], [pname])
318 def write_return(self, ptype, ownsreturn, info):
319 info.varlist.add('gint64', 'ret')
320 info.codeafter.append(' return PyLong_FromLongLong(ret);')
322 class UInt64Arg(ArgType):
323 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
325 info.varlist.add('guint64', pname + ' = ' + pdflt)
327 info.varlist.add('guint64', pname)
328 info.arglist.append(pname)
329 info.add_parselist('K', ['&' + pname], [pname])
330 def write_return(self, ptype, ownsreturn, info):
331 info.varlist.add('guint64', 'ret')
332 info.codeafter.append(' return PyLong_FromUnsignedLongLong(ret);')
335 class DoubleArg(ArgType):
336 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
338 info.varlist.add('double', pname + ' = ' + pdflt)
340 info.varlist.add('double', pname)
341 info.arglist.append(pname)
342 info.add_parselist('d', ['&' + pname], [pname])
343 def write_return(self, ptype, ownsreturn, info):
344 info.varlist.add('double', 'ret')
345 info.codeafter.append(' return PyFloat_FromDouble(ret);')
347 class FileArg(ArgType):
348 nulldflt = (' if (py_%(name)s == Py_None)\n'
349 ' %(name)s = NULL;\n'
350 ' else if (py_%(name)s && PyFile_Check(py_%(name)s)\n'
351 ' %s = PyFile_AsFile(py_%(name)s);\n'
352 ' else if (py_%(name)s) {\n'
353 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a file object or None");\n'
356 null = (' if (py_%(name)s && PyFile_Check(py_%(name)s)\n'
357 ' %(name)s = PyFile_AsFile(py_%(name)s);\n'
358 ' else if (py_%(name)s != Py_None) {\n'
359 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a file object or None");\n'
362 dflt = (' if (py_%(name)s)\n'
363 ' %(name)s = PyFile_AsFile(py_%(name)s);\n')
364 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
367 info.varlist.add('FILE', '*' + pname + ' = ' + pdflt)
368 info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
369 info.codebefore.append(self.nulldflt % {'name':pname})
371 info.varlist.add('FILE', '*' + pname + ' = NULL')
372 info.varlist.add('PyObject', '*py_' + pname)
373 info.codebefore.append(self.null & {'name':pname})
374 info.arglist.appned(pname)
375 info.add_parselist('O', ['&py_' + pname], [pname])
378 info.varlist.add('FILE', '*' + pname + ' = ' + pdflt)
379 info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
380 info.codebefore.append(self.dflt % {'name':pname})
381 info.arglist.append(pname)
383 info.varlist.add('PyObject', '*' + pname)
384 info.arglist.append('PyFile_AsFile(' + pname + ')')
385 info.add_parselist('O!', ['&PyFile_Type', '&' + pname], [pname])
386 def write_return(self, ptype, ownsreturn, info):
387 info.varlist.add('FILE', '*ret')
388 info.codeafter.append(' if (ret)\n' +
389 ' return PyFile_FromFile(ret, "", "", fclose);\n' +
390 ' Py_INCREF(Py_None);\n' +
393 class EnumArg(ArgType):
394 enum = (' if (pyg_enum_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
396 def __init__(self, enumname, typecode):
397 self.enumname = enumname
398 self.typecode = typecode
399 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
401 info.varlist.add(self.enumname, pname + ' = ' + pdflt)
403 info.varlist.add(self.enumname, pname)
404 info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
405 info.codebefore.append(self.enum % { 'typecode': self.typecode,
407 info.arglist.append(pname)
408 info.add_parselist('O', ['&py_' + pname], [pname]);
409 def write_return(self, ptype, ownsreturn, info):
410 info.varlist.add('gint', 'ret')
411 info.codeafter.append(' return pyg_enum_from_gtype(%s, ret);' % self.typecode)
413 class FlagsArg(ArgType):
414 flag = (' if (%(default)spyg_flags_get_value(%(typecode)s, py_%(name)s, (gint *)&%(name)s))\n'
416 def __init__(self, flagname, typecode):
417 self.flagname = flagname
418 self.typecode = typecode
419 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
421 info.varlist.add(self.flagname, pname + ' = ' + pdflt)
422 default = "py_%s && " % (pname,)
424 info.varlist.add(self.flagname, pname)
426 info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
427 info.codebefore.append(self.flag % {'default':default,
428 'typecode':self.typecode,
430 info.arglist.append(pname)
431 info.add_parselist('O', ['&py_' + pname], [pname])
432 def write_return(self, ptype, ownsreturn, info):
433 info.varlist.add('guint', 'ret')
434 info.codeafter.append(' return pyg_flags_from_gtype(%s, ret);' % self.typecode)
436 class ObjectArg(ArgType):
437 # should change these checks to more typesafe versions that check
438 # a little further down in the class heirachy.
439 nulldflt = (' if ((PyObject *)py_%(name)s == Py_None)\n'
440 ' %(name)s = NULL;\n'
441 ' else if (py_%(name)s && pygobject_check(py_%(name)s, &Py%(type)s_Type))\n'
442 ' %(name)s = %(cast)s(py_%(name)s->obj);\n'
443 ' else if (py_%(name)s) {\n'
444 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
447 null = (' if (py_%(name)s && pygobject_check(py_%(name)s, &Py%(type)s_Type))\n'
448 ' %(name)s = %(cast)s(py_%(name)s->obj);\n'
449 ' else if ((PyObject *)py_%(name)s != Py_None) {\n'
450 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
453 dflt = ' if (py_%(name)s)\n' \
454 ' %(name)s = %(cast)s(py_%(name)s->obj);\n'
455 def __init__(self, objname, parent, typecode):
456 self.objname = objname
457 self.cast = string.replace(typecode, '_TYPE_', '_', 1)
459 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
462 info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
463 info.varlist.add('PyGObject', '*py_' + pname + ' = NULL')
464 info.codebefore.append(self.nulldflt % {'name':pname,
466 'type':self.objname})
468 info.varlist.add(self.objname, '*' + pname + ' = NULL')
469 info.varlist.add('PyGObject', '*py_' + pname)
470 info.codebefore.append(self.null % {'name':pname,
472 'type':self.objname})
473 if ptype.endswith('*'):
474 typename = ptype[:-1]
476 const, typename = typename.split('const-')
479 if typename != ptype:
480 info.arglist.append('(%s *) %s' % (ptype[:-1], pname))
482 info.arglist.append(pname)
484 info.add_parselist('O', ['&py_' + pname], [pname])
487 info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
488 info.varlist.add('PyGObject', '*py_' + pname + ' = NULL')
489 info.codebefore.append(self.dflt % {'name':pname,
491 info.arglist.append(pname)
492 info.add_parselist('O!', ['&Py%s_Type' % self.objname,
493 '&py_' + pname], [pname])
495 info.varlist.add('PyGObject', '*' + pname)
496 info.arglist.append('%s(%s->obj)' % (self.cast, pname))
497 info.add_parselist('O!', ['&Py%s_Type' % self.objname,
498 '&' + pname], [pname])
499 def write_return(self, ptype, ownsreturn, info):
500 if ptype.endswith('*'):
501 typename = ptype[:-1]
503 const, typename = typename.split('const-')
506 info.varlist.add(typename, '*ret')
508 info.varlist.add('PyObject', '*py_ret')
509 # < GLib 2.8: using our custom _new and _unref functions
510 # makes sure we update the proper GstObject refcount
511 info.codeafter.append(' py_ret = pygobject_new((GObject *)ret);\n'
512 ' if (ret != NULL)\n'
513 ' g_object_unref((GObject *)ret);\n'
516 info.codeafter.append(' /* pygobject_new handles NULL checking */\n' +
517 ' return pygobject_new((GObject *)ret);')
519 class MiniObjectArg(ArgType):
520 # should change these checks to more typesafe versions that check
521 # a little further down in the class heirachy.
522 nulldflt = (' if ((PyObject *)py_%(name)s == Py_None)\n'
523 ' %(name)s = NULL;\n'
524 ' else if (py_%(name)s) && pygstminiobject_check(py_%(name)s, &Py%(type)s_Type))\n'
525 ' %(name)s = %(cast)s(py_%(name)s->obj);\n'
526 ' else if (py_%(name)s) {\n'
527 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
530 null = (' if (py_%(name)s && pygstminiobject_check(py_%(name)s, &Py%(type)s_Type))\n'
531 ' %(name)s = %(cast)s(py_%(name)s->obj);\n'
532 ' else if ((PyObject *)py_%(name)s != Py_None) {\n'
533 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
536 dflt = ' if (py_%(name)s)\n' \
537 ' %(name)s = %(cast)s(py_%(name)s->obj);\n'
538 def __init__(self, objname, parent, typecode):
539 self.objname = objname
540 self.cast = string.replace(typecode, '_TYPE_', '_', 1)
542 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
545 info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
546 info.varlist.add('PyGstMiniObject', '*py_' + pname + ' = NULL')
547 info.codebefore.append(self.nulldflt % {'name':pname,
549 'type':self.objname})
551 info.varlist.add(self.objname, '*' + pname + ' = NULL')
552 info.varlist.add('PyGstMiniObject', '*py_' + pname)
553 info.codebefore.append(self.null % {'name':pname,
555 'type':self.objname})
556 if ptype.endswith('*'):
557 typename = ptype[:-1]
559 const, typename = typename.split('const-')
562 if typename != ptype:
563 info.arglist.append('(%s *) %s' % (ptype[:-1], pname))
565 info.arglist.append(pname)
567 info.add_parselist('O', ['&py_' + pname], [pname])
570 info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt)
571 info.varlist.add('PyGstMiniObject', '*py_' + pname + ' = NULL')
572 info.codebefore.append(self.dflt % {'name':pname,
574 info.arglist.append(pname)
575 info.add_parselist('O', ['&Py%s_Type' % self.objname,
576 '&py_' + pname], [pname])
578 info.varlist.add('PyGstMiniObject', '*' + pname)
579 info.arglist.append('%s(%s->obj)' % (self.cast, pname))
580 info.add_parselist('O!', ['&Py%s_Type' % self.objname,
581 '&' + pname], [pname])
583 info.codebefore.append(' gst_mini_object_ref(GST_MINI_OBJECT(%s->obj));\n' % pname)
584 def write_return(self, ptype, ownsreturn, info):
585 if ptype.endswith('*'):
586 typename = ptype[:-1]
588 const, typename = typename.split('const-')
591 info.varlist.add(typename, '*ret')
593 info.varlist.add('PyObject', '*py_ret')
594 info.codeafter.append(' py_ret = pygstminiobject_new((GstMiniObject *)ret);\n'
595 ' if (ret != NULL)\n'
596 ' gst_mini_object_unref((GstMiniObject *)ret);\n'
599 info.codeafter.append(' /* pygobject_new handles NULL checking */\n' +
600 ' return pygstminiobject_new((GstMiniObject *)ret);')
602 class BoxedArg(ArgType):
603 # haven't done support for default args. Is it needed?
604 check = (' if (pyg_boxed_check(py_%(name)s, %(typecode)s))\n'
605 ' %(name)s = pyg_boxed_get(py_%(name)s, %(typename)s);\n'
607 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s");\n'
610 null = (' if (pyg_boxed_check(py_%(name)s, %(typecode)s))\n'
611 ' %(name)s = pyg_boxed_get(py_%(name)s, %(typename)s);\n'
612 ' else if (py_%(name)s != Py_None) {\n'
613 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s or None");\n'
616 def __init__(self, ptype, typecode):
617 self.typename = ptype
618 self.typecode = typecode
619 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
621 info.varlist.add(self.typename, '*' + pname + ' = NULL')
622 info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
623 info.codebefore.append(self.null % {'name': pname,
624 'typename': self.typename,
625 'typecode': self.typecode})
627 info.varlist.add(self.typename, '*' + pname + ' = NULL')
628 info.varlist.add('PyObject', '*py_' + pname)
629 info.codebefore.append(self.check % {'name': pname,
630 'typename': self.typename,
631 'typecode': self.typecode})
633 typename = ptype[:-1]
634 if typename[:6] == 'const-': typename = typename[6:]
635 if typename != self.typename:
636 info.arglist.append('(%s *)%s' % (ptype[:-1], pname))
638 info.arglist.append(pname)
640 info.arglist.append(pname)
641 info.add_parselist('O', ['&py_' + pname], [pname])
642 ret_tmpl = ' /* pyg_boxed_new handles NULL checking */\n' \
643 ' return pyg_boxed_new(%(typecode)s, %(ret)s, %(copy)s, TRUE);'
644 def write_return(self, ptype, ownsreturn, info):
646 info.varlist.add(self.typename, '*ret')
649 info.varlist.add(self.typename, 'ret')
651 ownsreturn = 0 # of course it can't own a ref to a local var ...
652 info.codeafter.append(self.ret_tmpl %
653 { 'typecode': self.typecode,
655 'copy': ownsreturn and 'FALSE' or 'TRUE'})
657 class CustomBoxedArg(ArgType):
658 # haven't done support for default args. Is it needed?
659 null = (' if (%(check)s(py_%(name)s))\n'
660 ' %(name)s = %(get)s(py_%(name)s);\n'
661 ' else if (py_%(name)s != Py_None) {\n'
662 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n'
665 def __init__(self, ptype, pytype, getter, new):
668 self.checker = 'Py' + ptype + '_Check'
670 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
672 info.varlist.add(ptype[:-1], '*' + pname + ' = NULL')
673 info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
674 info.codebefore.append(self.null % {'name': pname,
676 'check': self.checker,
678 info.arglist.append(pname)
679 info.add_parselist('O', ['&py_' + pname], [pname])
681 info.varlist.add('PyObject', '*' + pname)
682 info.arglist.append(self.getter + '(' + pname + ')')
683 info.add_parselist('O!', ['&' + self.pytype, '&' + pname], [pname])
684 def write_return(self, ptype, ownsreturn, info):
685 info.varlist.add(ptype[:-1], '*ret')
686 info.codeafter.append(' if (ret)\n' +
687 ' return ' + self.new + '(ret);\n' +
688 ' Py_INCREF(Py_None);\n' +
691 class PointerArg(ArgType):
692 # haven't done support for default args. Is it needed?
693 check = (' if (pyg_pointer_check(py_%(name)s, %(typecode)s))\n'
694 ' %(name)s = pyg_pointer_get(py_%(name)s, %(typename)s);\n'
696 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s");\n'
699 null = (' if (pyg_pointer_check(py_%(name)s, %(typecode)s))\n'
700 ' %(name)s = pyg_pointer_get(py_%(name)s, %(typename)s);\n'
701 ' else if (py_%(name)s != Py_None) {\n'
702 ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(typename)s or None");\n'
705 def __init__(self, ptype, typecode):
706 self.typename = ptype
707 self.typecode = typecode
708 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
710 info.varlist.add(self.typename, '*' + pname + ' = NULL')
711 info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
712 info.codebefore.append(self.null % {'name': pname,
713 'typename': self.typename,
714 'typecode': self.typecode})
716 info.varlist.add(self.typename, '*' + pname + ' = NULL')
717 info.varlist.add('PyObject', '*py_' + pname)
718 info.codebefore.append(self.check % {'name': pname,
719 'typename': self.typename,
720 'typecode': self.typecode})
721 info.arglist.append(pname)
722 info.add_parselist('O', ['&py_' + pname], [pname])
723 def write_return(self, ptype, ownsreturn, info):
725 info.varlist.add(self.typename, '*ret')
726 info.codeafter.append(' /* pyg_pointer_new handles NULL checking */\n' +
727 ' return pyg_pointer_new(' + self.typecode + ', ret);')
729 info.varlist.add(self.typename, 'ret')
730 info.codeafter.append(' /* pyg_pointer_new handles NULL checking */\n' +
731 ' return pyg_pointer_new(' + self.typecode + ', &ret);')
733 class AtomArg(IntArg):
734 dflt = ' if (py_%(name)s) {\n' \
735 ' %(name)s = pygdk_atom_from_pyobject(py_%(name)s);\n' \
736 ' if (PyErr_Occurred())\n' \
739 atom = (' %(name)s = pygdk_atom_from_pyobject(py_%(name)s);\n'
740 ' if (PyErr_Occurred())\n'
742 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
744 info.varlist.add('GdkAtom', pname + ' = ' + pdflt)
745 info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
746 info.codebefore.append(self.dflt % {'name': pname})
748 info.varlist.add('GdkAtom', pname)
749 info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
750 info.codebefore.append(self.atom % {'name': pname})
751 info.arglist.append(pname)
752 info.add_parselist('O', ['&py_' + pname], [pname])
753 def write_return(self, ptype, ownsreturn, info):
754 info.varlist.add('GdkAtom', 'ret')
755 info.varlist.add('PyObject *', 'py_ret')
756 info.varlist.add('gchar *', 'name')
757 info.codeafter.append(' name = gdk_atom_name(ret);\n'
758 ' py_ret = PyString_FromString(name);\n'
762 class GTypeArg(ArgType):
763 gtype = (' if ((%(name)s = pyg_type_from_object(py_%(name)s)) == 0)\n'
765 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
766 info.varlist.add('GType', pname)
767 info.varlist.add('PyObject', '*py_' + pname + ' = NULL')
768 info.codebefore.append(self.gtype % {'name': pname})
769 info.arglist.append(pname)
770 info.add_parselist('O', ['&py_' + pname], [pname])
771 def write_return(self, ptype, ownsreturn, info):
772 info.varlist.add('GType', 'ret')
773 info.codeafter.append(' return pyg_type_wrapper_new(ret);')
775 # simple GError handler.
776 class GErrorArg(ArgType):
777 handleerror = (' if (pyg_error_check(&%(name)s))\n'
779 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
780 info.varlist.add('GError', '*' + pname + ' = NULL')
781 info.arglist.append('&' + pname)
782 info.codeafter.append(self.handleerror % { 'name': pname })
784 class GtkTreePathArg(ArgType):
785 # haven't done support for default args. Is it needed?
786 normal = (' %(name)s = pygtk_tree_path_from_pyobject(py_%(name)s);\n'
787 ' if (!%(name)s) {\n'
788 ' PyErr_SetString(PyExc_TypeError, "could not convert %(name)s to a GtkTreePath");\n'
791 null = (' if (py_%(name)s != Py_None) {\n'
792 ' %(name)s = pygtk_tree_path_from_pyobject(py_%(name)s);\n'
793 ' if (!%(name)s) {\n'
794 ' PyErr_SetString(PyExc_TypeError, "could not convert %(name)s to a GtkTreePath");\n'
798 freepath = (' if (%(name)s)\n'
799 ' gtk_tree_path_free(%(name)s);\n')
802 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
804 info.varlist.add('GtkTreePath', '*' + pname + ' = NULL')
805 info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
806 info.codebefore.append(self.null % {'name': pname})
807 info.arglist.append(pname)
808 info.add_parselist('O', ['&py_' + pname], [pname])
810 info.varlist.add('GtkTreePath', '*' + pname)
811 info.varlist.add('PyObject', '*py_' + pname)
812 info.codebefore.append(self.normal % {'name': pname})
813 info.arglist.append(pname)
814 info.add_parselist('O', ['&py_' + pname], [pname])
815 info.codeafter.append(self.freepath % {'name': pname})
816 def write_return(self, ptype, ownsreturn, info):
817 info.varlist.add('GtkTreePath', '*ret')
819 info.codeafter.append(' if (ret) {\n'
820 ' PyObject *py_ret = pygtk_tree_path_to_pyobject(ret);\n'
821 ' gtk_tree_path_free(ret);\n'
824 ' Py_INCREF(Py_None);\n'
827 info.codeafter.append(' if (ret) {\n'
828 ' PyObject *py_ret = pygtk_tree_path_to_pyobject(ret);\n'
831 ' Py_INCREF(Py_None);\n'
834 class GdkRectanglePtrArg(ArgType):
835 normal = (' if (!pygdk_rectangle_from_pyobject(py_%(name)s, &%(name)s))\n'
837 null = (' if (py_%(name)s == Py_None)\n'
838 ' %(name)s = NULL;\n'
839 ' else if (pygdk_rectangle_from_pyobject(py_%(name)s, &%(name)s_rect))\n'
840 ' %(name)s = &%(name)s_rect;\n'
843 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
845 info.varlist.add('GdkRectangle', pname + '_rect = { 0, 0, 0, 0 }')
846 info.varlist.add('GdkRectangle', '*' + pname)
847 info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
848 info.add_parselist('O', ['&py_' + pname], [pname])
849 info.arglist.append(pname)
850 info.codebefore.append(self.null % {'name': pname})
852 info.varlist.add('GdkRectangle', pname + ' = { 0, 0, 0, 0 }')
853 info.varlist.add('PyObject', '*py_' + pname)
854 info.add_parselist('O', ['&py_' + pname], [pname])
855 info.arglist.append('&' + pname)
856 info.codebefore.append(self.normal % {'name': pname})
858 class GdkRectangleArg(ArgType):
859 def write_return(self, ptype, ownsreturn, info):
860 info.varlist.add('GdkRectangle', 'ret')
861 info.codeafter.append(' return pyg_boxed_new(GDK_TYPE_RECTANGLE, &ret, TRUE, TRUE);')
863 class PyObjectArg(ArgType):
864 def write_param(self, ptype, pname, pdflt, pnull, keeprefcount, info):
865 info.varlist.add('PyObject', '*' + pname)
866 info.add_parselist('O', ['&' + pname], [pname])
867 info.arglist.append(pname)
868 def write_return(self, ptype, ownsreturn, info):
869 info.varlist.add("PyObject", "*ret")
871 info.codeafter.append(' if (ret) {\n'
874 ' Py_INCREF(Py_None);\n'
877 info.codeafter.append(' if (!ret) ret = Py_None;\n'
884 self.reverse_argtypes = {}
885 self.reverse_rettypes = {}
887 def register(self, ptype, handler):
888 self.argtypes[ptype] = handler
889 def register_reverse(self, ptype, handler):
890 self.reverse_argtypes[ptype] = handler
891 def register_reverse_ret(self, ptype, handler):
892 self.reverse_rettypes[ptype] = handler
894 def register_enum(self, ptype, typecode):
896 typecode = "G_TYPE_NONE"
897 self.register(ptype, EnumArg(ptype, typecode))
898 def register_flag(self, ptype, typecode):
900 typecode = "G_TYPE_NONE"
901 self.register(ptype, FlagsArg(ptype, typecode))
902 def register_object(self, ptype, parent, typecode):
903 oa = ObjectArg(ptype, parent, typecode)
904 self.register(ptype, oa) # in case I forget the * in the .defs
905 self.register(ptype+'*', oa)
906 self.register('const-'+ptype+'*', oa)
907 if ptype == 'GdkPixmap':
908 # hack to handle GdkBitmap synonym.
909 self.register('GdkBitmap', oa)
910 self.register('GdkBitmap*', oa)
911 def register_miniobject(self, ptype, parent, typecode):
912 oa = MiniObjectArg(ptype, parent, typecode)
913 self.register(ptype, oa) # in case I forget the * in the .defs
914 self.register(ptype+'*', oa)
915 def register_boxed(self, ptype, typecode):
916 if self.argtypes.has_key(ptype): return
917 arg = BoxedArg(ptype, typecode)
918 self.register(ptype, arg)
919 self.register(ptype+'*', arg)
920 self.register('const-'+ptype+'*', arg)
921 def register_custom_boxed(self, ptype, pytype, getter, new):
922 arg = CustomBoxedArg(ptype, pytype, getter, new)
923 self.register(ptype+'*', arg)
924 self.register('const-'+ptype+'*', arg)
925 def register_pointer(self, ptype, typecode):
926 arg = PointerArg(ptype, typecode)
927 self.register(ptype, arg)
928 self.register(ptype+'*', arg)
929 self.register('const-'+ptype+'*', arg)
931 def get(self, ptype):
933 return self.argtypes[ptype]
935 if ptype[:8] == 'GdkEvent' and ptype[-1] == '*':
936 return self.argtypes['GdkEvent*']
938 def _get_reverse_common(self, ptype, registry):
939 props = dict(c_type=ptype)
941 return registry[ptype], props
944 handler = self.argtypes[ptype]
946 if ptype.startswith('GdkEvent') and ptype.endswith('*'):
947 handler = self.argtypes['GdkEvent*']
950 if isinstance(handler, ObjectArg):
951 return registry['GObject*'], props
952 elif isinstance(handler, EnumArg):
953 props['typecode'] = handler.typecode
954 props['enumname'] = handler.enumname
955 return registry['GEnum'], props
956 elif isinstance(handler, FlagsArg):
957 props['typecode'] = handler.typecode
958 props['flagname'] = handler.flagname
959 return registry['GFlags'], props
960 elif isinstance(handler, BoxedArg):
961 props['typecode'] = handler.typecode
962 props['typename'] = handler.typename
963 return registry['GBoxed'], props
966 def get_reverse(self, ptype):
967 return self._get_reverse_common(ptype, self.reverse_argtypes)
968 def get_reverse_ret(self, ptype):
969 return self._get_reverse_common(ptype, self.reverse_rettypes)
971 def object_is_a(self, otype, parent):
972 if otype == None: return 0
973 if otype == parent: return 1
974 if not self.argtypes.has_key(otype): return 0
975 return self.object_is_a(self.get(otype).parent, parent)
977 matcher = ArgMatcher()
980 matcher.register(None, arg)
981 matcher.register('none', arg)
984 matcher.register('char*', arg)
985 matcher.register('gchar*', arg)
986 matcher.register('const-char*', arg)
987 matcher.register('char-const*', arg)
988 matcher.register('const-gchar*', arg)
989 matcher.register('gchar-const*', arg)
990 matcher.register('string', arg)
991 matcher.register('static_string', arg)
994 matcher.register('unsigned-char*', arg)
995 matcher.register('const-guchar*', arg)
996 matcher.register('guchar*', arg)
999 matcher.register('char', arg)
1000 matcher.register('gchar', arg)
1001 matcher.register('guchar', arg)
1004 matcher.register('gunichar', arg)
1007 matcher.register('int', arg)
1008 matcher.register('gint', arg)
1009 matcher.register('short', arg)
1010 matcher.register('gshort', arg)
1011 matcher.register('gushort', arg)
1012 matcher.register('gsize', SizeArg())
1013 matcher.register('gssize', SSizeArg())
1014 matcher.register('guint8', arg)
1015 matcher.register('gint8', arg)
1016 matcher.register('guint16', arg)
1017 matcher.register('gint16', arg)
1018 matcher.register('gint32', arg)
1019 matcher.register('GTime', arg)
1022 matcher.register('long', arg)
1023 matcher.register('glong', arg)
1026 matcher.register('guint', arg)
1029 matcher.register('gboolean', arg)
1032 matcher.register('time_t', arg)
1034 matcher.register('guint32', UInt32Arg())
1037 matcher.register('gulong', arg)
1040 matcher.register('gint64', arg)
1041 matcher.register('long-long', arg)
1044 matcher.register('guint64', arg)
1045 matcher.register('unsigned-long-long', arg)
1048 matcher.register('double', arg)
1049 matcher.register('gdouble', arg)
1050 matcher.register('float', arg)
1051 matcher.register('gfloat', arg)
1054 matcher.register('FILE*', arg)
1056 # enums, flags, objects
1058 matcher.register('GdkAtom', AtomArg())
1060 matcher.register('GType', GTypeArg())
1061 matcher.register('GtkType', GTypeArg())
1063 matcher.register('GError**', GErrorArg())
1064 matcher.register('GtkTreePath*', GtkTreePathArg())
1065 matcher.register('GdkRectangle*', GdkRectanglePtrArg())
1066 matcher.register('GtkAllocation*', GdkRectanglePtrArg())
1067 matcher.register('GdkRectangle', GdkRectangleArg())
1068 matcher.register('PyObject*', PyObjectArg())
1070 matcher.register('GdkNativeWindow', ULongArg())
1072 matcher.register_object('GObject', None, 'G_TYPE_OBJECT')
1073 matcher.register_miniobject('GstMiniObject', None, 'GST_TYPE_MINI_OBJECT')