Home | History | Annotate | Download | only in res
      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