mirror of https://github.com/python/cpython
222 lines
7.1 KiB
Python
222 lines
7.1 KiB
Python
# 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 <Resources.h> 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 <Carbon/Carbon.h>
|
|
|
|
#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 = []
|
|
|
|
exec(open('resgen.py').read())
|
|
exec(open('resedit.py').read())
|
|
|
|
for f in functions: module.add(f)
|
|
for f in resmethods: resobject.add(f)
|
|
|
|
SetOutputFileName('_Resmodule.c')
|
|
module.generate()
|