Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 1 | # This script will generate the Resources interface for Python. |
| 2 | # It uses the "bgen" package to generate C code. |
| 3 | # It execs the file resgen.py which contain the function definitions |
| 4 | # (resgen.py was generated by resscan.py, scanning the <Resources.h> header file). |
| 5 | |
| 6 | from macsupport import * |
| 7 | |
| 8 | |
| 9 | class ResMixIn: |
| 10 | |
| 11 | def checkit(self): |
| 12 | OutLbrace() |
| 13 | Output("OSErr _err = ResError();") |
| 14 | Output("if (_err != noErr) return PyMac_Error(_err);") |
| 15 | OutRbrace() |
| 16 | FunctionGenerator.checkit(self) # XXX |
| 17 | |
| 18 | class ResFunction(ResMixIn, FunctionGenerator): pass |
| 19 | class ResMethod(ResMixIn, MethodGenerator): pass |
| 20 | |
| 21 | # includestuff etc. are imported from macsupport |
| 22 | |
| 23 | includestuff = includestuff + """ |
| 24 | #include <Resources.h> |
Jack Jansen | eaf3c9b | 1997-08-15 14:36:45 +0000 | [diff] [blame] | 25 | #include <string.h> |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 26 | |
| 27 | #define resNotFound -192 /* Can't include <Errors.h> because of Python's "errors.h" */ |
Jack Jansen | add03b6 | 2000-03-08 16:58:15 +0000 | [diff] [blame^] | 28 | |
| 29 | /* Function to dispose a resource, with a "normal" calling sequence */ |
| 30 | static void |
| 31 | PyMac_AutoDisposeHandle(Handle h) |
| 32 | { |
| 33 | DisposeHandle(h); |
| 34 | } |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 35 | """ |
| 36 | |
| 37 | finalstuff = finalstuff + """ |
Jack Jansen | 9f37c6d | 1995-08-17 14:29:23 +0000 | [diff] [blame] | 38 | |
| 39 | /* Alternative version of ResObj_New, which returns None for null argument */ |
Jack Jansen | 425e9eb | 1995-12-12 15:02:03 +0000 | [diff] [blame] | 40 | PyObject *OptResObj_New(itself) |
Jack Jansen | 9f37c6d | 1995-08-17 14:29:23 +0000 | [diff] [blame] | 41 | Handle itself; |
| 42 | { |
Jack Jansen | 9f37c6d | 1995-08-17 14:29:23 +0000 | [diff] [blame] | 43 | if (itself == NULL) { |
| 44 | Py_INCREF(Py_None); |
| 45 | return Py_None; |
| 46 | } |
| 47 | return ResObj_New(itself); |
| 48 | } |
| 49 | |
Jack Jansen | 425e9eb | 1995-12-12 15:02:03 +0000 | [diff] [blame] | 50 | OptResObj_Convert(v, p_itself) |
| 51 | PyObject *v; |
| 52 | Handle *p_itself; |
| 53 | { |
Jack Jansen | 2d76c25 | 1999-12-12 22:57:29 +0000 | [diff] [blame] | 54 | PyObject *tmp; |
| 55 | |
Jack Jansen | 425e9eb | 1995-12-12 15:02:03 +0000 | [diff] [blame] | 56 | if ( v == Py_None ) { |
| 57 | *p_itself = NULL; |
| 58 | return 1; |
| 59 | } |
Jack Jansen | 2d76c25 | 1999-12-12 22:57:29 +0000 | [diff] [blame] | 60 | if (ResObj_Check(v)) |
Jack Jansen | 425e9eb | 1995-12-12 15:02:03 +0000 | [diff] [blame] | 61 | { |
Jack Jansen | 2d76c25 | 1999-12-12 22:57:29 +0000 | [diff] [blame] | 62 | *p_itself = ((ResourceObject *)v)->ob_itself; |
| 63 | return 1; |
Jack Jansen | 425e9eb | 1995-12-12 15:02:03 +0000 | [diff] [blame] | 64 | } |
Jack Jansen | 2d76c25 | 1999-12-12 22:57:29 +0000 | [diff] [blame] | 65 | /* If it isn't a resource yet see whether it is convertible */ |
| 66 | if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) ) { |
| 67 | *p_itself = ((ResourceObject *)tmp)->ob_itself; |
| 68 | Py_DECREF(tmp); |
| 69 | return 1; |
| 70 | } |
| 71 | PyErr_Clear(); |
| 72 | PyErr_SetString(PyExc_TypeError, "Resource required"); |
| 73 | return 0; |
Jack Jansen | 425e9eb | 1995-12-12 15:02:03 +0000 | [diff] [blame] | 74 | } |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 75 | """ |
| 76 | |
| 77 | initstuff = initstuff + """ |
| 78 | """ |
| 79 | |
| 80 | module = MacModule('Res', 'Res', includestuff, finalstuff, initstuff) |
| 81 | |
| 82 | getattrHookCode = """ |
| 83 | if (strcmp(name, "size") == 0) |
| 84 | return PyInt_FromLong(GetHandleSize(self->ob_itself)); |
| 85 | if (strcmp(name, "data") == 0) { |
| 86 | PyObject *res; |
| 87 | char state; |
| 88 | state = HGetState(self->ob_itself); |
| 89 | HLock(self->ob_itself); |
| 90 | res = PyString_FromStringAndSize( |
| 91 | *self->ob_itself, |
| 92 | GetHandleSize(self->ob_itself)); |
| 93 | HUnlock(self->ob_itself); |
| 94 | HSetState(self->ob_itself, state); |
| 95 | return res; |
| 96 | } |
| 97 | if (strcmp(name, "__members__") == 0) |
| 98 | return Py_BuildValue("[ss]", "data", "size"); |
| 99 | """ |
| 100 | |
Jack Jansen | 1e05402 | 1995-06-18 20:20:27 +0000 | [diff] [blame] | 101 | setattrCode = """ |
| 102 | static int |
| 103 | ResObj_setattr(self, name, value) |
| 104 | ResourceObject *self; |
| 105 | char *name; |
| 106 | PyObject *value; |
| 107 | { |
| 108 | char *data; |
| 109 | long size; |
| 110 | |
| 111 | if (strcmp(name, "data") != 0 || value == NULL ) |
| 112 | return -1; |
| 113 | if ( !PyString_Check(value) ) |
| 114 | return -1; |
| 115 | size = PyString_Size(value); |
| 116 | data = PyString_AsString(value); |
| 117 | /* XXXX Do I need the GetState/SetState calls? */ |
| 118 | SetHandleSize(self->ob_itself, size); |
| 119 | if ( MemError()) |
| 120 | return -1; |
| 121 | HLock(self->ob_itself); |
| 122 | memcpy((char *)*self->ob_itself, data, size); |
| 123 | HUnlock(self->ob_itself); |
| 124 | /* XXXX Should I do the Changed call immedeately? */ |
| 125 | return 0; |
| 126 | } |
| 127 | """ |
| 128 | |
Jack Jansen | add03b6 | 2000-03-08 16:58:15 +0000 | [diff] [blame^] | 129 | class ResDefinition(GlobalObjectDefinition): |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 130 | |
| 131 | def outputCheckNewArg(self): |
| 132 | Output("if (itself == NULL) return PyMac_Error(resNotFound);") |
Jack Jansen | 2d76c25 | 1999-12-12 22:57:29 +0000 | [diff] [blame] | 133 | |
| 134 | def outputCheckConvertArg(self): |
| 135 | # if it isn't a resource we may be able to coerce it |
| 136 | Output("if (!%s_Check(v))", self.prefix) |
| 137 | OutLbrace() |
| 138 | Output("PyObject *tmp;") |
| 139 | Output('if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) )') |
| 140 | OutLbrace() |
| 141 | Output("*p_itself = ((ResourceObject *)tmp)->ob_itself;") |
| 142 | Output("Py_DECREF(tmp);") |
| 143 | Output("return 1;") |
| 144 | OutRbrace() |
| 145 | Output("PyErr_Clear();") |
| 146 | OutRbrace() |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 147 | |
| 148 | def outputGetattrHook(self): |
| 149 | Output(getattrHookCode) |
Jack Jansen | 1e05402 | 1995-06-18 20:20:27 +0000 | [diff] [blame] | 150 | |
| 151 | def outputSetattr(self): |
| 152 | Output(setattrCode) |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 153 | |
Jack Jansen | add03b6 | 2000-03-08 16:58:15 +0000 | [diff] [blame^] | 154 | def outputStructMembers(self): |
| 155 | GlobalObjectDefinition.outputStructMembers(self) |
| 156 | Output("void (*ob_freeit)(%s ptr);", self.itselftype) |
| 157 | |
| 158 | def outputInitStructMembers(self): |
| 159 | GlobalObjectDefinition.outputInitStructMembers(self) |
| 160 | Output("it->ob_freeit = NULL;") |
| 161 | |
| 162 | def outputCleanupStructMembers(self): |
| 163 | Output("if (self->ob_freeit && self->ob_itself)") |
| 164 | OutLbrace() |
| 165 | Output("self->ob_freeit(self->ob_itself);") |
| 166 | OutRbrace() |
| 167 | Output("self->ob_itself = NULL;") |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 168 | |
Jack Jansen | add03b6 | 2000-03-08 16:58:15 +0000 | [diff] [blame^] | 169 | |
| 170 | resobject = ResDefinition('Resource', 'ResObj', 'Handle') |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 171 | module.addobject(resobject) |
| 172 | |
| 173 | functions = [] |
| 174 | resmethods = [] |
| 175 | |
| 176 | execfile('resgen.py') |
Guido van Rossum | 9bcb641 | 1995-02-05 16:54:27 +0000 | [diff] [blame] | 177 | execfile('resedit.py') |
Guido van Rossum | 17448e2 | 1995-01-30 11:53:55 +0000 | [diff] [blame] | 178 | |
| 179 | for f in functions: module.add(f) |
| 180 | for f in resmethods: resobject.add(f) |
| 181 | |
| 182 | SetOutputFileName('Resmodule.c') |
| 183 | module.generate() |