blob: b7239d331f832eaa733998064516ed7e6f5af3e8 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
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}