blob: 352a5fb7bbf43d9db61c0545f809459444078362 [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 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000209 else if (strlen(*p) != getstringsize(arg)) {
210 err_setstr(ValueError, "embedded '\\0' in string arg");
211 return 0;
212 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000213 break;
214 }
215
216 case 'z': /* string, may be NULL (None) */ {
217 char **p = va_arg(va, char **);
218 if (arg == None)
219 *p = 0;
220 else if (is_stringobject(arg))
221 *p = getstringvalue(arg);
222 else
223 return 0;
224 if (*format == '#') {
225 int *q = va_arg(va, int *);
226 if (arg == None)
227 *q = 0;
228 else
229 *q = getstringsize(arg);
230 format++;
231 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000232 else if (*p != NULL && strlen(*p) != getstringsize(arg)) {
233 err_setstr(ValueError, "embedded '\\0' in string arg");
234 return 0;
235 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000236 break;
237 }
238
239 case 'S': /* string object */ {
240 object **p = va_arg(va, object **);
241 if (is_stringobject(arg))
242 *p = arg;
243 else
244 return 0;
245 break;
246 }
247
248 case 'O': /* object */ {
249 object **p = va_arg(va, object **);
250 *p = arg;
251 break;
252 }
253
254 default:
255 fprintf(stderr, "bad do_arg format: x%x '%c'\n",
256 format[-1], format[-1]);
257 return 0;
258
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000260
261 *p_va = va;
262 *p_format = format;
263
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264 return 1;
265}
266
Guido van Rossum922cfad1992-01-27 16:47:03 +0000267#ifdef USE_STDARG
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000268/* VARARGS2 */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000269int getargs(object *arg, char *format, ...)
270#else
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000271/* VARARGS */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000272int getargs(va_alist) va_dcl
273#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000275 char *f;
276 int ok;
277 va_list va;
278#ifdef USE_STDARG
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279
Guido van Rossum922cfad1992-01-27 16:47:03 +0000280 va_start(va, format);
281#else
282 object *arg;
283 char *format;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284
Guido van Rossum922cfad1992-01-27 16:47:03 +0000285 va_start(va);
286 arg = va_arg(va, object *);
287 format = va_arg(va, char *);
288#endif
289 if (*format == '\0') {
290 va_end(va);
291 if (arg != NULL) {
292 err_setstr(TypeError, "no arguments needed");
293 return 0;
294 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000295 return 1;
296 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000297
298 f = format;
299 ok = do_arg(arg, &f, &va) && *f == '\0';
300 va_end(va);
301 if (!ok) {
302 char buf[256];
Guido van Rossum96caaee1992-08-14 15:12:03 +0000303 if (!err_occurred()) {
304 sprintf(buf, "bad argument list (format '%s')",
305 format);
306 err_setstr(TypeError, buf);
307 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000308 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000309 return ok;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310}
311
312int
313getlongtuplearg(args, a, n)
314 object *args;
315 long *a; /* [n] */
316 int n;
317{
318 int i;
319 if (!is_tupleobject(args) || gettuplesize(args) != n) {
320 return err_badarg();
321 }
322 for (i = 0; i < n; i++) {
323 object *v = gettupleitem(args, i);
324 if (!is_intobject(v)) {
325 return err_badarg();
326 }
327 a[i] = getintvalue(v);
328 }
329 return 1;
330}
331
332int
333getshorttuplearg(args, a, n)
334 object *args;
335 short *a; /* [n] */
336 int n;
337{
338 int i;
339 if (!is_tupleobject(args) || gettuplesize(args) != n) {
340 return err_badarg();
341 }
342 for (i = 0; i < n; i++) {
343 object *v = gettupleitem(args, i);
344 if (!is_intobject(v)) {
345 return err_badarg();
346 }
347 a[i] = getintvalue(v);
348 }
349 return 1;
350}
351
352int
353getlonglistarg(args, a, n)
354 object *args;
355 long *a; /* [n] */
356 int n;
357{
358 int i;
359 if (!is_listobject(args) || getlistsize(args) != n) {
360 return err_badarg();
361 }
362 for (i = 0; i < n; i++) {
363 object *v = getlistitem(args, i);
364 if (!is_intobject(v)) {
365 return err_badarg();
366 }
367 a[i] = getintvalue(v);
368 }
369 return 1;
370}
371
372int
373getshortlistarg(args, a, n)
374 object *args;
375 short *a; /* [n] */
376 int n;
377{
378 int i;
379 if (!is_listobject(args) || getlistsize(args) != n) {
380 return err_badarg();
381 }
382 for (i = 0; i < n; i++) {
383 object *v = getlistitem(args, i);
384 if (!is_intobject(v)) {
385 return err_badarg();
386 }
387 a[i] = getintvalue(v);
388 }
389 return 1;
390}
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000391
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000392
393/* Generic function to create a value -- the inverse of getargs() */
394/* After an original idea and first implementation by Steven Miale */
395
396static object *do_mktuple PROTO((char**, va_list *, int, int));
397static object *do_mkvalue PROTO((char**, va_list *));
398
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000399static object *
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000400do_mktuple(p_format, p_va, endchar, n)
401 char **p_format;
402 va_list *p_va;
403 int endchar;
404 int n;
405{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000406 object *v;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000407 int i;
408 if (n < 0)
409 return NULL;
410 if ((v = newtupleobject(n)) == NULL)
411 return NULL;
412 for (i = 0; i < n; i++) {
413 object *w = do_mkvalue(p_format, p_va);
414 if (w == NULL) {
415 DECREF(v);
416 return NULL;
417 }
418 settupleitem(v, i, w);
419 }
420 if (v != NULL && **p_format != endchar) {
421 DECREF(v);
422 v = NULL;
423 err_setstr(SystemError, "Unmatched paren in format");
424 }
425 else if (endchar)
426 ++*p_format;
427 return v;
428}
429
430static object *
Guido van Rossum899dcf31992-05-15 11:04:59 +0000431do_mkvalue(p_format, p_va)
432 char **p_format;
433 va_list *p_va;
434{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000435
436 switch (*(*p_format)++) {
437
438 case '(':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000439 return do_mktuple(p_format, p_va, ')',
440 countformat(*p_format, ')'));
441
442 case 'b':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000443 case 'h':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000444 case 'i':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000445 return newintobject((long)va_arg(*p_va, int));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000446
447 case 'l':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000448 return newintobject((long)va_arg(*p_va, long));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000449
450 case 'f':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000451 case 'd':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000452 return newfloatobject((double)va_arg(*p_va, double));
453
454 case 'c':
455 {
456 char p[1];
457 p[0] = va_arg(*p_va, int);
458 return newsizedstringobject(p, 1);
459 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000460
461 case 's':
462 case 'z':
463 {
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000464 object *v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000465 char *str = va_arg(*p_va, char *);
466 int n;
467 if (**p_format == '#') {
468 ++*p_format;
469 n = va_arg(*p_va, int);
470 }
471 else
472 n = -1;
473 if (str == NULL) {
474 v = None;
475 INCREF(v);
476 }
477 else {
478 if (n < 0)
479 n = strlen(str);
480 v = newsizedstringobject(str, n);
481 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000482 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000483 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000484
485 case 'S':
486 case 'O':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000487 {
488 object *v;
489 v = va_arg(*p_va, object *);
490 if (v != NULL)
491 INCREF(v);
492 else if (!err_occurred())
493 /* If a NULL was passed because a call
494 that should have constructed a value
495 failed, that's OK, and we pass the error
496 on; but if no error occurred it's not
497 clear that the caller knew what she
498 was doing. */
499 err_setstr(SystemError,
500 "NULL object passed to mkvalue");
501 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000502 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000503
504 default:
505 err_setstr(SystemError, "bad format char passed to mkvalue");
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000506 return NULL;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000507
508 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000509}
510
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000511#ifdef USE_STDARG
512/* VARARGS 2 */
513object *mkvalue(char *format, ...)
514#else
515/* VARARGS */
516object *mkvalue(va_alist) va_dcl
517#endif
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000518{
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000519 int n;
520 char *f;
521 va_list va;
522 object* retval;
523#ifdef USE_STDARG
524 va_start(va, format);
525#else
526 char *format;
527
528 va_start(va);
529 format = va_arg(va, char *);
530#endif
531 f = format;
532 n = countformat(f, '\0');
533 if (n < 0)
534 retval = NULL; /* Error in the format */
535 else if (n == 0) {
536 retval = None;
537 INCREF(retval);
538 }
539 else if (n == 1)
540 retval = do_mkvalue(&f, &va);
541 else
542 retval = do_mktuple(&f, &va, '\0', n);
543 va_end(va);
544 if (retval == NULL)
545 fprintf(stderr, "format \"%s\", f \"%s\"\n", format, f);
546 return retval;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000547}