blob: dce3468eeb3f692da7e42bfa5a1df8514e4e7553 [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
221int getargs(object *arg, char *format, ...)
222#else
223int getargs(va_alist) va_dcl
224#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225{
Guido van Rossum922cfad1992-01-27 16:47:03 +0000226 char *f;
227 int ok;
228 va_list va;
229#ifdef USE_STDARG
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230
Guido van Rossum922cfad1992-01-27 16:47:03 +0000231 va_start(va, format);
232#else
233 object *arg;
234 char *format;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235
Guido van Rossum922cfad1992-01-27 16:47:03 +0000236 va_start(va);
237 arg = va_arg(va, object *);
238 format = va_arg(va, char *);
239#endif
240 if (*format == '\0') {
241 va_end(va);
242 if (arg != NULL) {
243 err_setstr(TypeError, "no arguments needed");
244 return 0;
245 }
Guido van Rossumc5da3501991-09-10 14:56:32 +0000246 return 1;
247 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000248
249 f = format;
250 ok = do_arg(arg, &f, &va) && *f == '\0';
251 va_end(va);
252 if (!ok) {
253 char buf[256];
254 sprintf(buf, "bad argument list (format '%s')", format);
255 err_setstr(TypeError, buf);
Guido van Rossumc5da3501991-09-10 14:56:32 +0000256 }
Guido van Rossum922cfad1992-01-27 16:47:03 +0000257 return ok;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258}
259
260int
261getlongtuplearg(args, a, n)
262 object *args;
263 long *a; /* [n] */
264 int n;
265{
266 int i;
267 if (!is_tupleobject(args) || gettuplesize(args) != n) {
268 return err_badarg();
269 }
270 for (i = 0; i < n; i++) {
271 object *v = gettupleitem(args, i);
272 if (!is_intobject(v)) {
273 return err_badarg();
274 }
275 a[i] = getintvalue(v);
276 }
277 return 1;
278}
279
280int
281getshorttuplearg(args, a, n)
282 object *args;
283 short *a; /* [n] */
284 int n;
285{
286 int i;
287 if (!is_tupleobject(args) || gettuplesize(args) != n) {
288 return err_badarg();
289 }
290 for (i = 0; i < n; i++) {
291 object *v = gettupleitem(args, i);
292 if (!is_intobject(v)) {
293 return err_badarg();
294 }
295 a[i] = getintvalue(v);
296 }
297 return 1;
298}
299
300int
301getlonglistarg(args, a, n)
302 object *args;
303 long *a; /* [n] */
304 int n;
305{
306 int i;
307 if (!is_listobject(args) || getlistsize(args) != n) {
308 return err_badarg();
309 }
310 for (i = 0; i < n; i++) {
311 object *v = getlistitem(args, i);
312 if (!is_intobject(v)) {
313 return err_badarg();
314 }
315 a[i] = getintvalue(v);
316 }
317 return 1;
318}
319
320int
321getshortlistarg(args, a, n)
322 object *args;
323 short *a; /* [n] */
324 int n;
325{
326 int i;
327 if (!is_listobject(args) || getlistsize(args) != n) {
328 return err_badarg();
329 }
330 for (i = 0; i < n; i++) {
331 object *v = getlistitem(args, i);
332 if (!is_intobject(v)) {
333 return err_badarg();
334 }
335 a[i] = getintvalue(v);
336 }
337 return 1;
338}