blob: 9f7a5b501fea0ec562ebb931081ba83faf1c0b90 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumbab9d031992-04-05 14:26:55 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumf70e43a1991-02-19 12:39:46 +00003Netherlands.
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 not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Module support implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028#include "modsupport.h"
29#include "import.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Guido van Rossum922cfad1992-01-27 16:47:03 +000031#ifdef HAVE_PROTOTYPES
32#define USE_STDARG
33#endif
34
35#ifdef USE_STDARG
36#include <stdarg.h>
37#else
38#include <varargs.h>
39#endif
40
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
42object *
43initmodule(name, methods)
44 char *name;
45 struct methodlist *methods;
46{
47 object *m, *d, *v;
48 struct methodlist *ml;
Guido van Rossum3f5da241990-12-20 15:06:42 +000049 char namebuf[256];
50 if ((m = add_module(name)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051 fprintf(stderr, "initializing module: %s\n", name);
52 fatal("can't create a module");
53 }
54 d = getmoduledict(m);
55 for (ml = methods; ml->ml_name != NULL; ml++) {
Guido van Rossum3f5da241990-12-20 15:06:42 +000056 sprintf(namebuf, "%s.%s", name, ml->ml_name);
57 v = newmethodobject(strdup(namebuf), ml->ml_meth,
Guido van Rossumc0602291991-12-16 13:07:24 +000058 (object *)NULL, ml->ml_varargs);
Guido van Rossum3f5da241990-12-20 15:06:42 +000059 /* XXX The strdup'ed memory is never freed */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060 if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
61 fprintf(stderr, "initializing module: %s\n", name);
62 fatal("can't initialize module");
63 }
64 DECREF(v);
65 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000066 return m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067}
68
69
Guido van Rossumfc61adb1992-04-13 15:53:41 +000070/* Helper for getargs() and mkvalue() to scan the length of a format */
71
72static int countformat PROTO((char *format, int endchar));
73static int countformat(format, endchar)
74 char *format;
75 int endchar;
76{
77 int count = 0;
78 int level = 0;
79 while (level > 0 || *format != endchar) {
80 if (*format == '\0') {
81 /* Premature end */
82 err_setstr(SystemError, "unmatched paren in format");
83 return -1;
84 }
85 else if (*format == '(') {
86 if (level == 0)
87 count++;
88 level++;
89 }
90 else if (*format == ')')
91 level--;
92 else if (level == 0 && *format != '#')
93 count++;
94 format++;
95 }
96 return count;
97}
98
99
Guido van Rossum922cfad1992-01-27 16:47:03 +0000100/* Generic argument list parser */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101
Guido van Rossum922cfad1992-01-27 16:47:03 +0000102static int do_arg PROTO((object *arg, char** p_format, va_list *p_va));
103static int
104do_arg(arg, p_format, p_va)
105 object *arg;
106 char** p_format;
107 va_list *p_va;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000109 char *format = *p_format;
110 va_list va = *p_va;
111
112 if (arg == NULL)
113 return 0; /* Incomplete tuple or list */
114
115 switch (*format++) {
116
117 case '('/*')'*/: /* tuple, distributed over C parameters */ {
118 int i, n;
119 if (!is_tupleobject(arg))
120 return 0;
121 n = gettuplesize(arg);
122 for (i = 0; i < n; i++) {
123 if (!do_arg(gettupleitem(arg, i), &format, &va))
124 return 0;
125 }
126 if (*format++ != /*'('*/')')
127 return 0;
128 break;
129 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000130
131 case 'b': /* byte -- very short int */ {
132 char *p = va_arg(va, char *);
133 if (is_intobject(arg))
134 *p = getintvalue(arg);
135 else
136 return 0;
137 break;
138 }
139
Guido van Rossum922cfad1992-01-27 16:47:03 +0000140 case 'h': /* short int */ {
141 short *p = va_arg(va, short *);
142 if (is_intobject(arg))
143 *p = getintvalue(arg);
144 else
145 return 0;
146 break;
147 }
148
149 case 'i': /* int */ {
150 int *p = va_arg(va, int *);
151 if (is_intobject(arg))
152 *p = getintvalue(arg);
153 else
154 return 0;
155 break;
156 }
157
158 case 'l': /* long int */ {
159 long *p = va_arg(va, long *);
160 if (is_intobject(arg))
161 *p = getintvalue(arg);
162 else
163 return 0;
164 break;
165 }
166
167 case 'f': /* float */ {
168 float *p = va_arg(va, float *);
169 if (is_floatobject(arg))
170 *p = getfloatvalue(arg);
171 else if (is_intobject(arg))
172 *p = (float)getintvalue(arg);
173 else
174 return 0;
175 break;
176 }
177
178 case 'd': /* double */ {
179 double *p = va_arg(va, double *);
180 if (is_floatobject(arg))
181 *p = getfloatvalue(arg);
182 else if (is_intobject(arg))
183 *p = (double)getintvalue(arg);
184 else
185 return 0;
186 break;
187 }
188
189 case 'c': /* char */ {
190 char *p = va_arg(va, char *);
191 if (is_stringobject(arg) && getstringsize(arg) == 1)
192 *p = getstringvalue(arg)[0];
193 else
194 return 0;
195 break;
196 }
197
198 case 's': /* string */ {
199 char **p = va_arg(va, char **);
200 if (is_stringobject(arg))
201 *p = getstringvalue(arg);
202 else
203 return 0;
204 if (*format == '#') {
205 int *q = va_arg(va, int *);
206 *q = getstringsize(arg);
207 format++;
208 }
209 break;
210 }
211
212 case 'z': /* string, may be NULL (None) */ {
213 char **p = va_arg(va, char **);
214 if (arg == None)
215 *p = 0;
216 else if (is_stringobject(arg))
217 *p = getstringvalue(arg);
218 else
219 return 0;
220 if (*format == '#') {
221 int *q = va_arg(va, int *);
222 if (arg == None)
223 *q = 0;
224 else
225 *q = getstringsize(arg);
226 format++;
227 }
228 break;
229 }
230
231 case 'S': /* string object */ {
232 object **p = va_arg(va, object **);
233 if (is_stringobject(arg))
234 *p = arg;
235 else
236 return 0;
237 break;
238 }
239
240 case 'O': /* object */ {
241 object **p = va_arg(va, object **);
242 *p = arg;
243 break;
244 }
245
246 default:
247 fprintf(stderr, "bad do_arg format: x%x '%c'\n",
248 format[-1], format[-1]);
249 return 0;
250
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000252
253 *p_va = va;
254 *p_format = format;
255
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000256 return 1;
257}
258
Guido van Rossum922cfad1992-01-27 16:47:03 +0000259#ifdef USE_STDARG
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000260/* VARARGS2 */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000261int getargs(object *arg, char *format, ...)
262#else
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000263/* VARARGS */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000264int getargs(va_alist) va_dcl
265#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000266{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000267 char *f;
268 int ok;
269 va_list va;
270#ifdef USE_STDARG
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271
Guido van Rossum922cfad1992-01-27 16:47:03 +0000272 va_start(va, format);
273#else
274 object *arg;
275 char *format;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276
Guido van Rossum922cfad1992-01-27 16:47:03 +0000277 va_start(va);
278 arg = va_arg(va, object *);
279 format = va_arg(va, char *);
280#endif
281 if (*format == '\0') {
282 va_end(va);
283 if (arg != NULL) {
284 err_setstr(TypeError, "no arguments needed");
285 return 0;
286 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000287 return 1;
288 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000289
290 f = format;
291 ok = do_arg(arg, &f, &va) && *f == '\0';
292 va_end(va);
293 if (!ok) {
294 char buf[256];
295 sprintf(buf, "bad argument list (format '%s')", format);
296 err_setstr(TypeError, buf);
Guido van Rossumc5da3501991-09-10 14:56:32 +0000297 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000298 return ok;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299}
300
301int
302getlongtuplearg(args, a, n)
303 object *args;
304 long *a; /* [n] */
305 int n;
306{
307 int i;
308 if (!is_tupleobject(args) || gettuplesize(args) != n) {
309 return err_badarg();
310 }
311 for (i = 0; i < n; i++) {
312 object *v = gettupleitem(args, i);
313 if (!is_intobject(v)) {
314 return err_badarg();
315 }
316 a[i] = getintvalue(v);
317 }
318 return 1;
319}
320
321int
322getshorttuplearg(args, a, n)
323 object *args;
324 short *a; /* [n] */
325 int n;
326{
327 int i;
328 if (!is_tupleobject(args) || gettuplesize(args) != n) {
329 return err_badarg();
330 }
331 for (i = 0; i < n; i++) {
332 object *v = gettupleitem(args, i);
333 if (!is_intobject(v)) {
334 return err_badarg();
335 }
336 a[i] = getintvalue(v);
337 }
338 return 1;
339}
340
341int
342getlonglistarg(args, a, n)
343 object *args;
344 long *a; /* [n] */
345 int n;
346{
347 int i;
348 if (!is_listobject(args) || getlistsize(args) != n) {
349 return err_badarg();
350 }
351 for (i = 0; i < n; i++) {
352 object *v = getlistitem(args, i);
353 if (!is_intobject(v)) {
354 return err_badarg();
355 }
356 a[i] = getintvalue(v);
357 }
358 return 1;
359}
360
361int
362getshortlistarg(args, a, n)
363 object *args;
364 short *a; /* [n] */
365 int n;
366{
367 int i;
368 if (!is_listobject(args) || getlistsize(args) != n) {
369 return err_badarg();
370 }
371 for (i = 0; i < n; i++) {
372 object *v = getlistitem(args, i);
373 if (!is_intobject(v)) {
374 return err_badarg();
375 }
376 a[i] = getintvalue(v);
377 }
378 return 1;
379}
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000380
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000381
382/* Generic function to create a value -- the inverse of getargs() */
383/* After an original idea and first implementation by Steven Miale */
384
385static object *do_mktuple PROTO((char**, va_list *, int, int));
386static object *do_mkvalue PROTO((char**, va_list *));
387
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000388static object *
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000389do_mktuple(p_format, p_va, endchar, n)
390 char **p_format;
391 va_list *p_va;
392 int endchar;
393 int n;
394{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000395 object *v;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000396 int i;
397 if (n < 0)
398 return NULL;
399 if ((v = newtupleobject(n)) == NULL)
400 return NULL;
401 for (i = 0; i < n; i++) {
402 object *w = do_mkvalue(p_format, p_va);
403 if (w == NULL) {
404 DECREF(v);
405 return NULL;
406 }
407 settupleitem(v, i, w);
408 }
409 if (v != NULL && **p_format != endchar) {
410 DECREF(v);
411 v = NULL;
412 err_setstr(SystemError, "Unmatched paren in format");
413 }
414 else if (endchar)
415 ++*p_format;
416 return v;
417}
418
419static object *
Guido van Rossum899dcf31992-05-15 11:04:59 +0000420do_mkvalue(p_format, p_va)
421 char **p_format;
422 va_list *p_va;
423{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000424
425 switch (*(*p_format)++) {
426
427 case '(':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000428 return do_mktuple(p_format, p_va, ')',
429 countformat(*p_format, ')'));
430
431 case 'b':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000432 case 'h':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000433 case 'i':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000434 return newintobject((long)va_arg(*p_va, int));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000435
436 case 'l':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000437 return newintobject((long)va_arg(*p_va, long));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000438
439 case 'f':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000440 case 'd':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000441 return newfloatobject((double)va_arg(*p_va, double));
442
443 case 'c':
444 {
445 char p[1];
446 p[0] = va_arg(*p_va, int);
447 return newsizedstringobject(p, 1);
448 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000449
450 case 's':
451 case 'z':
452 {
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000453 object *v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000454 char *str = va_arg(*p_va, char *);
455 int n;
456 if (**p_format == '#') {
457 ++*p_format;
458 n = va_arg(*p_va, int);
459 }
460 else
461 n = -1;
462 if (str == NULL) {
463 v = None;
464 INCREF(v);
465 }
466 else {
467 if (n < 0)
468 n = strlen(str);
469 v = newsizedstringobject(str, n);
470 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000471 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000472 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000473
474 case 'S':
475 case 'O':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000476 {
477 object *v;
478 v = va_arg(*p_va, object *);
479 if (v != NULL)
480 INCREF(v);
481 else if (!err_occurred())
482 /* If a NULL was passed because a call
483 that should have constructed a value
484 failed, that's OK, and we pass the error
485 on; but if no error occurred it's not
486 clear that the caller knew what she
487 was doing. */
488 err_setstr(SystemError,
489 "NULL object passed to mkvalue");
490 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000491 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000492
493 default:
494 err_setstr(SystemError, "bad format char passed to mkvalue");
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000495 return NULL;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000496
497 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000498}
499
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000500#ifdef USE_STDARG
501/* VARARGS 2 */
502object *mkvalue(char *format, ...)
503#else
504/* VARARGS */
505object *mkvalue(va_alist) va_dcl
506#endif
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000507{
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000508 int n;
509 char *f;
510 va_list va;
511 object* retval;
512#ifdef USE_STDARG
513 va_start(va, format);
514#else
515 char *format;
516
517 va_start(va);
518 format = va_arg(va, char *);
519#endif
520 f = format;
521 n = countformat(f, '\0');
522 if (n < 0)
523 retval = NULL; /* Error in the format */
524 else if (n == 0) {
525 retval = None;
526 INCREF(retval);
527 }
528 else if (n == 1)
529 retval = do_mkvalue(&f, &va);
530 else
531 retval = do_mktuple(&f, &va, '\0', n);
532 va_end(va);
533 if (retval == NULL)
534 fprintf(stderr, "format \"%s\", f \"%s\"\n", format, f);
535 return retval;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000536}