1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
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"
30 #ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */
31 typedef extended va_double
;
33 typedef double va_double
;
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
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";
50 initmodule4(name
, methods
, doc
, passthrough
, module_api_version
)
52 struct methodlist
*methods
;
55 int module_api_version
;
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");
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");
76 v
= newstringobject(doc
);
77 if (v
== NULL
|| dictinsert(d
, "__doc__", v
) != 0)
78 fatal("can't add doc string");
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
)
94 while (level
> 0 || *format
!= endchar
) {
98 err_setstr(SystemError
, "unmatched paren in format");
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 *));
139 do_mkdict(p_format
, p_va
, endchar
, n
)
149 if ((d
= newdictobject()) == NULL
)
151 for (i
= 0; i
< n
; i
+= 2) {
153 k
= do_mkvalue(p_format
, p_va
);
158 v
= do_mkvalue(p_format
, p_va
);
164 if (dict2insert(d
, k
, v
) < 0) {
171 if (d
!= NULL
&& **p_format
!= endchar
) {
174 err_setstr(SystemError
, "Unmatched paren in format");
182 do_mklist(p_format
, p_va
, endchar
, n
)
192 if ((v
= newlistobject(n
)) == NULL
)
194 for (i
= 0; i
< n
; i
++) {
195 object
*w
= do_mkvalue(p_format
, p_va
);
200 setlistitem(v
, i
, w
);
202 if (v
!= NULL
&& **p_format
!= endchar
) {
205 err_setstr(SystemError
, "Unmatched paren in format");
213 do_mktuple(p_format
, p_va
, endchar
, n
)
223 if ((v
= newtupleobject(n
)) == NULL
)
225 for (i
= 0; i
< n
; i
++) {
226 object
*w
= do_mkvalue(p_format
, p_va
);
231 settupleitem(v
, i
, w
);
233 if (v
!= NULL
&& **p_format
!= endchar
) {
236 err_setstr(SystemError
, "Unmatched paren in format");
244 do_mkvalue(p_format
, p_va
)
249 switch (*(*p_format
)++) {
251 return do_mktuple(p_format
, p_va
, ')',
252 countformat(*p_format
, ')'));
255 return do_mklist(p_format
, p_va
, ']',
256 countformat(*p_format
, ']'));
259 return do_mkdict(p_format
, p_va
, '}',
260 countformat(*p_format
, '}'));
265 return newintobject((long)va_arg(*p_va
, int));
268 return newintobject((long)va_arg(*p_va
, long));
272 return newfloatobject((double)va_arg(*p_va
, va_double
));
277 p
[0] = va_arg(*p_va
, int);
278 return newsizedstringobject(p
, 1);
285 char *str
= va_arg(*p_va
, char *);
287 if (**p_format
== '#') {
289 n
= va_arg(*p_va
, int);
300 v
= newsizedstringobject(str
, n
);
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 *);
316 v
= va_arg(*p_va
, object
*);
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");
340 err_setstr(SystemError
,
341 "bad format char passed to mkvalue");
349 #ifdef HAVE_STDARG_PROTOTYPES
351 object
*mkvalue(char *format
, ...)
354 object
*mkvalue(va_alist
) va_dcl
359 #ifdef HAVE_STDARG_PROTOTYPES
360 va_start(va
, format
);
364 format
= va_arg(va
, char *);
366 retval
= vmkvalue(format
, va
);
377 int n
= countformat(f
, '\0');
380 #ifdef VA_LIST_IS_ARRAY
381 memcpy(lva
, va
, sizeof(va_list));
393 return do_mkvalue(&f
, &lva
);
394 return do_mktuple(&f
, &lva
, '\0', n
);
398 #ifdef HAVE_STDARG_PROTOTYPES
400 PyEval_CallFunction(object
*obj
, char *format
, ...)
403 PyEval_CallFunction(obj
, format
, va_alist
)
413 #ifdef HAVE_STDARG_PROTOTYPES
414 va_start(vargs
, format
);
419 args
= vmkvalue(format
, vargs
);
425 res
= call_object(obj
, args
);
432 #ifdef HAVE_STDARG_PROTOTYPES
434 PyEval_CallMethod(object
*obj
, char *methonname
, char *format
, ...)
437 PyEval_CallMethod(obj
, methonname
, format
, va_alist
)
449 meth
= getattr(obj
, methonname
);
453 #ifdef HAVE_STDARG_PROTOTYPES
454 va_start(vargs
, format
);
459 args
= vmkvalue(format
, vargs
);
467 res
= call_object(meth
, args
);