]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.2/Tools/bgen/bgen/bgenObjectDefinition.py
1 from bgenOutput
import *
2 from bgenGeneratorGroup
import GeneratorGroup
4 class ObjectDefinition(GeneratorGroup
):
5 "Spit out code that together defines a new Python object type"
7 tp_flags
= "Py_TPFLAGS_DEFAULT"
9 argref
= "" # set to "*" if arg to <type>_New should be pointer
10 argconst
= "" # set to "const " if arg to <type>_New should be const
12 def __init__(self
, name
, prefix
, itselftype
):
13 """ObjectDefinition constructor. May be extended, but do not override.
15 - name: the object's official name, e.g. 'SndChannel'.
16 - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'.
17 - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'.
19 XXX For official Python data types, rules for the 'Py' prefix are a problem.
22 GeneratorGroup
.__init
__(self
, prefix
or name
)
24 self
.itselftype
= itselftype
25 self
.objecttype
= name
+ 'Object'
26 self
.typename
= name
+ '_Type'
27 self
.static
= "static " # set to "" to make <type>_New and <type>_Convert public
28 self
.modulename
= None
29 if hasattr(self
, "assertions"):
32 def add(self
, g
, dupcheck
=0):
33 g
.setselftype(self
.objecttype
, self
.itselftype
)
34 GeneratorGroup
.add(self
, g
, dupcheck
)
37 # In case we are referenced from a module
40 def setmodulename(self
, name
):
41 self
.modulename
= name
44 # XXX This should use long strings and %(varname)s substitution!
46 OutHeader2("Object type " + self
.name
)
50 Output("typedef struct %s {", self
.objecttype
)
52 Output("PyObject_HEAD")
53 self
.outputStructMembers()
55 Output("} %s;", self
.objecttype
)
63 GeneratorGroup
.generate(self
)
66 self
.outputMethodChain()
78 self
.outputPEP253Hooks()
80 self
.outputTypeObject()
82 OutHeader2("End object type " + self
.name
)
84 def outputCheck(self
):
85 sf
= self
.static
and "static "
86 Output("%sPyTypeObject %s;", sf
, self
.typename
)
88 Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))",
89 self
.prefix
, self
.typename
, self
.typename
)
92 def outputMethodChain(self
):
93 Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
94 self
.static
, self
.prefix
, self
.prefix
, self
.basechain
)
96 def outputStructMembers(self
):
97 Output("%s ob_itself;", self
.itselftype
)
101 Output("%sPyObject *%s_New(%s%s %sitself)", self
.static
, self
.prefix
,
102 self
.argconst
, self
.itselftype
, self
.argref
)
104 Output("%s *it;", self
.objecttype
)
105 self
.outputCheckNewArg()
106 Output("it = PyObject_NEW(%s, &%s);", self
.objecttype
, self
.typename
)
107 Output("if (it == NULL) return NULL;")
109 Output("/* XXXX Should we tp_init or tp_new our basetype? */")
110 self
.outputInitStructMembers()
111 Output("return (PyObject *)it;")
114 def outputInitStructMembers(self
):
115 Output("it->ob_itself = %sitself;", self
.argref
)
117 def outputCheckNewArg(self
):
118 "Override this method to apply additional checks/conversions"
120 def outputConvert(self
):
122 Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self
.static
, self
.prefix
,
125 self
.outputCheckConvertArg()
126 Output("if (!%s_Check(v))", self
.prefix
)
128 Output('PyErr_SetString(PyExc_TypeError, "%s required");', self
.name
)
131 Output("*p_itself = ((%s *)v)->ob_itself;", self
.objecttype
)
135 def outputCheckConvertArg(self
):
136 "Override this method to apply additional conversions"
138 def outputDealloc(self
):
140 Output("static void %s_dealloc(%s *self)", self
.prefix
, self
.objecttype
)
142 self
.outputCleanupStructMembers()
144 Output("%s.tp_dealloc((PyObject *)self);", self
.basetype
)
145 elif hasattr(self
, 'output_tp_free'):
146 # This is a new-style object with tp_free slot
147 Output("self->ob_type->tp_free((PyObject *)self);")
149 Output("PyObject_Free((PyObject *)self);")
152 def outputCleanupStructMembers(self
):
153 self
.outputFreeIt("self->ob_itself")
155 def outputFreeIt(self
, name
):
156 Output("/* Cleanup of %s goes here */", name
)
158 def outputGetattr(self
):
160 Output("static PyObject *%s_getattr(%s *self, char *name)", self
.prefix
, self
.objecttype
)
162 self
.outputGetattrBody()
165 def outputGetattrBody(self
):
166 self
.outputGetattrHook()
167 Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);",
170 def outputGetattrHook(self
):
173 def outputSetattr(self
):
175 Output("#define %s_setattr NULL", self
.prefix
)
177 def outputCompare(self
):
179 Output("#define %s_compare NULL", self
.prefix
)
181 def outputRepr(self
):
183 Output("#define %s_repr NULL", self
.prefix
)
185 def outputHash(self
):
187 Output("#define %s_hash NULL", self
.prefix
)
189 def outputTypeObject(self
):
190 sf
= self
.static
and "static "
192 Output("%sPyTypeObject %s = {", sf
, self
.typename
)
194 Output("PyObject_HEAD_INIT(NULL)")
195 Output("0, /*ob_size*/")
197 Output("\"%s.%s\", /*tp_name*/", self
.modulename
, self
.name
)
199 Output("\"%s\", /*tp_name*/", self
.name
)
200 Output("sizeof(%s), /*tp_basicsize*/", self
.objecttype
)
201 Output("0, /*tp_itemsize*/")
202 Output("/* methods */")
203 Output("(destructor) %s_dealloc, /*tp_dealloc*/", self
.prefix
)
204 Output("0, /*tp_print*/")
205 Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self
.prefix
)
206 Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self
.prefix
)
207 Output("(cmpfunc) %s_compare, /*tp_compare*/", self
.prefix
)
208 Output("(reprfunc) %s_repr, /*tp_repr*/", self
.prefix
)
209 Output("(PyNumberMethods *)0, /* tp_as_number */")
210 Output("(PySequenceMethods *)0, /* tp_as_sequence */")
211 Output("(PyMappingMethods *)0, /* tp_as_mapping */")
212 Output("(hashfunc) %s_hash, /*tp_hash*/", self
.prefix
)
216 def outputTypeObjectInitializer(self
):
217 Output("""%s.ob_type = &PyType_Type;""", self
.typename
)
219 Output("%s.tp_base = &%s;", self
.typename
, self
.basetype
)
220 Output("if (PyType_Ready(&%s) < 0) return;", self
.typename
)
221 Output("""Py_INCREF(&%s);""", self
.typename
)
222 Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self
.name
, self
.typename
);
223 self
.outputTypeObjectInitializerCompat()
225 def outputTypeObjectInitializerCompat(self
):
226 Output("/* Backward-compatible name */")
227 Output("""Py_INCREF(&%s);""", self
.typename
);
228 Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self
.name
, self
.typename
);
230 def outputPEP253Hooks(self
):
236 def assertions(self
):
237 # Check that various things aren't overridden. If they are it could
238 # signify a bgen-client that has been partially converted to PEP252.
239 assert self
.outputGetattr
.im_func
== PEP252Mixin
.outputGetattr
.im_func
240 assert self
.outputSetattr
.im_func
== PEP252Mixin
.outputSetattr
.im_func
241 assert self
.outputGetattrBody
== None
242 assert self
.outputGetattrHook
== None
243 assert self
.basechain
== "NULL"
245 def outputGetattr(self
):
248 outputGetattrBody
= None
250 outputGetattrHook
= None
252 def outputSetattr(self
):
255 def outputMethodChain(self
):
256 # This is a good place to output the getters and setters
257 self
.outputGetSetList()
259 def outputHook(self
, name
):
260 methodname
= "outputHook_" + name
261 if hasattr(self
, methodname
):
262 func
= getattr(self
, methodname
)
265 Output("0, /*%s*/", name
)
267 def outputTypeObject(self
):
268 sf
= self
.static
and "static "
270 Output("%sPyTypeObject %s = {", sf
, self
.typename
)
272 Output("PyObject_HEAD_INIT(NULL)")
273 Output("0, /*ob_size*/")
275 Output("\"%s.%s\", /*tp_name*/", self
.modulename
, self
.name
)
277 Output("\"%s\", /*tp_name*/", self
.name
)
278 Output("sizeof(%s), /*tp_basicsize*/", self
.objecttype
)
279 Output("0, /*tp_itemsize*/")
281 Output("/* methods */")
282 Output("(destructor) %s_dealloc, /*tp_dealloc*/", self
.prefix
)
283 Output("0, /*tp_print*/")
284 Output("(getattrfunc)0, /*tp_getattr*/")
285 Output("(setattrfunc)0, /*tp_setattr*/")
286 Output("(cmpfunc) %s_compare, /*tp_compare*/", self
.prefix
)
287 Output("(reprfunc) %s_repr, /*tp_repr*/", self
.prefix
)
289 Output("(PyNumberMethods *)0, /* tp_as_number */")
290 Output("(PySequenceMethods *)0, /* tp_as_sequence */")
291 Output("(PyMappingMethods *)0, /* tp_as_mapping */")
293 Output("(hashfunc) %s_hash, /*tp_hash*/", self
.prefix
)
294 self
.outputHook("tp_call")
295 Output("0, /*tp_str*/")
296 Output("PyObject_GenericGetAttr, /*tp_getattro*/")
297 Output("PyObject_GenericSetAttr, /*tp_setattro */")
299 self
.outputHook("tp_as_buffer")
300 Output("%s, /* tp_flags */", self
.tp_flags
)
301 self
.outputHook("tp_doc")
302 self
.outputHook("tp_traverse")
303 self
.outputHook("tp_clear")
304 self
.outputHook("tp_richcompare")
305 self
.outputHook("tp_weaklistoffset")
306 self
.outputHook("tp_iter")
307 self
.outputHook("tp_iternext")
308 Output("%s_methods, /* tp_methods */", self
.prefix
)
309 self
.outputHook("tp_members")
310 Output("%s_getsetlist, /*tp_getset*/", self
.prefix
)
311 self
.outputHook("tp_base")
312 self
.outputHook("tp_dict")
313 self
.outputHook("tp_descr_get")
314 self
.outputHook("tp_descr_set")
315 self
.outputHook("tp_dictoffset")
316 self
.outputHook("tp_init")
317 self
.outputHook("tp_alloc")
318 self
.outputHook("tp_new")
319 self
.outputHook("tp_free")
323 def outputGetSetList(self
):
325 for name
, get
, set, doc
in self
.getsetlist
:
327 self
.outputGetter(name
, get
)
329 Output("#define %s_get_%s NULL", self
.prefix
, name
)
332 self
.outputSetter(name
, set)
334 Output("#define %s_set_%s NULL", self
.prefix
, name
)
337 Output("static PyGetSetDef %s_getsetlist[] = {", self
.prefix
)
339 for name
, get
, set, doc
in self
.getsetlist
:
341 doc
= '"' + doc
+ '"'
344 Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},",
345 name
, self
.prefix
, name
, self
.prefix
, name
, doc
)
346 Output("{NULL, NULL, NULL, NULL},")
350 Output("#define %s_getsetlist NULL", self
.prefix
)
353 def outputGetter(self
, name
, code
):
354 Output("static PyObject *%s_get_%s(%s *self, void *closure)",
355 self
.prefix
, name
, self
.objecttype
)
361 def outputSetter(self
, name
, code
):
362 Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)",
363 self
.prefix
, name
, self
.objecttype
)
370 class PEP253Mixin(PEP252Mixin
):
371 tp_flags
= "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"
373 def outputHook_tp_init(self
):
374 Output("%s_tp_init, /* tp_init */", self
.prefix
)
376 def outputHook_tp_alloc(self
):
377 Output("%s_tp_alloc, /* tp_alloc */", self
.prefix
)
379 def outputHook_tp_new(self
):
380 Output("%s_tp_new, /* tp_new */", self
.prefix
)
382 def outputHook_tp_free(self
):
383 Output("%s_tp_free, /* tp_free */", self
.prefix
)
385 def output_tp_initBody_basecall(self
):
386 """If a type shares its init call with its base type set output_tp_initBody
387 to output_tp_initBody_basecall"""
389 Output("if (%s.tp_init)", self
.basetype
)
391 Output("if ( (*%s.tp_init)(_self, _args, _kwds) < 0) return -1;", self
.basetype
)
394 output_tp_initBody
= None
396 def output_tp_init(self
):
397 if self
.output_tp_initBody
:
398 Output("static int %s_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)", self
.prefix
)
400 self
.output_tp_initBody()
403 Output("#define %s_tp_init 0", self
.prefix
)
406 output_tp_allocBody
= None
408 def output_tp_alloc(self
):
409 if self
.output_tp_allocBody
:
410 Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)",
413 self
.output_tp_allocBody()
416 Output("#define %s_tp_alloc PyType_GenericAlloc", self
.prefix
)
419 def output_tp_newBody(self
):
420 Output("PyObject *_self;");
421 Output("%s itself;", self
.itselftype
);
422 Output("char *kw[] = {\"itself\", 0};")
424 Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;",
427 Output("if (%s.tp_new)", self
.basetype
)
429 Output("if ( (*%s.tp_new)(type, _args, _kwds) == NULL) return NULL;", self
.basetype
)
433 Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;")
436 Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;")
437 Output("((%s *)_self)->ob_itself = itself;", self
.objecttype
)
438 Output("return _self;")
440 def output_tp_new(self
):
441 if self
.output_tp_newBody
:
442 Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)", self
.prefix
)
444 self
.output_tp_newBody()
447 Output("#define %s_tp_new PyType_GenericNew", self
.prefix
)
450 output_tp_freeBody
= None
452 def output_tp_free(self
):
453 if self
.output_tp_freeBody
:
454 Output("static void %s_tp_free(PyObject *self)", self
.prefix
)
456 self
.output_tp_freeBody()
459 Output("#define %s_tp_free PyObject_Del", self
.prefix
)
462 def outputPEP253Hooks(self
):
463 self
.output_tp_init()
464 self
.output_tp_alloc()
466 self
.output_tp_free()
468 class GlobalObjectDefinition(ObjectDefinition
):
469 """Like ObjectDefinition but exports some parts.
471 XXX Should also somehow generate a .h file for them.
474 def __init__(self
, name
, prefix
= None, itselftype
= None):
475 ObjectDefinition
.__init
__(self
, name
, prefix
or name
, itselftype
or name
)
478 class ObjectIdentityMixin
:
479 """A mixin class for objects that makes the identity of ob_itself
480 govern comparisons and dictionary lookups. Useful if the C object can
481 be returned by library calls and it is difficult (or impossible) to find
482 the corresponding Python objects. With this you can create Python object
483 wrappers on the fly"""
485 def outputCompare(self
):
487 Output("static int %s_compare(%s *self, %s *other)", self
.prefix
, self
.objecttype
,
490 Output("unsigned long v, w;")
492 Output("if (!%s_Check((PyObject *)other))", self
.prefix
)
494 Output("v=(unsigned long)self;")
495 Output("w=(unsigned long)other;")
499 Output("v=(unsigned long)self->ob_itself;")
500 Output("w=(unsigned long)other->ob_itself;")
502 Output("if( v < w ) return -1;")
503 Output("if( v > w ) return 1;")
507 def outputHash(self
):
509 Output("static long %s_hash(%s *self)", self
.prefix
, self
.objecttype
)
511 Output("return (long)self->ob_itself;")