(py-indent-right, py-outdent-left): new commands, bound to C-c C-r and
[python/dscho.git] / Python / modsupport.c
blob63f5267cc38b0a1cbab92af2ac6c6e215e36421f
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* Module support implementation */
27 #include "allobjects.h"
28 #include "import.h"
30 #ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */
31 typedef extended va_double;
32 #else
33 typedef double va_double;
34 #endif
36 /* initmodule4() parameters:
37 - name is the module name
38 - methods is the list of top-level functions
39 - doc is the documentation string
40 - passthrough is passed as self to functions defined in the module
41 - api_version is the value of PYTHON_API_VERSION at the time the
42 module was compiled
45 static char api_version_warning[] =
46 "WARNING: Python C API version mismatch for module %s:\n\
47 This Python has API version %d, module %s has version %s.\n";
49 object *
50 initmodule4(name, methods, doc, passthrough, module_api_version)
51 char *name;
52 struct methodlist *methods;
53 char *doc;
54 object *passthrough;
55 int module_api_version;
57 object *m, *d, *v;
58 struct methodlist *ml;
59 if (module_api_version != PYTHON_API_VERSION)
60 fprintf(stderr, api_version_warning,
61 name, PYTHON_API_VERSION, name, module_api_version);
62 if ((m = add_module(name)) == NULL) {
63 fprintf(stderr, "initializing module: %s\n", name);
64 fatal("can't create a module");
66 d = getmoduledict(m);
67 for (ml = methods; ml->ml_name != NULL; ml++) {
68 v = newmethodobject(ml, passthrough);
69 if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
70 fprintf(stderr, "initializing module: %s\n", name);
71 fatal("can't initialize module");
73 DECREF(v);
75 if (doc != NULL) {
76 v = newstringobject(doc);
77 if (v == NULL || dictinsert(d, "__doc__", v) != 0)
78 fatal("can't add doc string");
79 DECREF(v);
81 return m;
85 /* Helper for mkvalue() to scan the length of a format */
87 static int countformat PROTO((char *format, int endchar));
88 static int countformat(format, endchar)
89 char *format;
90 int endchar;
92 int count = 0;
93 int level = 0;
94 while (level > 0 || *format != endchar) {
95 switch (*format) {
96 case '\0':
97 /* Premature end */
98 err_setstr(SystemError, "unmatched paren in format");
99 return -1;
100 case '(':
101 case '[':
102 case '{':
103 if (level == 0)
104 count++;
105 level++;
106 break;
107 case ')':
108 case ']':
109 case '}':
110 level--;
111 break;
112 case '#':
113 case '&':
114 case ',':
115 case ':':
116 case ' ':
117 case '\t':
118 break;
119 default:
120 if (level == 0)
121 count++;
123 format++;
125 return count;
129 /* Generic function to create a value -- the inverse of getargs() */
130 /* After an original idea and first implementation by Steven Miale */
132 static object *do_mktuple PROTO((char**, va_list *, int, int));
133 static object *do_mklist PROTO((char**, va_list *, int, int));
134 static object *do_mkdict PROTO((char**, va_list *, int, int));
135 static object *do_mkvalue PROTO((char**, va_list *));
138 static object *
139 do_mkdict(p_format, p_va, endchar, n)
140 char **p_format;
141 va_list *p_va;
142 int endchar;
143 int n;
145 object *d;
146 int i;
147 if (n < 0)
148 return NULL;
149 if ((d = newdictobject()) == NULL)
150 return NULL;
151 for (i = 0; i < n; i+= 2) {
152 object *k, *v;
153 k = do_mkvalue(p_format, p_va);
154 if (k == NULL) {
155 DECREF(d);
156 return NULL;
158 v = do_mkvalue(p_format, p_va);
159 if (v == NULL) {
160 DECREF(k);
161 DECREF(d);
162 return NULL;
164 if (dict2insert(d, k, v) < 0) {
165 DECREF(k);
166 DECREF(v);
167 DECREF(d);
168 return NULL;
171 if (d != NULL && **p_format != endchar) {
172 DECREF(d);
173 d = NULL;
174 err_setstr(SystemError, "Unmatched paren in format");
176 else if (endchar)
177 ++*p_format;
178 return d;
181 static object *
182 do_mklist(p_format, p_va, endchar, n)
183 char **p_format;
184 va_list *p_va;
185 int endchar;
186 int n;
188 object *v;
189 int i;
190 if (n < 0)
191 return NULL;
192 if ((v = newlistobject(n)) == NULL)
193 return NULL;
194 for (i = 0; i < n; i++) {
195 object *w = do_mkvalue(p_format, p_va);
196 if (w == NULL) {
197 DECREF(v);
198 return NULL;
200 setlistitem(v, i, w);
202 if (v != NULL && **p_format != endchar) {
203 DECREF(v);
204 v = NULL;
205 err_setstr(SystemError, "Unmatched paren in format");
207 else if (endchar)
208 ++*p_format;
209 return v;
212 static object *
213 do_mktuple(p_format, p_va, endchar, n)
214 char **p_format;
215 va_list *p_va;
216 int endchar;
217 int n;
219 object *v;
220 int i;
221 if (n < 0)
222 return NULL;
223 if ((v = newtupleobject(n)) == NULL)
224 return NULL;
225 for (i = 0; i < n; i++) {
226 object *w = do_mkvalue(p_format, p_va);
227 if (w == NULL) {
228 DECREF(v);
229 return NULL;
231 settupleitem(v, i, w);
233 if (v != NULL && **p_format != endchar) {
234 DECREF(v);
235 v = NULL;
236 err_setstr(SystemError, "Unmatched paren in format");
238 else if (endchar)
239 ++*p_format;
240 return v;
243 static object *
244 do_mkvalue(p_format, p_va)
245 char **p_format;
246 va_list *p_va;
248 for (;;) {
249 switch (*(*p_format)++) {
250 case '(':
251 return do_mktuple(p_format, p_va, ')',
252 countformat(*p_format, ')'));
254 case '[':
255 return do_mklist(p_format, p_va, ']',
256 countformat(*p_format, ']'));
258 case '{':
259 return do_mkdict(p_format, p_va, '}',
260 countformat(*p_format, '}'));
262 case 'b':
263 case 'h':
264 case 'i':
265 return newintobject((long)va_arg(*p_va, int));
267 case 'l':
268 return newintobject((long)va_arg(*p_va, long));
270 case 'f':
271 case 'd':
272 return newfloatobject((double)va_arg(*p_va, va_double));
274 case 'c':
276 char p[1];
277 p[0] = va_arg(*p_va, int);
278 return newsizedstringobject(p, 1);
281 case 's':
282 case 'z':
284 object *v;
285 char *str = va_arg(*p_va, char *);
286 int n;
287 if (**p_format == '#') {
288 ++*p_format;
289 n = va_arg(*p_va, int);
291 else
292 n = -1;
293 if (str == NULL) {
294 v = None;
295 INCREF(v);
297 else {
298 if (n < 0)
299 n = strlen(str);
300 v = newsizedstringobject(str, n);
302 return v;
305 case 'S':
306 case 'O':
307 if (**p_format == '&') {
308 typedef object *(*converter) PROTO((void *));
309 converter func = va_arg(*p_va, converter);
310 void *arg = va_arg(*p_va, void *);
311 ++*p_format;
312 return (*func)(arg);
314 else {
315 object *v;
316 v = va_arg(*p_va, object *);
317 if (v != NULL)
318 INCREF(v);
319 else if (!err_occurred())
320 /* If a NULL was passed
321 * because a call that should
322 * have constructed a value
323 * failed, that's OK, and we
324 * pass the error on; but if
325 * no error occurred it's not
326 * clear that the caller knew
327 * what she was doing. */
328 err_setstr(SystemError,
329 "NULL object passed to mkvalue");
330 return v;
333 case ':':
334 case ',':
335 case ' ':
336 case '\t':
337 break;
339 default:
340 err_setstr(SystemError,
341 "bad format char passed to mkvalue");
342 return NULL;
349 #ifdef HAVE_STDARG_PROTOTYPES
350 /* VARARGS 2 */
351 object *mkvalue(char *format, ...)
352 #else
353 /* VARARGS */
354 object *mkvalue(va_alist) va_dcl
355 #endif
357 va_list va;
358 object* retval;
359 #ifdef HAVE_STDARG_PROTOTYPES
360 va_start(va, format);
361 #else
362 char *format;
363 va_start(va);
364 format = va_arg(va, char *);
365 #endif
366 retval = vmkvalue(format, va);
367 va_end(va);
368 return retval;
371 object *
372 vmkvalue(format, va)
373 char *format;
374 va_list va;
376 char *f = format;
377 int n = countformat(f, '\0');
378 va_list lva;
380 #ifdef VA_LIST_IS_ARRAY
381 memcpy(lva, va, sizeof(va_list));
382 #else
383 lva = va;
384 #endif
386 if (n < 0)
387 return NULL;
388 if (n == 0) {
389 INCREF(None);
390 return None;
392 if (n == 1)
393 return do_mkvalue(&f, &lva);
394 return do_mktuple(&f, &lva, '\0', n);
398 #ifdef HAVE_STDARG_PROTOTYPES
399 object *
400 PyEval_CallFunction(object *obj, char *format, ...)
401 #else
402 object *
403 PyEval_CallFunction(obj, format, va_alist)
404 object *obj;
405 char *format;
406 va_dcl
407 #endif
409 va_list vargs;
410 object *args;
411 object *res;
413 #ifdef HAVE_STDARG_PROTOTYPES
414 va_start(vargs, format);
415 #else
416 va_start(vargs);
417 #endif
419 args = vmkvalue(format, vargs);
420 va_end(vargs);
422 if (args == NULL)
423 return NULL;
425 res = call_object(obj, args);
426 DECREF(args);
428 return res;
432 #ifdef HAVE_STDARG_PROTOTYPES
433 object *
434 PyEval_CallMethod(object *obj, char *methonname, char *format, ...)
435 #else
436 object *
437 PyEval_CallMethod(obj, methonname, format, va_alist)
438 object *obj;
439 char *methonname;
440 char *format;
441 va_dcl
442 #endif
444 va_list vargs;
445 object *meth;
446 object *args;
447 object *res;
449 meth = getattr(obj, methonname);
450 if (meth == NULL)
451 return NULL;
453 #ifdef HAVE_STDARG_PROTOTYPES
454 va_start(vargs, format);
455 #else
456 va_start(vargs);
457 #endif
459 args = vmkvalue(format, vargs);
460 va_end(vargs);
462 if (args == NULL) {
463 DECREF(meth);
464 return NULL;
467 res = call_object(meth, args);
468 DECREF(meth);
469 DECREF(args);
471 return res;