blob: 56f8c0bcb65b37b92cc555c2b74cf9fe65101426 [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
782static struct PyMethodDef cdf_methods[] = {
783
784 {NULL, NULL} /* sentinel */
785};
786
787/* ---------- */
788
789
790static cdfobject *
791newcdfobject(conn_id, name)
792 CFragConnectionID conn_id;
793 unsigned char *name;
794{
795 cdfobject *self;
796 int nlen;
797
798 self = PyObject_NEW(cdfobject, &Cdftype);
799 if (self == NULL)
800 return NULL;
801 self->conn_id = conn_id;
802 if ( name[0] > MAXNAME )
803 nlen = MAXNAME;
804 else
805 nlen = name[0];
806 strncpy(self->name, (char *)name+1, nlen);
807 self->name[nlen] = '\0';
808 return self;
809}
810
811static void
812cdf_dealloc(self)
813 cdfobject *self;
814{
815 PyMem_DEL(self);
816}
817
818static PyObject *
819cdf_repr(self)
820 cdfobject *self;
821{
822 PyObject *s;
823 char buf[256];
824
825 sprintf(buf, "<fragment %s connection, id 0x%x>", self->name, self->conn_id);
826 s = PyString_FromString(buf);
827 return s;
828}
829
830static PyObject *
831cdf_getattr(self, name)
832 cdfobject *self;
833 char *name;
834{
835 unsigned char *rtn_name;
836 anyroutine rtn;
837 OSErr err;
838 Str255 errMessage;
839 CFragSymbolClass class;
840 char buf[256];
841
842 rtn_name = Pstring(name);
843 err = FindSymbol(self->conn_id, rtn_name, (Ptr *)&rtn, &class);
844 if ( err ) {
845 sprintf(buf, "%.*s: %s", rtn_name[0], rtn_name+1, PyMac_StrError(err));
846 PyErr_SetString(ErrorObject, buf);
847 return NULL;
848 }
849 if( class != kTVectorCFragSymbol ) {
850 PyErr_SetString(ErrorObject, "Symbol is not a routine");
851 return NULL;
852 }
853
854 return (PyObject *)newcdrobject(rtn_name, rtn);
855}
856/* -------------------------------------------------------- */
857
858static char Cdftype__doc__[] =
859"Code Fragment library symbol table"
860;
861
862static PyTypeObject Cdftype = {
863 PyObject_HEAD_INIT(&PyType_Type)
864 0, /*ob_size*/
865 "fragment", /*tp_name*/
866 sizeof(cdfobject), /*tp_basicsize*/
867 0, /*tp_itemsize*/
868 /* methods */
869 (destructor)cdf_dealloc, /*tp_dealloc*/
870 (printfunc)0, /*tp_print*/
871 (getattrfunc)cdf_getattr, /*tp_getattr*/
872 (setattrfunc)0, /*tp_setattr*/
873 (cmpfunc)0, /*tp_compare*/
874 (reprfunc)cdf_repr, /*tp_repr*/
875 0, /*tp_as_number*/
876 0, /*tp_as_sequence*/
877 0, /*tp_as_mapping*/
878 (hashfunc)0, /*tp_hash*/
879 (ternaryfunc)0, /*tp_call*/
880 (reprfunc)0, /*tp_str*/
881
882 /* Space for future expansion */
883 0L,0L,0L,0L,
884 Cdftype__doc__ /* Documentation string */
885};
886
887/* End of code for fragment objects */
888/* -------------------------------------------------------- */
889
890
891static char cdll_getlibrary__doc__[] =
892"Load a shared library fragment and return the symbol table"
893;
894
895static PyObject *
896cdll_getlibrary(self, args)
897 PyObject *self; /* Not used */
898 PyObject *args;
899{
900 Str255 frag_name;
901 OSErr err;
902 Str255 errMessage;
903 Ptr main_addr;
904 CFragConnectionID conn_id;
905 char buf[256];
906
907 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, frag_name))
908 return NULL;
909
910 /* Find the library connection ID */
911 err = GetSharedLibrary(frag_name, kCurrentCFragArch, kLoadCFrag, &conn_id, &main_addr,
912 errMessage);
913 if ( err ) {
914 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
915 PyErr_SetString(ErrorObject, buf);
916 return NULL;
917 }
918 return (PyObject *)newcdfobject(conn_id, frag_name);
919}
920
921static char cdll_getdiskfragment__doc__[] =
922"Load a fragment from a disk file and return the symbol table"
923;
924
925static PyObject *
926cdll_getdiskfragment(self, args)
927 PyObject *self; /* Not used */
928 PyObject *args;
929{
930 FSSpec fsspec;
931 Str255 frag_name;
932 OSErr err;
933 Str255 errMessage;
934 Ptr main_addr;
935 CFragConnectionID conn_id;
936 char buf[256];
937 Boolean isfolder, didsomething;
938
939 if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetFSSpec, &fsspec,
940 PyMac_GetStr255, frag_name))
941 return NULL;
942 err = ResolveAliasFile(&fsspec, 1, &isfolder, &didsomething);
943 if ( err )
944 return PyErr_Mac(ErrorObject, err);
945
946 /* Load the fragment (or return the connID if it is already loaded */
947 err = GetDiskFragment(&fsspec, 0, 0, frag_name,
948 kLoadCFrag, &conn_id, &main_addr,
949 errMessage);
950 if ( err ) {
951 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
952 PyErr_SetString(ErrorObject, buf);
953 return NULL;
954 }
955 return (PyObject *)newcdfobject(conn_id, frag_name);
956}
957
958static char cdll_newcall__doc__[] =
959""
960;
961
962static PyObject *
963cdll_newcall(self, args)
964 PyObject *self; /* Not used */
965 PyObject *args;
966{
967 cdrobject *routine;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000968 conventry *argconv[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0};
969 rv2py_converter rvconv;
970 int npargs, ncargs;
Jack Jansenb3928d21997-02-17 16:56:56 +0000971
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000972 /* Note: the next format depends on MAXARG */
Jack Jansenb3928d21997-02-17 16:56:56 +0000973 if (!PyArg_ParseTuple(args, "O!O&|O&O&O&O&O&O&O&O&", &Cdrtype, &routine,
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000974 argparse_rvconv, &rvconv,
Jack Jansenb3928d21997-02-17 16:56:56 +0000975 argparse_conv, &argconv[0], argparse_conv, &argconv[1],
976 argparse_conv, &argconv[2], argparse_conv, &argconv[3],
977 argparse_conv, &argconv[4], argparse_conv, &argconv[5],
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000978 argparse_conv, &argconv[6], argparse_conv, &argconv[7]))
Jack Jansenb3928d21997-02-17 16:56:56 +0000979 return NULL;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000980 npargs = 0;
981 for(ncargs=0; ncargs < MAXARG && argconv[ncargs]; ncargs++) {
Jack Jansenb3928d21997-02-17 16:56:56 +0000982 if( argconv[ncargs]->get_uses_arg ) npargs++;
Jack Jansenb3928d21997-02-17 16:56:56 +0000983 }
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000984 return (PyObject *)newcdcobject(routine, npargs, ncargs, rvconv, argconv);
Jack Jansenb3928d21997-02-17 16:56:56 +0000985}
986
987/* List of methods defined in the module */
988
989static struct PyMethodDef cdll_methods[] = {
990 {"getlibrary", (PyCFunction)cdll_getlibrary, METH_VARARGS,
991 cdll_getlibrary__doc__},
992 {"getdiskfragment", (PyCFunction)cdll_getdiskfragment, METH_VARARGS,
993 cdll_getdiskfragment__doc__},
994 {"newcall", (PyCFunction)cdll_newcall, METH_VARARGS,
995 cdll_newcall__doc__},
996
997 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
998};
999
1000
1001/* Initialization function for the module (*must* be called initcalldll) */
1002
1003static char calldll_module_documentation[] =
1004""
1005;
1006
1007void
1008initcalldll()
1009{
1010 PyObject *m, *d;
1011
1012 /* Create the module and add the functions */
1013 m = Py_InitModule4("calldll", cdll_methods,
1014 calldll_module_documentation,
1015 (PyObject*)NULL,PYTHON_API_VERSION);
1016
1017 /* Add some symbolic constants to the module */
1018 d = PyModule_GetDict(m);
1019 ErrorObject = PyString_FromString("calldll.error");
1020 PyDict_SetItemString(d, "error", ErrorObject);
1021
1022 /* XXXX Add constants here */
1023
1024 /* Check for errors */
1025 if (PyErr_Occurred())
1026 Py_FatalError("can't initialize module calldll");
1027}
1028
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001029#ifdef TESTSUPPORT
1030
Jack Jansenb3928d21997-02-17 16:56:56 +00001031/* Test routine */
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001032int 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 +00001033{
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001034 return a1+a2+a3+a4+a5+a6+a7+a8;
Jack Jansenb3928d21997-02-17 16:56:56 +00001035}
1036
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001037short cdll_h_hhhhhhhh(short a1,short a2,short a3,short a4,short a5,short a6,short a7,short a8)
1038{
1039 return a1+a2+a3+a4+a5+a6+a7+a8;
1040}
1041
1042int cdll_l_llllllll(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
1043{
1044 return a1+a2+a3+a4+a5+a6+a7+a8;
1045}
1046
1047void cdll_N_ssssssss(char *a1,char *a2,char *a3,char *a4,char *a5,char *a6,char *a7,char *a8)
1048{
1049 printf("cdll_N_ssssssss args: %s %s %s %s %s %s %s %s\n", a1, a2, a3, a4,
1050 a5, a6, a7, a8);
1051}
1052
1053OSErr cdll_o_l(long l)
1054{
1055 return (OSErr)l;
1056}
1057
1058void cdll_N_pp(unsigned char *in, unsigned char *out)
1059{
1060 out[0] = in[0] + 5;
1061 strcpy((char *)out+1, "Was: ");
1062 memcpy(out+6, in+1, in[0]);
1063}
1064
1065void cdll_N_bb(char a1, char *a2)
1066{
1067 *a2 = a1;
1068}
1069
1070void cdll_N_hh(short a1, short *a2)
1071{
1072 *a2 = a1;
1073}
1074
1075void cdll_N_ll(long a1, long *a2)
1076{
1077 *a2 = a1;
1078}
1079
1080void cdll_N_sH(char *a1, Handle a2)
1081{
1082 int len;
1083
1084 len = strlen(a1);
1085 SetHandleSize(a2, len);
1086 HLock(a2);
1087 memcpy(*a2, a1, len);
1088 HUnlock(a2);
1089}
1090#endif