| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | /***********************************************************
 | 
					
						
							| 
									
										
										
										
											1993-01-26 13:33:44 +00:00
										 |  |  | Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, | 
					
						
							|  |  |  | Amsterdam, The Netherlands. | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         All Rights Reserved | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Permission to use, copy, modify, and distribute this software and its  | 
					
						
							|  |  |  | documentation for any purpose and without fee is hereby granted,  | 
					
						
							|  |  |  | provided that the above copyright notice appear in all copies and that | 
					
						
							|  |  |  | both that copyright notice and this permission notice appear in  | 
					
						
							|  |  |  | supporting documentation, and that the names of Stichting Mathematisch | 
					
						
							|  |  |  | Centrum or CWI not be used in advertising or publicity pertaining to | 
					
						
							|  |  |  | distribution of the software without specific, written prior permission. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO | 
					
						
							|  |  |  | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | 
					
						
							|  |  |  | FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM 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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ******************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 "modsupport.h"
 | 
					
						
							|  |  |  | #include "import.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | object * | 
					
						
							|  |  |  | initmodule(name, methods) | 
					
						
							|  |  |  | 	char *name; | 
					
						
							|  |  |  | 	struct methodlist *methods; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *m, *d, *v; | 
					
						
							|  |  |  | 	struct methodlist *ml; | 
					
						
							| 
									
										
										
										
											1993-01-04 09:09:59 +00:00
										 |  |  | 	char *namebuf; | 
					
						
							| 
									
										
										
										
											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++) { | 
					
						
							| 
									
										
										
										
											1993-01-04 09:09:59 +00:00
										 |  |  | 		namebuf = NEW(char, strlen(name) + strlen(ml->ml_name) + 2); | 
					
						
							|  |  |  | 		if (namebuf == NULL) | 
					
						
							|  |  |  | 			fatal("out of mem for method name"); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 		sprintf(namebuf, "%s.%s", name, ml->ml_name); | 
					
						
							| 
									
										
										
										
											1993-01-04 09:09:59 +00:00
										 |  |  | 		v = newmethodobject(namebuf, ml->ml_meth, | 
					
						
							| 
									
										
										
										
											1991-12-16 13:07:24 +00:00
										 |  |  | 					(object *)NULL, ml->ml_varargs); | 
					
						
							| 
									
										
										
										
											1993-01-04 09:09:59 +00:00
										 |  |  | 		/* XXX The malloc'ed memory in namebuf is never freed */ | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							|  |  |  | 		if (*format == '\0') { | 
					
						
							|  |  |  | 			/* Premature end */ | 
					
						
							|  |  |  | 			err_setstr(SystemError, "unmatched paren in format"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (*format == '(') { | 
					
						
							|  |  |  | 			if (level == 0) | 
					
						
							|  |  |  | 				count++; | 
					
						
							|  |  |  | 			level++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (*format == ')') | 
					
						
							|  |  |  | 			level--; | 
					
						
							|  |  |  | 		else if (level == 0 && *format != '#') | 
					
						
							|  |  |  | 			count++; | 
					
						
							|  |  |  | 		format++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | /* Generic argument list parser */ | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | static int do_arg PROTO((object *arg, char** p_format, va_list *p_va)); | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | do_arg(arg, p_format, p_va) | 
					
						
							|  |  |  | 	object *arg; | 
					
						
							|  |  |  | 	char** p_format; | 
					
						
							|  |  |  | 	va_list *p_va; | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	char *format = *p_format; | 
					
						
							|  |  |  | 	va_list va = *p_va; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (arg == NULL) | 
					
						
							|  |  |  | 		return 0; /* Incomplete tuple or list */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	switch (*format++) { | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1992-08-27 07:45:12 +00:00
										 |  |  | 	case '(': /* tuple, distributed over C parameters */ { | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 		int i, n; | 
					
						
							|  |  |  | 		if (!is_tupleobject(arg)) | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		n = gettuplesize(arg); | 
					
						
							|  |  |  | 		for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 			if (!do_arg(gettupleitem(arg, i), &format, &va)) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-08-27 07:45:12 +00:00
										 |  |  | 		if (*format++ != ')') | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-27 07:45:12 +00:00
										 |  |  | 	case ')': /* End of format -- too many arguments */ | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 	case 'b': /* byte -- very short int */ { | 
					
						
							|  |  |  | 		char *p = va_arg(va, char *); | 
					
						
							|  |  |  | 		if (is_intobject(arg)) | 
					
						
							|  |  |  | 			*p = getintvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	case 'h': /* short int */ { | 
					
						
							|  |  |  | 		short *p = va_arg(va, short *); | 
					
						
							|  |  |  | 		if (is_intobject(arg)) | 
					
						
							|  |  |  | 			*p = getintvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'i': /* int */ { | 
					
						
							|  |  |  | 		int *p = va_arg(va, int *); | 
					
						
							|  |  |  | 		if (is_intobject(arg)) | 
					
						
							|  |  |  | 			*p = getintvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'l': /* long int */ { | 
					
						
							|  |  |  | 		long *p = va_arg(va, long *); | 
					
						
							|  |  |  | 		if (is_intobject(arg)) | 
					
						
							|  |  |  | 			*p = getintvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'f': /* float */ { | 
					
						
							|  |  |  | 		float *p = va_arg(va, float *); | 
					
						
							|  |  |  | 		if (is_floatobject(arg)) | 
					
						
							|  |  |  | 			*p = getfloatvalue(arg); | 
					
						
							|  |  |  | 		else if (is_intobject(arg)) | 
					
						
							|  |  |  | 			*p = (float)getintvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'd': /* double */ { | 
					
						
							|  |  |  | 		double *p = va_arg(va, double *); | 
					
						
							|  |  |  | 		if (is_floatobject(arg)) | 
					
						
							|  |  |  | 			*p = getfloatvalue(arg); | 
					
						
							|  |  |  | 		else if (is_intobject(arg)) | 
					
						
							|  |  |  | 			*p = (double)getintvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'c': /* char */ { | 
					
						
							|  |  |  | 		char *p = va_arg(va, char *); | 
					
						
							|  |  |  | 		if (is_stringobject(arg) && getstringsize(arg) == 1) | 
					
						
							|  |  |  | 			*p = getstringvalue(arg)[0]; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 's': /* string */ { | 
					
						
							|  |  |  | 		char **p = va_arg(va, char **); | 
					
						
							|  |  |  | 		if (is_stringobject(arg)) | 
					
						
							|  |  |  | 			*p = getstringvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		if (*format == '#') { | 
					
						
							|  |  |  | 			int *q = va_arg(va, int *); | 
					
						
							|  |  |  | 			*q = getstringsize(arg); | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-08-14 15:12:03 +00:00
										 |  |  | 		else if (strlen(*p) != getstringsize(arg)) { | 
					
						
							|  |  |  | 			err_setstr(ValueError, "embedded '\\0' in string arg"); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'z': /* string, may be NULL (None) */ { | 
					
						
							|  |  |  | 		char **p = va_arg(va, char **); | 
					
						
							|  |  |  | 		if (arg == None) | 
					
						
							|  |  |  | 			*p = 0; | 
					
						
							|  |  |  | 		else if (is_stringobject(arg)) | 
					
						
							|  |  |  | 			*p = getstringvalue(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		if (*format == '#') { | 
					
						
							|  |  |  | 			int *q = va_arg(va, int *); | 
					
						
							|  |  |  | 			if (arg == None) | 
					
						
							|  |  |  | 				*q = 0; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				*q = getstringsize(arg); | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-08-14 15:12:03 +00:00
										 |  |  | 		else if (*p != NULL && strlen(*p) != getstringsize(arg)) { | 
					
						
							|  |  |  | 			err_setstr(ValueError, "embedded '\\0' in string arg"); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'S': /* string object */ { | 
					
						
							|  |  |  | 		object **p = va_arg(va, object **); | 
					
						
							|  |  |  | 		if (is_stringobject(arg)) | 
					
						
							|  |  |  | 			*p = arg; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'O': /* object */ { | 
					
						
							|  |  |  | 		object **p = va_arg(va, object **); | 
					
						
							|  |  |  | 		*p = arg; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		fprintf(stderr, "bad do_arg format: x%x '%c'\n", | 
					
						
							|  |  |  | 			format[-1], format[-1]); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	*p_va = va; | 
					
						
							|  |  |  | 	*p_format = format; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | #ifdef USE_STDARG
 | 
					
						
							| 
									
										
										
										
											1992-03-27 17:23:29 +00:00
										 |  |  | /* VARARGS2 */ | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | int getargs(object *arg, char *format, ...) | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											1992-03-27 17:23:29 +00:00
										 |  |  | /* VARARGS */ | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | int getargs(va_alist) va_dcl | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	char *f; | 
					
						
							|  |  |  | 	int ok; | 
					
						
							|  |  |  | 	va_list va; | 
					
						
							|  |  |  | #ifdef USE_STDARG
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	va_start(va, format); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	object *arg; | 
					
						
							|  |  |  | 	char *format; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	va_start(va); | 
					
						
							|  |  |  | 	arg = va_arg(va, object *); | 
					
						
							|  |  |  | 	format = va_arg(va, char *); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1993-02-08 15:49:17 +00:00
										 |  |  | 	if (*format == '\0' || *format == ';') { | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 		va_end(va); | 
					
						
							|  |  |  | 		if (arg != NULL) { | 
					
						
							| 
									
										
										
										
											1993-02-08 15:49:17 +00:00
										 |  |  | 			char *str = "no arguments needed"; | 
					
						
							|  |  |  | 			if (*format == ';') | 
					
						
							|  |  |  | 				str = format+1; | 
					
						
							|  |  |  | 			err_setstr(TypeError, str); | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	f = format; | 
					
						
							| 
									
										
										
										
											1993-02-08 15:49:17 +00:00
										 |  |  | 	ok = do_arg(arg, &f, &va) && (*f == '\0' || *f == ';'); | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	va_end(va); | 
					
						
							|  |  |  | 	if (!ok) { | 
					
						
							| 
									
										
										
										
											1992-08-14 15:12:03 +00:00
										 |  |  | 		if (!err_occurred()) { | 
					
						
							| 
									
										
										
										
											1993-02-08 15:49:17 +00:00
										 |  |  | 			char buf[256]; | 
					
						
							|  |  |  | 			char *str; | 
					
						
							|  |  |  | 			f = strchr(format, ';'); | 
					
						
							|  |  |  | 			if (f != NULL) | 
					
						
							|  |  |  | 				str = f+1; | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				sprintf(buf, "bad argument list (format '%s')", | 
					
						
							|  |  |  | 					format); | 
					
						
							|  |  |  | 				str = buf; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			err_setstr(TypeError, str); | 
					
						
							| 
									
										
										
										
											1992-08-14 15:12:03 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1992-01-27 16:47:03 +00:00
										 |  |  | 	return ok; | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-07-05 10:31:29 +00:00
										 |  |  | #ifdef UNUSED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-14 12:07:46 +00:00
										 |  |  | int | 
					
						
							|  |  |  | getlongtuplearg(args, a, n) | 
					
						
							|  |  |  | 	object *args; | 
					
						
							|  |  |  | 	long *a; /* [n] */ | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	if (!is_tupleobject(args) || gettuplesize(args) != n) { | 
					
						
							|  |  |  | 		return err_badarg(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 		object *v = gettupleitem(args, i); | 
					
						
							|  |  |  | 		if (!is_intobject(v)) { | 
					
						
							|  |  |  | 			return err_badarg(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		a[i] = getintvalue(v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | getshorttuplearg(args, a, n) | 
					
						
							|  |  |  | 	object *args; | 
					
						
							|  |  |  | 	short *a; /* [n] */ | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	if (!is_tupleobject(args) || gettuplesize(args) != n) { | 
					
						
							|  |  |  | 		return err_badarg(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 		object *v = gettupleitem(args, i); | 
					
						
							|  |  |  | 		if (!is_intobject(v)) { | 
					
						
							|  |  |  | 			return err_badarg(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		a[i] = getintvalue(v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | getlonglistarg(args, a, n) | 
					
						
							|  |  |  | 	object *args; | 
					
						
							|  |  |  | 	long *a; /* [n] */ | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	if (!is_listobject(args) || getlistsize(args) != n) { | 
					
						
							|  |  |  | 		return err_badarg(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 		object *v = getlistitem(args, i); | 
					
						
							|  |  |  | 		if (!is_intobject(v)) { | 
					
						
							|  |  |  | 			return err_badarg(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		a[i] = getintvalue(v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | getshortlistarg(args, a, n) | 
					
						
							|  |  |  | 	object *args; | 
					
						
							|  |  |  | 	short *a; /* [n] */ | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	if (!is_listobject(args) || getlistsize(args) != n) { | 
					
						
							|  |  |  | 		return err_badarg(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 		object *v = getlistitem(args, i); | 
					
						
							|  |  |  | 		if (!is_intobject(v)) { | 
					
						
							|  |  |  | 			return err_badarg(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		a[i] = getintvalue(v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-07-05 10:31:29 +00:00
										 |  |  | #endif /* UNUSED */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* 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)); | 
					
						
							|  |  |  | static object *do_mkvalue PROTO((char**, va_list *)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	switch (*(*p_format)++) { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case '(': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 		return do_mktuple(p_format, p_va, ')', | 
					
						
							|  |  |  | 				  countformat(*p_format, ')')); | 
					
						
							| 
									
										
										
										
											1993-03-16 12:15:04 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 	case 'b': | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 	case 'h': | 
					
						
							|  |  |  | 	case 'i': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 		return newintobject((long)va_arg(*p_va, int)); | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	case 'l': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 		return newintobject((long)va_arg(*p_va, long)); | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	case 'f': | 
					
						
							|  |  |  | 	case 'd': | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 		return newfloatobject((double)va_arg(*p_va, double)); | 
					
						
							| 
									
										
										
										
											1993-03-16 12:15:04 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 	case 'c': | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			char p[1]; | 
					
						
							|  |  |  | 			p[0] = va_arg(*p_va, int); | 
					
						
							|  |  |  | 			return newsizedstringobject(p, 1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	case 's': | 
					
						
							|  |  |  | 	case 'z': | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'S': | 
					
						
							|  |  |  | 	case 'O': | 
					
						
							| 
									
										
										
										
											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()) | 
					
						
							|  |  |  | 				/* 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. */ | 
					
						
							|  |  |  | 				err_setstr(SystemError, | 
					
						
							|  |  |  | 					   "NULL object passed to mkvalue"); | 
					
						
							|  |  |  | 			return v; | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		err_setstr(SystemError, "bad format char passed to mkvalue"); | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1992-04-13 10:48:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-04-13 15:53:41 +00:00
										 |  |  | #ifdef USE_STDARG
 | 
					
						
							|  |  |  | /* 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; | 
					
						
							|  |  |  | #ifdef USE_STDARG
 | 
					
						
							|  |  |  | 	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'); | 
					
						
							|  |  |  | 	if (n < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if (n == 0) { | 
					
						
							|  |  |  | 		INCREF(None); | 
					
						
							|  |  |  | 		return None; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (n == 1) | 
					
						
							|  |  |  | 		return do_mkvalue(&f, &va); | 
					
						
							|  |  |  | 	return do_mktuple(&f, &va, '\0', n); | 
					
						
							|  |  |  | } |