Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 1 | from bgenOutput import * |
| 2 | from bgenGeneratorGroup import GeneratorGroup |
| 3 | |
| 4 | class ObjectDefinition(GeneratorGroup): |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 5 | "Spit out code that together defines a new Python object type" |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 6 | |
| 7 | def __init__(self, name, prefix, itselftype): |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 8 | """ObjectDefinition constructor. May be extended, but do not override. |
| 9 | |
| 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'. |
| 13 | |
| 14 | XXX For official Python data types, rules for the 'Py' prefix are a problem. |
| 15 | """ |
| 16 | |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 17 | GeneratorGroup.__init__(self, prefix or name) |
| 18 | self.name = name |
| 19 | self.itselftype = itselftype |
| 20 | self.objecttype = name + 'Object' |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 21 | self.typename = name + '_Type' |
| 22 | self.argref = "" # set to "*" if arg to <type>_New should be pointer |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 23 | self.static = "static " # set to "" to make <type>_New and <type>_Convert public |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 24 | self.basechain = "NULL" # set to &<basetype>_chain to chain methods |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 25 | |
| 26 | def add(self, g): |
| 27 | g.setselftype(self.objecttype, self.itselftype) |
| 28 | GeneratorGroup.add(self, g) |
| 29 | |
| 30 | def reference(self): |
| 31 | # In case we are referenced from a module |
| 32 | pass |
| 33 | |
| 34 | def generate(self): |
| 35 | # XXX This should use long strings and %(varname)s substitution! |
| 36 | |
| 37 | OutHeader2("Object type " + self.name) |
| 38 | |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 39 | sf = self.static and "staticforward " |
| 40 | Output("%sPyTypeObject %s;", sf, self.typename) |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 41 | Output() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 42 | Output("#define %s_Check(x) ((x)->ob_type == &%s)", |
| 43 | self.prefix, self.typename) |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 44 | Output() |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 45 | Output("typedef struct %s {", self.objecttype) |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 46 | IndentLevel() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 47 | Output("PyObject_HEAD") |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 48 | self.outputStructMembers() |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 49 | DedentLevel() |
| 50 | Output("} %s;", self.objecttype) |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 51 | |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 52 | self.outputNew() |
| 53 | |
| 54 | self.outputConvert() |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 55 | |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 56 | self.outputDealloc() |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 57 | |
| 58 | GeneratorGroup.generate(self) |
| 59 | |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 60 | Output() |
| 61 | Output("%sPyMethodChain %s_chain = { %s_methods, %s };", |
| 62 | self.static, self.prefix, self.prefix, self.basechain) |
| 63 | |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 64 | self.outputGetattr() |
| 65 | |
| 66 | self.outputSetattr() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 67 | |
| 68 | self.outputTypeObject() |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 69 | |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 70 | OutHeader2("End object type " + self.name) |
| 71 | |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 72 | def outputStructMembers(self): |
| 73 | Output("%s ob_itself;", self.itselftype) |
| 74 | |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 75 | def outputNew(self): |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 76 | Output() |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 77 | Output("%sPyObject *%s_New(itself)", self.static, self.prefix) |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 78 | IndentLevel() |
Guido van Rossum | 9784295 | 1995-02-19 15:59:49 +0000 | [diff] [blame^] | 79 | Output("%s %sitself;", self.itselftype, self.argref) |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 80 | DedentLevel() |
| 81 | OutLbrace() |
| 82 | Output("%s *it;", self.objecttype) |
Guido van Rossum | f8de068 | 1995-01-22 18:35:09 +0000 | [diff] [blame] | 83 | self.outputCheckNewArg() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 84 | Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename) |
| 85 | Output("if (it == NULL) return NULL;") |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 86 | self.outputInitStructMembers() |
Guido van Rossum | f8de068 | 1995-01-22 18:35:09 +0000 | [diff] [blame] | 87 | Output("return (PyObject *)it;") |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 88 | OutRbrace() |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 89 | |
| 90 | def outputInitStructMembers(self): |
| 91 | Output("it->ob_itself = %sitself;", self.argref) |
Guido van Rossum | f8de068 | 1995-01-22 18:35:09 +0000 | [diff] [blame] | 92 | |
| 93 | def outputCheckNewArg(self): |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 94 | "Override this method to apply additional checks/conversions" |
| 95 | |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 96 | def outputConvert(self): |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 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() |
| 112 | |
| 113 | def outputCheckConvertArg(self): |
| 114 | "Override this method to apply additional conversions" |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 115 | |
| 116 | def outputDealloc(self): |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 117 | Output() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 118 | Output("static void %s_dealloc(self)", self.prefix) |
| 119 | IndentLevel() |
| 120 | Output("%s *self;", self.objecttype) |
| 121 | DedentLevel() |
| 122 | OutLbrace() |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 123 | self.outputCleanupStructMembers() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 124 | Output("PyMem_DEL(self);") |
| 125 | OutRbrace() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 126 | |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 127 | def outputCleanupStructMembers(self): |
| 128 | self.outputFreeIt("self->ob_itself") |
| 129 | |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 130 | def outputFreeIt(self, name): |
| 131 | Output("/* Cleanup of %s goes here */", name) |
| 132 | |
| 133 | def outputGetattr(self): |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 134 | Output() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 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() |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 143 | |
| 144 | def outputGetattrBody(self): |
| 145 | self.outputGetattrHook() |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 146 | Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);", |
| 147 | self.prefix) |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 148 | |
| 149 | def outputGetattrHook(self): |
| 150 | pass |
| 151 | |
| 152 | def outputSetattr(self): |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 153 | Output() |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 154 | Output("#define %s_setattr NULL", self.prefix) |
Guido van Rossum | 8d6c180 | 1995-01-18 23:46:59 +0000 | [diff] [blame] | 155 | |
| 156 | def outputTypeObject(self): |
Guido van Rossum | 9784295 | 1995-02-19 15:59:49 +0000 | [diff] [blame^] | 157 | sf = self.static and "staticforward " |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 158 | Output() |
Guido van Rossum | 9784295 | 1995-02-19 15:59:49 +0000 | [diff] [blame^] | 159 | Output("%sPyTypeObject %s = {", sf, self.typename) |
Guido van Rossum | 8cfc4bf | 1995-01-18 23:45:01 +0000 | [diff] [blame] | 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("};") |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 173 | |
| 174 | |
| 175 | class GlobalObjectDefinition(ObjectDefinition): |
Guido van Rossum | 80ffd66 | 1995-01-30 11:44:02 +0000 | [diff] [blame] | 176 | """Like ObjectDefinition but exports some parts. |
| 177 | |
| 178 | XXX Should also somehow generate a .h file for them. |
| 179 | """ |
Guido van Rossum | 01f5a81 | 1995-01-25 22:59:21 +0000 | [diff] [blame] | 180 | |
| 181 | def __init__(self, name, prefix = None, itselftype = None): |
| 182 | ObjectDefinition.__init__(self, name, prefix or name, itselftype or name) |
| 183 | self.static = "" |