blob: 87ae40f8c1a5c251c40af95e30621645f574b50b [file] [log] [blame]
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +00001from bgenOutput import *
2from bgenGeneratorGroup import GeneratorGroup
3
4class ObjectDefinition(GeneratorGroup):
Guido van Rossum01f5a811995-01-25 22:59:21 +00005 "Spit out code that together defines a new Python object type"
Jack Jansen1319abf2001-06-28 22:07:30 +00006 basechain = "NULL"
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +00007
8 def __init__(self, name, prefix, itselftype):
Guido van Rossum01f5a811995-01-25 22:59:21 +00009 """ObjectDefinition constructor. May be extended, but do not override.
10
11 - name: the object's official name, e.g. 'SndChannel'.
12 - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'.
13 - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'.
14
15 XXX For official Python data types, rules for the 'Py' prefix are a problem.
16 """
17
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000018 GeneratorGroup.__init__(self, prefix or name)
19 self.name = name
20 self.itselftype = itselftype
21 self.objecttype = name + 'Object'
Guido van Rossum8d6c1801995-01-18 23:46:59 +000022 self.typename = name + '_Type'
23 self.argref = "" # set to "*" if arg to <type>_New should be pointer
Guido van Rossum01f5a811995-01-25 22:59:21 +000024 self.static = "static " # set to "" to make <type>_New and <type>_Convert public
Jack Jansen5801a2d2001-12-09 23:25:00 +000025 self.modulename = None
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000026
Jack Jansen27489d42000-12-12 22:24:35 +000027 def add(self, g, dupcheck=0):
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000028 g.setselftype(self.objecttype, self.itselftype)
Jack Jansen27489d42000-12-12 22:24:35 +000029 GeneratorGroup.add(self, g, dupcheck)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000030
31 def reference(self):
32 # In case we are referenced from a module
33 pass
Jack Jansen5801a2d2001-12-09 23:25:00 +000034
35 def setmodulename(self, name):
36 self.modulename = name
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000037
38 def generate(self):
39 # XXX This should use long strings and %(varname)s substitution!
40
41 OutHeader2("Object type " + self.name)
42
Guido van Rossum01f5a811995-01-25 22:59:21 +000043 sf = self.static and "staticforward "
44 Output("%sPyTypeObject %s;", sf, self.typename)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000045 Output()
Guido van Rossum8d6c1801995-01-18 23:46:59 +000046 Output("#define %s_Check(x) ((x)->ob_type == &%s)",
47 self.prefix, self.typename)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000048 Output()
Guido van Rossum01f5a811995-01-25 22:59:21 +000049 Output("typedef struct %s {", self.objecttype)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000050 IndentLevel()
Guido van Rossum8d6c1801995-01-18 23:46:59 +000051 Output("PyObject_HEAD")
Guido van Rossum01f5a811995-01-25 22:59:21 +000052 self.outputStructMembers()
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000053 DedentLevel()
54 Output("} %s;", self.objecttype)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000055
Guido van Rossum8d6c1801995-01-18 23:46:59 +000056 self.outputNew()
57
58 self.outputConvert()
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000059
Guido van Rossum8d6c1801995-01-18 23:46:59 +000060 self.outputDealloc()
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000061
62 GeneratorGroup.generate(self)
63
Guido van Rossum80ffd661995-01-30 11:44:02 +000064 Output()
65 Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
66 self.static, self.prefix, self.prefix, self.basechain)
67
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000068 self.outputGetattr()
69
70 self.outputSetattr()
Guido van Rossum8d6c1801995-01-18 23:46:59 +000071
Guido van Rossumc7e7c601999-03-15 16:37:54 +000072 self.outputCompare()
73
74 self.outputRepr()
75
76 self.outputHash()
77
Guido van Rossum8d6c1801995-01-18 23:46:59 +000078 self.outputTypeObject()
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +000079
Guido van Rossum8d6c1801995-01-18 23:46:59 +000080 OutHeader2("End object type " + self.name)
81
Guido van Rossum01f5a811995-01-25 22:59:21 +000082 def outputStructMembers(self):
83 Output("%s ob_itself;", self.itselftype)
84
Guido van Rossum8d6c1801995-01-18 23:46:59 +000085 def outputNew(self):
Guido van Rossum80ffd661995-01-30 11:44:02 +000086 Output()
Jack Jansen656fe692001-05-19 13:59:18 +000087 Output("%sPyObject *%s_New(%s %sitself)", self.static, self.prefix,
88 self.itselftype, self.argref)
Guido van Rossum8d6c1801995-01-18 23:46:59 +000089 OutLbrace()
90 Output("%s *it;", self.objecttype)
Guido van Rossumf8de0681995-01-22 18:35:09 +000091 self.outputCheckNewArg()
Guido van Rossum8d6c1801995-01-18 23:46:59 +000092 Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
93 Output("if (it == NULL) return NULL;")
Guido van Rossum01f5a811995-01-25 22:59:21 +000094 self.outputInitStructMembers()
Guido van Rossumf8de0681995-01-22 18:35:09 +000095 Output("return (PyObject *)it;")
Guido van Rossum8d6c1801995-01-18 23:46:59 +000096 OutRbrace()
Guido van Rossum01f5a811995-01-25 22:59:21 +000097
98 def outputInitStructMembers(self):
99 Output("it->ob_itself = %sitself;", self.argref)
Guido van Rossumf8de0681995-01-22 18:35:09 +0000100
101 def outputCheckNewArg(self):
Guido van Rossum01f5a811995-01-25 22:59:21 +0000102 "Override this method to apply additional checks/conversions"
103
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000104 def outputConvert(self):
Jack Jansend157b372001-09-04 22:16:33 +0000105 Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix,
Jack Jansen656fe692001-05-19 13:59:18 +0000106 self.itselftype)
Guido van Rossum01f5a811995-01-25 22:59:21 +0000107 OutLbrace()
108 self.outputCheckConvertArg()
109 Output("if (!%s_Check(v))", self.prefix)
110 OutLbrace()
111 Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name)
112 Output("return 0;")
113 OutRbrace()
114 Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype)
115 Output("return 1;")
116 OutRbrace()
117
118 def outputCheckConvertArg(self):
119 "Override this method to apply additional conversions"
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000120
121 def outputDealloc(self):
Guido van Rossum80ffd661995-01-30 11:44:02 +0000122 Output()
Jack Jansen656fe692001-05-19 13:59:18 +0000123 Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype)
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000124 OutLbrace()
Guido van Rossum01f5a811995-01-25 22:59:21 +0000125 self.outputCleanupStructMembers()
Jack Jansena6aa71d2002-04-19 14:29:47 +0000126 Output("PyObject_Del(self);")
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000127 OutRbrace()
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000128
Guido van Rossum01f5a811995-01-25 22:59:21 +0000129 def outputCleanupStructMembers(self):
130 self.outputFreeIt("self->ob_itself")
131
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000132 def outputFreeIt(self, name):
133 Output("/* Cleanup of %s goes here */", name)
134
135 def outputGetattr(self):
Guido van Rossum80ffd661995-01-30 11:44:02 +0000136 Output()
Jack Jansen656fe692001-05-19 13:59:18 +0000137 Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype)
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000138 OutLbrace()
139 self.outputGetattrBody()
140 OutRbrace()
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000141
142 def outputGetattrBody(self):
143 self.outputGetattrHook()
Guido van Rossum80ffd661995-01-30 11:44:02 +0000144 Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);",
145 self.prefix)
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000146
147 def outputGetattrHook(self):
148 pass
149
150 def outputSetattr(self):
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000151 Output()
Guido van Rossum80ffd661995-01-30 11:44:02 +0000152 Output("#define %s_setattr NULL", self.prefix)
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000153
Guido van Rossumc7e7c601999-03-15 16:37:54 +0000154 def outputCompare(self):
155 Output()
156 Output("#define %s_compare NULL", self.prefix)
157
158 def outputRepr(self):
159 Output()
160 Output("#define %s_repr NULL", self.prefix)
161
162 def outputHash(self):
163 Output()
164 Output("#define %s_hash NULL", self.prefix)
165
Guido van Rossum8d6c1801995-01-18 23:46:59 +0000166 def outputTypeObject(self):
Guido van Rossum97842951995-02-19 15:59:49 +0000167 sf = self.static and "staticforward "
Guido van Rossum80ffd661995-01-30 11:44:02 +0000168 Output()
Guido van Rossum97842951995-02-19 15:59:49 +0000169 Output("%sPyTypeObject %s = {", sf, self.typename)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +0000170 IndentLevel()
Jack Jansen1062e702001-11-14 15:48:13 +0000171 Output("PyObject_HEAD_INIT(NULL)")
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +0000172 Output("0, /*ob_size*/")
Jack Jansen5801a2d2001-12-09 23:25:00 +0000173 if self.modulename:
174 Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name)
175 else:
176 Output("\"%s\", /*tp_name*/", self.name)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +0000177 Output("sizeof(%s), /*tp_basicsize*/", self.objecttype)
178 Output("0, /*tp_itemsize*/")
179 Output("/* methods */")
180 Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix)
181 Output("0, /*tp_print*/")
182 Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix)
183 Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix)
Guido van Rossumc7e7c601999-03-15 16:37:54 +0000184 Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix)
185 Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix)
186 Output("(PyNumberMethods *)0, /* tp_as_number */")
187 Output("(PySequenceMethods *)0, /* tp_as_sequence */")
188 Output("(PyMappingMethods *)0, /* tp_as_mapping */")
189 Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix)
Guido van Rossum8cfc4bf1995-01-18 23:45:01 +0000190 DedentLevel()
191 Output("};")
Guido van Rossum03be7f51997-09-22 16:13:19 +0000192
193 def outputTypeObjectInitializer(self):
194 Output("""%s.ob_type = &PyType_Type;""", self.typename);
195 Output("""Py_INCREF(&%s);""", self.typename);
196 Output("""if (PyDict_SetItemString(d, "%sType", (PyObject *)&%s) != 0)""",
197 self.name, self.typename);
198 IndentLevel()
Jack Jansen94035912001-08-27 14:30:55 +0000199 Output("""Py_FatalError("can\'t initialize %sType");""",
Guido van Rossum03be7f51997-09-22 16:13:19 +0000200 self.name)
201 DedentLevel()
202
Guido van Rossum01f5a811995-01-25 22:59:21 +0000203
204
205class GlobalObjectDefinition(ObjectDefinition):
Guido van Rossum80ffd661995-01-30 11:44:02 +0000206 """Like ObjectDefinition but exports some parts.
207
208 XXX Should also somehow generate a .h file for them.
209 """
Guido van Rossum01f5a811995-01-25 22:59:21 +0000210
211 def __init__(self, name, prefix = None, itselftype = None):
212 ObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
213 self.static = ""
Guido van Rossumc7e7c601999-03-15 16:37:54 +0000214
215class ObjectIdentityMixin:
216 """A mixin class for objects that makes the identity of ob_itself
217 govern comparisons and dictionary lookups. Useful if the C object can
218 be returned by library calls and it is difficult (or impossible) to find
219 the corresponding Python objects. With this you can create Python object
220 wrappers on the fly"""
221
222 def outputCompare(self):
223 Output()
Jack Jansen656fe692001-05-19 13:59:18 +0000224 Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype,
225 self.objecttype)
Guido van Rossumc7e7c601999-03-15 16:37:54 +0000226 OutLbrace()
227 Output("unsigned long v, w;")
228 Output()
229 Output("if (!%s_Check((PyObject *)other))", self.prefix)
230 OutLbrace()
231 Output("v=(unsigned long)self;")
232 Output("w=(unsigned long)other;")
233 OutRbrace()
234 Output("else")
235 OutLbrace()
236 Output("v=(unsigned long)self->ob_itself;")
237 Output("w=(unsigned long)other->ob_itself;")
238 OutRbrace()
239 Output("if( v < w ) return -1;")
240 Output("if( v > w ) return 1;")
241 Output("return 0;")
242 OutRbrace()
243
244 def outputHash(self):
245 Output()
Jack Jansen656fe692001-05-19 13:59:18 +0000246 Output("static long %s_hash(%s *self)", self.prefix, self.objecttype)
Guido van Rossumc7e7c601999-03-15 16:37:54 +0000247 OutLbrace()
248 Output("return (long)self->ob_itself;")
249 OutRbrace()
250
251