mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1194 lines
		
	
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1194 lines
		
	
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/***********************************************************
 | 
						|
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.
 | 
						|
 | 
						|
******************************************************************/
 | 
						|
 | 
						|
/* Sanity check */
 | 
						|
#ifndef __powerc
 | 
						|
#error Please port this code to your architecture first...
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
** Define to include testroutines (at the end)
 | 
						|
*/
 | 
						|
#define TESTSUPPORT
 | 
						|
 | 
						|
#include "Python.h"
 | 
						|
#include "macglue.h"
 | 
						|
#include "macdefs.h"
 | 
						|
#include <CodeFragments.h>
 | 
						|
 | 
						|
/* Prototypes for routines not in any include file (shame, shame) */
 | 
						|
extern PyObject *ResObj_New Py_PROTO((Handle));
 | 
						|
extern int ResObj_Convert Py_PROTO((PyObject *, Handle *));
 | 
						|
 | 
						|
static PyObject *ErrorObject;
 | 
						|
 | 
						|
/* Debugging macro */
 | 
						|
#ifdef TESTSUPPORT
 | 
						|
#define PARANOID(arg) \
 | 
						|
	if ( arg == 0 ) {PyErr_SetString(ErrorObject, "Internal error: NULL arg!"); return 0; }
 | 
						|
#else
 | 
						|
#define PARANOID(arg) /*pass*/
 | 
						|
#endif
 | 
						|
 | 
						|
/* Prototypes we use for routines and arguments */
 | 
						|
 | 
						|
typedef long anything;
 | 
						|
typedef anything (*anyroutine) Py_PROTO((...));
 | 
						|
 | 
						|
/* Other constants */
 | 
						|
#define MAXNAME 31	/* Maximum size of names, for printing only */
 | 
						|
#define MAXARG 12	/* Maximum number of arguments */
 | 
						|
 | 
						|
/*
 | 
						|
** Routines to convert arguments between Python and C.
 | 
						|
** Note return-value converters return NULL if this argument (or return value)
 | 
						|
** doesn't return anything. The call-wrapper code collects all return values,
 | 
						|
** and does the expected thing based on the number of return values: return None, a single
 | 
						|
** value or a tuple of values.
 | 
						|
**
 | 
						|
** Hence, optional return values are also implementable.
 | 
						|
*/
 | 
						|
typedef anything (*py2c_converter) Py_PROTO((PyObject *));
 | 
						|
typedef PyObject *(*c2py_converter) Py_PROTO((anything));
 | 
						|
typedef PyObject *(*rv2py_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;
 | 
						|
}
 | 
						|
 | 
						|
/* Dummy routine for void return value */
 | 
						|
static PyObject *
 | 
						|
rv2py_none(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;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
** OSErr return value.
 | 
						|
*/
 | 
						|
static PyObject *
 | 
						|
rv2py_oserr(arg)
 | 
						|
	anything arg;
 | 
						|
{
 | 
						|
	OSErr err = (OSErr)arg;
 | 
						|
	
 | 
						|
	if (err)
 | 
						|
		return PyMac_Error(err);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
** Input integers of all sizes (PPC only)
 | 
						|
*/
 | 
						|
static anything
 | 
						|
py2c_in_int(arg)
 | 
						|
	PyObject  *arg;
 | 
						|
{
 | 
						|
	return PyInt_AsLong(arg);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
** Integer return values of all sizes (PPC only)
 | 
						|
*/
 | 
						|
static PyObject *
 | 
						|
rv2py_int(arg)
 | 
						|
	anything arg;
 | 
						|
{
 | 
						|
	return PyInt_FromLong((long)arg);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
** Integer output parameters
 | 
						|
*/
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
rv2py_pstring(arg)
 | 
						|
	anything arg;
 | 
						|
{
 | 
						|
	unsigned char *p = (unsigned char *)arg;
 | 
						|
	PyObject *rv;
 | 
						|
	
 | 
						|
	if ( arg == NULL ) return NULL;
 | 
						|
	rv = PyString_FromStringAndSize((char *)p+1, p[0]);
 | 
						|
	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;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
rv2py_cobject(arg)
 | 
						|
	anything arg;
 | 
						|
{
 | 
						|
	void *ptr = (void *)arg;
 | 
						|
	PyObject *rv;
 | 
						|
	
 | 
						|
	if ( ptr == 0 ) return NULL;
 | 
						|
	rv = PyCObject_FromVoidPtr(ptr, 0);
 | 
						|
	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;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
rv2py_handle(arg)
 | 
						|
	anything arg;
 | 
						|
{
 | 
						|
	Handle rv = (Handle)arg;
 | 
						|
	
 | 
						|
	if ( rv == NULL ) return NULL;
 | 
						|
	return ResObj_New(rv);
 | 
						|
}
 | 
						|
 | 
						|
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 */
 | 
						|
} conventry;
 | 
						|
 | 
						|
static conventry converters[] = {
 | 
						|
	{"InByte",	py2c_in_int,	1,	c2py_dummy},
 | 
						|
	{"InShort",	py2c_in_int,	1,	c2py_dummy},
 | 
						|
	{"InLong",	py2c_in_int,	1,	c2py_dummy},
 | 
						|
	{"OutLong",	py2c_alloc,	0,	c2py_out_long},
 | 
						|
	{"OutShort",	py2c_alloc,	0,	c2py_out_short},
 | 
						|
	{"OutByte",	py2c_alloc,	0,	c2py_out_byte},
 | 
						|
	{"InString",	py2c_in_string,	1,	c2py_dummy},
 | 
						|
	{"InPstring",	py2c_in_pstring,1,	c2py_free},
 | 
						|
	{"OutPstring",	py2c_out_pstring,0,	c2py_out_pstring},
 | 
						|
	{"InCobject",	py2c_in_cobject,1,	c2py_dummy},
 | 
						|
	{"OutCobject",	py2c_alloc,	0,	c2py_out_cobject},
 | 
						|
	{"InHandle",	py2c_in_handle,	1,	c2py_dummy},
 | 
						|
	{"OutHandle",	py2c_alloc,	0,	c2py_out_handle},
 | 
						|
	{0, 0, 0, 0}
 | 
						|
};
 | 
						|
 | 
						|
typedef struct {
 | 
						|
	char *name;
 | 
						|
	rv2py_converter rtn;
 | 
						|
} rvconventry;
 | 
						|
 | 
						|
static rvconventry rvconverters[] = {
 | 
						|
	{"None",	rv2py_none},
 | 
						|
	{"OSErr",	rv2py_oserr},
 | 
						|
	{"Byte",	rv2py_int},
 | 
						|
	{"Short",	rv2py_int},
 | 
						|
	{"Long",	rv2py_int},
 | 
						|
	{"Pstring",	rv2py_pstring},
 | 
						|
	{"Cobject",	rv2py_cobject},
 | 
						|
	{"Handle",	rv2py_handle},
 | 
						|
	{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 rvconventry *
 | 
						|
getrvconverter(name)
 | 
						|
	char *name;
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	char buf[256];
 | 
						|
	
 | 
						|
	for(i=0; rvconverters[i].name; i++ )
 | 
						|
		if ( strcmp(name, rvconverters[i].name) == 0 )
 | 
						|
			return &rvconverters[i];
 | 
						|
	sprintf(buf, "Unknown return value type: %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;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
argparse_rvconv(obj, ptr)
 | 
						|
	PyObject *obj;
 | 
						|
	rvconventry **ptr;
 | 
						|
{
 | 
						|
	char *name;
 | 
						|
	int i;
 | 
						|
	rvconventry *item;
 | 
						|
	
 | 
						|
	if( (name=PyString_AsString(obj)) == NULL )
 | 
						|
		return 0;
 | 
						|
	if( (item=getrvconverter(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 ncargs;			/* C argument count + 1 */
 | 
						|
	rvconventry *rvconv;		/* Return value converter */
 | 
						|
	conventry *argconv[MAXARG];	/* 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, ncargs, rvconv, argconv)
 | 
						|
	cdrobject *routine;
 | 
						|
	int npargs;
 | 
						|
	int ncargs;
 | 
						|
	rvconventry *rvconv;
 | 
						|
	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->ncargs = ncargs;
 | 
						|
	self->rvconv = rvconv;
 | 
						|
	for(i=0; i<MAXARG; 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->rvconv->name, self->routine->name);
 | 
						|
	for(i=0; 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] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 | 
						|
	anything c_rv;
 | 
						|
	conventry *cp;
 | 
						|
	PyObject *curarg;
 | 
						|
	anyroutine func;
 | 
						|
	PyObject *returnvalues[MAXARG+1];
 | 
						|
	PyObject *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;
 | 
						|
	c_rv = (*func)(c_args[0], c_args[1], c_args[2], c_args[3],
 | 
						|
			c_args[4], c_args[5], c_args[6], c_args[7],
 | 
						|
			c_args[8], c_args[9], c_args[10], c_args[11]);
 | 
						|
 | 
						|
	/* Decode return value, and store into returnvalues if needed */
 | 
						|
	pargindex = 0;
 | 
						|
	curarg = (*self->rvconv->rtn)(c_rv);
 | 
						|
	if ( curarg )
 | 
						|
		returnvalues[pargindex++] = curarg;
 | 
						|
		
 | 
						|
	/* Decode returnvalue parameters and cleanup any storage allocated */
 | 
						|
	for(i=0; i<self->ncargs; i++) {
 | 
						|
		cp = self->argconv[i];
 | 
						|
		curarg = (*cp->put)(c_args[i]);
 | 
						|
		if(curarg)
 | 
						|
			returnvalues[pargindex++] = curarg;
 | 
						|
		/* NOTE: We only check errors at the end (so we free() everything) */
 | 
						|
	}
 | 
						|
	if ( PyErr_Occurred() ) {
 | 
						|
		/* An error did occur. Free the python objects created */
 | 
						|
		for(i=0; i<pargindex; i++)
 | 
						|
			Py_XDECREF(returnvalues[i]);
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	/* Zero and one return values cases are special: */
 | 
						|
	if ( pargindex == 0 ) {
 | 
						|
		Py_INCREF(Py_None);
 | 
						|
		return Py_None;
 | 
						|
	}
 | 
						|
	if ( pargindex == 1 )
 | 
						|
		return returnvalues[0];
 | 
						|
		
 | 
						|
	/* More than one return value: put in a tuple */
 | 
						|
	rv = PyTuple_New(pargindex);
 | 
						|
	for(i=0; i<pargindex; i++)
 | 
						|
		if(rv)
 | 
						|
			PyTuple_SET_ITEM(rv, i, returnvalues[i]);
 | 
						|
		else
 | 
						|
			Py_XDECREF(returnvalues[i]);
 | 
						|
	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 char cdf_keys__doc__[] =
 | 
						|
"Return list of symbol names in fragment";
 | 
						|
 | 
						|
static PyObject *
 | 
						|
cdf_keys(self, args)
 | 
						|
	cdfobject *self;
 | 
						|
	PyObject *args;
 | 
						|
{
 | 
						|
	long symcount;
 | 
						|
	PyObject *rv, *obj;
 | 
						|
	Str255 symname;
 | 
						|
	Ptr dummy1;
 | 
						|
	CFragSymbolClass dummy2;
 | 
						|
	int i;
 | 
						|
	OSErr err;
 | 
						|
	
 | 
						|
	if (!PyArg_ParseTuple(args, ""))
 | 
						|
		return NULL;
 | 
						|
	if ( (err=CountSymbols(self->conn_id, &symcount)) < 0 )
 | 
						|
		return PyMac_Error(err);
 | 
						|
	if ( (rv=PyList_New(symcount)) == NULL )
 | 
						|
		return NULL;
 | 
						|
	for (i=0; i<symcount; i++) {
 | 
						|
		if ((err=GetIndSymbol(self->conn_id, i, symname, &dummy1, &dummy2)) < 0 ) {
 | 
						|
			Py_XDECREF(rv);
 | 
						|
			return PyMac_Error(err);
 | 
						|
		}
 | 
						|
		if ((obj=PyString_FromStringAndSize((char *)symname+1, symname[0])) == NULL ) {
 | 
						|
			Py_XDECREF(rv);
 | 
						|
			return PyMac_Error(err);
 | 
						|
		}
 | 
						|
		if (PyList_SetItem(rv, i, obj) < 0 ) {
 | 
						|
			Py_XDECREF(rv);
 | 
						|
			return NULL;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return rv;
 | 
						|
}
 | 
						|
		
 | 
						|
 | 
						|
static struct PyMethodDef cdf_methods[] = {
 | 
						|
	{"keys",		(PyCFunction)cdf_keys,		METH_VARARGS,	
 | 
						|
							cdf_keys__doc__},
 | 
						|
	
 | 
						|
	{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_helper(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 PyObject *
 | 
						|
cdf_getattr(self, name)
 | 
						|
	cdfobject *self;
 | 
						|
	char *name;
 | 
						|
{
 | 
						|
	PyObject *rv;
 | 
						|
	
 | 
						|
	if ((rv=Py_FindMethod(cdf_methods, (PyObject *)self, name)))
 | 
						|
		return rv;
 | 
						|
	PyErr_Clear();
 | 
						|
	return cdf_getattr_helper(self, name);
 | 
						|
}
 | 
						|
 | 
						|
/* -------------------------------------------------------- */
 | 
						|
/* Code to access cdf objects as mappings */
 | 
						|
 | 
						|
static int
 | 
						|
cdf_length(self)
 | 
						|
	cdfobject *self;
 | 
						|
{
 | 
						|
	long symcount;
 | 
						|
	OSErr err;
 | 
						|
	
 | 
						|
	err = CountSymbols(self->conn_id, &symcount);
 | 
						|
	if ( err ) {
 | 
						|
		PyMac_Error(err);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
	return symcount;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
cdf_subscript(self, key)
 | 
						|
	cdfobject *self;
 | 
						|
	PyObject *key;
 | 
						|
{
 | 
						|
	char *name;
 | 
						|
	
 | 
						|
	if ((name=PyString_AsString(key)) == 0 )
 | 
						|
		return 0;
 | 
						|
	return cdf_getattr_helper(self, name);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
cdf_ass_sub(self, v, w)
 | 
						|
	cdfobject *self;
 | 
						|
	PyObject *v, *w;
 | 
						|
{
 | 
						|
	/* XXXX Put w in self under key v */
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static PyMappingMethods cdf_as_mapping = {
 | 
						|
	(inquiry)cdf_length,		/*mp_length*/
 | 
						|
	(binaryfunc)cdf_subscript,		/*mp_subscript*/
 | 
						|
	(objobjargproc)cdf_ass_sub,	/*mp_ass_subscript*/
 | 
						|
};
 | 
						|
 | 
						|
/* -------------------------------------------------------- */
 | 
						|
 | 
						|
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*/
 | 
						|
	&cdf_as_mapping,		/*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, kCompiledCFragArch, 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] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 | 
						|
	rv2py_converter rvconv;
 | 
						|
	int npargs, ncargs;
 | 
						|
 | 
						|
	/* Note: the next format depends on MAXARG */
 | 
						|
	if (!PyArg_ParseTuple(args, "O!O&|O&O&O&O&O&O&O&O&O&O&O&O&", &Cdrtype, &routine,
 | 
						|
		argparse_rvconv, &rvconv,
 | 
						|
		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], argparse_conv, &argconv[9],
 | 
						|
		argparse_conv, &argconv[10], argparse_conv, &argconv[11]))
 | 
						|
		return NULL;
 | 
						|
	npargs = 0;
 | 
						|
	for(ncargs=0; ncargs < MAXARG && argconv[ncargs]; ncargs++) {
 | 
						|
		if( argconv[ncargs]->get_uses_arg ) npargs++;
 | 
						|
	}
 | 
						|
	return (PyObject *)newcdcobject(routine, npargs, ncargs, rvconv, 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");
 | 
						|
}
 | 
						|
 | 
						|
#ifdef TESTSUPPORT
 | 
						|
 | 
						|
/* Test routine */
 | 
						|
int cdll_b_bbbbbbbb(char a1,char  a2,char  a3,char  a4,char  a5,char  a6,char  a7,char  a8)
 | 
						|
{
 | 
						|
	return a1+a2+a3+a4+a5+a6+a7+a8;
 | 
						|
}
 | 
						|
 | 
						|
short cdll_h_hhhhhhhh(short a1,short  a2,short  a3,short  a4,short  a5,short  a6,short  a7,short  a8)
 | 
						|
{
 | 
						|
	return a1+a2+a3+a4+a5+a6+a7+a8;
 | 
						|
}
 | 
						|
 | 
						|
int cdll_l_llllllll(int a1,int  a2,int  a3,int  a4,int  a5,int  a6,int  a7,int  a8)
 | 
						|
{
 | 
						|
	return a1+a2+a3+a4+a5+a6+a7+a8;
 | 
						|
}
 | 
						|
 | 
						|
void cdll_N_ssssssss(char *a1,char  *a2,char  *a3,char  *a4,char  *a5,char  *a6,char  *a7,char *a8)
 | 
						|
{
 | 
						|
	printf("cdll_N_ssssssss args: %s %s %s %s %s %s %s %s\n", a1, a2, a3, a4, 
 | 
						|
			a5, a6, a7, a8);
 | 
						|
}
 | 
						|
 | 
						|
OSErr cdll_o_l(long l)
 | 
						|
{
 | 
						|
	return (OSErr)l;
 | 
						|
}
 | 
						|
 | 
						|
void cdll_N_pp(unsigned char *in, unsigned char *out)
 | 
						|
{
 | 
						|
	out[0] = in[0] + 5;
 | 
						|
	strcpy((char *)out+1, "Was: ");
 | 
						|
	memcpy(out+6, in+1, in[0]);
 | 
						|
}
 | 
						|
 | 
						|
void cdll_N_bb(char a1, char *a2)
 | 
						|
{
 | 
						|
	*a2 = a1;
 | 
						|
}
 | 
						|
 | 
						|
void cdll_N_hh(short a1, short *a2)
 | 
						|
{
 | 
						|
	*a2 = a1;
 | 
						|
}
 | 
						|
 | 
						|
void cdll_N_ll(long a1, long *a2)
 | 
						|
{
 | 
						|
	*a2 = a1;
 | 
						|
}
 | 
						|
 | 
						|
void cdll_N_sH(char *a1, Handle a2)
 | 
						|
{
 | 
						|
	int len;
 | 
						|
	
 | 
						|
	len = strlen(a1);
 | 
						|
	SetHandleSize(a2, len);
 | 
						|
	HLock(a2);
 | 
						|
	memcpy(*a2, a1, len);
 | 
						|
	HUnlock(a2);
 | 
						|
}
 | 
						|
#endif
 |