changes by Barry, e.g. font lock & email addresses
[python/dscho.git] / Tools / bgen / bgen / bgenObjectDefinition.py
blobdd1ad326edd01760df40d1d6f9241dca0981b48a
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 def __init__(self, name, prefix, itselftype):
8 """ObjectDefinition constructor. May be extended, but do not override.
10 - name: the object's official name, e.g. 'SndChannel'.
11 - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'.
12 - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'.
14 XXX For official Python data types, rules for the 'Py' prefix are a problem.
15 """
17 GeneratorGroup.__init__(self, prefix or name)
18 self.name = name
19 self.itselftype = itselftype
20 self.objecttype = name + 'Object'
21 self.typename = name + '_Type'
22 self.argref = "" # set to "*" if arg to <type>_New should be pointer
23 self.static = "static " # set to "" to make <type>_New and <type>_Convert public
24 self.basechain = "NULL" # set to &<basetype>_chain to chain methods
26 def add(self, g):
27 g.setselftype(self.objecttype, self.itselftype)
28 GeneratorGroup.add(self, g)
30 def reference(self):
31 # In case we are referenced from a module
32 pass
34 def generate(self):
35 # XXX This should use long strings and %(varname)s substitution!
37 OutHeader2("Object type " + self.name)
39 sf = self.static and "staticforward "
40 Output("%sPyTypeObject %s;", sf, self.typename)
41 Output()
42 Output("#define %s_Check(x) ((x)->ob_type == &%s)",
43 self.prefix, self.typename)
44 Output()
45 Output("typedef struct %s {", self.objecttype)
46 IndentLevel()
47 Output("PyObject_HEAD")
48 self.outputStructMembers()
49 DedentLevel()
50 Output("} %s;", self.objecttype)
52 self.outputNew()
54 self.outputConvert()
56 self.outputDealloc()
58 GeneratorGroup.generate(self)
60 Output()
61 Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
62 self.static, self.prefix, self.prefix, self.basechain)
64 self.outputGetattr()
66 self.outputSetattr()
68 self.outputTypeObject()
70 OutHeader2("End object type " + self.name)
72 def outputStructMembers(self):
73 Output("%s ob_itself;", self.itselftype)
75 def outputNew(self):
76 Output()
77 Output("%sPyObject *%s_New(itself)", self.static, self.prefix)
78 IndentLevel()
79 Output("%s %sitself;", self.itselftype, self.argref)
80 DedentLevel()
81 OutLbrace()
82 Output("%s *it;", self.objecttype)
83 self.outputCheckNewArg()
84 Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
85 Output("if (it == NULL) return NULL;")
86 self.outputInitStructMembers()
87 Output("return (PyObject *)it;")
88 OutRbrace()
90 def outputInitStructMembers(self):
91 Output("it->ob_itself = %sitself;", self.argref)
93 def outputCheckNewArg(self):
94 "Override this method to apply additional checks/conversions"
96 def outputConvert(self):
97 Output("%s%s_Convert(v, p_itself)", self.static, self.prefix)
98 IndentLevel()
99 Output("PyObject *v;")
100 Output("%s *p_itself;", self.itselftype)
101 DedentLevel()
102 OutLbrace()
103 self.outputCheckConvertArg()
104 Output("if (!%s_Check(v))", self.prefix)
105 OutLbrace()
106 Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name)
107 Output("return 0;")
108 OutRbrace()
109 Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype)
110 Output("return 1;")
111 OutRbrace()
113 def outputCheckConvertArg(self):
114 "Override this method to apply additional conversions"
116 def outputDealloc(self):
117 Output()
118 Output("static void %s_dealloc(self)", self.prefix)
119 IndentLevel()
120 Output("%s *self;", self.objecttype)
121 DedentLevel()
122 OutLbrace()
123 self.outputCleanupStructMembers()
124 Output("PyMem_DEL(self);")
125 OutRbrace()
127 def outputCleanupStructMembers(self):
128 self.outputFreeIt("self->ob_itself")
130 def outputFreeIt(self, name):
131 Output("/* Cleanup of %s goes here */", name)
133 def outputGetattr(self):
134 Output()
135 Output("static PyObject *%s_getattr(self, name)", self.prefix)
136 IndentLevel()
137 Output("%s *self;", self.objecttype)
138 Output("char *name;")
139 DedentLevel()
140 OutLbrace()
141 self.outputGetattrBody()
142 OutRbrace()
144 def outputGetattrBody(self):
145 self.outputGetattrHook()
146 Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);",
147 self.prefix)
149 def outputGetattrHook(self):
150 pass
152 def outputSetattr(self):
153 Output()
154 Output("#define %s_setattr NULL", self.prefix)
156 def outputTypeObject(self):
157 sf = self.static and "staticforward "
158 Output()
159 Output("%sPyTypeObject %s = {", sf, self.typename)
160 IndentLevel()
161 Output("PyObject_HEAD_INIT(&PyType_Type)")
162 Output("0, /*ob_size*/")
163 Output("\"%s\", /*tp_name*/", self.name)
164 Output("sizeof(%s), /*tp_basicsize*/", self.objecttype)
165 Output("0, /*tp_itemsize*/")
166 Output("/* methods */")
167 Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix)
168 Output("0, /*tp_print*/")
169 Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix)
170 Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix)
171 DedentLevel()
172 Output("};")
175 class GlobalObjectDefinition(ObjectDefinition):
176 """Like ObjectDefinition but exports some parts.
178 XXX Should also somehow generate a .h file for them.
181 def __init__(self, name, prefix = None, itselftype = None):
182 ObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
183 self.static = ""