blob: b464c8e36d0d89a7430bd0b1a35248433a887571 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum34679b71993-01-26 13:33:44 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
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 Rossuma2b7f401993-01-04 09:09:59 +000049 char *namebuf;
Guido van Rossum3f5da241990-12-20 15:06:42 +000050 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 Rossuma2b7f401993-01-04 09:09:59 +000056 namebuf = NEW(char, strlen(name) + strlen(ml->ml_name) + 2);
57 if (namebuf == NULL)
58 fatal("out of mem for method name");
Guido van Rossum3f5da241990-12-20 15:06:42 +000059 sprintf(namebuf, "%s.%s", name, ml->ml_name);
Guido van Rossuma2b7f401993-01-04 09:09:59 +000060 v = newmethodobject(namebuf, ml->ml_meth,
Guido van Rossumc0602291991-12-16 13:07:24 +000061 (object *)NULL, ml->ml_varargs);
Guido van Rossuma2b7f401993-01-04 09:09:59 +000062 /* XXX The malloc'ed memory in namebuf is never freed */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000063 if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
64 fprintf(stderr, "initializing module: %s\n", name);
65 fatal("can't initialize module");
66 }
67 DECREF(v);
68 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000069 return m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070}
71
72
Guido van Rossumbf80e541993-02-08 15:49:17 +000073/* Helper for mkvalue() to scan the length of a format */
Guido van Rossumfc61adb1992-04-13 15:53:41 +000074
75static int countformat PROTO((char *format, int endchar));
76static int countformat(format, endchar)
77 char *format;
78 int endchar;
79{
80 int count = 0;
81 int level = 0;
82 while (level > 0 || *format != endchar) {
83 if (*format == '\0') {
84 /* Premature end */
85 err_setstr(SystemError, "unmatched paren in format");
86 return -1;
87 }
88 else if (*format == '(') {
89 if (level == 0)
90 count++;
91 level++;
92 }
93 else if (*format == ')')
94 level--;
95 else if (level == 0 && *format != '#')
96 count++;
97 format++;
98 }
99 return count;
100}
101
102
Guido van Rossum922cfad1992-01-27 16:47:03 +0000103/* Generic argument list parser */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104
Guido van Rossum922cfad1992-01-27 16:47:03 +0000105static int do_arg PROTO((object *arg, char** p_format, va_list *p_va));
106static int
107do_arg(arg, p_format, p_va)
108 object *arg;
109 char** p_format;
110 va_list *p_va;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000112 char *format = *p_format;
113 va_list va = *p_va;
114
115 if (arg == NULL)
116 return 0; /* Incomplete tuple or list */
117
118 switch (*format++) {
119
Guido van Rossuma93265a1992-08-27 07:45:12 +0000120 case '(': /* tuple, distributed over C parameters */ {
Guido van Rossum922cfad1992-01-27 16:47:03 +0000121 int i, n;
122 if (!is_tupleobject(arg))
123 return 0;
124 n = gettuplesize(arg);
125 for (i = 0; i < n; i++) {
126 if (!do_arg(gettupleitem(arg, i), &format, &va))
127 return 0;
128 }
Guido van Rossuma93265a1992-08-27 07:45:12 +0000129 if (*format++ != ')')
Guido van Rossum922cfad1992-01-27 16:47:03 +0000130 return 0;
131 break;
132 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000133
Guido van Rossuma93265a1992-08-27 07:45:12 +0000134 case ')': /* End of format -- too many arguments */
135 return 0;
136
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000137 case 'b': /* byte -- very short int */ {
138 char *p = va_arg(va, char *);
139 if (is_intobject(arg))
140 *p = getintvalue(arg);
141 else
142 return 0;
143 break;
144 }
145
Guido van Rossum922cfad1992-01-27 16:47:03 +0000146 case 'h': /* short int */ {
147 short *p = va_arg(va, short *);
148 if (is_intobject(arg))
149 *p = getintvalue(arg);
150 else
151 return 0;
152 break;
153 }
154
155 case 'i': /* int */ {
156 int *p = va_arg(va, int *);
157 if (is_intobject(arg))
158 *p = getintvalue(arg);
159 else
160 return 0;
161 break;
162 }
163
164 case 'l': /* long int */ {
165 long *p = va_arg(va, long *);
166 if (is_intobject(arg))
167 *p = getintvalue(arg);
168 else
169 return 0;
170 break;
171 }
172
173 case 'f': /* float */ {
174 float *p = va_arg(va, float *);
175 if (is_floatobject(arg))
176 *p = getfloatvalue(arg);
177 else if (is_intobject(arg))
178 *p = (float)getintvalue(arg);
179 else
180 return 0;
181 break;
182 }
183
184 case 'd': /* double */ {
185 double *p = va_arg(va, double *);
186 if (is_floatobject(arg))
187 *p = getfloatvalue(arg);
188 else if (is_intobject(arg))
189 *p = (double)getintvalue(arg);
190 else
191 return 0;
192 break;
193 }
194
195 case 'c': /* char */ {
196 char *p = va_arg(va, char *);
197 if (is_stringobject(arg) && getstringsize(arg) == 1)
198 *p = getstringvalue(arg)[0];
199 else
200 return 0;
201 break;
202 }
203
204 case 's': /* string */ {
205 char **p = va_arg(va, char **);
206 if (is_stringobject(arg))
207 *p = getstringvalue(arg);
208 else
209 return 0;
210 if (*format == '#') {
211 int *q = va_arg(va, int *);
212 *q = getstringsize(arg);
213 format++;
214 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000215 else if (strlen(*p) != getstringsize(arg)) {
216 err_setstr(ValueError, "embedded '\\0' in string arg");
217 return 0;
218 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000219 break;
220 }
221
222 case 'z': /* string, may be NULL (None) */ {
223 char **p = va_arg(va, char **);
224 if (arg == None)
225 *p = 0;
226 else if (is_stringobject(arg))
227 *p = getstringvalue(arg);
228 else
229 return 0;
230 if (*format == '#') {
231 int *q = va_arg(va, int *);
232 if (arg == None)
233 *q = 0;
234 else
235 *q = getstringsize(arg);
236 format++;
237 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000238 else if (*p != NULL && strlen(*p) != getstringsize(arg)) {
239 err_setstr(ValueError, "embedded '\\0' in string arg");
240 return 0;
241 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000242 break;
243 }
244
245 case 'S': /* string object */ {
246 object **p = va_arg(va, object **);
247 if (is_stringobject(arg))
248 *p = arg;
249 else
250 return 0;
251 break;
252 }
253
254 case 'O': /* object */ {
255 object **p = va_arg(va, object **);
256 *p = arg;
257 break;
258 }
259
260 default:
261 fprintf(stderr, "bad do_arg format: x%x '%c'\n",
262 format[-1], format[-1]);
263 return 0;
264
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000265 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000266
267 *p_va = va;
268 *p_format = format;
269
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 return 1;
271}
272
Guido van Rossum922cfad1992-01-27 16:47:03 +0000273#ifdef USE_STDARG
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000274/* VARARGS2 */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000275int getargs(object *arg, char *format, ...)
276#else
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000277/* VARARGS */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000278int getargs(va_alist) va_dcl
279#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000281 char *f;
282 int ok;
283 va_list va;
284#ifdef USE_STDARG
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285
Guido van Rossum922cfad1992-01-27 16:47:03 +0000286 va_start(va, format);
287#else
288 object *arg;
289 char *format;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290
Guido van Rossum922cfad1992-01-27 16:47:03 +0000291 va_start(va);
292 arg = va_arg(va, object *);
293 format = va_arg(va, char *);
294#endif
Guido van Rossumbf80e541993-02-08 15:49:17 +0000295 if (*format == '\0' || *format == ';') {
Guido van Rossum922cfad1992-01-27 16:47:03 +0000296 va_end(va);
297 if (arg != NULL) {
Guido van Rossumbf80e541993-02-08 15:49:17 +0000298 char *str = "no arguments needed";
299 if (*format == ';')
300 str = format+1;
301 err_setstr(TypeError, str);
Guido van Rossum922cfad1992-01-27 16:47:03 +0000302 return 0;
303 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000304 return 1;
305 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000306
307 f = format;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000308 ok = do_arg(arg, &f, &va) && (*f == '\0' || *f == ';');
Guido van Rossum922cfad1992-01-27 16:47:03 +0000309 va_end(va);
310 if (!ok) {
Guido van Rossum96caaee1992-08-14 15:12:03 +0000311 if (!err_occurred()) {
Guido van Rossumbf80e541993-02-08 15:49:17 +0000312 char buf[256];
313 char *str;
314 f = strchr(format, ';');
315 if (f != NULL)
316 str = f+1;
317 else {
318 sprintf(buf, "bad argument list (format '%s')",
319 format);
320 str = buf;
321 }
322 err_setstr(TypeError, str);
Guido van Rossum96caaee1992-08-14 15:12:03 +0000323 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000324 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000325 return ok;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326}
327
328int
329getlongtuplearg(args, a, n)
330 object *args;
331 long *a; /* [n] */
332 int n;
333{
334 int i;
335 if (!is_tupleobject(args) || gettuplesize(args) != n) {
336 return err_badarg();
337 }
338 for (i = 0; i < n; i++) {
339 object *v = gettupleitem(args, i);
340 if (!is_intobject(v)) {
341 return err_badarg();
342 }
343 a[i] = getintvalue(v);
344 }
345 return 1;
346}
347
348int
349getshorttuplearg(args, a, n)
350 object *args;
351 short *a; /* [n] */
352 int n;
353{
354 int i;
355 if (!is_tupleobject(args) || gettuplesize(args) != n) {
356 return err_badarg();
357 }
358 for (i = 0; i < n; i++) {
359 object *v = gettupleitem(args, i);
360 if (!is_intobject(v)) {
361 return err_badarg();
362 }
363 a[i] = getintvalue(v);
364 }
365 return 1;
366}
367
368int
369getlonglistarg(args, a, n)
370 object *args;
371 long *a; /* [n] */
372 int n;
373{
374 int i;
375 if (!is_listobject(args) || getlistsize(args) != n) {
376 return err_badarg();
377 }
378 for (i = 0; i < n; i++) {
379 object *v = getlistitem(args, i);
380 if (!is_intobject(v)) {
381 return err_badarg();
382 }
383 a[i] = getintvalue(v);
384 }
385 return 1;
386}
387
388int
389getshortlistarg(args, a, n)
390 object *args;
391 short *a; /* [n] */
392 int n;
393{
394 int i;
395 if (!is_listobject(args) || getlistsize(args) != n) {
396 return err_badarg();
397 }
398 for (i = 0; i < n; i++) {
399 object *v = getlistitem(args, i);
400 if (!is_intobject(v)) {
401 return err_badarg();
402 }
403 a[i] = getintvalue(v);
404 }
405 return 1;
406}
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000407
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000408
409/* Generic function to create a value -- the inverse of getargs() */
410/* After an original idea and first implementation by Steven Miale */
411
412static object *do_mktuple PROTO((char**, va_list *, int, int));
413static object *do_mkvalue PROTO((char**, va_list *));
414
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000415static object *
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000416do_mktuple(p_format, p_va, endchar, n)
417 char **p_format;
418 va_list *p_va;
419 int endchar;
420 int n;
421{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000422 object *v;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000423 int i;
424 if (n < 0)
425 return NULL;
426 if ((v = newtupleobject(n)) == NULL)
427 return NULL;
428 for (i = 0; i < n; i++) {
429 object *w = do_mkvalue(p_format, p_va);
430 if (w == NULL) {
431 DECREF(v);
432 return NULL;
433 }
434 settupleitem(v, i, w);
435 }
436 if (v != NULL && **p_format != endchar) {
437 DECREF(v);
438 v = NULL;
439 err_setstr(SystemError, "Unmatched paren in format");
440 }
441 else if (endchar)
442 ++*p_format;
443 return v;
444}
445
446static object *
Guido van Rossum899dcf31992-05-15 11:04:59 +0000447do_mkvalue(p_format, p_va)
448 char **p_format;
449 va_list *p_va;
450{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000451
452 switch (*(*p_format)++) {
453
454 case '(':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000455 return do_mktuple(p_format, p_va, ')',
456 countformat(*p_format, ')'));
457
458 case 'b':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000459 case 'h':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000460 case 'i':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000461 return newintobject((long)va_arg(*p_va, int));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000462
463 case 'l':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000464 return newintobject((long)va_arg(*p_va, long));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000465
466 case 'f':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000467 case 'd':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000468 return newfloatobject((double)va_arg(*p_va, double));
469
470 case 'c':
471 {
472 char p[1];
473 p[0] = va_arg(*p_va, int);
474 return newsizedstringobject(p, 1);
475 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000476
477 case 's':
478 case 'z':
479 {
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000480 object *v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000481 char *str = va_arg(*p_va, char *);
482 int n;
483 if (**p_format == '#') {
484 ++*p_format;
485 n = va_arg(*p_va, int);
486 }
487 else
488 n = -1;
489 if (str == NULL) {
490 v = None;
491 INCREF(v);
492 }
493 else {
494 if (n < 0)
495 n = strlen(str);
496 v = newsizedstringobject(str, n);
497 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000498 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000499 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000500
501 case 'S':
502 case 'O':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000503 {
504 object *v;
505 v = va_arg(*p_va, object *);
506 if (v != NULL)
507 INCREF(v);
508 else if (!err_occurred())
509 /* If a NULL was passed because a call
510 that should have constructed a value
511 failed, that's OK, and we pass the error
512 on; but if no error occurred it's not
513 clear that the caller knew what she
514 was doing. */
515 err_setstr(SystemError,
516 "NULL object passed to mkvalue");
517 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000518 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000519
520 default:
521 err_setstr(SystemError, "bad format char passed to mkvalue");
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000522 return NULL;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000523
524 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000525}
526
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000527#ifdef USE_STDARG
528/* VARARGS 2 */
529object *mkvalue(char *format, ...)
530#else
531/* VARARGS */
532object *mkvalue(va_alist) va_dcl
533#endif
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000534{
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000535 int n;
536 char *f;
537 va_list va;
538 object* retval;
539#ifdef USE_STDARG
540 va_start(va, format);
541#else
542 char *format;
543
544 va_start(va);
545 format = va_arg(va, char *);
546#endif
547 f = format;
548 n = countformat(f, '\0');
549 if (n < 0)
550 retval = NULL; /* Error in the format */
551 else if (n == 0) {
552 retval = None;
553 INCREF(retval);
554 }
555 else if (n == 1)
556 retval = do_mkvalue(&f, &va);
557 else
558 retval = do_mktuple(&f, &va, '\0', n);
559 va_end(va);
560 if (retval == NULL)
561 fprintf(stderr, "format \"%s\", f \"%s\"\n", format, f);
562 return retval;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000563}