blob: beb5c34f48e9a649272c195f3bc6e767951114ea [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 Rossum85a5fbb1990-10-14 12:07:46 +000031object *
32initmodule(name, methods)
33 char *name;
34 struct methodlist *methods;
35{
36 object *m, *d, *v;
37 struct methodlist *ml;
Guido van Rossuma2b7f401993-01-04 09:09:59 +000038 char *namebuf;
Guido van Rossum3f5da241990-12-20 15:06:42 +000039 if ((m = add_module(name)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000040 fprintf(stderr, "initializing module: %s\n", name);
41 fatal("can't create a module");
42 }
43 d = getmoduledict(m);
44 for (ml = methods; ml->ml_name != NULL; ml++) {
Guido van Rossuma2b7f401993-01-04 09:09:59 +000045 namebuf = NEW(char, strlen(name) + strlen(ml->ml_name) + 2);
46 if (namebuf == NULL)
47 fatal("out of mem for method name");
Guido van Rossum3f5da241990-12-20 15:06:42 +000048 sprintf(namebuf, "%s.%s", name, ml->ml_name);
Guido van Rossuma2b7f401993-01-04 09:09:59 +000049 v = newmethodobject(namebuf, ml->ml_meth,
Guido van Rossumc0602291991-12-16 13:07:24 +000050 (object *)NULL, ml->ml_varargs);
Guido van Rossuma2b7f401993-01-04 09:09:59 +000051 /* XXX The malloc'ed memory in namebuf is never freed */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052 if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
53 fprintf(stderr, "initializing module: %s\n", name);
54 fatal("can't initialize module");
55 }
56 DECREF(v);
57 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000058 return m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059}
60
61
Guido van Rossumbf80e541993-02-08 15:49:17 +000062/* Helper for mkvalue() to scan the length of a format */
Guido van Rossumfc61adb1992-04-13 15:53:41 +000063
64static int countformat PROTO((char *format, int endchar));
65static int countformat(format, endchar)
66 char *format;
67 int endchar;
68{
69 int count = 0;
70 int level = 0;
71 while (level > 0 || *format != endchar) {
72 if (*format == '\0') {
73 /* Premature end */
74 err_setstr(SystemError, "unmatched paren in format");
75 return -1;
76 }
77 else if (*format == '(') {
78 if (level == 0)
79 count++;
80 level++;
81 }
82 else if (*format == ')')
83 level--;
84 else if (level == 0 && *format != '#')
85 count++;
86 format++;
87 }
88 return count;
89}
90
91
Guido van Rossum922cfad1992-01-27 16:47:03 +000092/* Generic argument list parser */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000093
Guido van Rossum922cfad1992-01-27 16:47:03 +000094static int do_arg PROTO((object *arg, char** p_format, va_list *p_va));
95static int
96do_arg(arg, p_format, p_va)
97 object *arg;
98 char** p_format;
99 va_list *p_va;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000101 char *format = *p_format;
102 va_list va = *p_va;
103
104 if (arg == NULL)
105 return 0; /* Incomplete tuple or list */
106
107 switch (*format++) {
108
Guido van Rossuma93265a1992-08-27 07:45:12 +0000109 case '(': /* tuple, distributed over C parameters */ {
Guido van Rossum922cfad1992-01-27 16:47:03 +0000110 int i, n;
111 if (!is_tupleobject(arg))
112 return 0;
113 n = gettuplesize(arg);
114 for (i = 0; i < n; i++) {
115 if (!do_arg(gettupleitem(arg, i), &format, &va))
116 return 0;
117 }
Guido van Rossuma93265a1992-08-27 07:45:12 +0000118 if (*format++ != ')')
Guido van Rossum922cfad1992-01-27 16:47:03 +0000119 return 0;
120 break;
121 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000122
Guido van Rossuma93265a1992-08-27 07:45:12 +0000123 case ')': /* End of format -- too many arguments */
124 return 0;
125
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000126 case 'b': /* byte -- very short int */ {
127 char *p = va_arg(va, char *);
128 if (is_intobject(arg))
129 *p = getintvalue(arg);
130 else
131 return 0;
132 break;
133 }
134
Guido van Rossum922cfad1992-01-27 16:47:03 +0000135 case 'h': /* short int */ {
136 short *p = va_arg(va, short *);
137 if (is_intobject(arg))
138 *p = getintvalue(arg);
139 else
140 return 0;
141 break;
142 }
143
144 case 'i': /* int */ {
145 int *p = va_arg(va, int *);
146 if (is_intobject(arg))
147 *p = getintvalue(arg);
148 else
149 return 0;
150 break;
151 }
152
153 case 'l': /* long int */ {
154 long *p = va_arg(va, long *);
155 if (is_intobject(arg))
156 *p = getintvalue(arg);
157 else
158 return 0;
159 break;
160 }
161
162 case 'f': /* float */ {
163 float *p = va_arg(va, float *);
164 if (is_floatobject(arg))
165 *p = getfloatvalue(arg);
166 else if (is_intobject(arg))
167 *p = (float)getintvalue(arg);
168 else
169 return 0;
170 break;
171 }
172
173 case 'd': /* double */ {
174 double *p = va_arg(va, double *);
175 if (is_floatobject(arg))
176 *p = getfloatvalue(arg);
177 else if (is_intobject(arg))
178 *p = (double)getintvalue(arg);
179 else
180 return 0;
181 break;
182 }
183
184 case 'c': /* char */ {
185 char *p = va_arg(va, char *);
186 if (is_stringobject(arg) && getstringsize(arg) == 1)
187 *p = getstringvalue(arg)[0];
188 else
189 return 0;
190 break;
191 }
192
193 case 's': /* string */ {
194 char **p = va_arg(va, char **);
195 if (is_stringobject(arg))
196 *p = getstringvalue(arg);
197 else
198 return 0;
199 if (*format == '#') {
200 int *q = va_arg(va, int *);
201 *q = getstringsize(arg);
202 format++;
203 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000204 else if (strlen(*p) != getstringsize(arg)) {
205 err_setstr(ValueError, "embedded '\\0' in string arg");
206 return 0;
207 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000208 break;
209 }
210
211 case 'z': /* string, may be NULL (None) */ {
212 char **p = va_arg(va, char **);
213 if (arg == None)
214 *p = 0;
215 else if (is_stringobject(arg))
216 *p = getstringvalue(arg);
217 else
218 return 0;
219 if (*format == '#') {
220 int *q = va_arg(va, int *);
221 if (arg == None)
222 *q = 0;
223 else
224 *q = getstringsize(arg);
225 format++;
226 }
Guido van Rossum96caaee1992-08-14 15:12:03 +0000227 else if (*p != NULL && strlen(*p) != getstringsize(arg)) {
228 err_setstr(ValueError, "embedded '\\0' in string arg");
229 return 0;
230 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000231 break;
232 }
233
234 case 'S': /* string object */ {
235 object **p = va_arg(va, object **);
236 if (is_stringobject(arg))
237 *p = arg;
238 else
239 return 0;
240 break;
241 }
242
243 case 'O': /* object */ {
244 object **p = va_arg(va, object **);
245 *p = arg;
246 break;
247 }
248
249 default:
250 fprintf(stderr, "bad do_arg format: x%x '%c'\n",
251 format[-1], format[-1]);
252 return 0;
253
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000255
256 *p_va = va;
257 *p_format = format;
258
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 return 1;
260}
261
Guido van Rossum922cfad1992-01-27 16:47:03 +0000262#ifdef USE_STDARG
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000263/* VARARGS2 */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000264int getargs(object *arg, char *format, ...)
265#else
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000266/* VARARGS */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000267int getargs(va_alist) va_dcl
268#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000270 char *f;
271 int ok;
272 va_list va;
273#ifdef USE_STDARG
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Guido van Rossum922cfad1992-01-27 16:47:03 +0000275 va_start(va, format);
276#else
277 object *arg;
278 char *format;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279
Guido van Rossum922cfad1992-01-27 16:47:03 +0000280 va_start(va);
281 arg = va_arg(va, object *);
282 format = va_arg(va, char *);
283#endif
Guido van Rossumbf80e541993-02-08 15:49:17 +0000284 if (*format == '\0' || *format == ';') {
Guido van Rossum922cfad1992-01-27 16:47:03 +0000285 va_end(va);
286 if (arg != NULL) {
Guido van Rossumbf80e541993-02-08 15:49:17 +0000287 char *str = "no arguments needed";
288 if (*format == ';')
289 str = format+1;
290 err_setstr(TypeError, str);
Guido van Rossum922cfad1992-01-27 16:47:03 +0000291 return 0;
292 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000293 return 1;
294 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000295
296 f = format;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000297 ok = do_arg(arg, &f, &va) && (*f == '\0' || *f == ';');
Guido van Rossum922cfad1992-01-27 16:47:03 +0000298 va_end(va);
299 if (!ok) {
Guido van Rossum96caaee1992-08-14 15:12:03 +0000300 if (!err_occurred()) {
Guido van Rossumbf80e541993-02-08 15:49:17 +0000301 char buf[256];
302 char *str;
303 f = strchr(format, ';');
304 if (f != NULL)
305 str = f+1;
306 else {
307 sprintf(buf, "bad argument list (format '%s')",
308 format);
309 str = buf;
310 }
311 err_setstr(TypeError, str);
Guido van Rossum96caaee1992-08-14 15:12:03 +0000312 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000313 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000314 return ok;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315}
316
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000317#ifdef UNUSED
318
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319int
320getlongtuplearg(args, a, n)
321 object *args;
322 long *a; /* [n] */
323 int n;
324{
325 int i;
326 if (!is_tupleobject(args) || gettuplesize(args) != n) {
327 return err_badarg();
328 }
329 for (i = 0; i < n; i++) {
330 object *v = gettupleitem(args, i);
331 if (!is_intobject(v)) {
332 return err_badarg();
333 }
334 a[i] = getintvalue(v);
335 }
336 return 1;
337}
338
339int
340getshorttuplearg(args, a, n)
341 object *args;
342 short *a; /* [n] */
343 int n;
344{
345 int i;
346 if (!is_tupleobject(args) || gettuplesize(args) != n) {
347 return err_badarg();
348 }
349 for (i = 0; i < n; i++) {
350 object *v = gettupleitem(args, i);
351 if (!is_intobject(v)) {
352 return err_badarg();
353 }
354 a[i] = getintvalue(v);
355 }
356 return 1;
357}
358
359int
360getlonglistarg(args, a, n)
361 object *args;
362 long *a; /* [n] */
363 int n;
364{
365 int i;
366 if (!is_listobject(args) || getlistsize(args) != n) {
367 return err_badarg();
368 }
369 for (i = 0; i < n; i++) {
370 object *v = getlistitem(args, i);
371 if (!is_intobject(v)) {
372 return err_badarg();
373 }
374 a[i] = getintvalue(v);
375 }
376 return 1;
377}
378
379int
380getshortlistarg(args, a, n)
381 object *args;
382 short *a; /* [n] */
383 int n;
384{
385 int i;
386 if (!is_listobject(args) || getlistsize(args) != n) {
387 return err_badarg();
388 }
389 for (i = 0; i < n; i++) {
390 object *v = getlistitem(args, i);
391 if (!is_intobject(v)) {
392 return err_badarg();
393 }
394 a[i] = getintvalue(v);
395 }
396 return 1;
397}
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000398
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000399#endif /* UNUSED */
400
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000401
402/* Generic function to create a value -- the inverse of getargs() */
403/* After an original idea and first implementation by Steven Miale */
404
405static object *do_mktuple PROTO((char**, va_list *, int, int));
406static object *do_mkvalue PROTO((char**, va_list *));
407
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000408static object *
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000409do_mktuple(p_format, p_va, endchar, n)
410 char **p_format;
411 va_list *p_va;
412 int endchar;
413 int n;
414{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000415 object *v;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000416 int i;
417 if (n < 0)
418 return NULL;
419 if ((v = newtupleobject(n)) == NULL)
420 return NULL;
421 for (i = 0; i < n; i++) {
422 object *w = do_mkvalue(p_format, p_va);
423 if (w == NULL) {
424 DECREF(v);
425 return NULL;
426 }
427 settupleitem(v, i, w);
428 }
429 if (v != NULL && **p_format != endchar) {
430 DECREF(v);
431 v = NULL;
432 err_setstr(SystemError, "Unmatched paren in format");
433 }
434 else if (endchar)
435 ++*p_format;
436 return v;
437}
438
439static object *
Guido van Rossum899dcf31992-05-15 11:04:59 +0000440do_mkvalue(p_format, p_va)
441 char **p_format;
442 va_list *p_va;
443{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000444
445 switch (*(*p_format)++) {
446
447 case '(':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000448 return do_mktuple(p_format, p_va, ')',
449 countformat(*p_format, ')'));
Guido van Rossume5372401993-03-16 12:15:04 +0000450
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000451 case 'b':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000452 case 'h':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000453 case 'i':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000454 return newintobject((long)va_arg(*p_va, int));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000455
456 case 'l':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000457 return newintobject((long)va_arg(*p_va, long));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000458
459 case 'f':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000460 case 'd':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000461 return newfloatobject((double)va_arg(*p_va, double));
Guido van Rossume5372401993-03-16 12:15:04 +0000462
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000463 case 'c':
464 {
465 char p[1];
466 p[0] = va_arg(*p_va, int);
467 return newsizedstringobject(p, 1);
468 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000469
470 case 's':
471 case 'z':
472 {
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000473 object *v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000474 char *str = va_arg(*p_va, char *);
475 int n;
476 if (**p_format == '#') {
477 ++*p_format;
478 n = va_arg(*p_va, int);
479 }
480 else
481 n = -1;
482 if (str == NULL) {
483 v = None;
484 INCREF(v);
485 }
486 else {
487 if (n < 0)
488 n = strlen(str);
489 v = newsizedstringobject(str, n);
490 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000491 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000492 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000493
494 case 'S':
495 case 'O':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000496 {
497 object *v;
498 v = va_arg(*p_va, object *);
499 if (v != NULL)
500 INCREF(v);
501 else if (!err_occurred())
502 /* If a NULL was passed because a call
503 that should have constructed a value
504 failed, that's OK, and we pass the error
505 on; but if no error occurred it's not
506 clear that the caller knew what she
507 was doing. */
508 err_setstr(SystemError,
509 "NULL object passed to mkvalue");
510 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000511 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000512
513 default:
514 err_setstr(SystemError, "bad format char passed to mkvalue");
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000515 return NULL;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000516
517 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000518}
519
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000520#ifdef USE_STDARG
521/* VARARGS 2 */
522object *mkvalue(char *format, ...)
523#else
524/* VARARGS */
525object *mkvalue(va_alist) va_dcl
526#endif
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000527{
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000528 va_list va;
529 object* retval;
530#ifdef USE_STDARG
531 va_start(va, format);
532#else
533 char *format;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000534 va_start(va);
535 format = va_arg(va, char *);
536#endif
Guido van Rossume5372401993-03-16 12:15:04 +0000537 retval = vmkvalue(format, va);
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000538 va_end(va);
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000539 return retval;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000540}
Guido van Rossume5372401993-03-16 12:15:04 +0000541
542object *
543vmkvalue(format, va)
544 char *format;
545 va_list va;
546{
547 char *f = format;
548 int n = countformat(f, '\0');
549 if (n < 0)
550 return NULL;
551 if (n == 0) {
552 INCREF(None);
553 return None;
554 }
555 if (n == 1)
556 return do_mkvalue(&f, &va);
557 return do_mktuple(&f, &va, '\0', n);
558}