| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | /***********************************************************
 | 
					
						
							| 
									
										
										
										
											1995-01-04 19:12:13 +00:00
										 |  |  | Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, | 
					
						
							|  |  |  | The Netherlands. | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         All Rights Reserved | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Permission to use, copy, modify, and distribute this software and its | 
					
						
							|  |  |  | documentation for any purpose and without fee is hereby granted, | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | provided that the above copyright notice appear in all copies and that | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | both that copyright notice and this permission notice appear in | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | supporting documentation, and that the names of Stichting Mathematisch | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Centrum or CWI or Corporation for National Research Initiatives or | 
					
						
							|  |  |  | CNRI not be used in advertising or publicity pertaining to | 
					
						
							|  |  |  | distribution of the software without specific, written prior | 
					
						
							|  |  |  | permission. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | While CWI is the initial source for this software, a modified version | 
					
						
							|  |  |  | is made available by the Corporation for National Research Initiatives | 
					
						
							|  |  |  | (CNRI) at the Internet address ftp://ftp.python.org.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH | 
					
						
							|  |  |  | REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF | 
					
						
							|  |  |  | MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH | 
					
						
							|  |  |  | CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | 
					
						
							|  |  |  | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | 
					
						
							|  |  |  | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | 
					
						
							|  |  |  | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | 
					
						
							|  |  |  | PERFORMANCE OF THIS SOFTWARE. | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ******************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | /* Module support implementation */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | #include "allobjects.h"
 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | #include "import.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-30 08:27:36 +00:00
										 |  |  | #ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */
 | 
					
						
							|  |  |  | typedef extended va_double; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											1994-08-30 08:27:36 +00:00
										 |  |  | typedef double va_double; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-09 17:47:20 +00:00
										 |  |  | /* initmodule4() parameters:
 | 
					
						
							|  |  |  |    - name is the module name | 
					
						
							|  |  |  |    - methods is the list of top-level functions | 
					
						
							|  |  |  |    - doc is the documentation string | 
					
						
							|  |  |  |    - passthrough is passed as self to functions defined in the module | 
					
						
							|  |  |  |    - api_version is the value of PYTHON_API_VERSION at the time the | 
					
						
							|  |  |  |      module was compiled | 
					
						
							| 
									
										
										
										
											1995-01-07 12:43:18 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											1994-08-30 08:27:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-09 17:47:20 +00:00
										 |  |  | static char api_version_warning[] = | 
					
						
							|  |  |  | "WARNING: Python C API version mismatch for module %s:\n\
 | 
					
						
							| 
									
										
										
										
											1996-01-23 16:07:29 +00:00
										 |  |  |   This Python has API version %d, module %s has version %d.\n"; | 
					
						
							| 
									
										
										
										
											1995-01-09 17:47:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | object * | 
					
						
							| 
									
										
										
										
											1995-01-09 17:47:20 +00:00
										 |  |  | initmodule4(name, methods, doc, passthrough, module_api_version) | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 	char *name; | 
					
						
							|  |  |  | 	struct methodlist *methods; | 
					
						
							| 
									
										
										
										
											1995-01-07 12:43:18 +00:00
										 |  |  | 	char *doc; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	object *passthrough; | 
					
						
							| 
									
										
										
										
											1995-01-09 17:47:20 +00:00
										 |  |  | 	int module_api_version; | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	object *m, *d, *v; | 
					
						
							|  |  |  | 	struct methodlist *ml; | 
					
						
							| 
									
										
										
										
											1995-01-09 17:47:20 +00:00
										 |  |  | 	if (module_api_version != PYTHON_API_VERSION) | 
					
						
							|  |  |  | 		fprintf(stderr, api_version_warning, | 
					
						
							|  |  |  | 			name, PYTHON_API_VERSION, name, module_api_version); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	if ((m = add_module(name)) == NULL) { | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 		fprintf(stderr, "initializing module: %s\n", name); | 
					
						
							|  |  |  | 		fatal("can't create a module"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	d = getmoduledict(m); | 
					
						
							|  |  |  | 	for (ml = methods; ml->ml_name != NULL; ml++) { | 
					
						
							| 
									
										
										
										
											1995-01-07 12:43:18 +00:00
										 |  |  | 		v = newmethodobject(ml, passthrough); | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 		if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) { | 
					
						
							|  |  |  | 			fprintf(stderr, "initializing module: %s\n", name); | 
					
						
							|  |  |  | 			fatal("can't initialize module"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		DECREF(v); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1995-01-07 12:43:18 +00:00
										 |  |  | 	if (doc != NULL) { | 
					
						
							|  |  |  | 		v = newstringobject(doc); | 
					
						
							|  |  |  | 		if (v == NULL || dictinsert(d, "__doc__", v) != 0) | 
					
						
							|  |  |  | 			fatal("can't add doc string"); | 
					
						
							|  |  |  | 		DECREF(v); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	return m; | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-08 15:49:17 +00:00
										 |  |  | /* Helper for mkvalue() to scan the length of a format */ | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int countformat PROTO((char *format, int endchar)); | 
					
						
							|  |  |  | static int countformat(format, endchar) | 
					
						
							|  |  |  | 	char *format; | 
					
						
							|  |  |  | 	int endchar; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int count = 0; | 
					
						
							|  |  |  | 	int level = 0; | 
					
						
							|  |  |  | 	while (level > 0 || *format != endchar) { | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 		switch (*format) { | 
					
						
							|  |  |  | 		case '\0': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 			/* Premature end */ | 
					
						
							|  |  |  | 			err_setstr(SystemError, "unmatched paren in format"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 		case '(': | 
					
						
							|  |  |  | 		case '[': | 
					
						
							|  |  |  | 		case '{': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 			if (level == 0) | 
					
						
							|  |  |  | 				count++; | 
					
						
							|  |  |  | 			level++; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case ')': | 
					
						
							|  |  |  | 		case ']': | 
					
						
							|  |  |  | 		case '}': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 			level--; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case '#': | 
					
						
							| 
									
										
										
										
											1995-01-20 16:56:02 +00:00
										 |  |  | 		case '&': | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 		case ',': | 
					
						
							|  |  |  | 		case ':': | 
					
						
							|  |  |  | 		case ' ': | 
					
						
							|  |  |  | 		case '\t': | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			if (level == 0) | 
					
						
							|  |  |  | 				count++; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 		format++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Generic function to create a value -- the inverse of getargs() */ | 
					
						
							|  |  |  | /* After an original idea and first implementation by Steven Miale */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static object *do_mktuple PROTO((char**, va_list *, int, int)); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | static object *do_mklist PROTO((char**, va_list *, int, int)); | 
					
						
							|  |  |  | static object *do_mkdict PROTO((char**, va_list *, int, int)); | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | static object *do_mkvalue PROTO((char**, va_list *)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static object * | 
					
						
							|  |  |  | do_mkdict(p_format, p_va, endchar, n) | 
					
						
							|  |  |  | 	char **p_format; | 
					
						
							|  |  |  | 	va_list *p_va; | 
					
						
							|  |  |  | 	int endchar; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *d; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	if (n < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if ((d = newdictobject()) == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	for (i = 0; i < n; i+= 2) { | 
					
						
							|  |  |  | 		object *k, *v; | 
					
						
							|  |  |  | 		k = do_mkvalue(p_format, p_va); | 
					
						
							|  |  |  | 		if (k == NULL) { | 
					
						
							|  |  |  | 			DECREF(d); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		v = do_mkvalue(p_format, p_va); | 
					
						
							|  |  |  | 		if (v == NULL) { | 
					
						
							|  |  |  | 			DECREF(k); | 
					
						
							|  |  |  | 			DECREF(d); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (dict2insert(d, k, v) < 0) { | 
					
						
							|  |  |  | 			DECREF(k); | 
					
						
							|  |  |  | 			DECREF(v); | 
					
						
							|  |  |  | 			DECREF(d); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (d != NULL && **p_format != endchar) { | 
					
						
							|  |  |  | 		DECREF(d); | 
					
						
							|  |  |  | 		d = NULL; | 
					
						
							|  |  |  | 		err_setstr(SystemError, "Unmatched paren in format"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (endchar) | 
					
						
							|  |  |  | 		++*p_format; | 
					
						
							|  |  |  | 	return d; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static object * | 
					
						
							|  |  |  | do_mklist(p_format, p_va, endchar, n) | 
					
						
							|  |  |  | 	char **p_format; | 
					
						
							|  |  |  | 	va_list *p_va; | 
					
						
							|  |  |  | 	int endchar; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *v; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	if (n < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if ((v = newlistobject(n)) == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 		object *w = do_mkvalue(p_format, p_va); | 
					
						
							|  |  |  | 		if (w == NULL) { | 
					
						
							|  |  |  | 			DECREF(v); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		setlistitem(v, i, w); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (v != NULL && **p_format != endchar) { | 
					
						
							|  |  |  | 		DECREF(v); | 
					
						
							|  |  |  | 		v = NULL; | 
					
						
							|  |  |  | 		err_setstr(SystemError, "Unmatched paren in format"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (endchar) | 
					
						
							|  |  |  | 		++*p_format; | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | static object * | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | do_mktuple(p_format, p_va, endchar, n) | 
					
						
							|  |  |  | 	char **p_format; | 
					
						
							|  |  |  | 	va_list *p_va; | 
					
						
							|  |  |  | 	int endchar; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 	object *v; | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 	if (n < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if ((v = newtupleobject(n)) == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 		object *w = do_mkvalue(p_format, p_va); | 
					
						
							|  |  |  | 		if (w == NULL) { | 
					
						
							|  |  |  | 			DECREF(v); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		settupleitem(v, i, w); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (v != NULL && **p_format != endchar) { | 
					
						
							|  |  |  | 		DECREF(v); | 
					
						
							|  |  |  | 		v = NULL; | 
					
						
							|  |  |  | 		err_setstr(SystemError, "Unmatched paren in format"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (endchar) | 
					
						
							|  |  |  | 		++*p_format; | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static object * | 
					
						
							| 
									
										
										
										
											1992-05-15 11:04:59 +00:00
										 |  |  | do_mkvalue(p_format, p_va) | 
					
						
							|  |  |  | 	char **p_format; | 
					
						
							|  |  |  | 	va_list *p_va; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		switch (*(*p_format)++) { | 
					
						
							|  |  |  | 		case '(': | 
					
						
							|  |  |  | 			return do_mktuple(p_format, p_va, ')', | 
					
						
							|  |  |  | 					  countformat(*p_format, ')')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case '[': | 
					
						
							|  |  |  | 			return do_mklist(p_format, p_va, ']', | 
					
						
							|  |  |  | 					 countformat(*p_format, ']')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case '{': | 
					
						
							|  |  |  | 			return do_mkdict(p_format, p_va, '}', | 
					
						
							|  |  |  | 					 countformat(*p_format, '}')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'b': | 
					
						
							|  |  |  | 		case 'h': | 
					
						
							|  |  |  | 		case 'i': | 
					
						
							|  |  |  | 			return newintobject((long)va_arg(*p_va, int)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'l': | 
					
						
							|  |  |  | 			return newintobject((long)va_arg(*p_va, long)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'f': | 
					
						
							|  |  |  | 		case 'd': | 
					
						
							| 
									
										
										
										
											1995-01-20 16:56:02 +00:00
										 |  |  | 			return newfloatobject((double)va_arg(*p_va, va_double)); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case 'c': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			char p[1]; | 
					
						
							|  |  |  | 			p[0] = va_arg(*p_va, int); | 
					
						
							|  |  |  | 			return newsizedstringobject(p, 1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case 's': | 
					
						
							|  |  |  | 		case 'z': | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 			object *v; | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 			char *str = va_arg(*p_va, char *); | 
					
						
							|  |  |  | 			int n; | 
					
						
							|  |  |  | 			if (**p_format == '#') { | 
					
						
							|  |  |  | 				++*p_format; | 
					
						
							|  |  |  | 				n = va_arg(*p_va, int); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				n = -1; | 
					
						
							|  |  |  | 			if (str == NULL) { | 
					
						
							|  |  |  | 				v = None; | 
					
						
							|  |  |  | 				INCREF(v); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				if (n < 0) | 
					
						
							|  |  |  | 					n = strlen(str); | 
					
						
							|  |  |  | 				v = newsizedstringobject(str, n); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 			return v; | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case 'S': | 
					
						
							|  |  |  | 		case 'O': | 
					
						
							| 
									
										
										
										
											1995-01-20 16:56:02 +00:00
										 |  |  | 		if (**p_format == '&') { | 
					
						
							| 
									
										
										
										
											1995-03-09 12:10:50 +00:00
										 |  |  | 			typedef object *(*converter) PROTO((void *)); | 
					
						
							| 
									
										
										
										
											1995-01-20 16:56:02 +00:00
										 |  |  | 			converter func = va_arg(*p_va, converter); | 
					
						
							|  |  |  | 			void *arg = va_arg(*p_va, void *); | 
					
						
							|  |  |  | 			++*p_format; | 
					
						
							|  |  |  | 			return (*func)(arg); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 			object *v; | 
					
						
							|  |  |  | 			v = va_arg(*p_va, object *); | 
					
						
							|  |  |  | 			if (v != NULL) | 
					
						
							|  |  |  | 				INCREF(v); | 
					
						
							|  |  |  | 			else if (!err_occurred()) | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 				/* If a NULL was passed
 | 
					
						
							|  |  |  | 				 * because a call that should | 
					
						
							|  |  |  | 				 * have constructed a value | 
					
						
							|  |  |  | 				 * failed, that's OK, and we | 
					
						
							|  |  |  | 				 * pass the error on; but if | 
					
						
							|  |  |  | 				 * no error occurred it's not | 
					
						
							|  |  |  | 				 * clear that the caller knew | 
					
						
							|  |  |  | 				 * what she was doing. */ | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 				err_setstr(SystemError, | 
					
						
							|  |  |  | 					   "NULL object passed to mkvalue"); | 
					
						
							|  |  |  | 			return v; | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case ':': | 
					
						
							|  |  |  | 		case ',': | 
					
						
							|  |  |  | 		case ' ': | 
					
						
							|  |  |  | 		case '\t': | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			err_setstr(SystemError, | 
					
						
							|  |  |  | 				   "bad format char passed to mkvalue"); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-30 08:27:36 +00:00
										 |  |  | #ifdef HAVE_STDARG_PROTOTYPES
 | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | /* VARARGS 2 */ | 
					
						
							|  |  |  | object *mkvalue(char *format, ...) | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | /* VARARGS */ | 
					
						
							|  |  |  | object *mkvalue(va_alist) va_dcl | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 	va_list va; | 
					
						
							|  |  |  | 	object* retval; | 
					
						
							| 
									
										
										
										
											1994-08-30 08:27:36 +00:00
										 |  |  | #ifdef HAVE_STDARG_PROTOTYPES
 | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 	va_start(va, format); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	char *format; | 
					
						
							|  |  |  | 	va_start(va); | 
					
						
							|  |  |  | 	format = va_arg(va, char *); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1993-03-16 12:15:04 +00:00
										 |  |  | 	retval = vmkvalue(format, va); | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 	va_end(va); | 
					
						
							|  |  |  | 	return retval; | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											1993-03-16 12:15:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | object * | 
					
						
							|  |  |  | vmkvalue(format, va) | 
					
						
							|  |  |  | 	char *format; | 
					
						
							|  |  |  | 	va_list va; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *f = format; | 
					
						
							|  |  |  | 	int n = countformat(f, '\0'); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	va_list lva; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef VA_LIST_IS_ARRAY
 | 
					
						
							|  |  |  | 	memcpy(lva, va, sizeof(va_list)); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	lva = va; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-03-16 12:15:04 +00:00
										 |  |  | 	if (n < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if (n == 0) { | 
					
						
							|  |  |  | 		INCREF(None); | 
					
						
							|  |  |  | 		return None; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (n == 1) | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 		return do_mkvalue(&f, &lva); | 
					
						
							|  |  |  | 	return do_mktuple(&f, &lva, '\0', n); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_STDARG_PROTOTYPES
 | 
					
						
							|  |  |  | object * | 
					
						
							|  |  |  | PyEval_CallFunction(object *obj, char *format, ...) | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | object * | 
					
						
							|  |  |  | PyEval_CallFunction(obj, format, va_alist) | 
					
						
							|  |  |  | 	object *obj; | 
					
						
							|  |  |  | 	char *format; | 
					
						
							|  |  |  | 	va_dcl | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	va_list vargs; | 
					
						
							|  |  |  | 	object *args; | 
					
						
							|  |  |  | 	object *res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_STDARG_PROTOTYPES
 | 
					
						
							|  |  |  | 	va_start(vargs, format); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	va_start(vargs); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	args = vmkvalue(format, vargs); | 
					
						
							|  |  |  | 	va_end(vargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (args == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	res = call_object(obj, args); | 
					
						
							|  |  |  | 	DECREF(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_STDARG_PROTOTYPES
 | 
					
						
							|  |  |  | object * | 
					
						
							| 
									
										
										
										
											1995-01-17 16:31:01 +00:00
										 |  |  | PyEval_CallMethod(object *obj, char *methonname, char *format, ...) | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | object * | 
					
						
							| 
									
										
										
										
											1995-01-17 16:31:01 +00:00
										 |  |  | PyEval_CallMethod(obj, methonname, format, va_alist) | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	object *obj; | 
					
						
							| 
									
										
										
										
											1995-01-17 16:31:01 +00:00
										 |  |  | 	char *methonname; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	char *format; | 
					
						
							|  |  |  | 	va_dcl | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	va_list vargs; | 
					
						
							|  |  |  | 	object *meth; | 
					
						
							|  |  |  | 	object *args; | 
					
						
							|  |  |  | 	object *res; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-17 16:31:01 +00:00
										 |  |  | 	meth = getattr(obj, methonname); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	if (meth == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_STDARG_PROTOTYPES
 | 
					
						
							|  |  |  | 	va_start(vargs, format); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	va_start(vargs); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	args = vmkvalue(format, vargs); | 
					
						
							|  |  |  | 	va_end(vargs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (args == NULL) { | 
					
						
							|  |  |  | 		DECREF(meth); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	res = call_object(meth, args); | 
					
						
							|  |  |  | 	DECREF(meth); | 
					
						
							|  |  |  | 	DECREF(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											1993-03-16 12:15:04 +00:00
										 |  |  | } |