blob: 63c2e7768f2e31ad9cba4f717c759342ed65a4e4 [file] [log] [blame]
Jack Jansenb3928d21997-02-17 16:56:56 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
Jack Jansene0e1f1a1997-02-20 15:18:32 +000032/* Sanity check */
33#ifndef __powerc
34#error Please port this code to your architecture first...
35#endif
36
37/*
38** Define to include testroutines (at the end)
39*/
40#define TESTSUPPORT
41
Jack Jansenb3928d21997-02-17 16:56:56 +000042#include "Python.h"
43#include "macglue.h"
44#include "macdefs.h"
Jack Jansene0e1f1a1997-02-20 15:18:32 +000045#include <CodeFragments.h>
Jack Jansenb3928d21997-02-17 16:56:56 +000046
Jack Jansene0e1f1a1997-02-20 15:18:32 +000047/* Prototypes for routines not in any include file (shame, shame) */
Jack Jansenb3928d21997-02-17 16:56:56 +000048extern PyObject *ResObj_New Py_PROTO((Handle));
49extern int ResObj_Convert Py_PROTO((PyObject *, Handle *));
50
Jack Jansenb3928d21997-02-17 16:56:56 +000051static PyObject *ErrorObject;
52
Jack Jansene0e1f1a1997-02-20 15:18:32 +000053/* Debugging macro */
54#ifdef TESTSUPPORT
Jack Jansenb3928d21997-02-17 16:56:56 +000055#define PARANOID(arg) \
56 if ( arg == 0 ) {PyErr_SetString(ErrorObject, "Internal error: NULL arg!"); return 0; }
Jack Jansene0e1f1a1997-02-20 15:18:32 +000057#else
58#define PARANOID(arg) /*pass*/
59#endif
60
61/* Prototypes we use for routines and arguments */
Jack Jansenb3928d21997-02-17 16:56:56 +000062
63typedef long anything;
64typedef anything (*anyroutine) Py_PROTO((...));
65
Jack Jansene0e1f1a1997-02-20 15:18:32 +000066/* Other constants */
Jack Jansenb3928d21997-02-17 16:56:56 +000067#define MAXNAME 31 /* Maximum size of names, for printing only */
68#define MAXARG 8 /* Maximum number of arguments */
69
70/*
Jack Jansene0e1f1a1997-02-20 15:18:32 +000071** 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.
76**
77** Hence, optional return values are also implementable.
Jack Jansenb3928d21997-02-17 16:56:56 +000078*/
79typedef anything (*py2c_converter) Py_PROTO((PyObject *));
80typedef PyObject *(*c2py_converter) Py_PROTO((anything));
Jack Jansene0e1f1a1997-02-20 15:18:32 +000081typedef PyObject *(*rv2py_converter) Py_PROTO((anything));
82
Jack Jansenb3928d21997-02-17 16:56:56 +000083
84/* Dummy routine for arguments that are output-only */
85static anything
86py2c_dummy(arg)
87 PyObject *arg;
88{
89 return 0;
90}
91
92/* Routine to allocate storage for output integers */
93static anything
94py2c_alloc(arg)
95 PyObject *arg;
96{
97 char *ptr;
98
99 if( (ptr=malloc(sizeof(anything))) == 0 )
100 PyErr_NoMemory();
101 return (anything)ptr;
102}
103
104/* Dummy routine for arguments that are input-only */
105static PyObject *
106c2py_dummy(arg)
107 anything arg;
108{
109 return 0;
110}
111
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000112/* Dummy routine for void return value */
113static PyObject *
114rv2py_none(arg)
115 anything arg;
116{
117 return 0;
118}
119
Jack Jansenb3928d21997-02-17 16:56:56 +0000120/* Routine to de-allocate storage for input-only arguments */
121static PyObject *
122c2py_free(arg)
123 anything arg;
124{
125 if ( arg )
126 free((char *)arg);
127 return 0;
128}
129
130/*
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000131** OSErr return value.
Jack Jansenb3928d21997-02-17 16:56:56 +0000132*/
133static PyObject *
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000134rv2py_oserr(arg)
Jack Jansenb3928d21997-02-17 16:56:56 +0000135 anything arg;
136{
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000137 OSErr err = (OSErr)arg;
Jack Jansenb3928d21997-02-17 16:56:56 +0000138
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000139 if (err)
140 return PyMac_Error(err);
141 return 0;
Jack Jansenb3928d21997-02-17 16:56:56 +0000142}
143
144/*
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000145** Input integers of all sizes (PPC only)
Jack Jansenb3928d21997-02-17 16:56:56 +0000146*/
147static anything
148py2c_in_int(arg)
149 PyObject *arg;
150{
151 return PyInt_AsLong(arg);
152}
153
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000154/*
155** Integer return values of all sizes (PPC only)
156*/
157static PyObject *
158rv2py_int(arg)
159 anything arg;
160{
161 return PyInt_FromLong((long)arg);
162}
163
164/*
165** Integer output parameters
166*/
Jack Jansenb3928d21997-02-17 16:56:56 +0000167static PyObject *
168c2py_out_long(arg)
169 anything arg;
170{
171 PyObject *rv;
172
173 PARANOID(arg);
174 rv = PyInt_FromLong(*(long *)arg);
175 free((char *)arg);
176 return rv;
177}
178
179static PyObject *
180c2py_out_short(arg)
181 anything arg;
182{
183 PyObject *rv;
184
185 PARANOID(arg);
186 rv = PyInt_FromLong((long)*(short *)arg);
187 free((char *)arg);
188 return rv;
189}
190
191static PyObject *
192c2py_out_byte(arg)
193 anything arg;
194{
195 PyObject *rv;
196
197 PARANOID(arg);
198 rv = PyInt_FromLong((long)*(char *)arg);
199 free((char *)arg);
200 return rv;
201}
202
203/*
204** Strings
205*/
206static anything
207py2c_in_string(arg)
208 PyObject *arg;
209{
210 return (anything)PyString_AsString(arg);
211}
212
213/*
214** Pascal-style strings
215*/
216static anything
217py2c_in_pstring(arg)
218 PyObject *arg;
219{
220 unsigned char *p;
221 int size;
222
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;
228 }
229 if( (p=(unsigned char *)malloc(256)) == 0 ) {
230 PyErr_NoMemory();
231 return 0;
232 }
233 p[0] = size;
234 memcpy(p+1, PyString_AsString(arg), size);
235 return (anything)p;
236}
237
238static anything
239py2c_out_pstring(arg)
240 PyObject *arg;
241{
242 unsigned char *p;
243
244 if( (p=(unsigned char *)malloc(256)) == 0 ) {
245 PyErr_NoMemory();
246 return 0;
247 }
248 p[0] = 0;
249 return (anything)p;
250}
251
252static PyObject *
253c2py_out_pstring(arg)
254 anything arg;
255{
256 unsigned char *p = (unsigned char *)arg;
257 PyObject *rv;
258
259 PARANOID(arg);
260 rv = PyString_FromStringAndSize((char *)p+1, p[0]);
261 free(p);
262 return rv;
263}
264
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000265static PyObject *
266rv2py_pstring(arg)
267 anything arg;
268{
269 unsigned char *p = (unsigned char *)arg;
270 PyObject *rv;
271
272 if ( arg == NULL ) return NULL;
273 rv = PyString_FromStringAndSize((char *)p+1, p[0]);
274 return rv;
275}
276
Jack Jansenb3928d21997-02-17 16:56:56 +0000277/*
278** C objects.
279*/
280static anything
281py2c_in_cobject(arg)
282 PyObject *arg;
283{
284 if ( arg == Py_None )
285 return 0;
286 return (anything)PyCObject_AsVoidPtr(arg);
287}
288
289static PyObject *
290c2py_out_cobject(arg)
291 anything arg;
292{
293 void **ptr = (void **)arg;
294 PyObject *rv;
295
296 PARANOID(arg);
297 if ( *ptr == 0 ) {
298 Py_INCREF(Py_None);
299 rv = Py_None;
300 } else {
301 rv = PyCObject_FromVoidPtr(*ptr, 0);
302 }
303 free((char *)ptr);
304 return rv;
305}
306
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000307static PyObject *
308rv2py_cobject(arg)
309 anything arg;
310{
311 void *ptr = (void *)arg;
312 PyObject *rv;
313
314 if ( ptr == 0 ) return NULL;
315 rv = PyCObject_FromVoidPtr(ptr, 0);
316 return rv;
317}
318
Jack Jansenb3928d21997-02-17 16:56:56 +0000319/*
320** Handles.
321*/
322static anything
323py2c_in_handle(arg)
324 PyObject *arg;
325{
326 Handle h = 0;
327 ResObj_Convert(arg, &h);
328 return (anything)h;
329}
330
331static PyObject *
332c2py_out_handle(arg)
333 anything arg;
334{
335 Handle *rv = (Handle *)arg;
336 PyObject *prv;
337
338 PARANOID(arg);
339 if ( *rv == 0 ) {
340 Py_INCREF(Py_None);
341 prv = Py_None;
342 } else {
343 prv = ResObj_New(*rv);
344 }
345 free((char *)rv);
346 return prv;
347}
348
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000349static PyObject *
350rv2py_handle(arg)
351 anything arg;
352{
353 Handle rv = (Handle)arg;
354
355 if ( rv == NULL ) return NULL;
356 return ResObj_New(rv);
357}
358
Jack Jansenb3928d21997-02-17 16:56:56 +0000359typedef 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 */
Jack Jansenb3928d21997-02-17 16:56:56 +0000364} conventry;
365
366static conventry converters[] = {
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000367 {"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}
381};
382
383typedef struct {
384 char *name;
385 rv2py_converter rtn;
386} rvconventry;
387
388static 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}
Jack Jansenb3928d21997-02-17 16:56:56 +0000398};
399
400static conventry *
401getconverter(name)
402 char *name;
403{
404 int i;
405 char buf[256];
406
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;
413}
414
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000415static rvconventry *
416getrvconverter(name)
417 char *name;
418{
419 int i;
420 char buf[256];
421
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;
428}
429
Jack Jansenb3928d21997-02-17 16:56:56 +0000430static int
431argparse_conv(obj, ptr)
432 PyObject *obj;
433 conventry **ptr;
434{
435 char *name;
436 int i;
437 conventry *item;
438
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;
445}
446
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000447static int
448argparse_rvconv(obj, ptr)
449 PyObject *obj;
450 rvconventry **ptr;
451{
452 char *name;
453 int i;
454 rvconventry *item;
455
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;
462}
463
Jack Jansenb3928d21997-02-17 16:56:56 +0000464/* ----------------------------------------------------- */
465
466/* Declarations for objects of type fragment */
467
468typedef struct {
469 PyObject_HEAD
470 CFragConnectionID conn_id;
471 char name[MAXNAME+1];
472} cdfobject;
473
474staticforward PyTypeObject Cdftype;
475
476
477
478/* ---------------------------------------------------------------- */
479
480/* Declarations for objects of type routine */
481
482typedef struct {
483 PyObject_HEAD
484 anyroutine rtn;
485 char name[MAXNAME+1];
486} cdrobject;
487
488staticforward PyTypeObject Cdrtype;
489
490
491
492/* ---------------------------------------------------------------- */
493
494/* Declarations for objects of type callable */
495
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000496
Jack Jansenb3928d21997-02-17 16:56:56 +0000497typedef struct {
498 PyObject_HEAD
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000499 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 */
Jack Jansenb3928d21997-02-17 16:56:56 +0000504} cdcobject;
505
506staticforward PyTypeObject Cdctype;
507
508
509
510/* -------------------------------------------------------- */
511
512
513static struct PyMethodDef cdr_methods[] = {
514
515 {NULL, NULL} /* sentinel */
516};
517
518/* ---------- */
519
520
521static cdrobject *
522newcdrobject(name, routine)
523 unsigned char *name;
524 anyroutine routine;
525{
526 cdrobject *self;
527 int nlen;
528
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;
540}
541
542static void
543cdr_dealloc(self)
544 cdrobject *self;
545{
546 PyMem_DEL(self);
547}
548
549static PyObject *
550cdr_repr(self)
551 cdrobject *self;
552{
553 PyObject *s;
554 char buf[256];
555
556 sprintf(buf, "<Calldll routine %s address 0x%x>", self->name, self->rtn);
557 s = PyString_FromString(buf);
558 return s;
559}
560
561static char Cdrtype__doc__[] =
562"C Routine address"
563;
564
565static 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*/
584
585 /* Space for future expansion */
586 0L,0L,0L,0L,
587 Cdrtype__doc__ /* Documentation string */
588};
589
590/* End of code for routine objects */
591/* -------------------------------------------------------- */
592
593
594static struct PyMethodDef cdc_methods[] = {
595
596 {NULL, NULL} /* sentinel */
597};
598
599/* ---------- */
600
601
602static cdcobject *
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000603newcdcobject(routine, npargs, ncargs, rvconv, argconv)
Jack Jansenb3928d21997-02-17 16:56:56 +0000604 cdrobject *routine;
605 int npargs;
Jack Jansenb3928d21997-02-17 16:56:56 +0000606 int ncargs;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000607 rvconventry *rvconv;
Jack Jansenb3928d21997-02-17 16:56:56 +0000608 conventry *argconv[];
609{
610 cdcobject *self;
611 int i;
612
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;
Jack Jansenb3928d21997-02-17 16:56:56 +0000619 self->ncargs = ncargs;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000620 self->rvconv = rvconv;
621 for(i=0; i<MAXARG; i++)
Jack Jansenb3928d21997-02-17 16:56:56 +0000622 if ( i < ncargs )
623 self->argconv[i] = argconv[i];
624 else
625 self->argconv[i] = 0;
626 return self;
627}
628
629static void
630cdc_dealloc(self)
631 cdcobject *self;
632{
633 Py_XDECREF(self->routine);
634 PyMem_DEL(self);
635}
636
637
638static PyObject *
639cdc_repr(self)
640 cdcobject *self;
641{
642 PyObject *s;
643 char buf[256];
644 int i;
645
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000646 sprintf(buf, "<callable %s = %s(", self->rvconv->name, self->routine->name);
647 for(i=0; i< self->ncargs; i++) {
Jack Jansenb3928d21997-02-17 16:56:56 +0000648 strcat(buf, self->argconv[i]->name);
649 if ( i < self->ncargs-1 )
650 strcat(buf, ", ");
651 }
652 strcat(buf, ") >");
653
654 s = PyString_FromString(buf);
655 return s;
656}
657
658/*
659** And this is what we all do it for: call a C function.
660*/
661static PyObject *
662cdc_call(self, args, kwargs)
663 cdcobject *self;
664 PyObject *args;
665 PyObject *kwargs;
666{
667 char buf[256];
668 int i, pargindex;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000669 anything c_args[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0};
670 anything c_rv;
Jack Jansenb3928d21997-02-17 16:56:56 +0000671 conventry *cp;
672 PyObject *curarg;
673 anyroutine func;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000674 PyObject *returnvalues[MAXARG+1];
675 PyObject *rv;
Jack Jansenb3928d21997-02-17 16:56:56 +0000676
677 if( kwargs ) {
678 PyErr_SetString(PyExc_TypeError, "Keyword args not allowed");
679 return 0;
680 }
681 if( !PyTuple_Check(args) ) {
682 PyErr_SetString(PyExc_TypeError, "Arguments not in tuple");
683 return 0;
684 }
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;
689 }
690
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;
700 }
701 c_args[i] = (*cp->get)(curarg);
702 }
703 if (PyErr_Occurred())
704 return 0;
705
706 /* Call function */
707 func = self->routine->rtn;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000708 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]);
Jack Jansenb3928d21997-02-17 16:56:56 +0000710
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000711 /* Decode return value, and store into returnvalues if needed */
Jack Jansenb3928d21997-02-17 16:56:56 +0000712 pargindex = 0;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000713 curarg = (*self->rvconv->rtn)(c_rv);
714 if ( curarg )
715 returnvalues[pargindex++] = curarg;
716
717 /* Decode returnvalue parameters and cleanup any storage allocated */
Jack Jansenb3928d21997-02-17 16:56:56 +0000718 for(i=0; i<self->ncargs; i++) {
719 cp = self->argconv[i];
720 curarg = (*cp->put)(c_args[i]);
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000721 if(curarg)
722 returnvalues[pargindex++] = curarg;
Jack Jansenb3928d21997-02-17 16:56:56 +0000723 /* NOTE: We only check errors at the end (so we free() everything) */
724 }
725 if ( PyErr_Occurred() ) {
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000726 /* An error did occur. Free the python objects created */
727 for(i=0; i<pargindex; i++)
728 Py_XDECREF(returnvalues[i]);
Jack Jansenb3928d21997-02-17 16:56:56 +0000729 return NULL;
730 }
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000731
732 /* Zero and one return values cases are special: */
733 if ( pargindex == 0 ) {
734 Py_INCREF(Py_None);
735 return Py_None;
736 }
737 if ( pargindex == 1 )
738 return returnvalues[0];
739
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]);
Jack Jansenb3928d21997-02-17 16:56:56 +0000747 return rv;
748}
749
750static char Cdctype__doc__[] =
751""
752;
753
754static 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*/
773
774 /* Space for future expansion */
775 0L,0L,0L,0L,
776 Cdctype__doc__ /* Documentation string */
777};
778
779/* End of code for callable objects */
780/* ---------------------------------------------------------------- */
781
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000782static char cdf_keys__doc__[] =
783"Return list of symbol names in fragment";
784
785static PyObject *
786cdf_keys(self, args)
787 cdfobject *self;
788 PyObject *args;
789{
790 long symcount;
791 PyObject *rv, *obj;
792 Str255 symname;
793 Ptr dummy1;
794 CFragSymbolClass dummy2;
795 int i;
796 OSErr err;
797
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);
808 }
809 if ((obj=PyString_FromStringAndSize((char *)symname+1, symname[0])) == NULL ) {
810 Py_XDECREF(rv);
811 return PyMac_Error(err);
812 }
813 if (PyList_SetItem(rv, i, obj) < 0 ) {
814 Py_XDECREF(rv);
815 return NULL;
816 }
817 }
818 return rv;
819}
820
821
Jack Jansenb3928d21997-02-17 16:56:56 +0000822static struct PyMethodDef cdf_methods[] = {
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000823 {"keys", (PyCFunction)cdf_keys, METH_VARARGS,
824 cdf_keys__doc__},
Jack Jansenb3928d21997-02-17 16:56:56 +0000825
826 {NULL, NULL} /* sentinel */
827};
828
829/* ---------- */
830
831
832static cdfobject *
833newcdfobject(conn_id, name)
834 CFragConnectionID conn_id;
835 unsigned char *name;
836{
837 cdfobject *self;
838 int nlen;
839
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;
851}
852
853static void
854cdf_dealloc(self)
855 cdfobject *self;
856{
857 PyMem_DEL(self);
858}
859
860static PyObject *
861cdf_repr(self)
862 cdfobject *self;
863{
864 PyObject *s;
865 char buf[256];
866
867 sprintf(buf, "<fragment %s connection, id 0x%x>", self->name, self->conn_id);
868 s = PyString_FromString(buf);
869 return s;
870}
871
872static PyObject *
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000873cdf_getattr_helper(self, name)
Jack Jansenb3928d21997-02-17 16:56:56 +0000874 cdfobject *self;
875 char *name;
876{
877 unsigned char *rtn_name;
878 anyroutine rtn;
879 OSErr err;
880 Str255 errMessage;
881 CFragSymbolClass class;
882 char buf[256];
883
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;
890 }
891 if( class != kTVectorCFragSymbol ) {
892 PyErr_SetString(ErrorObject, "Symbol is not a routine");
893 return NULL;
894 }
895
896 return (PyObject *)newcdrobject(rtn_name, rtn);
897}
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000898
899static PyObject *
900cdf_getattr(self, name)
901 cdfobject *self;
902 char *name;
903{
904 PyObject *rv;
905
906 if ((rv=Py_FindMethod(cdf_methods, (PyObject *)self, name)))
907 return rv;
908 PyErr_Clear();
909 return cdf_getattr_helper(self, name);
910}
911
912/* -------------------------------------------------------- */
913/* Code to access cdf objects as mappings */
914
915static int
916cdf_length(self)
917 cdfobject *self;
918{
919 long symcount;
920 OSErr err;
921
922 err = CountSymbols(self->conn_id, &symcount);
923 if ( err ) {
924 PyMac_Error(err);
925 return -1;
926 }
927 return symcount;
928}
929
930static PyObject *
931cdf_subscript(self, key)
932 cdfobject *self;
933 PyObject *key;
934{
935 char *name;
936
937 if ((name=PyString_AsString(key)) == 0 )
938 return 0;
939 return cdf_getattr_helper(self, name);
940}
941
942static int
943cdf_ass_sub(self, v, w)
944 cdfobject *self;
945 PyObject *v, *w;
946{
947 /* XXXX Put w in self under key v */
948 return 0;
949}
950
951static PyMappingMethods cdf_as_mapping = {
952 (inquiry)cdf_length, /*mp_length*/
953 (binaryfunc)cdf_subscript, /*mp_subscript*/
954 (objobjargproc)cdf_ass_sub, /*mp_ass_subscript*/
955};
956
Jack Jansenb3928d21997-02-17 16:56:56 +0000957/* -------------------------------------------------------- */
958
959static char Cdftype__doc__[] =
960"Code Fragment library symbol table"
961;
962
963static 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*/
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000978 &cdf_as_mapping, /*tp_as_mapping*/
Jack Jansenb3928d21997-02-17 16:56:56 +0000979 (hashfunc)0, /*tp_hash*/
980 (ternaryfunc)0, /*tp_call*/
981 (reprfunc)0, /*tp_str*/
982
983 /* Space for future expansion */
984 0L,0L,0L,0L,
985 Cdftype__doc__ /* Documentation string */
986};
987
988/* End of code for fragment objects */
989/* -------------------------------------------------------- */
990
991
992static char cdll_getlibrary__doc__[] =
993"Load a shared library fragment and return the symbol table"
994;
995
996static PyObject *
997cdll_getlibrary(self, args)
998 PyObject *self; /* Not used */
999 PyObject *args;
1000{
1001 Str255 frag_name;
1002 OSErr err;
1003 Str255 errMessage;
1004 Ptr main_addr;
1005 CFragConnectionID conn_id;
1006 char buf[256];
1007
1008 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, frag_name))
1009 return NULL;
1010
1011 /* Find the library connection ID */
Jack Jansen1b5b37f1998-02-20 15:55:30 +00001012 err = GetSharedLibrary(frag_name, kCompiledCFragArch, kLoadCFrag, &conn_id, &main_addr,
Jack Jansenb3928d21997-02-17 16:56:56 +00001013 errMessage);
1014 if ( err ) {
1015 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
1016 PyErr_SetString(ErrorObject, buf);
1017 return NULL;
1018 }
1019 return (PyObject *)newcdfobject(conn_id, frag_name);
1020}
1021
1022static char cdll_getdiskfragment__doc__[] =
1023"Load a fragment from a disk file and return the symbol table"
1024;
1025
1026static PyObject *
1027cdll_getdiskfragment(self, args)
1028 PyObject *self; /* Not used */
1029 PyObject *args;
1030{
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;
1039
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);
1046
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;
1055 }
1056 return (PyObject *)newcdfobject(conn_id, frag_name);
1057}
1058
1059static char cdll_newcall__doc__[] =
1060""
1061;
1062
1063static PyObject *
1064cdll_newcall(self, args)
1065 PyObject *self; /* Not used */
1066 PyObject *args;
1067{
1068 cdrobject *routine;
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001069 conventry *argconv[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0};
1070 rv2py_converter rvconv;
1071 int npargs, ncargs;
Jack Jansenb3928d21997-02-17 16:56:56 +00001072
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001073 /* Note: the next format depends on MAXARG */
Jack Jansenb3928d21997-02-17 16:56:56 +00001074 if (!PyArg_ParseTuple(args, "O!O&|O&O&O&O&O&O&O&O&", &Cdrtype, &routine,
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001075 argparse_rvconv, &rvconv,
Jack Jansenb3928d21997-02-17 16:56:56 +00001076 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],
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001079 argparse_conv, &argconv[6], argparse_conv, &argconv[7]))
Jack Jansenb3928d21997-02-17 16:56:56 +00001080 return NULL;
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001081 npargs = 0;
1082 for(ncargs=0; ncargs < MAXARG && argconv[ncargs]; ncargs++) {
Jack Jansenb3928d21997-02-17 16:56:56 +00001083 if( argconv[ncargs]->get_uses_arg ) npargs++;
Jack Jansenb3928d21997-02-17 16:56:56 +00001084 }
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001085 return (PyObject *)newcdcobject(routine, npargs, ncargs, rvconv, argconv);
Jack Jansenb3928d21997-02-17 16:56:56 +00001086}
1087
1088/* List of methods defined in the module */
1089
1090static 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__},
1097
1098 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
1099};
1100
1101
1102/* Initialization function for the module (*must* be called initcalldll) */
1103
1104static char calldll_module_documentation[] =
1105""
1106;
1107
1108void
1109initcalldll()
1110{
1111 PyObject *m, *d;
1112
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);
1117
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);
1122
1123 /* XXXX Add constants here */
1124
1125 /* Check for errors */
1126 if (PyErr_Occurred())
1127 Py_FatalError("can't initialize module calldll");
1128}
1129
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001130#ifdef TESTSUPPORT
1131
Jack Jansenb3928d21997-02-17 16:56:56 +00001132/* Test routine */
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001133int cdll_b_bbbbbbbb(char a1,char a2,char a3,char a4,char a5,char a6,char a7,char a8)
Jack Jansenb3928d21997-02-17 16:56:56 +00001134{
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001135 return a1+a2+a3+a4+a5+a6+a7+a8;
Jack Jansenb3928d21997-02-17 16:56:56 +00001136}
1137
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001138short cdll_h_hhhhhhhh(short a1,short a2,short a3,short a4,short a5,short a6,short a7,short a8)
1139{
1140 return a1+a2+a3+a4+a5+a6+a7+a8;
1141}
1142
1143int cdll_l_llllllll(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
1144{
1145 return a1+a2+a3+a4+a5+a6+a7+a8;
1146}
1147
1148void cdll_N_ssssssss(char *a1,char *a2,char *a3,char *a4,char *a5,char *a6,char *a7,char *a8)
1149{
1150 printf("cdll_N_ssssssss args: %s %s %s %s %s %s %s %s\n", a1, a2, a3, a4,
1151 a5, a6, a7, a8);
1152}
1153
1154OSErr cdll_o_l(long l)
1155{
1156 return (OSErr)l;
1157}
1158
1159void cdll_N_pp(unsigned char *in, unsigned char *out)
1160{
1161 out[0] = in[0] + 5;
1162 strcpy((char *)out+1, "Was: ");
1163 memcpy(out+6, in+1, in[0]);
1164}
1165
1166void cdll_N_bb(char a1, char *a2)
1167{
1168 *a2 = a1;
1169}
1170
1171void cdll_N_hh(short a1, short *a2)
1172{
1173 *a2 = a1;
1174}
1175
1176void cdll_N_ll(long a1, long *a2)
1177{
1178 *a2 = a1;
1179}
1180
1181void cdll_N_sH(char *a1, Handle a2)
1182{
1183 int len;
1184
1185 len = strlen(a1);
1186 SetHandleSize(a2, len);
1187 HLock(a2);
1188 memcpy(*a2, a1, len);
1189 HUnlock(a2);
1190}
1191#endif