summaryrefslogtreecommitdiffstats
path: root/Mac
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>1997-02-17 16:56:56 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>1997-02-17 16:56:56 (GMT)
commitb3928d2ffdc75e621b410bec99aec878f2c20d2f (patch)
treeafa946200b65cf7864a2ea42e07e2d98279fef3e /Mac
parentce7fc98d86edca289462e3bc70436a5b68763913 (diff)
downloadcpython-b3928d2ffdc75e621b410bec99aec878f2c20d2f.zip
cpython-b3928d2ffdc75e621b410bec99aec878f2c20d2f.tar.gz
cpython-b3928d2ffdc75e621b410bec99aec878f2c20d2f.tar.bz2
An initial stab at calling random C routines from Python
Diffstat (limited to 'Mac')
-rw-r--r--Mac/Modules/calldll.c903
1 files changed, 903 insertions, 0 deletions
diff --git a/Mac/Modules/calldll.c b/Mac/Modules/calldll.c
new file mode 100644
index 0000000..02e0162
--- /dev/null
+++ b/Mac/Modules/calldll.c
@@ -0,0 +1,903 @@
+/***********************************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#include "Python.h"
+#include "macglue.h"
+#include "macdefs.h"
+
+extern PyObject *ResObj_New Py_PROTO((Handle));
+extern int ResObj_Convert Py_PROTO((PyObject *, Handle *));
+
+#include <CodeFragments.h>
+
+static PyObject *ErrorObject;
+
+#define PARANOID(arg) \
+ if ( arg == 0 ) {PyErr_SetString(ErrorObject, "Internal error: NULL arg!"); return 0; }
+
+/* Prototype we use for routines */
+
+typedef long anything;
+typedef anything (*anyroutine) Py_PROTO((...));
+
+#define MAXNAME 31 /* Maximum size of names, for printing only */
+#define MAXARG 8 /* Maximum number of arguments */
+
+/*
+** Routines to convert arguments between Python and C
+*/
+typedef anything (*py2c_converter) Py_PROTO((PyObject *));
+typedef PyObject *(*c2py_converter) Py_PROTO((anything));
+
+/* Dummy routine for arguments that are output-only */
+static anything
+py2c_dummy(arg)
+ PyObject *arg;
+{
+ return 0;
+}
+
+/* Routine to allocate storage for output integers */
+static anything
+py2c_alloc(arg)
+ PyObject *arg;
+{
+ char *ptr;
+
+ if( (ptr=malloc(sizeof(anything))) == 0 )
+ PyErr_NoMemory();
+ return (anything)ptr;
+}
+
+/* Dummy routine for arguments that are input-only */
+static PyObject *
+c2py_dummy(arg)
+ anything arg;
+{
+ return 0;
+}
+
+/* Routine to de-allocate storage for input-only arguments */
+static PyObject *
+c2py_free(arg)
+ anything arg;
+{
+ if ( arg )
+ free((char *)arg);
+ return 0;
+}
+
+/*
+** None
+*/
+static PyObject *
+c2py_none(arg)
+ anything arg;
+{
+ if ( arg )
+ free((char *)arg);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+** OSErr
+*/
+static PyObject *
+c2py_oserr(arg)
+ anything arg;
+{
+ OSErr *ptr = (OSErr *)arg;
+
+ PARANOID(arg);
+ if (*ptr) {
+ PyErr_Mac(PyMac_OSErrException, *ptr);
+ free(ptr);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+** integers of all sizes (PPC only)
+*/
+static anything
+py2c_in_int(arg)
+ PyObject *arg;
+{
+ return PyInt_AsLong(arg);
+}
+
+static PyObject *
+c2py_out_long(arg)
+ anything arg;
+{
+ PyObject *rv;
+
+ PARANOID(arg);
+ rv = PyInt_FromLong(*(long *)arg);
+ free((char *)arg);
+ return rv;
+}
+
+static PyObject *
+c2py_out_short(arg)
+ anything arg;
+{
+ PyObject *rv;
+
+ PARANOID(arg);
+ rv = PyInt_FromLong((long)*(short *)arg);
+ free((char *)arg);
+ return rv;
+}
+
+static PyObject *
+c2py_out_byte(arg)
+ anything arg;
+{
+ PyObject *rv;
+
+ PARANOID(arg);
+ rv = PyInt_FromLong((long)*(char *)arg);
+ free((char *)arg);
+ return rv;
+}
+
+/*
+** Strings
+*/
+static anything
+py2c_in_string(arg)
+ PyObject *arg;
+{
+ return (anything)PyString_AsString(arg);
+}
+
+/*
+** Pascal-style strings
+*/
+static anything
+py2c_in_pstring(arg)
+ PyObject *arg;
+{
+ unsigned char *p;
+ int size;
+
+ if( (size = PyString_Size(arg)) < 0)
+ return 0;
+ if ( size > 255 ) {
+ PyErr_SetString(ErrorObject, "Pstring must be <= 255 chars");
+ return 0;
+ }
+ if( (p=(unsigned char *)malloc(256)) == 0 ) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ p[0] = size;
+ memcpy(p+1, PyString_AsString(arg), size);
+ return (anything)p;
+}
+
+static anything
+py2c_out_pstring(arg)
+ PyObject *arg;
+{
+ unsigned char *p;
+
+ if( (p=(unsigned char *)malloc(256)) == 0 ) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ p[0] = 0;
+ return (anything)p;
+}
+
+static PyObject *
+c2py_out_pstring(arg)
+ anything arg;
+{
+ unsigned char *p = (unsigned char *)arg;
+ PyObject *rv;
+
+ PARANOID(arg);
+ rv = PyString_FromStringAndSize((char *)p+1, p[0]);
+ free(p);
+ return rv;
+}
+
+/*
+** C objects.
+*/
+static anything
+py2c_in_cobject(arg)
+ PyObject *arg;
+{
+ if ( arg == Py_None )
+ return 0;
+ return (anything)PyCObject_AsVoidPtr(arg);
+}
+
+static PyObject *
+c2py_out_cobject(arg)
+ anything arg;
+{
+ void **ptr = (void **)arg;
+ PyObject *rv;
+
+ PARANOID(arg);
+ if ( *ptr == 0 ) {
+ Py_INCREF(Py_None);
+ rv = Py_None;
+ } else {
+ rv = PyCObject_FromVoidPtr(*ptr, 0);
+ }
+ free((char *)ptr);
+ return rv;
+}
+
+/*
+** Handles.
+*/
+static anything
+py2c_in_handle(arg)
+ PyObject *arg;
+{
+ Handle h = 0;
+ ResObj_Convert(arg, &h);
+ return (anything)h;
+}
+
+static PyObject *
+c2py_out_handle(arg)
+ anything arg;
+{
+ Handle *rv = (Handle *)arg;
+ PyObject *prv;
+
+ PARANOID(arg);
+ if ( *rv == 0 ) {
+ Py_INCREF(Py_None);
+ prv = Py_None;
+ } else {
+ prv = ResObj_New(*rv);
+ }
+ free((char *)rv);
+ return prv;
+}
+
+typedef struct {
+ char *name; /* Name */
+ py2c_converter get; /* Get argument */
+ int get_uses_arg; /* True if the above consumes an argument */
+ c2py_converter put; /* Put result value */
+ int put_gives_result; /* True if above produces a result */
+} conventry;
+
+static conventry converters[] = {
+ {"OutNone", py2c_alloc, 0, c2py_none, 1},
+ {"OutOSErr", py2c_alloc, 0, c2py_oserr, 1},
+#define OSERRORCONVERTER (&converters[1])
+ {"InInt", py2c_in_int, 1, c2py_dummy, 0},
+ {"OutLong", py2c_alloc, 0, c2py_out_long, 1},
+ {"OutShort", py2c_alloc, 0, c2py_out_short, 1},
+ {"OutByte", py2c_alloc, 0, c2py_out_byte, 1},
+ {"InString", py2c_in_string, 1, c2py_dummy, 0},
+ {"InPstring", py2c_in_pstring,1, c2py_free, 0},
+ {"OutPstring", py2c_out_pstring,0, c2py_out_pstring,1},
+ {"InCobject", py2c_in_cobject,1, c2py_dummy, 0},
+ {"OutCobject", py2c_alloc, 0, c2py_out_cobject,0},
+ {"InHandle", py2c_in_handle, 1, c2py_dummy, 0},
+ {"OutHandle", py2c_alloc, 0, c2py_out_handle,1},
+ {0, 0, 0, 0, 0}
+};
+
+static conventry *
+getconverter(name)
+ char *name;
+{
+ int i;
+ char buf[256];
+
+ for(i=0; converters[i].name; i++ )
+ if ( strcmp(name, converters[i].name) == 0 )
+ return &converters[i];
+ sprintf(buf, "Unknown argtype: %s", name);
+ PyErr_SetString(ErrorObject, buf);
+ return 0;
+}
+
+static int
+argparse_conv(obj, ptr)
+ PyObject *obj;
+ conventry **ptr;
+{
+ char *name;
+ int i;
+ conventry *item;
+
+ if( (name=PyString_AsString(obj)) == NULL )
+ return 0;
+ if( (item=getconverter(name)) == NULL )
+ return 0;
+ *ptr = item;
+ return 1;
+}
+
+/* ----------------------------------------------------- */
+
+/* Declarations for objects of type fragment */
+
+typedef struct {
+ PyObject_HEAD
+ CFragConnectionID conn_id;
+ char name[MAXNAME+1];
+} cdfobject;
+
+staticforward PyTypeObject Cdftype;
+
+
+
+/* ---------------------------------------------------------------- */
+
+/* Declarations for objects of type routine */
+
+typedef struct {
+ PyObject_HEAD
+ anyroutine rtn;
+ char name[MAXNAME+1];
+} cdrobject;
+
+staticforward PyTypeObject Cdrtype;
+
+
+
+/* ---------------------------------------------------------------- */
+
+/* Declarations for objects of type callable */
+
+typedef struct {
+ PyObject_HEAD
+ cdrobject *routine; /* The routine to call */
+ int npargs; /* Python argument count */
+ int npreturn; /* Python return value count */
+ int ncargs; /* C argument count + 1 */
+ conventry *argconv[MAXARG+1]; /* Value converter list */
+} cdcobject;
+
+staticforward PyTypeObject Cdctype;
+
+
+
+/* -------------------------------------------------------- */
+
+
+static struct PyMethodDef cdr_methods[] = {
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+
+static cdrobject *
+newcdrobject(name, routine)
+ unsigned char *name;
+ anyroutine routine;
+{
+ cdrobject *self;
+ int nlen;
+
+ self = PyObject_NEW(cdrobject, &Cdrtype);
+ if (self == NULL)
+ return NULL;
+ if ( name[0] > MAXNAME )
+ nlen = MAXNAME;
+ else
+ nlen = name[0];
+ memcpy(self->name, name+1, nlen);
+ self->name[nlen] = '\0';
+ self->rtn = routine;
+ return self;
+}
+
+static void
+cdr_dealloc(self)
+ cdrobject *self;
+{
+ PyMem_DEL(self);
+}
+
+static PyObject *
+cdr_repr(self)
+ cdrobject *self;
+{
+ PyObject *s;
+ char buf[256];
+
+ sprintf(buf, "<Calldll routine %s address 0x%x>", self->name, self->rtn);
+ s = PyString_FromString(buf);
+ return s;
+}
+
+static char Cdrtype__doc__[] =
+"C Routine address"
+;
+
+static PyTypeObject Cdrtype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "routine", /*tp_name*/
+ sizeof(cdrobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)cdr_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)cdr_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+
+ /* Space for future expansion */
+ 0L,0L,0L,0L,
+ Cdrtype__doc__ /* Documentation string */
+};
+
+/* End of code for routine objects */
+/* -------------------------------------------------------- */
+
+
+static struct PyMethodDef cdc_methods[] = {
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+
+static cdcobject *
+newcdcobject(routine, npargs, npreturn, ncargs, argconv)
+ cdrobject *routine;
+ int npargs;
+ int npreturn;
+ int ncargs;
+ conventry *argconv[];
+{
+ cdcobject *self;
+ int i;
+
+ self = PyObject_NEW(cdcobject, &Cdctype);
+ if (self == NULL)
+ return NULL;
+ self->routine = routine;
+ Py_INCREF(routine);
+ self->npargs = npargs;
+ self->npreturn = npreturn;
+ self->ncargs = ncargs;
+ for(i=0; i<MAXARG+1; i++)
+ if ( i < ncargs )
+ self->argconv[i] = argconv[i];
+ else
+ self->argconv[i] = 0;
+ return self;
+}
+
+static void
+cdc_dealloc(self)
+ cdcobject *self;
+{
+ Py_XDECREF(self->routine);
+ PyMem_DEL(self);
+}
+
+
+static PyObject *
+cdc_repr(self)
+ cdcobject *self;
+{
+ PyObject *s;
+ char buf[256];
+ int i;
+
+ sprintf(buf, "<callable %s = %s(", self->argconv[0]->name, self->routine->name);
+ for(i=1; i< self->ncargs; i++) {
+ strcat(buf, self->argconv[i]->name);
+ if ( i < self->ncargs-1 )
+ strcat(buf, ", ");
+ }
+ strcat(buf, ") >");
+
+ s = PyString_FromString(buf);
+ return s;
+}
+
+/*
+** And this is what we all do it for: call a C function.
+*/
+static PyObject *
+cdc_call(self, args, kwargs)
+ cdcobject *self;
+ PyObject *args;
+ PyObject *kwargs;
+{
+ char buf[256];
+ int i, pargindex;
+ anything c_args[MAXARG+1] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+ conventry *cp;
+ PyObject *curarg;
+ anyroutine func;
+ PyObject *rv0, *rv;
+
+ if( kwargs ) {
+ PyErr_SetString(PyExc_TypeError, "Keyword args not allowed");
+ return 0;
+ }
+ if( !PyTuple_Check(args) ) {
+ PyErr_SetString(PyExc_TypeError, "Arguments not in tuple");
+ return 0;
+ }
+ if( PyTuple_Size(args) != self->npargs ) {
+ sprintf(buf, "%d arguments, expected %d", PyTuple_Size(args), self->npargs);
+ PyErr_SetString(PyExc_TypeError, buf);
+ return 0;
+ }
+
+ /* Decode arguments */
+ pargindex = 0;
+ for(i=0; i<self->ncargs; i++) {
+ cp = self->argconv[i];
+ if ( cp->get_uses_arg ) {
+ curarg = PyTuple_GET_ITEM(args, pargindex);
+ pargindex++;
+ } else {
+ curarg = (PyObject *)NULL;
+ }
+ c_args[i] = (*cp->get)(curarg);
+ }
+ if (PyErr_Occurred())
+ return 0;
+
+ /* Call function */
+ func = self->routine->rtn;
+ *(anything *)c_args[0] = (*func)(c_args[1], c_args[2], c_args[3], c_args[4],
+ c_args[5], c_args[6], c_args[7], c_args[8]);
+
+ /* Build return tuple (always a tuple, for now */
+ if( (rv=PyTuple_New(self->npreturn)) == NULL )
+ return NULL;
+ pargindex = 0;
+ for(i=0; i<self->ncargs; i++) {
+ cp = self->argconv[i];
+ curarg = (*cp->put)(c_args[i]);
+ if( cp->put_gives_result )
+ PyTuple_SET_ITEM(rv, pargindex, curarg);
+ /* NOTE: We only check errors at the end (so we free() everything) */
+ }
+ if ( PyErr_Occurred() ) {
+ Py_DECREF(rv);
+ return NULL;
+ }
+ return rv;
+}
+
+static char Cdctype__doc__[] =
+""
+;
+
+static PyTypeObject Cdctype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "callable", /*tp_name*/
+ sizeof(cdcobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)cdc_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)cdc_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)cdc_call, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+
+ /* Space for future expansion */
+ 0L,0L,0L,0L,
+ Cdctype__doc__ /* Documentation string */
+};
+
+/* End of code for callable objects */
+/* ---------------------------------------------------------------- */
+
+static struct PyMethodDef cdf_methods[] = {
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+
+static cdfobject *
+newcdfobject(conn_id, name)
+ CFragConnectionID conn_id;
+ unsigned char *name;
+{
+ cdfobject *self;
+ int nlen;
+
+ self = PyObject_NEW(cdfobject, &Cdftype);
+ if (self == NULL)
+ return NULL;
+ self->conn_id = conn_id;
+ if ( name[0] > MAXNAME )
+ nlen = MAXNAME;
+ else
+ nlen = name[0];
+ strncpy(self->name, (char *)name+1, nlen);
+ self->name[nlen] = '\0';
+ return self;
+}
+
+static void
+cdf_dealloc(self)
+ cdfobject *self;
+{
+ PyMem_DEL(self);
+}
+
+static PyObject *
+cdf_repr(self)
+ cdfobject *self;
+{
+ PyObject *s;
+ char buf[256];
+
+ sprintf(buf, "<fragment %s connection, id 0x%x>", self->name, self->conn_id);
+ s = PyString_FromString(buf);
+ return s;
+}
+
+static PyObject *
+cdf_getattr(self, name)
+ cdfobject *self;
+ char *name;
+{
+ unsigned char *rtn_name;
+ anyroutine rtn;
+ OSErr err;
+ Str255 errMessage;
+ CFragSymbolClass class;
+ char buf[256];
+
+ rtn_name = Pstring(name);
+ err = FindSymbol(self->conn_id, rtn_name, (Ptr *)&rtn, &class);
+ if ( err ) {
+ sprintf(buf, "%.*s: %s", rtn_name[0], rtn_name+1, PyMac_StrError(err));
+ PyErr_SetString(ErrorObject, buf);
+ return NULL;
+ }
+ if( class != kTVectorCFragSymbol ) {
+ PyErr_SetString(ErrorObject, "Symbol is not a routine");
+ return NULL;
+ }
+
+ return (PyObject *)newcdrobject(rtn_name, rtn);
+}
+/* -------------------------------------------------------- */
+
+static char Cdftype__doc__[] =
+"Code Fragment library symbol table"
+;
+
+static PyTypeObject Cdftype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "fragment", /*tp_name*/
+ sizeof(cdfobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)cdf_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)cdf_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)cdf_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+
+ /* Space for future expansion */
+ 0L,0L,0L,0L,
+ Cdftype__doc__ /* Documentation string */
+};
+
+/* End of code for fragment objects */
+/* -------------------------------------------------------- */
+
+
+static char cdll_getlibrary__doc__[] =
+"Load a shared library fragment and return the symbol table"
+;
+
+static PyObject *
+cdll_getlibrary(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ Str255 frag_name;
+ OSErr err;
+ Str255 errMessage;
+ Ptr main_addr;
+ CFragConnectionID conn_id;
+ char buf[256];
+
+ if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, frag_name))
+ return NULL;
+
+ /* Find the library connection ID */
+ err = GetSharedLibrary(frag_name, kCurrentCFragArch, kLoadCFrag, &conn_id, &main_addr,
+ errMessage);
+ if ( err ) {
+ sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
+ PyErr_SetString(ErrorObject, buf);
+ return NULL;
+ }
+ return (PyObject *)newcdfobject(conn_id, frag_name);
+}
+
+static char cdll_getdiskfragment__doc__[] =
+"Load a fragment from a disk file and return the symbol table"
+;
+
+static PyObject *
+cdll_getdiskfragment(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ FSSpec fsspec;
+ Str255 frag_name;
+ OSErr err;
+ Str255 errMessage;
+ Ptr main_addr;
+ CFragConnectionID conn_id;
+ char buf[256];
+ Boolean isfolder, didsomething;
+
+ if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetFSSpec, &fsspec,
+ PyMac_GetStr255, frag_name))
+ return NULL;
+ err = ResolveAliasFile(&fsspec, 1, &isfolder, &didsomething);
+ if ( err )
+ return PyErr_Mac(ErrorObject, err);
+
+ /* Load the fragment (or return the connID if it is already loaded */
+ err = GetDiskFragment(&fsspec, 0, 0, frag_name,
+ kLoadCFrag, &conn_id, &main_addr,
+ errMessage);
+ if ( err ) {
+ sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
+ PyErr_SetString(ErrorObject, buf);
+ return NULL;
+ }
+ return (PyObject *)newcdfobject(conn_id, frag_name);
+}
+
+static char cdll_newcall__doc__[] =
+""
+;
+
+static PyObject *
+cdll_newcall(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ cdrobject *routine;
+ conventry *argconv[MAXARG+1] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+ int npargs, npreturn, ncargs;
+
+ /* Note: the next format depends on MAXARG+1 */
+ if (!PyArg_ParseTuple(args, "O!O&|O&O&O&O&O&O&O&O&", &Cdrtype, &routine,
+ argparse_conv, &argconv[0], argparse_conv, &argconv[1],
+ argparse_conv, &argconv[2], argparse_conv, &argconv[3],
+ argparse_conv, &argconv[4], argparse_conv, &argconv[5],
+ argparse_conv, &argconv[6], argparse_conv, &argconv[7],
+ argparse_conv, &argconv[8]))
+ return NULL;
+ npargs = npreturn = 0;
+ for(ncargs=0; ncargs < MAXARG+1 && argconv[ncargs]; ncargs++) {
+ if( argconv[ncargs]->get_uses_arg ) npargs++;
+ if( argconv[ncargs]->put_gives_result ) npreturn++;
+ }
+ return (PyObject *)newcdcobject(routine, npargs, npreturn, ncargs, argconv);
+}
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef cdll_methods[] = {
+ {"getlibrary", (PyCFunction)cdll_getlibrary, METH_VARARGS,
+ cdll_getlibrary__doc__},
+ {"getdiskfragment", (PyCFunction)cdll_getdiskfragment, METH_VARARGS,
+ cdll_getdiskfragment__doc__},
+ {"newcall", (PyCFunction)cdll_newcall, METH_VARARGS,
+ cdll_newcall__doc__},
+
+ {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initcalldll) */
+
+static char calldll_module_documentation[] =
+""
+;
+
+void
+initcalldll()
+{
+ PyObject *m, *d;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule4("calldll", cdll_methods,
+ calldll_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ ErrorObject = PyString_FromString("calldll.error");
+ PyDict_SetItemString(d, "error", ErrorObject);
+
+ /* XXXX Add constants here */
+
+ /* Check for errors */
+ if (PyErr_Occurred())
+ Py_FatalError("can't initialize module calldll");
+}
+
+/* Test routine */
+int calldlltester(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
+{
+ printf("Tester1: %x %x %x %x %x %x %x %x\n", a1, a2, a3, a4, a5, a6, a7, a8);
+ return a1;
+}
+