mirror of https://github.com/python/cpython.git
An initial stab at calling random C routines from Python
This commit is contained in:
parent
ce7fc98d86
commit
b3928d2ffd
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue