blob: e8d4736ee039459695990de9598f72bbf19f541e [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 Jansenb88b0bc2000-07-31 22:07:49 +000048extern PyObject *ResObj_New(Handle);
49extern int ResObj_Convert(PyObject *, Handle *);
Jack Jansenb3928d21997-02-17 16:56:56 +000050
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;
Jack Jansenb88b0bc2000-07-31 22:07:49 +000064typedef anything (*anyroutine)(...);
Jack Jansenb3928d21997-02-17 16:56:56 +000065
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 */
Jack Jansen75e62f21999-12-03 23:35:47 +000068#define MAXARG 12 /* Maximum number of arguments */
Jack Jansenb3928d21997-02-17 16:56:56 +000069
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*/
Jack Jansenb88b0bc2000-07-31 22:07:49 +000079typedef anything (*py2c_converter)(PyObject *);
80typedef PyObject *(*c2py_converter)(anything);
81typedef PyObject *(*rv2py_converter)(anything);
Jack Jansene0e1f1a1997-02-20 15:18:32 +000082
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 Jansen75e62f21999-12-03 23:35:47 +0000669 anything c_args[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000670 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],
Jack Jansen75e62f21999-12-03 23:35:47 +0000709 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]);
Jack Jansenb3928d21997-02-17 16:56:56 +0000711
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000712 /* Decode return value, and store into returnvalues if needed */
Jack Jansenb3928d21997-02-17 16:56:56 +0000713 pargindex = 0;
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000714 curarg = (*self->rvconv->rtn)(c_rv);
715 if ( curarg )
716 returnvalues[pargindex++] = curarg;
717
718 /* Decode returnvalue parameters and cleanup any storage allocated */
Jack Jansenb3928d21997-02-17 16:56:56 +0000719 for(i=0; i<self->ncargs; i++) {
720 cp = self->argconv[i];
721 curarg = (*cp->put)(c_args[i]);
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000722 if(curarg)
723 returnvalues[pargindex++] = curarg;
Jack Jansenb3928d21997-02-17 16:56:56 +0000724 /* NOTE: We only check errors at the end (so we free() everything) */
725 }
726 if ( PyErr_Occurred() ) {
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000727 /* An error did occur. Free the python objects created */
728 for(i=0; i<pargindex; i++)
729 Py_XDECREF(returnvalues[i]);
Jack Jansenb3928d21997-02-17 16:56:56 +0000730 return NULL;
731 }
Jack Jansene0e1f1a1997-02-20 15:18:32 +0000732
733 /* Zero and one return values cases are special: */
734 if ( pargindex == 0 ) {
735 Py_INCREF(Py_None);
736 return Py_None;
737 }
738 if ( pargindex == 1 )
739 return returnvalues[0];
740
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]);
Jack Jansenb3928d21997-02-17 16:56:56 +0000748 return rv;
749}
750
751static char Cdctype__doc__[] =
752""
753;
754
755static PyTypeObject Cdctype = {
756 PyObject_HEAD_INIT(&PyType_Type)
757 0, /*ob_size*/
758 "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*/
774
775 /* Space for future expansion */
776 0L,0L,0L,0L,
777 Cdctype__doc__ /* Documentation string */
778};
779
780/* End of code for callable objects */
781/* ---------------------------------------------------------------- */
782
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000783static char cdf_keys__doc__[] =
784"Return list of symbol names in fragment";
785
786static PyObject *
787cdf_keys(self, args)
788 cdfobject *self;
789 PyObject *args;
790{
791 long symcount;
792 PyObject *rv, *obj;
793 Str255 symname;
794 Ptr dummy1;
795 CFragSymbolClass dummy2;
796 int i;
797 OSErr err;
798
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);
809 }
810 if ((obj=PyString_FromStringAndSize((char *)symname+1, symname[0])) == NULL ) {
811 Py_XDECREF(rv);
812 return PyMac_Error(err);
813 }
814 if (PyList_SetItem(rv, i, obj) < 0 ) {
815 Py_XDECREF(rv);
816 return NULL;
817 }
818 }
819 return rv;
820}
821
822
Jack Jansenb3928d21997-02-17 16:56:56 +0000823static struct PyMethodDef cdf_methods[] = {
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000824 {"keys", (PyCFunction)cdf_keys, METH_VARARGS,
825 cdf_keys__doc__},
Jack Jansenb3928d21997-02-17 16:56:56 +0000826
827 {NULL, NULL} /* sentinel */
828};
829
830/* ---------- */
831
832
833static cdfobject *
834newcdfobject(conn_id, name)
835 CFragConnectionID conn_id;
836 unsigned char *name;
837{
838 cdfobject *self;
839 int nlen;
840
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;
852}
853
854static void
855cdf_dealloc(self)
856 cdfobject *self;
857{
858 PyMem_DEL(self);
859}
860
861static PyObject *
862cdf_repr(self)
863 cdfobject *self;
864{
865 PyObject *s;
866 char buf[256];
867
868 sprintf(buf, "<fragment %s connection, id 0x%x>", self->name, self->conn_id);
869 s = PyString_FromString(buf);
870 return s;
871}
872
873static PyObject *
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000874cdf_getattr_helper(self, name)
Jack Jansenb3928d21997-02-17 16:56:56 +0000875 cdfobject *self;
876 char *name;
877{
878 unsigned char *rtn_name;
879 anyroutine rtn;
880 OSErr err;
881 Str255 errMessage;
882 CFragSymbolClass class;
883 char buf[256];
884
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;
891 }
892 if( class != kTVectorCFragSymbol ) {
893 PyErr_SetString(ErrorObject, "Symbol is not a routine");
894 return NULL;
895 }
896
897 return (PyObject *)newcdrobject(rtn_name, rtn);
898}
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000899
900static PyObject *
901cdf_getattr(self, name)
902 cdfobject *self;
903 char *name;
904{
905 PyObject *rv;
906
907 if ((rv=Py_FindMethod(cdf_methods, (PyObject *)self, name)))
908 return rv;
909 PyErr_Clear();
910 return cdf_getattr_helper(self, name);
911}
912
913/* -------------------------------------------------------- */
914/* Code to access cdf objects as mappings */
915
916static int
917cdf_length(self)
918 cdfobject *self;
919{
920 long symcount;
921 OSErr err;
922
923 err = CountSymbols(self->conn_id, &symcount);
924 if ( err ) {
925 PyMac_Error(err);
926 return -1;
927 }
928 return symcount;
929}
930
931static PyObject *
932cdf_subscript(self, key)
933 cdfobject *self;
934 PyObject *key;
935{
936 char *name;
937
938 if ((name=PyString_AsString(key)) == 0 )
939 return 0;
940 return cdf_getattr_helper(self, name);
941}
942
943static int
944cdf_ass_sub(self, v, w)
945 cdfobject *self;
946 PyObject *v, *w;
947{
948 /* XXXX Put w in self under key v */
949 return 0;
950}
951
952static PyMappingMethods cdf_as_mapping = {
953 (inquiry)cdf_length, /*mp_length*/
954 (binaryfunc)cdf_subscript, /*mp_subscript*/
955 (objobjargproc)cdf_ass_sub, /*mp_ass_subscript*/
956};
957
Jack Jansenb3928d21997-02-17 16:56:56 +0000958/* -------------------------------------------------------- */
959
960static char Cdftype__doc__[] =
961"Code Fragment library symbol table"
962;
963
964static PyTypeObject Cdftype = {
965 PyObject_HEAD_INIT(&PyType_Type)
966 0, /*ob_size*/
967 "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*/
Jack Jansene8b9b9f1997-05-23 15:36:13 +0000979 &cdf_as_mapping, /*tp_as_mapping*/
Jack Jansenb3928d21997-02-17 16:56:56 +0000980 (hashfunc)0, /*tp_hash*/
981 (ternaryfunc)0, /*tp_call*/
982 (reprfunc)0, /*tp_str*/
983
984 /* Space for future expansion */
985 0L,0L,0L,0L,
986 Cdftype__doc__ /* Documentation string */
987};
988
989/* End of code for fragment objects */
990/* -------------------------------------------------------- */
991
992
993static char cdll_getlibrary__doc__[] =
994"Load a shared library fragment and return the symbol table"
995;
996
997static PyObject *
998cdll_getlibrary(self, args)
999 PyObject *self; /* Not used */
1000 PyObject *args;
1001{
1002 Str255 frag_name;
1003 OSErr err;
1004 Str255 errMessage;
1005 Ptr main_addr;
1006 CFragConnectionID conn_id;
1007 char buf[256];
1008
1009 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, frag_name))
1010 return NULL;
1011
1012 /* Find the library connection ID */
Jack Jansen1b5b37f1998-02-20 15:55:30 +00001013 err = GetSharedLibrary(frag_name, kCompiledCFragArch, kLoadCFrag, &conn_id, &main_addr,
Jack Jansenb3928d21997-02-17 16:56:56 +00001014 errMessage);
1015 if ( err ) {
1016 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
1017 PyErr_SetString(ErrorObject, buf);
1018 return NULL;
1019 }
1020 return (PyObject *)newcdfobject(conn_id, frag_name);
1021}
1022
1023static char cdll_getdiskfragment__doc__[] =
1024"Load a fragment from a disk file and return the symbol table"
1025;
1026
1027static PyObject *
1028cdll_getdiskfragment(self, args)
1029 PyObject *self; /* Not used */
1030 PyObject *args;
1031{
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;
1040
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);
1047
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;
1056 }
1057 return (PyObject *)newcdfobject(conn_id, frag_name);
1058}
1059
1060static char cdll_newcall__doc__[] =
1061""
1062;
1063
1064static PyObject *
1065cdll_newcall(self, args)
1066 PyObject *self; /* Not used */
1067 PyObject *args;
1068{
1069 cdrobject *routine;
Jack Jansen75e62f21999-12-03 23:35:47 +00001070 conventry *argconv[MAXARG] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001071 rv2py_converter rvconv;
1072 int npargs, ncargs;
Jack Jansenb3928d21997-02-17 16:56:56 +00001073
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001074 /* Note: the next format depends on MAXARG */
Jack Jansen75e62f21999-12-03 23:35:47 +00001075 if (!PyArg_ParseTuple(args, "O!O&|O&O&O&O&O&O&O&O&O&O&O&O&", &Cdrtype, &routine,
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001076 argparse_rvconv, &rvconv,
Jack Jansenb3928d21997-02-17 16:56:56 +00001077 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],
Jack Jansen75e62f21999-12-03 23:35:47 +00001080 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]))
Jack Jansenb3928d21997-02-17 16:56:56 +00001083 return NULL;
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001084 npargs = 0;
1085 for(ncargs=0; ncargs < MAXARG && argconv[ncargs]; ncargs++) {
Jack Jansenb3928d21997-02-17 16:56:56 +00001086 if( argconv[ncargs]->get_uses_arg ) npargs++;
Jack Jansenb3928d21997-02-17 16:56:56 +00001087 }
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001088 return (PyObject *)newcdcobject(routine, npargs, ncargs, rvconv, argconv);
Jack Jansenb3928d21997-02-17 16:56:56 +00001089}
1090
1091/* List of methods defined in the module */
1092
1093static 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__},
1100
1101 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
1102};
1103
1104
1105/* Initialization function for the module (*must* be called initcalldll) */
1106
1107static char calldll_module_documentation[] =
1108""
1109;
1110
1111void
1112initcalldll()
1113{
1114 PyObject *m, *d;
1115
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);
1120
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);
1125
1126 /* XXXX Add constants here */
1127
1128 /* Check for errors */
1129 if (PyErr_Occurred())
1130 Py_FatalError("can't initialize module calldll");
1131}
1132
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001133#ifdef TESTSUPPORT
1134
Jack Jansenb3928d21997-02-17 16:56:56 +00001135/* Test routine */
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001136int 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 +00001137{
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001138 return a1+a2+a3+a4+a5+a6+a7+a8;
Jack Jansenb3928d21997-02-17 16:56:56 +00001139}
1140
Jack Jansene0e1f1a1997-02-20 15:18:32 +00001141short cdll_h_hhhhhhhh(short a1,short a2,short a3,short a4,short a5,short a6,short a7,short a8)
1142{
1143 return a1+a2+a3+a4+a5+a6+a7+a8;
1144}
1145
1146int cdll_l_llllllll(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8)
1147{
1148 return a1+a2+a3+a4+a5+a6+a7+a8;
1149}
1150
1151void cdll_N_ssssssss(char *a1,char *a2,char *a3,char *a4,char *a5,char *a6,char *a7,char *a8)
1152{
1153 printf("cdll_N_ssssssss args: %s %s %s %s %s %s %s %s\n", a1, a2, a3, a4,
1154 a5, a6, a7, a8);
1155}
1156
1157OSErr cdll_o_l(long l)
1158{
1159 return (OSErr)l;
1160}
1161
1162void cdll_N_pp(unsigned char *in, unsigned char *out)
1163{
1164 out[0] = in[0] + 5;
1165 strcpy((char *)out+1, "Was: ");
1166 memcpy(out+6, in+1, in[0]);
1167}
1168
1169void cdll_N_bb(char a1, char *a2)
1170{
1171 *a2 = a1;
1172}
1173
1174void cdll_N_hh(short a1, short *a2)
1175{
1176 *a2 = a1;
1177}
1178
1179void cdll_N_ll(long a1, long *a2)
1180{
1181 *a2 = a1;
1182}
1183
1184void cdll_N_sH(char *a1, Handle a2)
1185{
1186 int len;
1187
1188 len = strlen(a1);
1189 SetHandleSize(a2, len);
1190 HLock(a2);
1191 memcpy(*a2, a1, len);
1192 HUnlock(a2);
1193}
1194#endif