# This script will generate the Resources interface for Python. # It uses the "bgen" package to generate C code. # It execs the file resgen.py which contain the function definitions # (resgen.py was generated by resscan.py, scanning the header file). from macsupport import * class ResMixIn: def checkit(self): if self.returntype.__class__ != OSErrType: OutLbrace() Output("OSErr _err = ResError();") Output("if (_err != noErr) return PyMac_Error(_err);") OutRbrace() FunctionGenerator.checkit(self) # XXX class ResFunction(ResMixIn, OSErrWeakLinkFunctionGenerator): pass class ResMethod(ResMixIn, OSErrWeakLinkMethodGenerator): pass RsrcChainLocation = Type("RsrcChainLocation", "h") FSCatalogInfoBitmap = FakeType("0") # Type("FSCatalogInfoBitmap", "l") FSCatalogInfo_ptr = FakeType("(FSCatalogInfo *)0") # includestuff etc. are imported from macsupport includestuff = includestuff + """ #include #ifdef USE_TOOLBOX_OBJECT_GLUE extern PyObject *_ResObj_New(Handle); extern int _ResObj_Convert(PyObject *, Handle *); extern PyObject *_OptResObj_New(Handle); extern int _OptResObj_Convert(PyObject *, Handle *); #define ResObj_New _ResObj_New #define ResObj_Convert _ResObj_Convert #define OptResObj_New _OptResObj_New #define OptResObj_Convert _OptResObj_Convert #endif /* Function to dispose a resource, with a "normal" calling sequence */ static void PyMac_AutoDisposeHandle(Handle h) { DisposeHandle(h); } """ finalstuff = finalstuff + """ /* Alternative version of ResObj_New, which returns None for null argument */ PyObject *OptResObj_New(Handle itself) { if (itself == NULL) { Py_INCREF(Py_None); return Py_None; } return ResObj_New(itself); } int OptResObj_Convert(PyObject *v, Handle *p_itself) { PyObject *tmp; if ( v == Py_None ) { *p_itself = NULL; return 1; } if (ResObj_Check(v)) { *p_itself = ((ResourceObject *)v)->ob_itself; return 1; } /* If it isn't a resource yet see whether it is convertible */ if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) ) { *p_itself = ((ResourceObject *)tmp)->ob_itself; Py_DECREF(tmp); return 1; } PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "Resource required"); return 0; } """ initstuff = initstuff + """ PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, ResObj_New); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, ResObj_Convert); PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, OptResObj_New); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, OptResObj_Convert); """ module = MacModule('_Res', 'Res', includestuff, finalstuff, initstuff) class ResDefinition(PEP253Mixin, GlobalObjectDefinition): getsetlist = [ ('data', """ PyObject *res; char state; state = HGetState(self->ob_itself); HLock(self->ob_itself); res = PyString_FromStringAndSize( *self->ob_itself, GetHandleSize(self->ob_itself)); HUnlock(self->ob_itself); HSetState(self->ob_itself, state); return res; """, """ char *data; long size; if ( v == NULL ) return -1; if ( !PyString_Check(v) ) return -1; size = PyString_Size(v); data = PyString_AsString(v); /* XXXX Do I need the GetState/SetState calls? */ SetHandleSize(self->ob_itself, size); if ( MemError()) return -1; HLock(self->ob_itself); memcpy((char *)*self->ob_itself, data, size); HUnlock(self->ob_itself); /* XXXX Should I do the Changed call immedeately? */ return 0; """, 'The resource data' ), ( 'size', 'return PyInt_FromLong(GetHandleSize(self->ob_itself));', None, 'The length of the resource data' )] def outputCheckNewArg(self): Output("if (itself == NULL) return PyMac_Error(resNotFound);") def outputCheckConvertArg(self): # if it isn't a resource we may be able to coerce it Output("if (!%s_Check(v))", self.prefix) OutLbrace() Output("PyObject *tmp;") Output('if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) )') OutLbrace() Output("*p_itself = ((ResourceObject *)tmp)->ob_itself;") Output("Py_DECREF(tmp);") Output("return 1;") OutRbrace() Output("PyErr_Clear();") OutRbrace() def outputStructMembers(self): GlobalObjectDefinition.outputStructMembers(self) Output("void (*ob_freeit)(%s ptr);", self.itselftype) def outputInitStructMembers(self): GlobalObjectDefinition.outputInitStructMembers(self) Output("it->ob_freeit = NULL;") def outputCleanupStructMembers(self): Output("if (self->ob_freeit && self->ob_itself)") OutLbrace() Output("self->ob_freeit(self->ob_itself);") OutRbrace() Output("self->ob_itself = NULL;") def output_tp_newBody(self): Output("PyObject *self;") Output Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") Output("((%s *)self)->ob_itself = NULL;", self.objecttype) Output("((%s *)self)->ob_freeit = NULL;", self.objecttype) Output("return self;") def output_tp_initBody(self): Output("char *srcdata = NULL;") Output("int srclen = 0;") Output("%s itself;", self.itselftype); Output("char *kw[] = {\"itself\", 0};") Output() Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself))", self.prefix); OutLbrace() Output("((%s *)_self)->ob_itself = itself;", self.objecttype) Output("return 0;") OutRbrace() Output("PyErr_Clear();") Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|s#\", kw, &srcdata, &srclen)) return -1;") Output("if ((itself = NewHandle(srclen)) == NULL)") OutLbrace() Output("PyErr_NoMemory();") Output("return 0;") OutRbrace() Output("((%s *)_self)->ob_itself = itself;", self.objecttype) # XXXX Output("((%s *)self)->ob_freeit = PyMac_AutoDisposeHandle;") Output("if (srclen && srcdata)") OutLbrace() Output("HLock(itself);") Output("memcpy(*itself, srcdata, srclen);") Output("HUnlock(itself);") OutRbrace() Output("return 0;") resobject = ResDefinition('Resource', 'ResObj', 'Handle') module.addobject(resobject) functions = [] resmethods = [] execfile('resgen.py') execfile('resedit.py') for f in functions: module.add(f) for f in resmethods: resobject.add(f) SetOutputFileName('_Resmodule.c') module.generate()