This commit was manufactured by cvs2svn to create tag 'r221'.
[python/dscho.git] / Mac / Modules / calldll.c
blob8d130ceb7ee38555e32ccf2fb861a621e18910f4
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Sanity check */
33 #ifndef __powerc
34 #error Please port this code to your architecture first...
35 #endif
38 ** Define to include testroutines (at the end)
40 #define TESTSUPPORT
42 #include "Python.h"
43 #include "macglue.h"
44 #include "macdefs.h"
45 #include <CodeFragments.h>
47 /* Prototypes for routines not in any include file (shame, shame) */
48 extern PyObject *ResObj_New(Handle);
49 extern int ResObj_Convert(PyObject *, Handle *);
51 static PyObject *ErrorObject;
53 /* Debugging macro */
54 #ifdef TESTSUPPORT
55 #define PARANOID(arg) \
56 if ( arg == 0 ) {PyErr_SetString(ErrorObject, "Internal error: NULL arg!"); return 0; }
57 #else
58 #define PARANOID(arg) /*pass*/
59 #endif
61 /* Prototypes we use for routines and arguments */
63 typedef long anything;
64 typedef anything (*anyroutine)(...);
66 /* Other constants */
67 #define MAXNAME 31 /* Maximum size of names, for printing only */
68 #define MAXARG 12 /* Maximum number of arguments */
71 ** Routines to convert arguments between Python and C.
72 ** Note return-value converters return NULL if this argument (or return value)
73 ** doesn't return anything. The call-wrapper code collects all return values,
74 ** and does the expected thing based on the number of return values: return None, a single
75 ** value or a tuple of values.
77 ** Hence, optional return values are also implementable.
79 typedef anything (*py2c_converter)(PyObject *);
80 typedef PyObject *(*c2py_converter)(anything);
81 typedef PyObject *(*rv2py_converter)(anything);
84 /* Dummy routine for arguments that are output-only */
85 static anything
86 py2c_dummy(arg)
87 PyObject *arg;
89 return 0;
92 /* Routine to allocate storage for output integers */
93 static anything
94 py2c_alloc(arg)
95 PyObject *arg;
97 char *ptr;
99 if( (ptr=malloc(sizeof(anything))) == 0 )
100 PyErr_NoMemory();
101 return (anything)ptr;
104 /* Dummy routine for arguments that are input-only */
105 static PyObject *
106 c2py_dummy(arg)
107 anything arg;
109 return 0;
112 /* Dummy routine for void return value */
113 static PyObject *
114 rv2py_none(arg)
115 anything arg;
117 return 0;
120 /* Routine to de-allocate storage for input-only arguments */
121 static PyObject *
122 c2py_free(arg)
123 anything arg;
125 if ( arg )
126 free((char *)arg);
127 return 0;
131 ** OSErr return value.
133 static PyObject *
134 rv2py_oserr(arg)
135 anything arg;
137 OSErr err = (OSErr)arg;
139 if (err)
140 return PyMac_Error(err);
141 return 0;
145 ** Input integers of all sizes (PPC only)
147 static anything
148 py2c_in_int(arg)
149 PyObject *arg;
151 return PyInt_AsLong(arg);
155 ** Integer return values of all sizes (PPC only)
157 static PyObject *
158 rv2py_int(arg)
159 anything arg;
161 return PyInt_FromLong((long)arg);
165 ** Integer output parameters
167 static PyObject *
168 c2py_out_long(arg)
169 anything arg;
171 PyObject *rv;
173 PARANOID(arg);
174 rv = PyInt_FromLong(*(long *)arg);
175 free((char *)arg);
176 return rv;
179 static PyObject *
180 c2py_out_short(arg)
181 anything arg;
183 PyObject *rv;
185 PARANOID(arg);
186 rv = PyInt_FromLong((long)*(short *)arg);
187 free((char *)arg);
188 return rv;
191 static PyObject *
192 c2py_out_byte(arg)
193 anything arg;
195 PyObject *rv;
197 PARANOID(arg);
198 rv = PyInt_FromLong((long)*(char *)arg);
199 free((char *)arg);
200 return rv;
204 ** Strings
206 static anything
207 py2c_in_string(arg)
208 PyObject *arg;
210 return (anything)PyString_AsString(arg);
214 ** Pascal-style strings
216 static anything
217 py2c_in_pstring(arg)
218 PyObject *arg;
220 unsigned char *p;
221 int size;
223 if( (size = PyString_Size(arg)) < 0)
224 return 0;
225 if ( size > 255 ) {
226 PyErr_SetString(ErrorObject, "Pstring must be <= 255 chars");
227 return 0;
229 if( (p=(unsigned char *)malloc(256)) == 0 ) {
230 PyErr_NoMemory();
231 return 0;
233 p[0] = size;
234 memcpy(p+1, PyString_AsString(arg), size);
235 return (anything)p;
238 static anything
239 py2c_out_pstring(arg)
240 PyObject *arg;
242 unsigned char *p;
244 if( (p=(unsigned char *)malloc(256)) == 0 ) {
245 PyErr_NoMemory();
246 return 0;
248 p[0] = 0;
249 return (anything)p;
252 static PyObject *
253 c2py_out_pstring(arg)
254 anything arg;
256 unsigned char *p = (unsigned char *)arg;
257 PyObject *rv;
259 PARANOID(arg);
260 rv = PyString_FromStringAndSize((char *)p+1, p[0]);
261 free(p);
262 return rv;
265 static PyObject *
266 rv2py_pstring(arg)
267 anything arg;
269 unsigned char *p = (unsigned char *)arg;
270 PyObject *rv;
272 if ( arg == NULL ) return NULL;
273 rv = PyString_FromStringAndSize((char *)p+1, p[0]);
274 return rv;
278 ** C objects.
280 static anything
281 py2c_in_cobject(arg)
282 PyObject *arg;
284 if ( arg == Py_None )
285 return 0;
286 return (anything)PyCObject_AsVoidPtr(arg);
289 static PyObject *
290 c2py_out_cobject(arg)
291 anything arg;
293 void **ptr = (void **)arg;
294 PyObject *rv;
296 PARANOID(arg);
297 if ( *ptr == 0 ) {
298 Py_INCREF(Py_None);
299 rv = Py_None;
300 } else {
301 rv = PyCObject_FromVoidPtr(*ptr, 0);
303 free((char *)ptr);
304 return rv;
307 static PyObject *
308 rv2py_cobject(arg)
309 anything arg;
311 void *ptr = (void *)arg;
312 PyObject *rv;
314 if ( ptr == 0 ) return NULL;
315 rv = PyCObject_FromVoidPtr(ptr, 0);
316 return rv;
320 ** Handles.
322 static anything
323 py2c_in_handle(arg)
324 PyObject *arg;
326 Handle h = 0;
327 ResObj_Convert(arg, &h);
328 return (anything)h;
331 static PyObject *
332 c2py_out_handle(arg)
333 anything arg;
335 Handle *rv = (Handle *)arg;
336 PyObject *prv;
338 PARANOID(arg);
339 if ( *rv == 0 ) {
340 Py_INCREF(Py_None);
341 prv = Py_None;
342 } else {
343 prv = ResObj_New(*rv);
345 free((char *)rv);
346 return prv;
349 static PyObject *
350 rv2py_handle(arg)
351 anything arg;
353 Handle rv = (Handle)arg;
355 if ( rv == NULL ) return NULL;
356 return ResObj_New(rv);
359 typedef struct {
360 char *name; /* Name */
361 py2c_converter get; /* Get argument */
362 int get_uses_arg; /* True if the above consumes an argument */
363 c2py_converter put; /* Put result value */
364 } conventry;
366 static conventry converters[] = {
367 {"InByte", py2c_in_int, 1, c2py_dummy},
368 {"InShort", py2c_in_int, 1, c2py_dummy},
369 {"InLong", py2c_in_int, 1, c2py_dummy},
370 {"OutLong", py2c_alloc, 0, c2py_out_long},
371 {"OutShort", py2c_alloc, 0, c2py_out_short},
372 {"OutByte", py2c_alloc, 0, c2py_out_byte},
373 {"InString", py2c_in_string, 1, c2py_dummy},
374 {"InPstring", py2c_in_pstring,1, c2py_free},
375 {"OutPstring", py2c_out_pstring,0, c2py_out_pstring},
376 {"InCobject", py2c_in_cobject,1, c2py_dummy},
377 {"OutCobject", py2c_alloc, 0, c2py_out_cobject},
378 {"InHandle", py2c_in_handle, 1, c2py_dummy},
379 {"OutHandle", py2c_alloc, 0, c2py_out_handle},
380 {0, 0, 0, 0}
383 typedef struct {
384 char *name;
385 rv2py_converter rtn;
386 } rvconventry;
388 static rvconventry rvconverters[] = {
389 {"None", rv2py_none},
390 {"OSErr", rv2py_oserr},
391 {"Byte", rv2py_int},
392 {"Short", rv2py_int},
393 {"Long", rv2py_int},
394 {"Pstring", rv2py_pstring},
395 {"Cobject", rv2py_cobject},
396 {"Handle", rv2py_handle},
397 {0, 0}
400 static conventry *
401 getconverter(name)
402 char *name;
404 int i;
405 char buf[256];
407 for(i=0; converters[i].name; i++ )
408 if ( strcmp(name, converters[i].name) == 0 )
409 return &converters[i];
410 sprintf(buf, "Unknown argtype: %s", name);
411 PyErr_SetString(ErrorObject, buf);
412 return 0;
415 static rvconventry *
416 getrvconverter(name)
417 char *name;
419 int i;
420 char buf[256];
422 for(i=0; rvconverters[i].name; i++ )
423 if ( strcmp(name, rvconverters[i].name) == 0 )
424 return &rvconverters[i];
425 sprintf(buf, "Unknown return value type: %s", name);
426 PyErr_SetString(ErrorObject, buf);
427 return 0;
430 static int
431 argparse_conv(obj, ptr)
432 PyObject *obj;
433 conventry **ptr;
435 char *name;
436 int i;
437 conventry *item;
439 if( (name=PyString_AsString(obj)) == NULL )
440 return 0;
441 if( (item=getconverter(name)) == NULL )
442 return 0;
443 *ptr = item;
444 return 1;
447 static int
448 argparse_rvconv(obj, ptr)
449 PyObject *obj;
450 rvconventry **ptr;
452 char *name;
453 int i;
454 rvconventry *item;
456 if( (name=PyString_AsString(obj)) == NULL )
457 return 0;
458 if( (item=getrvconverter(name)) == NULL )
459 return 0;
460 *ptr = item;
461 return 1;
464 /* ----------------------------------------------------- */
466 /* Declarations for objects of type fragment */
468 typedef struct {
469 PyObject_HEAD
470 CFragConnectionID conn_id;
471 char name[MAXNAME+1];
472 } cdfobject;
474 staticforward PyTypeObject Cdftype;
478 /* ---------------------------------------------------------------- */
480 /* Declarations for objects of type routine */
482 typedef struct {
483 PyObject_HEAD
484 anyroutine rtn;
485 char name[MAXNAME+1];
486 } cdrobject;
488 staticforward PyTypeObject Cdrtype;
492 /* ---------------------------------------------------------------- */
494 /* Declarations for objects of type callable */
497 typedef struct {
498 PyObject_HEAD
499 cdrobject *routine; /* The routine to call */
500 int npargs; /* Python argument count */
501 int ncargs; /* C argument count + 1 */
502 rvconventry *rvconv; /* Return value converter */
503 conventry *argconv[MAXARG]; /* Value converter list */
504 } cdcobject;
506 staticforward PyTypeObject Cdctype;
510 /* -------------------------------------------------------- */
513 static struct PyMethodDef cdr_methods[] = {
515 {NULL, NULL} /* sentinel */
518 /* ---------- */
521 static cdrobject *
522 newcdrobject(name, routine)
523 unsigned char *name;
524 anyroutine routine;
526 cdrobject *self;
527 int nlen;
529 self = PyObject_NEW(cdrobject, &Cdrtype);
530 if (self == NULL)
531 return NULL;
532 if ( name[0] > MAXNAME )
533 nlen = MAXNAME;
534 else
535 nlen = name[0];
536 memcpy(self->name, name+1, nlen);
537 self->name[nlen] = '\0';
538 self->rtn = routine;
539 return self;
542 static void
543 cdr_dealloc(self)
544 cdrobject *self;
546 PyMem_DEL(self);
549 static PyObject *
550 cdr_repr(self)
551 cdrobject *self;
553 PyObject *s;
554 char buf[256];
556 sprintf(buf, "<Calldll routine %s address 0x%x>", self->name, self->rtn);
557 s = PyString_FromString(buf);
558 return s;
561 static char Cdrtype__doc__[] =
562 "C Routine address"
565 static PyTypeObject Cdrtype = {
566 PyObject_HEAD_INIT(&PyType_Type)
567 0, /*ob_size*/
568 "calldll.routine", /*tp_name*/
569 sizeof(cdrobject), /*tp_basicsize*/
570 0, /*tp_itemsize*/
571 /* methods */
572 (destructor)cdr_dealloc, /*tp_dealloc*/
573 (printfunc)0, /*tp_print*/
574 (getattrfunc)0, /*tp_getattr*/
575 (setattrfunc)0, /*tp_setattr*/
576 (cmpfunc)0, /*tp_compare*/
577 (reprfunc)cdr_repr, /*tp_repr*/
578 0, /*tp_as_number*/
579 0, /*tp_as_sequence*/
580 0, /*tp_as_mapping*/
581 (hashfunc)0, /*tp_hash*/
582 (ternaryfunc)0, /*tp_call*/
583 (reprfunc)0, /*tp_str*/
585 /* Space for future expansion */
586 0L,0L,0L,0L,
587 Cdrtype__doc__ /* Documentation string */
590 /* End of code for routine objects */
591 /* -------------------------------------------------------- */
594 static struct PyMethodDef cdc_methods[] = {
596 {NULL, NULL} /* sentinel */
599 /* ---------- */
602 static cdcobject *
603 newcdcobject(routine, npargs, ncargs, rvconv, argconv)
604 cdrobject *routine;
605 int npargs;
606 int ncargs;
607 rvconventry *rvconv;
608 conventry *argconv[];
610 cdcobject *self;
611 int i;
613 self = PyObject_NEW(cdcobject, &Cdctype);
614 if (self == NULL)
615 return NULL;
616 self->routine = routine;
617 Py_INCREF(routine);
618 self->npargs = npargs;
619 self->ncargs = ncargs;
620 self->rvconv = rvconv;
621 for(i=0; i<MAXARG; i++)
622 if ( i < ncargs )
623 self->argconv[i] = argconv[i];
624 else
625 self->argconv[i] = 0;
626 return self;
629 static void
630 cdc_dealloc(self)
631 cdcobject *self;
633 Py_XDECREF(self->routine);
634 PyMem_DEL(self);
638 static PyObject *
639 cdc_repr(self)
640 cdcobject *self;
642 PyObject *s;
643 char buf[256];
644 int i;
646 sprintf(buf, "<callable %s = %s(", self->rvconv->name, self->routine->name);
647 for(i=0; i< self->ncargs; i++) {
648 strcat(buf, self->argconv[i]->name);
649 if ( i < self->ncargs-1 )
650 strcat(buf, ", ");
652 strcat(buf, ") >");
654 s = PyString_FromString(buf);
655 return s;
659 ** And this is what we all do it for: call a C function.
661 static PyObject *
662 cdc_call(self, args, kwargs)
663 cdcobject *self;
664 PyObject *args;
665 PyObject *kwargs;
667 char buf[256];
668 int i, pargindex;
669 anything c_args[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
670 anything c_rv;
671 conventry *cp;
672 PyObject *curarg;
673 anyroutine func;
674 PyObject *returnvalues[MAXARG+1];
675 PyObject *rv;
677 if( kwargs ) {
678 PyErr_SetString(PyExc_TypeError, "Keyword args not allowed");
679 return 0;
681 if( !PyTuple_Check(args) ) {
682 PyErr_SetString(PyExc_TypeError, "Arguments not in tuple");
683 return 0;
685 if( PyTuple_Size(args) != self->npargs ) {
686 sprintf(buf, "%d arguments, expected %d", PyTuple_Size(args), self->npargs);
687 PyErr_SetString(PyExc_TypeError, buf);
688 return 0;
691 /* Decode arguments */
692 pargindex = 0;
693 for(i=0; i<self->ncargs; i++) {
694 cp = self->argconv[i];
695 if ( cp->get_uses_arg ) {
696 curarg = PyTuple_GET_ITEM(args, pargindex);
697 pargindex++;
698 } else {
699 curarg = (PyObject *)NULL;
701 c_args[i] = (*cp->get)(curarg);
703 if (PyErr_Occurred())
704 return 0;
706 /* Call function */
707 func = self->routine->rtn;
708 c_rv = (*func)(c_args[0], c_args[1], c_args[2], c_args[3],
709 c_args[4], c_args[5], c_args[6], c_args[7],
710 c_args[8], c_args[9], c_args[10], c_args[11]);
712 /* Decode return value, and store into returnvalues if needed */
713 pargindex = 0;
714 curarg = (*self->rvconv->rtn)(c_rv);
715 if ( curarg )
716 returnvalues[pargindex++] = curarg;
718 /* Decode returnvalue parameters and cleanup any storage allocated */
719 for(i=0; i<self->ncargs; i++) {
720 cp = self->argconv[i];
721 curarg = (*cp->put)(c_args[i]);
722 if(curarg)
723 returnvalues[pargindex++] = curarg;
724 /* NOTE: We only check errors at the end (so we free() everything) */
726 if ( PyErr_Occurred() ) {
727 /* An error did occur. Free the python objects created */
728 for(i=0; i<pargindex; i++)
729 Py_XDECREF(returnvalues[i]);
730 return NULL;
733 /* Zero and one return values cases are special: */
734 if ( pargindex == 0 ) {
735 Py_INCREF(Py_None);
736 return Py_None;
738 if ( pargindex == 1 )
739 return returnvalues[0];
741 /* More than one return value: put in a tuple */
742 rv = PyTuple_New(pargindex);
743 for(i=0; i<pargindex; i++)
744 if(rv)
745 PyTuple_SET_ITEM(rv, i, returnvalues[i]);
746 else
747 Py_XDECREF(returnvalues[i]);
748 return rv;
751 static char Cdctype__doc__[] =
755 static PyTypeObject Cdctype = {
756 PyObject_HEAD_INIT(&PyType_Type)
757 0, /*ob_size*/
758 "calldll.callable", /*tp_name*/
759 sizeof(cdcobject), /*tp_basicsize*/
760 0, /*tp_itemsize*/
761 /* methods */
762 (destructor)cdc_dealloc, /*tp_dealloc*/
763 (printfunc)0, /*tp_print*/
764 (getattrfunc)0, /*tp_getattr*/
765 (setattrfunc)0, /*tp_setattr*/
766 (cmpfunc)0, /*tp_compare*/
767 (reprfunc)cdc_repr, /*tp_repr*/
768 0, /*tp_as_number*/
769 0, /*tp_as_sequence*/
770 0, /*tp_as_mapping*/
771 (hashfunc)0, /*tp_hash*/
772 (ternaryfunc)cdc_call, /*tp_call*/
773 (reprfunc)0, /*tp_str*/
775 /* Space for future expansion */
776 0L,0L,0L,0L,
777 Cdctype__doc__ /* Documentation string */
780 /* End of code for callable objects */
781 /* ---------------------------------------------------------------- */
783 static char cdf_keys__doc__[] =
784 "Return list of symbol names in fragment";
786 static PyObject *
787 cdf_keys(self, args)
788 cdfobject *self;
789 PyObject *args;
791 long symcount;
792 PyObject *rv, *obj;
793 Str255 symname;
794 Ptr dummy1;
795 CFragSymbolClass dummy2;
796 int i;
797 OSErr err;
799 if (!PyArg_ParseTuple(args, ""))
800 return NULL;
801 if ( (err=CountSymbols(self->conn_id, &symcount)) < 0 )
802 return PyMac_Error(err);
803 if ( (rv=PyList_New(symcount)) == NULL )
804 return NULL;
805 for (i=0; i<symcount; i++) {
806 if ((err=GetIndSymbol(self->conn_id, i, symname, &dummy1, &dummy2)) < 0 ) {
807 Py_XDECREF(rv);
808 return PyMac_Error(err);
810 if ((obj=PyString_FromStringAndSize((char *)symname+1, symname[0])) == NULL ) {
811 Py_XDECREF(rv);
812 return PyMac_Error(err);
814 if (PyList_SetItem(rv, i, obj) < 0 ) {
815 Py_XDECREF(rv);
816 return NULL;
819 return rv;
823 static struct PyMethodDef cdf_methods[] = {
824 {"keys", (PyCFunction)cdf_keys, METH_VARARGS,
825 cdf_keys__doc__},
827 {NULL, NULL} /* sentinel */
830 /* ---------- */
833 static cdfobject *
834 newcdfobject(conn_id, name)
835 CFragConnectionID conn_id;
836 unsigned char *name;
838 cdfobject *self;
839 int nlen;
841 self = PyObject_NEW(cdfobject, &Cdftype);
842 if (self == NULL)
843 return NULL;
844 self->conn_id = conn_id;
845 if ( name[0] > MAXNAME )
846 nlen = MAXNAME;
847 else
848 nlen = name[0];
849 strncpy(self->name, (char *)name+1, nlen);
850 self->name[nlen] = '\0';
851 return self;
854 static void
855 cdf_dealloc(self)
856 cdfobject *self;
858 PyMem_DEL(self);
861 static PyObject *
862 cdf_repr(self)
863 cdfobject *self;
865 PyObject *s;
866 char buf[256];
868 sprintf(buf, "<fragment %s connection, id 0x%x>", self->name, self->conn_id);
869 s = PyString_FromString(buf);
870 return s;
873 static PyObject *
874 cdf_getattr_helper(self, name)
875 cdfobject *self;
876 char *name;
878 unsigned char *rtn_name;
879 anyroutine rtn;
880 OSErr err;
881 Str255 errMessage;
882 CFragSymbolClass class;
883 char buf[256];
885 rtn_name = Pstring(name);
886 err = FindSymbol(self->conn_id, rtn_name, (Ptr *)&rtn, &class);
887 if ( err ) {
888 sprintf(buf, "%.*s: %s", rtn_name[0], rtn_name+1, PyMac_StrError(err));
889 PyErr_SetString(ErrorObject, buf);
890 return NULL;
892 if( class != kTVectorCFragSymbol ) {
893 PyErr_SetString(ErrorObject, "Symbol is not a routine");
894 return NULL;
897 return (PyObject *)newcdrobject(rtn_name, rtn);
900 static PyObject *
901 cdf_getattr(self, name)
902 cdfobject *self;
903 char *name;
905 PyObject *rv;
907 if ((rv=Py_FindMethod(cdf_methods, (PyObject *)self, name)))
908 return rv;
909 PyErr_Clear();
910 return cdf_getattr_helper(self, name);
913 /* -------------------------------------------------------- */
914 /* Code to access cdf objects as mappings */
916 static int
917 cdf_length(self)
918 cdfobject *self;
920 long symcount;
921 OSErr err;
923 err = CountSymbols(self->conn_id, &symcount);
924 if ( err ) {
925 PyMac_Error(err);
926 return -1;
928 return symcount;
931 static PyObject *
932 cdf_subscript(self, key)
933 cdfobject *self;
934 PyObject *key;
936 char *name;
938 if ((name=PyString_AsString(key)) == 0 )
939 return 0;
940 return cdf_getattr_helper(self, name);
943 static int
944 cdf_ass_sub(self, v, w)
945 cdfobject *self;
946 PyObject *v, *w;
948 /* XXXX Put w in self under key v */
949 return 0;
952 static PyMappingMethods cdf_as_mapping = {
953 (inquiry)cdf_length, /*mp_length*/
954 (binaryfunc)cdf_subscript, /*mp_subscript*/
955 (objobjargproc)cdf_ass_sub, /*mp_ass_subscript*/
958 /* -------------------------------------------------------- */
960 static char Cdftype__doc__[] =
961 "Code Fragment library symbol table"
964 static PyTypeObject Cdftype = {
965 PyObject_HEAD_INIT(&PyType_Type)
966 0, /*ob_size*/
967 "calldll.fragment", /*tp_name*/
968 sizeof(cdfobject), /*tp_basicsize*/
969 0, /*tp_itemsize*/
970 /* methods */
971 (destructor)cdf_dealloc, /*tp_dealloc*/
972 (printfunc)0, /*tp_print*/
973 (getattrfunc)cdf_getattr, /*tp_getattr*/
974 (setattrfunc)0, /*tp_setattr*/
975 (cmpfunc)0, /*tp_compare*/
976 (reprfunc)cdf_repr, /*tp_repr*/
977 0, /*tp_as_number*/
978 0, /*tp_as_sequence*/
979 &cdf_as_mapping, /*tp_as_mapping*/
980 (hashfunc)0, /*tp_hash*/
981 (ternaryfunc)0, /*tp_call*/
982 (reprfunc)0, /*tp_str*/
984 /* Space for future expansion */
985 0L,0L,0L,0L,
986 Cdftype__doc__ /* Documentation string */
989 /* End of code for fragment objects */
990 /* -------------------------------------------------------- */
993 static char cdll_getlibrary__doc__[] =
994 "Load a shared library fragment and return the symbol table"
997 static PyObject *
998 cdll_getlibrary(self, args)
999 PyObject *self; /* Not used */
1000 PyObject *args;
1002 Str255 frag_name;
1003 OSErr err;
1004 Str255 errMessage;
1005 Ptr main_addr;
1006 CFragConnectionID conn_id;
1007 char buf[256];
1009 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, frag_name))
1010 return NULL;
1012 /* Find the library connection ID */
1013 err = GetSharedLibrary(frag_name, kCompiledCFragArch, kLoadCFrag, &conn_id, &main_addr,
1014 errMessage);
1015 if ( err ) {
1016 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
1017 PyErr_SetString(ErrorObject, buf);
1018 return NULL;
1020 return (PyObject *)newcdfobject(conn_id, frag_name);
1023 static char cdll_getdiskfragment__doc__[] =
1024 "Load a fragment from a disk file and return the symbol table"
1027 static PyObject *
1028 cdll_getdiskfragment(self, args)
1029 PyObject *self; /* Not used */
1030 PyObject *args;
1032 FSSpec fsspec;
1033 Str255 frag_name;
1034 OSErr err;
1035 Str255 errMessage;
1036 Ptr main_addr;
1037 CFragConnectionID conn_id;
1038 char buf[256];
1039 Boolean isfolder, didsomething;
1041 if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetFSSpec, &fsspec,
1042 PyMac_GetStr255, frag_name))
1043 return NULL;
1044 err = ResolveAliasFile(&fsspec, 1, &isfolder, &didsomething);
1045 if ( err )
1046 return PyErr_Mac(ErrorObject, err);
1048 /* Load the fragment (or return the connID if it is already loaded */
1049 err = GetDiskFragment(&fsspec, 0, 0, frag_name,
1050 kLoadCFrag, &conn_id, &main_addr,
1051 errMessage);
1052 if ( err ) {
1053 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
1054 PyErr_SetString(ErrorObject, buf);
1055 return NULL;
1057 return (PyObject *)newcdfobject(conn_id, frag_name);
1060 static char cdll_newcall__doc__[] =
1064 static PyObject *
1065 cdll_newcall(self, args)
1066 PyObject *self; /* Not used */
1067 PyObject *args;
1069 cdrobject *routine;
1070 conventry *argconv[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1071 rv2py_converter rvconv;
1072 int npargs, ncargs;
1074 /* Note: the next format depends on MAXARG */
1075 if (!PyArg_ParseTuple(args, "O!O&|O&O&O&O&O&O&O&O&O&O&O&O&", &Cdrtype, &routine,
1076 argparse_rvconv, &rvconv,
1077 argparse_conv, &argconv[0], argparse_conv, &argconv[1],
1078 argparse_conv, &argconv[2], argparse_conv, &argconv[3],
1079 argparse_conv, &argconv[4], argparse_conv, &argconv[5],
1080 argparse_conv, &argconv[6], argparse_conv, &argconv[7],
1081 argparse_conv, &argconv[8], argparse_conv, &argconv[9],
1082 argparse_conv, &argconv[10], argparse_conv, &argconv[11]))
1083 return NULL;
1084 npargs = 0;
1085 for(ncargs=0; ncargs < MAXARG && argconv[ncargs]; ncargs++) {
1086 if( argconv[ncargs]->get_uses_arg ) npargs++;
1088 return (PyObject *)newcdcobject(routine, npargs, ncargs, rvconv, argconv);
1091 /* List of methods defined in the module */
1093 static struct PyMethodDef cdll_methods[] = {
1094 {"getlibrary", (PyCFunction)cdll_getlibrary, METH_VARARGS,
1095 cdll_getlibrary__doc__},
1096 {"getdiskfragment", (PyCFunction)cdll_getdiskfragment, METH_VARARGS,
1097 cdll_getdiskfragment__doc__},
1098 {"newcall", (PyCFunction)cdll_newcall, METH_VARARGS,
1099 cdll_newcall__doc__},
1101 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
1105 /* Initialization function for the module (*must* be called initcalldll) */
1107 static char calldll_module_documentation[] =
1111 void
1112 initcalldll()
1114 PyObject *m, *d;
1116 /* Create the module and add the functions */
1117 m = Py_InitModule4("calldll", cdll_methods,
1118 calldll_module_documentation,
1119 (PyObject*)NULL,PYTHON_API_VERSION);
1121 /* Add some symbolic constants to the module */
1122 d = PyModule_GetDict(m);
1123 ErrorObject = PyString_FromString("calldll.error");
1124 PyDict_SetItemString(d, "error", ErrorObject);
1126 /* XXXX Add constants here */
1128 /* Check for errors */
1129 if (PyErr_Occurred())
1130 Py_FatalError("can't initialize module calldll");
1133 #ifdef TESTSUPPORT
1135 /* Test routine */
1136 int cdll_b_bbbbbbbb(char a1,char a2,char a3,char a4,char a5,char a6,char a7,char a8)
1138 return a1+a2+a3+a4+a5+a6+a7+a8;
1141 short cdll_h_hhhhhhhh(short a1,short a2,short a3,short a4,short a5,short a6,short a7,short a8)
1143 return a1+a2+a3+a4+a5+a6+a7+a8;
1146 int cdll_l_llllllll(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
1148 return a1+a2+a3+a4+a5+a6+a7+a8;
1151 void cdll_N_ssssssss(char *a1,char *a2,char *a3,char *a4,char *a5,char *a6,char *a7,char *a8)
1153 printf("cdll_N_ssssssss args: %s %s %s %s %s %s %s %s\n", a1, a2, a3, a4,
1154 a5, a6, a7, a8);
1157 OSErr cdll_o_l(long l)
1159 return (OSErr)l;
1162 void cdll_N_pp(unsigned char *in, unsigned char *out)
1164 out[0] = in[0] + 5;
1165 strcpy((char *)out+1, "Was: ");
1166 memcpy(out+6, in+1, in[0]);
1169 void cdll_N_bb(char a1, char *a2)
1171 *a2 = a1;
1174 void cdll_N_hh(short a1, short *a2)
1176 *a2 = a1;
1179 void cdll_N_ll(long a1, long *a2)
1181 *a2 = a1;
1184 void cdll_N_sH(char *a1, Handle a2)
1186 int len;
1188 len = strlen(a1);
1189 SetHandleSize(a2, len);
1190 HLock(a2);
1191 memcpy(*a2, a1, len);
1192 HUnlock(a2);
1194 #endif