blob: 6dcac00ac19aa53b7f0159630800bab39661261b [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 Rossum922cfad1992-01-27 16:47:03 +000070/* Generic argument list parser */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071
Guido van Rossum922cfad1992-01-27 16:47:03 +000072static int do_arg PROTO((object *arg, char** p_format, va_list *p_va));
73static int
74do_arg(arg, p_format, p_va)
75 object *arg;
76 char** p_format;
77 va_list *p_va;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078{
Guido van Rossum922cfad1992-01-27 16:47:03 +000079 char *format = *p_format;
80 va_list va = *p_va;
81
82 if (arg == NULL)
83 return 0; /* Incomplete tuple or list */
84
85 switch (*format++) {
86
87 case '('/*')'*/: /* tuple, distributed over C parameters */ {
88 int i, n;
89 if (!is_tupleobject(arg))
90 return 0;
91 n = gettuplesize(arg);
92 for (i = 0; i < n; i++) {
93 if (!do_arg(gettupleitem(arg, i), &format, &va))
94 return 0;
95 }
96 if (*format++ != /*'('*/')')
97 return 0;
98 break;
99 }
100
101 case 'h': /* short int */ {
102 short *p = va_arg(va, short *);
103 if (is_intobject(arg))
104 *p = getintvalue(arg);
105 else
106 return 0;
107 break;
108 }
109
110 case 'i': /* int */ {
111 int *p = va_arg(va, int *);
112 if (is_intobject(arg))
113 *p = getintvalue(arg);
114 else
115 return 0;
116 break;
117 }
118
119 case 'l': /* long int */ {
120 long *p = va_arg(va, long *);
121 if (is_intobject(arg))
122 *p = getintvalue(arg);
123 else
124 return 0;
125 break;
126 }
127
128 case 'f': /* float */ {
129 float *p = va_arg(va, float *);
130 if (is_floatobject(arg))
131 *p = getfloatvalue(arg);
132 else if (is_intobject(arg))
133 *p = (float)getintvalue(arg);
134 else
135 return 0;
136 break;
137 }
138
139 case 'd': /* double */ {
140 double *p = va_arg(va, double *);
141 if (is_floatobject(arg))
142 *p = getfloatvalue(arg);
143 else if (is_intobject(arg))
144 *p = (double)getintvalue(arg);
145 else
146 return 0;
147 break;
148 }
149
150 case 'c': /* char */ {
151 char *p = va_arg(va, char *);
152 if (is_stringobject(arg) && getstringsize(arg) == 1)
153 *p = getstringvalue(arg)[0];
154 else
155 return 0;
156 break;
157 }
158
159 case 's': /* string */ {
160 char **p = va_arg(va, char **);
161 if (is_stringobject(arg))
162 *p = getstringvalue(arg);
163 else
164 return 0;
165 if (*format == '#') {
166 int *q = va_arg(va, int *);
167 *q = getstringsize(arg);
168 format++;
169 }
170 break;
171 }
172
173 case 'z': /* string, may be NULL (None) */ {
174 char **p = va_arg(va, char **);
175 if (arg == None)
176 *p = 0;
177 else if (is_stringobject(arg))
178 *p = getstringvalue(arg);
179 else
180 return 0;
181 if (*format == '#') {
182 int *q = va_arg(va, int *);
183 if (arg == None)
184 *q = 0;
185 else
186 *q = getstringsize(arg);
187 format++;
188 }
189 break;
190 }
191
192 case 'S': /* string object */ {
193 object **p = va_arg(va, object **);
194 if (is_stringobject(arg))
195 *p = arg;
196 else
197 return 0;
198 break;
199 }
200
201 case 'O': /* object */ {
202 object **p = va_arg(va, object **);
203 *p = arg;
204 break;
205 }
206
207 default:
208 fprintf(stderr, "bad do_arg format: x%x '%c'\n",
209 format[-1], format[-1]);
210 return 0;
211
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000213
214 *p_va = va;
215 *p_format = format;
216
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 return 1;
218}
219
Guido van Rossum922cfad1992-01-27 16:47:03 +0000220#ifdef USE_STDARG
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000221/* VARARGS2 */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000222int getargs(object *arg, char *format, ...)
223#else
Guido van Rossum292bb8e1992-03-27 17:23:29 +0000224/* VARARGS */
Guido van Rossum922cfad1992-01-27 16:47:03 +0000225int getargs(va_alist) va_dcl
226#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000228 char *f;
229 int ok;
230 va_list va;
231#ifdef USE_STDARG
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232
Guido van Rossum922cfad1992-01-27 16:47:03 +0000233 va_start(va, format);
234#else
235 object *arg;
236 char *format;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Guido van Rossum922cfad1992-01-27 16:47:03 +0000238 va_start(va);
239 arg = va_arg(va, object *);
240 format = va_arg(va, char *);
241#endif
242 if (*format == '\0') {
243 va_end(va);
244 if (arg != NULL) {
245 err_setstr(TypeError, "no arguments needed");
246 return 0;
247 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000248 return 1;
249 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000250
251 f = format;
252 ok = do_arg(arg, &f, &va) && *f == '\0';
253 va_end(va);
254 if (!ok) {
255 char buf[256];
256 sprintf(buf, "bad argument list (format '%s')", format);
257 err_setstr(TypeError, buf);
Guido van Rossumc5da3501991-09-10 14:56:32 +0000258 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000259 return ok;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260}
261
262int
263getlongtuplearg(args, a, n)
264 object *args;
265 long *a; /* [n] */
266 int n;
267{
268 int i;
269 if (!is_tupleobject(args) || gettuplesize(args) != n) {
270 return err_badarg();
271 }
272 for (i = 0; i < n; i++) {
273 object *v = gettupleitem(args, i);
274 if (!is_intobject(v)) {
275 return err_badarg();
276 }
277 a[i] = getintvalue(v);
278 }
279 return 1;
280}
281
282int
283getshorttuplearg(args, a, n)
284 object *args;
285 short *a; /* [n] */
286 int n;
287{
288 int i;
289 if (!is_tupleobject(args) || gettuplesize(args) != n) {
290 return err_badarg();
291 }
292 for (i = 0; i < n; i++) {
293 object *v = gettupleitem(args, i);
294 if (!is_intobject(v)) {
295 return err_badarg();
296 }
297 a[i] = getintvalue(v);
298 }
299 return 1;
300}
301
302int
303getlonglistarg(args, a, n)
304 object *args;
305 long *a; /* [n] */
306 int n;
307{
308 int i;
309 if (!is_listobject(args) || getlistsize(args) != n) {
310 return err_badarg();
311 }
312 for (i = 0; i < n; i++) {
313 object *v = getlistitem(args, i);
314 if (!is_intobject(v)) {
315 return err_badarg();
316 }
317 a[i] = getintvalue(v);
318 }
319 return 1;
320}
321
322int
323getshortlistarg(args, a, n)
324 object *args;
325 short *a; /* [n] */
326 int n;
327{
328 int i;
329 if (!is_listobject(args) || getlistsize(args) != n) {
330 return err_badarg();
331 }
332 for (i = 0; i < n; i++) {
333 object *v = getlistitem(args, i);
334 if (!is_intobject(v)) {
335 return err_badarg();
336 }
337 a[i] = getintvalue(v);
338 }
339 return 1;
340}
Guido van Rossum3cfe6fa1992-04-13 10:48:55 +0000341
342static object *
343do_mkval(char **p_format, va_list *p_va) {
344 object *v;
345
346 switch (*(*p_format)++) {
347
348 case '(':
349 {
350 int n = 0;
351 char *p = *p_format;
352 int level = 0;
353 int i;
354 while (level > 0 || *p != ')') {
355 if (*p == '\0') {
356 err_setstr(SystemError, "missing ')' in mkvalue format");
357 return NULL;
358 }
359 else if (*p == '(') {
360 if (level == 0)
361 n++;
362 level++;
363 }
364 else if (*p == ')')
365 level--;
366 else if (level == 0 && *p != '#')
367 n++;
368 p++;
369 }
370 v = newtupleobject(n);
371 if (v == NULL)
372 break;
373 for (i = 0; i < n; i++) {
374 object *w = do_mkval(p_format, p_va);
375 if (w == NULL) {
376 DECREF(v);
377 v = NULL;
378 break;
379 }
380 settupleitem(v, i, w);
381 }
382 if (v != NULL && *(*p_format)++ != ')') {
383 /* "Cannot happen" */
384 err_setstr(SystemError, "inconsistent format in mkvalue???");
385 DECREF(v);
386 v = NULL;
387 }
388 }
389 break;
390
391 case 'h':
392 v = newintobject((long)va_arg(*p_va, short));
393 break;
394
395 case 'i':
396 v = newintobject((long)va_arg(*p_va, int));
397 break;
398
399 case 'l':
400 v = newintobject((long)va_arg(*p_va, long));
401 break;
402
403 case 'f':
404 v = newfloatobject((double)va_arg(*p_va, float));
405 break;
406
407 case 'd':
408 v = newfloatobject((double)va_arg(*p_va, double));
409 break;
410
411 case 's':
412 case 'z':
413 {
414 char *str = va_arg(*p_va, char *);
415 int n;
416 if (**p_format == '#') {
417 ++*p_format;
418 n = va_arg(*p_va, int);
419 }
420 else
421 n = -1;
422 if (str == NULL) {
423 v = None;
424 INCREF(v);
425 }
426 else {
427 if (n < 0)
428 n = strlen(str);
429 v = newsizedstringobject(str, n);
430 }
431 }
432 break;
433
434 case 'S':
435 case 'O':
436 v = va_arg(*p_va, object *);
437 if (v == NULL) {
438 if (!err_occurred())
439 err_setstr(SystemError, "NULL object passed to mkvalue");
440 }
441 else
442 INCREF(v);
443 break;
444
445 default:
446 err_setstr(SystemError, "bad format char passed to mkvalue");
447 v = NULL;
448 break;
449
450 }
451
452 return v;
453}
454
455object *
456mkvalue(char *format, ...)
457{
458 char *fmt = format;
459 object *v;
460 va_list p;
461 va_start(p, format);
462 v = do_mkval(&fmt, &p);
463 va_end(p);
464 if (v == NULL)
465 fprintf(stderr, "mkvalue: format = \"%s\" \"%s\"\n", format, fmt);
466 return v;
467}