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 class ResMixIn: 9 10 def checkit(self): 11 if self.returntype.__class__ != OSErrType: 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, OSErrWeakLinkFunctionGenerator): pass 19 class ResMethod(ResMixIn, OSErrWeakLinkMethodGenerator): pass 20 21 RsrcChainLocation = Type("RsrcChainLocation", "h") 22 FSCatalogInfoBitmap = FakeType("0") # Type("FSCatalogInfoBitmap", "l") 23 FSCatalogInfo_ptr = FakeType("(FSCatalogInfo *)0") 24 25 # includestuff etc. are imported from macsupport 26 27 includestuff = includestuff + """ 28 #include <Carbon/Carbon.h> 29 30 #ifdef USE_TOOLBOX_OBJECT_GLUE 31 extern PyObject *_ResObj_New(Handle); 32 extern int _ResObj_Convert(PyObject *, Handle *); 33 extern PyObject *_OptResObj_New(Handle); 34 extern int _OptResObj_Convert(PyObject *, Handle *); 35 #define ResObj_New _ResObj_New 36 #define ResObj_Convert _ResObj_Convert 37 #define OptResObj_New _OptResObj_New 38 #define OptResObj_Convert _OptResObj_Convert 39 #endif 40 41 /* Function to dispose a resource, with a "normal" calling sequence */ 42 static void 43 PyMac_AutoDisposeHandle(Handle h) 44 { 45 DisposeHandle(h); 46 } 47 """ 48 49 finalstuff = finalstuff + """ 50 51 /* Alternative version of ResObj_New, which returns None for null argument */ 52 PyObject *OptResObj_New(Handle itself) 53 { 54 if (itself == NULL) { 55 Py_INCREF(Py_None); 56 return Py_None; 57 } 58 return ResObj_New(itself); 59 } 60 61 int OptResObj_Convert(PyObject *v, Handle *p_itself) 62 { 63 PyObject *tmp; 64 65 if ( v == Py_None ) { 66 *p_itself = NULL; 67 return 1; 68 } 69 if (ResObj_Check(v)) 70 { 71 *p_itself = ((ResourceObject *)v)->ob_itself; 72 return 1; 73 } 74 /* If it isn't a resource yet see whether it is convertible */ 75 if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) ) { 76 *p_itself = ((ResourceObject *)tmp)->ob_itself; 77 Py_DECREF(tmp); 78 return 1; 79 } 80 PyErr_Clear(); 81 PyErr_SetString(PyExc_TypeError, "Resource required"); 82 return 0; 83 } 84 """ 85 86 initstuff = initstuff + """ 87 PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, ResObj_New); 88 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, ResObj_Convert); 89 PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, OptResObj_New); 90 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, OptResObj_Convert); 91 """ 92 93 module = MacModule('_Res', 'Res', includestuff, finalstuff, initstuff) 94 95 class ResDefinition(PEP253Mixin, GlobalObjectDefinition): 96 getsetlist = [ 97 ('data', 98 """ 99 PyObject *res; 100 char state; 101 102 state = HGetState(self->ob_itself); 103 HLock(self->ob_itself); 104 res = PyString_FromStringAndSize( 105 *self->ob_itself, 106 GetHandleSize(self->ob_itself)); 107 HUnlock(self->ob_itself); 108 HSetState(self->ob_itself, state); 109 return res; 110 """, 111 """ 112 char *data; 113 long size; 114 115 if ( v == NULL ) 116 return -1; 117 if ( !PyString_Check(v) ) 118 return -1; 119 size = PyString_Size(v); 120 data = PyString_AsString(v); 121 /* XXXX Do I need the GetState/SetState calls? */ 122 SetHandleSize(self->ob_itself, size); 123 if ( MemError()) 124 return -1; 125 HLock(self->ob_itself); 126 memcpy((char *)*self->ob_itself, data, size); 127 HUnlock(self->ob_itself); 128 /* XXXX Should I do the Changed call immediately? */ 129 return 0; 130 """, 131 'The resource data' 132 ), ( 133 'size', 134 'return PyInt_FromLong(GetHandleSize(self->ob_itself));', 135 None, 136 'The length of the resource data' 137 )] 138 139 def outputCheckNewArg(self): 140 Output("if (itself == NULL) return PyMac_Error(resNotFound);") 141 142 def outputCheckConvertArg(self): 143 # if it isn't a resource we may be able to coerce it 144 Output("if (!%s_Check(v))", self.prefix) 145 OutLbrace() 146 Output("PyObject *tmp;") 147 Output('if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) )') 148 OutLbrace() 149 Output("*p_itself = ((ResourceObject *)tmp)->ob_itself;") 150 Output("Py_DECREF(tmp);") 151 Output("return 1;") 152 OutRbrace() 153 Output("PyErr_Clear();") 154 OutRbrace() 155 156 def outputStructMembers(self): 157 GlobalObjectDefinition.outputStructMembers(self) 158 Output("void (*ob_freeit)(%s ptr);", self.itselftype) 159 160 def outputInitStructMembers(self): 161 GlobalObjectDefinition.outputInitStructMembers(self) 162 Output("it->ob_freeit = NULL;") 163 164 def outputCleanupStructMembers(self): 165 Output("if (self->ob_freeit && self->ob_itself)") 166 OutLbrace() 167 Output("self->ob_freeit(self->ob_itself);") 168 OutRbrace() 169 Output("self->ob_itself = NULL;") 170 171 def output_tp_newBody(self): 172 Output("PyObject *self;") 173 Output 174 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") 175 Output("((%s *)self)->ob_itself = NULL;", self.objecttype) 176 Output("((%s *)self)->ob_freeit = NULL;", self.objecttype) 177 Output("return self;") 178 179 def output_tp_initBody(self): 180 Output("char *srcdata = NULL;") 181 Output("int srclen = 0;") 182 Output("%s itself;", self.itselftype); 183 Output("char *kw[] = {\"itself\", 0};") 184 Output() 185 Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself))", 186 self.prefix); 187 OutLbrace() 188 Output("((%s *)_self)->ob_itself = itself;", self.objecttype) 189 Output("return 0;") 190 OutRbrace() 191 Output("PyErr_Clear();") 192 Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|s#\", kw, &srcdata, &srclen)) return -1;") 193 Output("if ((itself = NewHandle(srclen)) == NULL)") 194 OutLbrace() 195 Output("PyErr_NoMemory();") 196 Output("return 0;") 197 OutRbrace() 198 Output("((%s *)_self)->ob_itself = itself;", self.objecttype) 199 # XXXX Output("((%s *)self)->ob_freeit = PyMac_AutoDisposeHandle;") 200 Output("if (srclen && srcdata)") 201 OutLbrace() 202 Output("HLock(itself);") 203 Output("memcpy(*itself, srcdata, srclen);") 204 Output("HUnlock(itself);") 205 OutRbrace() 206 Output("return 0;") 207 208 resobject = ResDefinition('Resource', 'ResObj', 'Handle') 209 module.addobject(resobject) 210 211 functions = [] 212 resmethods = [] 213 214 execfile('resgen.py') 215 execfile('resedit.py') 216 217 for f in functions: module.add(f) 218 for f in resmethods: resobject.add(f) 219 220 SetOutputFileName('_Resmodule.c') 221 module.generate() 222