blob: d998ad822f5b7d6a3988e28d453ccc5682d26a3c [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
317int
318getlongtuplearg(args, a, n)
319 object *args;
320 long *a; /* [n] */
321 int n;
322{
323 int i;
324 if (!is_tupleobject(args) || gettuplesize(args) != n) {
325 return err_badarg();
326 }
327 for (i = 0; i < n; i++) {
328 object *v = gettupleitem(args, i);
329 if (!is_intobject(v)) {
330 return err_badarg();
331 }
332 a[i] = getintvalue(v);
333 }
334 return 1;
335}
336
337int
338getshorttuplearg(args, a, n)
339 object *args;
340 short *a; /* [n] */
341 int n;
342{
343 int i;
344 if (!is_tupleobject(args) || gettuplesize(args) != n) {
345 return err_badarg();
346 }
347 for (i = 0; i < n; i++) {
348 object *v = gettupleitem(args, i);
349 if (!is_intobject(v)) {
350 return err_badarg();
351 }
352 a[i] = getintvalue(v);
353 }
354 return 1;
355}
356
357int
358getlonglistarg(args, a, n)
359 object *args;
360 long *a; /* [n] */
361 int n;
362{
363 int i;
364 if (!is_listobject(args) || getlistsize(args) != n) {
365 return err_badarg();
366 }
367 for (i = 0; i < n; i++) {
368 object *v = getlistitem(args, i);
369 if (!is_intobject(v)) {
370 return err_badarg();
371 }
372 a[i] = getintvalue(v);
373 }
374 return 1;
375}
376
377int
378getshortlistarg(args, a, n)
379 object *args;
380 short *a; /* [n] */
381 int n;
382{
383 int i;
384 if (!is_listobject(args) || getlistsize(args) != n) {
385 return err_badarg();
386 }
387 for (i = 0; i < n; i++) {
388 object *v = getlistitem(args, i);
389 if (!is_intobject(v)) {
390 return err_badarg();
391 }
392 a[i] = getintvalue(v);
393 }
394 return 1;
395}
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000396
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000397
398/* Generic function to create a value -- the inverse of getargs() */
399/* After an original idea and first implementation by Steven Miale */
400
401static object *do_mktuple PROTO((char**, va_list *, int, int));
402static object *do_mkvalue PROTO((char**, va_list *));
403
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000404static object *
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000405do_mktuple(p_format, p_va, endchar, n)
406 char **p_format;
407 va_list *p_va;
408 int endchar;
409 int n;
410{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000411 object *v;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000412 int i;
413 if (n < 0)
414 return NULL;
415 if ((v = newtupleobject(n)) == NULL)
416 return NULL;
417 for (i = 0; i < n; i++) {
418 object *w = do_mkvalue(p_format, p_va);
419 if (w == NULL) {
420 DECREF(v);
421 return NULL;
422 }
423 settupleitem(v, i, w);
424 }
425 if (v != NULL && **p_format != endchar) {
426 DECREF(v);
427 v = NULL;
428 err_setstr(SystemError, "Unmatched paren in format");
429 }
430 else if (endchar)
431 ++*p_format;
432 return v;
433}
434
435static object *
Guido van Rossum899dcf31992-05-15 11:04:59 +0000436do_mkvalue(p_format, p_va)
437 char **p_format;
438 va_list *p_va;
439{
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000440
441 switch (*(*p_format)++) {
442
443 case '(':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000444 return do_mktuple(p_format, p_va, ')',
445 countformat(*p_format, ')'));
Guido van Rossume5372401993-03-16 12:15:04 +0000446
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000447 case 'b':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000448 case 'h':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000449 case 'i':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000450 return newintobject((long)va_arg(*p_va, int));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000451
452 case 'l':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000453 return newintobject((long)va_arg(*p_va, long));
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000454
455 case 'f':
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000456 case 'd':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000457 return newfloatobject((double)va_arg(*p_va, double));
Guido van Rossume5372401993-03-16 12:15:04 +0000458
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000459 case 'c':
460 {
461 char p[1];
462 p[0] = va_arg(*p_va, int);
463 return newsizedstringobject(p, 1);
464 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000465
466 case 's':
467 case 'z':
468 {
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000469 object *v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000470 char *str = va_arg(*p_va, char *);
471 int n;
472 if (**p_format == '#') {
473 ++*p_format;
474 n = va_arg(*p_va, int);
475 }
476 else
477 n = -1;
478 if (str == NULL) {
479 v = None;
480 INCREF(v);
481 }
482 else {
483 if (n < 0)
484 n = strlen(str);
485 v = newsizedstringobject(str, n);
486 }
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000487 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000488 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000489
490 case 'S':
491 case 'O':
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000492 {
493 object *v;
494 v = va_arg(*p_va, object *);
495 if (v != NULL)
496 INCREF(v);
497 else if (!err_occurred())
498 /* If a NULL was passed because a call
499 that should have constructed a value
500 failed, that's OK, and we pass the error
501 on; but if no error occurred it's not
502 clear that the caller knew what she
503 was doing. */
504 err_setstr(SystemError,
505 "NULL object passed to mkvalue");
506 return v;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000507 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000508
509 default:
510 err_setstr(SystemError, "bad format char passed to mkvalue");
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000511 return NULL;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000512
513 }
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000514}
515
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000516#ifdef USE_STDARG
517/* VARARGS 2 */
518object *mkvalue(char *format, ...)
519#else
520/* VARARGS */
521object *mkvalue(va_alist) va_dcl
522#endif
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000523{
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000524 va_list va;
525 object* retval;
526#ifdef USE_STDARG
527 va_start(va, format);
528#else
529 char *format;
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000530 va_start(va);
531 format = va_arg(va, char *);
532#endif
Guido van Rossume5372401993-03-16 12:15:04 +0000533 retval = vmkvalue(format, va);
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000534 va_end(va);
Guido van Rossumfc61adb1992-04-13 15:53:41 +0000535 return retval;
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000536}
Guido van Rossume5372401993-03-16 12:15:04 +0000537
538object *
539vmkvalue(format, va)
540 char *format;
541 va_list va;
542{
543 char *f = format;
544 int n = countformat(f, '\0');
545 if (n < 0)
546 return NULL;
547 if (n == 0) {
548 INCREF(None);
549 return None;
550 }
551 if (n == 1)
552 return do_mkvalue(&f, &va);
553 return do_mktuple(&f, &va, '\0', n);
554}