blob: 1934cad52d2be54fc6ed58f80df0ed382daad912 [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
Guido van Rossuma93265a1992-08-27 07:45:12 +0000117 case '(': /* tuple, distributed over C parameters */ {
Guido van Rossum922cfad1992-01-27 16:47:03 +0000118 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 }
Guido van Rossuma93265a1992-08-27 07:45:12 +0000126 if (*format++ != ')')
Guido van Rossum922cfad1992-01-27 16:47:03 +0000127 return 0;
128 break;
129 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000130
Guido van Rossuma93265a1992-08-27 07:45:12 +0000131 case ')': /* End of format -- too many arguments */
132 return 0;
133
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000134 case 'b': /* byte -- very short int */ {
135 char *p = va_arg(va, char *);
136 if (is_intobject(arg))
137 *p = getintvalue(arg);
138 else
139 return 0;
140 break;
141 }
142
Guido van Rossum922cfad1992-01-27 16:47:03 +0000143 case 'h': /* short int */ {
144 short *p = va_arg(va, short *);
145 if (is_intobject(arg))
146 *p = getintvalue(arg);
147 else
148 return 0;
149 break;
150 }
151
152 case 'i': /* int */ {
153 int *p = va_arg(va, int *);
154 if (is_intobject(arg))
155 *p = getintvalue(arg);
156 else
157 return 0;
158 break;
159 }
160
161 case 'l': /* long int */ {
162 long *p = va_arg(va, long *);
163 if (is_intobject(arg))
164 *p = getintvalue(arg);
165 else
166 return 0;
167 break;
168 }
169
170 case 'f': /* float */ {
171 float *p = va_arg(va, float *);
172 if (is_floatobject(arg))
173 *p = getfloatvalue(arg);
174 else if (is_intobject(arg))
175 *p = (float)getintvalue(arg);
176 else
177 return 0;
178 break;
179 }
180
181 case 'd': /* double */ {
182 double *p = va_arg(va, double *);
183 if (is_floatobject(arg))
184 *p = getfloatvalue(arg);
185 else if (is_intobject(arg))
186 *p = (double)getintvalue(arg);
187 else
188 return 0;
189 break;
190 }
191
192 case 'c': /* char */ {
193 char *p = va_arg(va, char *);
194 if (is_stringobject(arg) && getstringsize(arg) == 1)
195 *p = getstringvalue(arg)[0];
196 else
197 return 0;
198 break;
199 }
200
201 case 's': /* string */ {
202 char **p = va_arg(va, char **);
203 if (is_stringobject(arg))
204 *p = getstringvalue(arg);
205 else
206 return 0;
207 if (*format == '#') {
208 int *q = va_arg(va, int *);
209 *q = getstringsize(arg);
210 format++;
211 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000212 else if (strlen(*p) != getstringsize(arg)) {
213 err_setstr(ValueError, "embedded '\\0' in string arg");
214 return 0;
215 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000216 break;
217 }
218
219 case 'z': /* string, may be NULL (None) */ {
220 char **p = va_arg(va, char **);
221 if (arg == None)
222 *p = 0;
223 else if (is_stringobject(arg))
224 *p = getstringvalue(arg);
225 else
226 return 0;
227 if (*format == '#') {
228 int *q = va_arg(va, int *);
229 if (arg == None)
230 *q = 0;
231 else
232 *q = getstringsize(arg);
233 format++;
234 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000235 else if (*p != NULL && strlen(*p) != getstringsize(arg)) {
236 err_setstr(ValueError, "embedded '\\0' in string arg");
237 return 0;
238 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000239 break;
240 }
241
242 case 'S': /* string object */ {
243 object **p = va_arg(va, object **);
244 if (is_stringobject(arg))
245 *p = arg;
246 else
247 return 0;
248 break;
249 }
250
251 case 'O': /* object */ {
252 object **p = va_arg(va, object **);
253 *p = arg;
254 break;
255 }
256
257 default:
258 fprintf(stderr, "bad do_arg format: x%x '%c'\n",
259 format[-1], format[-1]);
260 return 0;
261
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000262 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000263
264 *p_va = va;
265 *p_format = format;
266
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267 return 1;
268}
269
Guido van Rossum922cfad1992-01-27 16:47:03 +0000270#ifdef USE_STDARG
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000271/* VARARGS2 */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000272int getargs(object *arg, char *format, ...)
273#else
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000274/* VARARGS */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000275int getargs(va_alist) va_dcl
276#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000278 char *f;
279 int ok;
280 va_list va;
281#ifdef USE_STDARG
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282
Guido van Rossum922cfad1992-01-27 16:47:03 +0000283 va_start(va, format);
284#else
285 object *arg;
286 char *format;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287
Guido van Rossum922cfad1992-01-27 16:47:03 +0000288 va_start(va);
289 arg = va_arg(va, object *);
290 format = va_arg(va, char *);
291#endif
292 if (*format == '\0') {
293 va_end(va);
294 if (arg != NULL) {
295 err_setstr(TypeError, "no arguments needed");
296 return 0;
297 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000298 return 1;
299 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000300
301 f = format;
302 ok = do_arg(arg, &f, &va) && *f == '\0';
303 va_end(va);
304 if (!ok) {
305 char buf[256];
Guido van Rossum96caaee1992-08-14 15:12:03 +0000306 if (!err_occurred()) {
307 sprintf(buf, "bad argument list (format '%s')",
308 format);
309 err_setstr(TypeError, buf);
310 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000311 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000312 return ok;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313}
314
315int
316getlongtuplearg(args, a, n)
317 object *args;
318 long *a; /* [n] */
319 int n;
320{
321 int i;
322 if (!is_tupleobject(args) || gettuplesize(args) != n) {
323 return err_badarg();
324 }
325 for (i = 0; i < n; i++) {
326 object *v = gettupleitem(args, i);
327 if (!is_intobject(v)) {
328 return err_badarg();
329 }
330 a[i] = getintvalue(v);
331 }
332 return 1;
333}
334
335int
336getshorttuplearg(args, a, n)
337 object *args;
338 short *a; /* [n] */
339 int n;
340{
341 int i;
342 if (!is_tupleobject(args) || gettuplesize(args) != n) {
343 return err_badarg();
344 }
345 for (i = 0; i < n; i++) {
346 object *v = gettupleitem(args, i);
347 if (!is_intobject(v)) {
348 return err_badarg();
349 }
350 a[i] = getintvalue(v);
351 }
352 return 1;
353}
354
355int
356getlonglistarg(args, a, n)
357 object *args;
358 long *a; /* [n] */
359 int n;
360{
361 int i;
362 if (!is_listobject(args) || getlistsize(args) != n) {
363 return err_badarg();
364 }
365 for (i = 0; i < n; i++) {
366 object *v = getlistitem(args, i);
367 if (!is_intobject(v)) {
368 return err_badarg();
369 }
370 a[i] = getintvalue(v);
371 }
372 return 1;
373}
374
375int
376getshortlistarg(args, a, n)
377 object *args;
378 short *a; /* [n] */
379 int n;
380{
381 int i;
382 if (!is_listobject(args) || getlistsize(args) != n) {
383 return err_badarg();
384 }
385 for (i = 0; i < n; i++) {
386 object *v = getlistitem(args, i);
387 if (!is_intobject(v)) {
388 return err_badarg();
389 }
390 a[i] = getintvalue(v);
391 }
392 return 1;
393}
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000394
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000395
396/* Generic function to create a value -- the inverse of getargs() */
397/* After an original idea and first implementation by Steven Miale */
398
399static object *do_mktuple PROTO((char**, va_list *, int, int));
400static object *do_mkvalue PROTO((char**, va_list *));
401
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000402static object *
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000403do_mktuple(p_format, p_va, endchar, n)
404 char **p_format;
405 va_list *p_va;
406 int endchar;
407 int n;
408{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000409 object *v;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000410 int i;
411 if (n < 0)
412 return NULL;
413 if ((v = newtupleobject(n)) == NULL)
414 return NULL;
415 for (i = 0; i < n; i++) {
416 object *w = do_mkvalue(p_format, p_va);
417 if (w == NULL) {
418 DECREF(v);
419 return NULL;
420 }
421 settupleitem(v, i, w);
422 }
423 if (v != NULL && **p_format != endchar) {
424 DECREF(v);
425 v = NULL;
426 err_setstr(SystemError, "Unmatched paren in format");
427 }
428 else if (endchar)
429 ++*p_format;
430 return v;
431}
432
433static object *
Guido van Rossum899dcf31992-05-15 11:04:59 +0000434do_mkvalue(p_format, p_va)
435 char **p_format;
436 va_list *p_va;
437{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000438
439 switch (*(*p_format)++) {
440
441 case '(':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000442 return do_mktuple(p_format, p_va, ')',
443 countformat(*p_format, ')'));
444
445 case 'b':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000446 case 'h':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000447 case 'i':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000448 return newintobject((long)va_arg(*p_va, int));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000449
450 case 'l':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000451 return newintobject((long)va_arg(*p_va, long));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000452
453 case 'f':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000454 case 'd':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000455 return newfloatobject((double)va_arg(*p_va, double));
456
457 case 'c':
458 {
459 char p[1];
460 p[0] = va_arg(*p_va, int);
461 return newsizedstringobject(p, 1);
462 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000463
464 case 's':
465 case 'z':
466 {
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000467 object *v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000468 char *str = va_arg(*p_va, char *);
469 int n;
470 if (**p_format == '#') {
471 ++*p_format;
472 n = va_arg(*p_va, int);
473 }
474 else
475 n = -1;
476 if (str == NULL) {
477 v = None;
478 INCREF(v);
479 }
480 else {
481 if (n < 0)
482 n = strlen(str);
483 v = newsizedstringobject(str, n);
484 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000485 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000486 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000487
488 case 'S':
489 case 'O':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000490 {
491 object *v;
492 v = va_arg(*p_va, object *);
493 if (v != NULL)
494 INCREF(v);
495 else if (!err_occurred())
496 /* If a NULL was passed because a call
497 that should have constructed a value
498 failed, that's OK, and we pass the error
499 on; but if no error occurred it's not
500 clear that the caller knew what she
501 was doing. */
502 err_setstr(SystemError,
503 "NULL object passed to mkvalue");
504 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000505 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000506
507 default:
508 err_setstr(SystemError, "bad format char passed to mkvalue");
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000509 return NULL;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000510
511 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000512}
513
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000514#ifdef USE_STDARG
515/* VARARGS 2 */
516object *mkvalue(char *format, ...)
517#else
518/* VARARGS */
519object *mkvalue(va_alist) va_dcl
520#endif
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000521{
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000522 int n;
523 char *f;
524 va_list va;
525 object* retval;
526#ifdef USE_STDARG
527 va_start(va, format);
528#else
529 char *format;
530
531 va_start(va);
532 format = va_arg(va, char *);
533#endif
534 f = format;
535 n = countformat(f, '\0');
536 if (n < 0)
537 retval = NULL; /* Error in the format */
538 else if (n == 0) {
539 retval = None;
540 INCREF(retval);
541 }
542 else if (n == 1)
543 retval = do_mkvalue(&f, &va);
544 else
545 retval = do_mktuple(&f, &va, '\0', n);
546 va_end(va);
547 if (retval == NULL)
548 fprintf(stderr, "format \"%s\", f \"%s\"\n", format, f);
549 return retval;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000550}