/***********************************************************
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(Handle);
extern int ResObj_Convert(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)(...);

/* 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)(PyObject *);
typedef PyObject *(*c2py_converter)(anything);
typedef PyObject *(*rv2py_converter)(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;

static PyTypeObject Cdftype;



/* ---------------------------------------------------------------- */

/* Declarations for objects of type routine */

typedef struct {
	PyObject_HEAD
	anyroutine rtn;
	char name[MAXNAME+1];
} cdrobject;

static 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;

static 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;
{
	PyObject_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*/
	"calldll.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);
	PyObject_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*/
	"calldll.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;
{
	PyObject_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*/
	"calldll.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
