Clarify portability and main program.
[python/dscho.git] / Mac / Modules / calldll.c
blob63c2e7768f2e31ad9cba4f717c759342ed65a4e4
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 Py_PROTO((Handle));
49 extern int ResObj_Convert Py_PROTO((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) Py_PROTO((...));
66 /* Other constants */
67 #define MAXNAME 31 /* Maximum size of names, for printing only */
68 #define MAXARG 8 /* 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) Py_PROTO((PyObject *));
80 typedef PyObject *(*c2py_converter) Py_PROTO((anything));
81 typedef PyObject *(*rv2py_converter) Py_PROTO((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 "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};
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]);
711 /* Decode return value, and store into returnvalues if needed */
712 pargindex = 0;
713 curarg = (*self->rvconv->rtn)(c_rv);
714 if ( curarg )
715 returnvalues[pargindex++] = curarg;
717 /* Decode returnvalue parameters and cleanup any storage allocated */
718 for(i=0; i<self->ncargs; i++) {
719 cp = self->argconv[i];
720 curarg = (*cp->put)(c_args[i]);
721 if(curarg)
722 returnvalues[pargindex++] = curarg;
723 /* NOTE: We only check errors at the end (so we free() everything) */
725 if ( PyErr_Occurred() ) {
726 /* An error did occur. Free the python objects created */
727 for(i=0; i<pargindex; i++)
728 Py_XDECREF(returnvalues[i]);
729 return NULL;
732 /* Zero and one return values cases are special: */
733 if ( pargindex == 0 ) {
734 Py_INCREF(Py_None);
735 return Py_None;
737 if ( pargindex == 1 )
738 return returnvalues[0];
740 /* More than one return value: put in a tuple */
741 rv = PyTuple_New(pargindex);
742 for(i=0; i<pargindex; i++)
743 if(rv)
744 PyTuple_SET_ITEM(rv, i, returnvalues[i]);
745 else
746 Py_XDECREF(returnvalues[i]);
747 return rv;
750 static char Cdctype__doc__[] =
754 static PyTypeObject Cdctype = {
755 PyObject_HEAD_INIT(&PyType_Type)
756 0, /*ob_size*/
757 "callable", /*tp_name*/
758 sizeof(cdcobject), /*tp_basicsize*/
759 0, /*tp_itemsize*/
760 /* methods */
761 (destructor)cdc_dealloc, /*tp_dealloc*/
762 (printfunc)0, /*tp_print*/
763 (getattrfunc)0, /*tp_getattr*/
764 (setattrfunc)0, /*tp_setattr*/
765 (cmpfunc)0, /*tp_compare*/
766 (reprfunc)cdc_repr, /*tp_repr*/
767 0, /*tp_as_number*/
768 0, /*tp_as_sequence*/
769 0, /*tp_as_mapping*/
770 (hashfunc)0, /*tp_hash*/
771 (ternaryfunc)cdc_call, /*tp_call*/
772 (reprfunc)0, /*tp_str*/
774 /* Space for future expansion */
775 0L,0L,0L,0L,
776 Cdctype__doc__ /* Documentation string */
779 /* End of code for callable objects */
780 /* ---------------------------------------------------------------- */
782 static char cdf_keys__doc__[] =
783 "Return list of symbol names in fragment";
785 static PyObject *
786 cdf_keys(self, args)
787 cdfobject *self;
788 PyObject *args;
790 long symcount;
791 PyObject *rv, *obj;
792 Str255 symname;
793 Ptr dummy1;
794 CFragSymbolClass dummy2;
795 int i;
796 OSErr err;
798 if (!PyArg_ParseTuple(args, ""))
799 return NULL;
800 if ( (err=CountSymbols(self->conn_id, &symcount)) < 0 )
801 return PyMac_Error(err);
802 if ( (rv=PyList_New(symcount)) == NULL )
803 return NULL;
804 for (i=0; i<symcount; i++) {
805 if ((err=GetIndSymbol(self->conn_id, i, symname, &dummy1, &dummy2)) < 0 ) {
806 Py_XDECREF(rv);
807 return PyMac_Error(err);
809 if ((obj=PyString_FromStringAndSize((char *)symname+1, symname[0])) == NULL ) {
810 Py_XDECREF(rv);
811 return PyMac_Error(err);
813 if (PyList_SetItem(rv, i, obj) < 0 ) {
814 Py_XDECREF(rv);
815 return NULL;
818 return rv;
822 static struct PyMethodDef cdf_methods[] = {
823 {"keys", (PyCFunction)cdf_keys, METH_VARARGS,
824 cdf_keys__doc__},
826 {NULL, NULL} /* sentinel */
829 /* ---------- */
832 static cdfobject *
833 newcdfobject(conn_id, name)
834 CFragConnectionID conn_id;
835 unsigned char *name;
837 cdfobject *self;
838 int nlen;
840 self = PyObject_NEW(cdfobject, &Cdftype);
841 if (self == NULL)
842 return NULL;
843 self->conn_id = conn_id;
844 if ( name[0] > MAXNAME )
845 nlen = MAXNAME;
846 else
847 nlen = name[0];
848 strncpy(self->name, (char *)name+1, nlen);
849 self->name[nlen] = '\0';
850 return self;
853 static void
854 cdf_dealloc(self)
855 cdfobject *self;
857 PyMem_DEL(self);
860 static PyObject *
861 cdf_repr(self)
862 cdfobject *self;
864 PyObject *s;
865 char buf[256];
867 sprintf(buf, "<fragment %s connection, id 0x%x>", self->name, self->conn_id);
868 s = PyString_FromString(buf);
869 return s;
872 static PyObject *
873 cdf_getattr_helper(self, name)
874 cdfobject *self;
875 char *name;
877 unsigned char *rtn_name;
878 anyroutine rtn;
879 OSErr err;
880 Str255 errMessage;
881 CFragSymbolClass class;
882 char buf[256];
884 rtn_name = Pstring(name);
885 err = FindSymbol(self->conn_id, rtn_name, (Ptr *)&rtn, &class);
886 if ( err ) {
887 sprintf(buf, "%.*s: %s", rtn_name[0], rtn_name+1, PyMac_StrError(err));
888 PyErr_SetString(ErrorObject, buf);
889 return NULL;
891 if( class != kTVectorCFragSymbol ) {
892 PyErr_SetString(ErrorObject, "Symbol is not a routine");
893 return NULL;
896 return (PyObject *)newcdrobject(rtn_name, rtn);
899 static PyObject *
900 cdf_getattr(self, name)
901 cdfobject *self;
902 char *name;
904 PyObject *rv;
906 if ((rv=Py_FindMethod(cdf_methods, (PyObject *)self, name)))
907 return rv;
908 PyErr_Clear();
909 return cdf_getattr_helper(self, name);
912 /* -------------------------------------------------------- */
913 /* Code to access cdf objects as mappings */
915 static int
916 cdf_length(self)
917 cdfobject *self;
919 long symcount;
920 OSErr err;
922 err = CountSymbols(self->conn_id, &symcount);
923 if ( err ) {
924 PyMac_Error(err);
925 return -1;
927 return symcount;
930 static PyObject *
931 cdf_subscript(self, key)
932 cdfobject *self;
933 PyObject *key;
935 char *name;
937 if ((name=PyString_AsString(key)) == 0 )
938 return 0;
939 return cdf_getattr_helper(self, name);
942 static int
943 cdf_ass_sub(self, v, w)
944 cdfobject *self;
945 PyObject *v, *w;
947 /* XXXX Put w in self under key v */
948 return 0;
951 static PyMappingMethods cdf_as_mapping = {
952 (inquiry)cdf_length, /*mp_length*/
953 (binaryfunc)cdf_subscript, /*mp_subscript*/
954 (objobjargproc)cdf_ass_sub, /*mp_ass_subscript*/
957 /* -------------------------------------------------------- */
959 static char Cdftype__doc__[] =
960 "Code Fragment library symbol table"
963 static PyTypeObject Cdftype = {
964 PyObject_HEAD_INIT(&PyType_Type)
965 0, /*ob_size*/
966 "fragment", /*tp_name*/
967 sizeof(cdfobject), /*tp_basicsize*/
968 0, /*tp_itemsize*/
969 /* methods */
970 (destructor)cdf_dealloc, /*tp_dealloc*/
971 (printfunc)0, /*tp_print*/
972 (getattrfunc)cdf_getattr, /*tp_getattr*/
973 (setattrfunc)0, /*tp_setattr*/
974 (cmpfunc)0, /*tp_compare*/
975 (reprfunc)cdf_repr, /*tp_repr*/
976 0, /*tp_as_number*/
977 0, /*tp_as_sequence*/
978 &cdf_as_mapping, /*tp_as_mapping*/
979 (hashfunc)0, /*tp_hash*/
980 (ternaryfunc)0, /*tp_call*/
981 (reprfunc)0, /*tp_str*/
983 /* Space for future expansion */
984 0L,0L,0L,0L,
985 Cdftype__doc__ /* Documentation string */
988 /* End of code for fragment objects */
989 /* -------------------------------------------------------- */
992 static char cdll_getlibrary__doc__[] =
993 "Load a shared library fragment and return the symbol table"
996 static PyObject *
997 cdll_getlibrary(self, args)
998 PyObject *self; /* Not used */
999 PyObject *args;
1001 Str255 frag_name;
1002 OSErr err;
1003 Str255 errMessage;
1004 Ptr main_addr;
1005 CFragConnectionID conn_id;
1006 char buf[256];
1008 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, frag_name))
1009 return NULL;
1011 /* Find the library connection ID */
1012 err = GetSharedLibrary(frag_name, kCompiledCFragArch, kLoadCFrag, &conn_id, &main_addr,
1013 errMessage);
1014 if ( err ) {
1015 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
1016 PyErr_SetString(ErrorObject, buf);
1017 return NULL;
1019 return (PyObject *)newcdfobject(conn_id, frag_name);
1022 static char cdll_getdiskfragment__doc__[] =
1023 "Load a fragment from a disk file and return the symbol table"
1026 static PyObject *
1027 cdll_getdiskfragment(self, args)
1028 PyObject *self; /* Not used */
1029 PyObject *args;
1031 FSSpec fsspec;
1032 Str255 frag_name;
1033 OSErr err;
1034 Str255 errMessage;
1035 Ptr main_addr;
1036 CFragConnectionID conn_id;
1037 char buf[256];
1038 Boolean isfolder, didsomething;
1040 if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetFSSpec, &fsspec,
1041 PyMac_GetStr255, frag_name))
1042 return NULL;
1043 err = ResolveAliasFile(&fsspec, 1, &isfolder, &didsomething);
1044 if ( err )
1045 return PyErr_Mac(ErrorObject, err);
1047 /* Load the fragment (or return the connID if it is already loaded */
1048 err = GetDiskFragment(&fsspec, 0, 0, frag_name,
1049 kLoadCFrag, &conn_id, &main_addr,
1050 errMessage);
1051 if ( err ) {
1052 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
1053 PyErr_SetString(ErrorObject, buf);
1054 return NULL;
1056 return (PyObject *)newcdfobject(conn_id, frag_name);
1059 static char cdll_newcall__doc__[] =
1063 static PyObject *
1064 cdll_newcall(self, args)
1065 PyObject *self; /* Not used */
1066 PyObject *args;
1068 cdrobject *routine;
1069 conventry *argconv[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0};
1070 rv2py_converter rvconv;
1071 int npargs, ncargs;
1073 /* Note: the next format depends on MAXARG */
1074 if (!PyArg_ParseTuple(args, "O!O&|O&O&O&O&O&O&O&O&", &Cdrtype, &routine,
1075 argparse_rvconv, &rvconv,
1076 argparse_conv, &argconv[0], argparse_conv, &argconv[1],
1077 argparse_conv, &argconv[2], argparse_conv, &argconv[3],
1078 argparse_conv, &argconv[4], argparse_conv, &argconv[5],
1079 argparse_conv, &argconv[6], argparse_conv, &argconv[7]))
1080 return NULL;
1081 npargs = 0;
1082 for(ncargs=0; ncargs < MAXARG && argconv[ncargs]; ncargs++) {
1083 if( argconv[ncargs]->get_uses_arg ) npargs++;
1085 return (PyObject *)newcdcobject(routine, npargs, ncargs, rvconv, argconv);
1088 /* List of methods defined in the module */
1090 static struct PyMethodDef cdll_methods[] = {
1091 {"getlibrary", (PyCFunction)cdll_getlibrary, METH_VARARGS,
1092 cdll_getlibrary__doc__},
1093 {"getdiskfragment", (PyCFunction)cdll_getdiskfragment, METH_VARARGS,
1094 cdll_getdiskfragment__doc__},
1095 {"newcall", (PyCFunction)cdll_newcall, METH_VARARGS,
1096 cdll_newcall__doc__},
1098 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
1102 /* Initialization function for the module (*must* be called initcalldll) */
1104 static char calldll_module_documentation[] =
1108 void
1109 initcalldll()
1111 PyObject *m, *d;
1113 /* Create the module and add the functions */
1114 m = Py_InitModule4("calldll", cdll_methods,
1115 calldll_module_documentation,
1116 (PyObject*)NULL,PYTHON_API_VERSION);
1118 /* Add some symbolic constants to the module */
1119 d = PyModule_GetDict(m);
1120 ErrorObject = PyString_FromString("calldll.error");
1121 PyDict_SetItemString(d, "error", ErrorObject);
1123 /* XXXX Add constants here */
1125 /* Check for errors */
1126 if (PyErr_Occurred())
1127 Py_FatalError("can't initialize module calldll");
1130 #ifdef TESTSUPPORT
1132 /* Test routine */
1133 int cdll_b_bbbbbbbb(char a1,char a2,char a3,char a4,char a5,char a6,char a7,char a8)
1135 return a1+a2+a3+a4+a5+a6+a7+a8;
1138 short cdll_h_hhhhhhhh(short a1,short a2,short a3,short a4,short a5,short a6,short a7,short a8)
1140 return a1+a2+a3+a4+a5+a6+a7+a8;
1143 int cdll_l_llllllll(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
1145 return a1+a2+a3+a4+a5+a6+a7+a8;
1148 void cdll_N_ssssssss(char *a1,char *a2,char *a3,char *a4,char *a5,char *a6,char *a7,char *a8)
1150 printf("cdll_N_ssssssss args: %s %s %s %s %s %s %s %s\n", a1, a2, a3, a4,
1151 a5, a6, a7, a8);
1154 OSErr cdll_o_l(long l)
1156 return (OSErr)l;
1159 void cdll_N_pp(unsigned char *in, unsigned char *out)
1161 out[0] = in[0] + 5;
1162 strcpy((char *)out+1, "Was: ");
1163 memcpy(out+6, in+1, in[0]);
1166 void cdll_N_bb(char a1, char *a2)
1168 *a2 = a1;
1171 void cdll_N_hh(short a1, short *a2)
1173 *a2 = a1;
1176 void cdll_N_ll(long a1, long *a2)
1178 *a2 = a1;
1181 void cdll_N_sH(char *a1, Handle a2)
1183 int len;
1185 len = strlen(a1);
1186 SetHandleSize(a2, len);
1187 HLock(a2);
1188 memcpy(*a2, a1, len);
1189 HUnlock(a2);
1191 #endif