| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* New getargs implementation */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* XXX There are several unchecked sprintf or strcat calls in this file.
 | 
					
						
							|  |  |  |    XXX The only way these can become a danger is if some C code in the | 
					
						
							|  |  |  |    XXX Python source (or in an extension) uses ridiculously long names | 
					
						
							| 
									
										
										
										
											2000-07-16 12:04:32 +00:00
										 |  |  |    XXX or ridiculously deep nesting in format strings. */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-21 23:38:24 +00:00
										 |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | int PyArg_Parse(PyObject *, char *, ...); | 
					
						
							|  |  |  | int PyArg_ParseTuple(PyObject *, char *, ...); | 
					
						
							|  |  |  | int PyArg_VaParse(PyObject *, char *, va_list); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, | 
					
						
							|  |  |  | 				char *, char **, ...); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Forward */ | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | static int vgetargs1(PyObject *, char *, va_list *, int); | 
					
						
							|  |  |  | static void seterror(int, char *, int *, char *, char *); | 
					
						
							|  |  |  | static char *convertitem(PyObject *, char **, va_list *, int *, char *); | 
					
						
							|  |  |  | static char *converttuple(PyObject *, char **, va_list *, | 
					
						
							|  |  |  | 			  int *, char *, int); | 
					
						
							|  |  |  | static char *convertsimple(PyObject *, char **, va_list *, char *); | 
					
						
							|  |  |  | static char *convertsimple1(PyObject *, char **, va_list *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int vgetargskeywords(PyObject *, PyObject *, | 
					
						
							|  |  |  | 			    char *, char **, va_list *); | 
					
						
							|  |  |  | static char *skipitem(char **, va_list *); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | int PyArg_Parse(PyObject *args, char *format, ...) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int retval; | 
					
						
							|  |  |  | 	va_list va; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	va_start(va, format); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	retval = vgetargs1(args, format, &va, 1); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	va_end(va); | 
					
						
							|  |  |  | 	return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | int PyArg_ParseTuple(PyObject *args, char *format, ...) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int retval; | 
					
						
							|  |  |  | 	va_list va; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	va_start(va, format); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	retval = vgetargs1(args, format, &va, 0); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	va_end(va); | 
					
						
							|  |  |  | 	return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | PyArg_VaParse(PyObject *args, char *format, va_list va) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return vgetargs1(args, format, &lva, 0); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | vgetargs1(PyObject *args, char *format, va_list *p_va, int compat) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char msgbuf[256]; | 
					
						
							|  |  |  | 	int levels[32]; | 
					
						
							|  |  |  | 	char *fname = NULL; | 
					
						
							|  |  |  | 	char *message = NULL; | 
					
						
							|  |  |  | 	int min = -1; | 
					
						
							|  |  |  | 	int max = 0; | 
					
						
							|  |  |  | 	int level = 0; | 
					
						
							|  |  |  | 	char *formatsave = format; | 
					
						
							|  |  |  | 	int i, len; | 
					
						
							|  |  |  | 	char *msg; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-02-12 22:13:26 +00:00
										 |  |  | 	assert(compat || (args != (PyObject*)NULL)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		int c = *format++; | 
					
						
							|  |  |  | 		if (c == '(' /* ')' */) { | 
					
						
							|  |  |  | 			if (level == 0) | 
					
						
							|  |  |  | 				max++; | 
					
						
							|  |  |  | 			level++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (/* '(' */ c == ')') { | 
					
						
							|  |  |  | 			if (level == 0) | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 				Py_FatalError(/* '(' */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				      "excess ')' in getargs format"); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				level--; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c == '\0') | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		else if (c == ':') { | 
					
						
							|  |  |  | 			fname = format; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c == ';') { | 
					
						
							|  |  |  | 			message = format; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (level != 0) | 
					
						
							|  |  |  | 			; /* Pass */ | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 		else if (c == 'e') | 
					
						
							|  |  |  | 			; /* Pass */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		else if (isalpha(c)) | 
					
						
							|  |  |  | 			max++; | 
					
						
							|  |  |  | 		else if (c == '|') | 
					
						
							|  |  |  | 			min = max; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (level != 0) | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 		Py_FatalError(/* '(' */ "missing ')' in getargs format"); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (min < 0) | 
					
						
							|  |  |  | 		min = max; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	format = formatsave; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (compat) { | 
					
						
							|  |  |  | 		if (max == 0) { | 
					
						
							|  |  |  | 			if (args == NULL) | 
					
						
							|  |  |  | 				return 1; | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 			sprintf(msgbuf, "%s%s takes no arguments", | 
					
						
							|  |  |  | 				fname==NULL ? "function" : fname, | 
					
						
							|  |  |  | 				fname==NULL ? "" : "()"); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			PyErr_SetString(PyExc_TypeError, msgbuf); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (min == 1 && max == 1) { | 
					
						
							| 
									
										
										
										
											1994-11-10 22:35:48 +00:00
										 |  |  | 			if (args == NULL) { | 
					
						
							|  |  |  | 				sprintf(msgbuf, | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 					"%s%s takes at least one argument", | 
					
						
							|  |  |  | 					fname==NULL ? "function" : fname, | 
					
						
							|  |  |  | 					fname==NULL ? "" : "()"); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 				PyErr_SetString(PyExc_TypeError, msgbuf); | 
					
						
							| 
									
										
										
										
											1994-11-10 22:35:48 +00:00
										 |  |  | 				return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 			msg = convertitem(args, &format, p_va, levels, msgbuf); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			if (msg == NULL) | 
					
						
							|  |  |  | 				return 1; | 
					
						
							|  |  |  | 			seterror(levels[0], msg, levels+1, fname, message); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			PyErr_SetString(PyExc_SystemError, | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			    "old style getargs format uses new features"); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 	if (!PyTuple_Check(args)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_SystemError, | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		    "new style getargs format but argument is not a tuple"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 	len = PyTuple_Size(args); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (len < min || max < len) { | 
					
						
							|  |  |  | 		if (message == NULL) { | 
					
						
							|  |  |  | 			sprintf(msgbuf, | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 				"%s%s takes %s %d argument%s (%d given)", | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				fname==NULL ? "function" : fname, | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 				fname==NULL ? "" : "()", | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				min==max ? "exactly" | 
					
						
							|  |  |  | 				         : len < min ? "at least" : "at most", | 
					
						
							|  |  |  | 				len < min ? min : max, | 
					
						
							|  |  |  | 				(len < min ? min : max) == 1 ? "" : "s", | 
					
						
							|  |  |  | 				len); | 
					
						
							|  |  |  | 			message = msgbuf; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 		PyErr_SetString(PyExc_TypeError, message); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (i = 0; i < len; i++) { | 
					
						
							|  |  |  | 		if (*format == '|') | 
					
						
							|  |  |  | 			format++; | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 		msg = convertitem(PyTuple_GetItem(args, i), &format, p_va, | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				 levels, msgbuf); | 
					
						
							|  |  |  | 		if (msg) { | 
					
						
							|  |  |  | 			seterror(i+1, msg, levels, fname, message); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-12-09 20:36:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-10 22:27:42 +00:00
										 |  |  | 	if (*format != '\0' && !isalpha((int)(*format)) && | 
					
						
							| 
									
										
										
										
											1997-12-19 04:25:23 +00:00
										 |  |  | 	    *format != '(' && | 
					
						
							| 
									
										
										
										
											1997-12-09 20:36:39 +00:00
										 |  |  | 	    *format != '|' && *format != ':' && *format != ';') { | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_SystemError, | 
					
						
							| 
									
										
										
										
											1998-01-19 22:22:44 +00:00
										 |  |  | 			     "bad format string: %.200s", formatsave); | 
					
						
							| 
									
										
										
										
											1997-12-09 20:36:39 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | seterror(int iarg, char *msg, int *levels, char *fname, char *message) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char buf[256]; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	char *p = buf; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 	if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1995-01-21 14:09:37 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	else if (message == NULL) { | 
					
						
							|  |  |  | 		if (fname != NULL) { | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 			sprintf(p, "%s() ", fname); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			p += strlen(p); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 		if (iarg != 0) { | 
					
						
							|  |  |  | 			sprintf(p, "argument %d", iarg); | 
					
						
							|  |  |  | 			i = 0; | 
					
						
							|  |  |  | 			p += strlen(p); | 
					
						
							|  |  |  | 			while (levels[i] > 0) { | 
					
						
							|  |  |  | 				sprintf(p, ", item %d", levels[i]-1); | 
					
						
							|  |  |  | 				p += strlen(p); | 
					
						
							|  |  |  | 				i++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			sprintf(p, "argument"); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			p += strlen(p); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 		sprintf(p, " %s", msg); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		message = buf; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 	PyErr_SetString(PyExc_TypeError, message); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Convert a tuple argument.
 | 
					
						
							|  |  |  |    On entry, *p_format points to the character _after_ the opening '('. | 
					
						
							|  |  |  |    On successful exit, *p_format points to the closing ')'. | 
					
						
							|  |  |  |    If successful: | 
					
						
							|  |  |  |       *p_format and *p_va are updated, | 
					
						
							|  |  |  |       *levels and *msgbuf are untouched, | 
					
						
							|  |  |  |       and NULL is returned. | 
					
						
							|  |  |  |    If the argument is invalid: | 
					
						
							|  |  |  |       *p_format is unchanged, | 
					
						
							|  |  |  |       *p_va is undefined, | 
					
						
							|  |  |  |       *levels is a 0-terminated list of item numbers, | 
					
						
							|  |  |  |       *msgbuf contains an error message, whose format is: | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  |          "must be <typename1>, not <typename2>", where: | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  |             <typename1> is the name of the expected type, and | 
					
						
							|  |  |  |             <typename2> is the name of the actual type, | 
					
						
							|  |  |  |       and msgbuf is returned. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels, | 
					
						
							|  |  |  | 	     char *msgbuf, int toplevel) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int level = 0; | 
					
						
							|  |  |  | 	int n = 0; | 
					
						
							|  |  |  | 	char *format = *p_format; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		int c = *format++; | 
					
						
							|  |  |  | 		if (c == '(') { | 
					
						
							|  |  |  | 			if (level == 0) | 
					
						
							|  |  |  | 				n++; | 
					
						
							|  |  |  | 			level++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c == ')') { | 
					
						
							|  |  |  | 			if (level == 0) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			level--; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c == ':' || c == ';' || c == '\0') | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		else if (level == 0 && isalpha(c)) | 
					
						
							|  |  |  | 			n++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 	if (!PySequence_Check(arg) || PyString_Check(arg)) { | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		levels[0] = 0; | 
					
						
							|  |  |  | 		sprintf(msgbuf, | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 			toplevel ? "expected %d arguments, not %s" : | 
					
						
							|  |  |  | 				   "must be %d-item sequence, not %s", | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			n, arg == Py_None ? "None" : arg->ob_type->tp_name); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		return msgbuf; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-07-12 13:05:33 +00:00
										 |  |  | 	if ((i = PySequence_Size(arg)) != n) { | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		levels[0] = 0; | 
					
						
							|  |  |  | 		sprintf(msgbuf, | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 			toplevel ? "expected %d arguments, not %d" : | 
					
						
							|  |  |  | 				   "must be sequence of length %d, not %d", | 
					
						
							|  |  |  | 			n, i); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		return msgbuf; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	format = *p_format; | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 		char *msg; | 
					
						
							| 
									
										
										
										
											1999-02-17 23:16:43 +00:00
										 |  |  | 		PyObject *item; | 
					
						
							|  |  |  | 		item = PySequence_GetItem(arg, i); | 
					
						
							|  |  |  | 		msg = convertitem(item, &format, p_va, levels+1, msgbuf); | 
					
						
							|  |  |  | 		/* PySequence_GetItem calls tp->sq_item, which INCREFs */ | 
					
						
							|  |  |  | 		Py_XDECREF(item); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		if (msg != NULL) { | 
					
						
							|  |  |  | 			levels[0] = i+1; | 
					
						
							|  |  |  | 			return msg; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	*p_format = format; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Convert a single item. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | convertitem(PyObject *arg, char **p_format, va_list *p_va, int *levels, | 
					
						
							|  |  |  | 	    char *msgbuf) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *msg; | 
					
						
							|  |  |  | 	char *format = *p_format; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (*format == '(' /* ')' */) { | 
					
						
							|  |  |  | 		format++; | 
					
						
							|  |  |  | 		msg = converttuple(arg, &format, p_va, levels, msgbuf, 0); | 
					
						
							|  |  |  | 		if (msg == NULL) | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		msg = convertsimple(arg, &format, p_va, msgbuf); | 
					
						
							|  |  |  | 		if (msg != NULL) | 
					
						
							|  |  |  | 			levels[0] = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (msg == NULL) | 
					
						
							|  |  |  | 		*p_format = format; | 
					
						
							|  |  |  | 	return msg; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Convert a non-tuple argument.  Adds to convertsimple1 functionality
 | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  |    by formatting messages as "must be <desired type>, not <actual type>". */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *msg = convertsimple1(arg, p_format, p_va); | 
					
						
							|  |  |  | 	if (msg != NULL) { | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 		sprintf(msgbuf, "must be %.50s, not %.50s", msg, | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			arg == Py_None ? "None" : arg->ob_type->tp_name); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		msg = msgbuf; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return msg; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-04-27 20:13:18 +00:00
										 |  |  | /* Internal API needed by convertsimple1(): */ | 
					
						
							|  |  |  | extern  | 
					
						
							| 
									
										
										
										
											2000-08-03 18:46:08 +00:00
										 |  |  | PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode, | 
					
						
							| 
									
										
										
										
											2000-04-27 20:13:18 +00:00
										 |  |  | 				  const char *errors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | /* Convert a non-tuple argument.  Return NULL if conversion went OK,
 | 
					
						
							|  |  |  |    or a string representing the expected type if the conversion failed. | 
					
						
							|  |  |  |    When failing, an exception may or may not have been raised. | 
					
						
							|  |  |  |    Don't call if a tuple is expected. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | convertsimple1(PyObject *arg, char **p_format, va_list *p_va) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *format = *p_format; | 
					
						
							|  |  |  | 	char c = *format++; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	switch (c) { | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-05-09 21:50:00 +00:00
										 |  |  | 	case 'b': /* unsigned byte -- very short int */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			char *p = va_arg(*p_va, char *); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			long ival = PyInt_AsLong(arg); | 
					
						
							|  |  |  | 			if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				return "integer<b>"; | 
					
						
							| 
									
										
										
										
											2000-05-09 21:50:00 +00:00
										 |  |  | 			else if (ival < 0) { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 			      "unsigned byte integer is less than minimum"); | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				return "integer<b>"; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2000-05-09 21:50:00 +00:00
										 |  |  | 			else if (ival > UCHAR_MAX) { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 			      "unsigned byte integer is greater than maximum"); | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				return "integer<b>"; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2000-05-09 21:50:00 +00:00
										 |  |  | 				*p = (unsigned char) ival; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 	case 'B': /* byte sized bitfield - both signed and unsigned values allowed */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			char *p = va_arg(*p_va, char *); | 
					
						
							|  |  |  | 			long ival = PyInt_AsLong(arg); | 
					
						
							|  |  |  | 			if (ival == -1 && PyErr_Occurred()) | 
					
						
							|  |  |  | 				return "integer<b>"; | 
					
						
							|  |  |  | 			else if (ival < SCHAR_MIN) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  | 			      "byte-sized integer bitfield is less than minimum"); | 
					
						
							|  |  |  | 				return "integer<B>"; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2000-09-15 12:52:19 +00:00
										 |  |  | 			else if (ival > (int)UCHAR_MAX) { | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  | 			      "byte-sized integer bitfield is greater than maximum"); | 
					
						
							|  |  |  | 				return "integer<B>"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				*p = (unsigned char) ival; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-05-09 21:50:00 +00:00
										 |  |  | 	case 'h': /* signed short int */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			short *p = va_arg(*p_va, short *); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			long ival = PyInt_AsLong(arg); | 
					
						
							|  |  |  | 			if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				return "integer<h>"; | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 			else if (ival < SHRT_MIN) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 			      "signed short integer is less than minimum"); | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				return "integer<h>"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else if (ival > SHRT_MAX) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 			      "signed short integer is greater than maximum"); | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				return "integer<h>"; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											1997-04-11 20:37:35 +00:00
										 |  |  | 				*p = (short) ival; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 	case 'H': /* short int sized bitfield, both signed and unsigned allowed */ | 
					
						
							| 
									
										
										
										
											2000-07-06 12:22:00 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			unsigned short *p = va_arg(*p_va, unsigned short *); | 
					
						
							|  |  |  | 			long ival = PyInt_AsLong(arg); | 
					
						
							|  |  |  | 			if (ival == -1 && PyErr_Occurred()) | 
					
						
							|  |  |  | 				return "integer<H>"; | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 			else if (ival < SHRT_MIN) { | 
					
						
							| 
									
										
										
										
											2000-07-06 12:22:00 +00:00
										 |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 			      "short integer bitfield is less than minimum"); | 
					
						
							| 
									
										
										
										
											2000-07-06 12:22:00 +00:00
										 |  |  | 				return "integer<H>"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else if (ival > USHRT_MAX) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 			      "short integer bitfield is greater than maximum"); | 
					
						
							| 
									
										
										
										
											2000-07-06 12:22:00 +00:00
										 |  |  | 				return "integer<H>"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				*p = (unsigned short) ival; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-05-09 21:50:00 +00:00
										 |  |  | 	case 'i': /* signed int */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			int *p = va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			long ival = PyInt_AsLong(arg); | 
					
						
							|  |  |  | 			if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				return "integer<i>"; | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 			else if (ival > INT_MAX) { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 				    "signed integer is greater than maximum"); | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				return "integer<i>"; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 			else if (ival < INT_MIN) { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2000-06-28 23:53:56 +00:00
										 |  |  | 				    "signed integer is less than minimum"); | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				return "integer<i>"; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				*p = ival; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	case 'l': /* long int */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			long *p = va_arg(*p_va, long *); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			long ival = PyInt_AsLong(arg); | 
					
						
							|  |  |  | 			if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				return "integer<l>"; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				*p = ival; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-01-25 21:48:56 +00:00
										 |  |  | #ifdef HAVE_LONG_LONG
 | 
					
						
							| 
									
										
										
										
											1998-08-25 16:07:15 +00:00
										 |  |  | 	case 'L': /* LONG_LONG */ | 
					
						
							| 
									
										
										
										
											1998-08-04 22:46:29 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1998-08-25 16:07:15 +00:00
										 |  |  | 			LONG_LONG *p = va_arg( *p_va, LONG_LONG * ); | 
					
						
							|  |  |  | 			LONG_LONG ival = PyLong_AsLongLong( arg ); | 
					
						
							|  |  |  | 			if( ival == (LONG_LONG)-1 && PyErr_Occurred() ) { | 
					
						
							| 
									
										
										
										
											1998-08-04 22:46:29 +00:00
										 |  |  | 				return "long<L>"; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				*p = ival; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	case 'f': /* float */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			float *p = va_arg(*p_va, float *); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			double dval = PyFloat_AsDouble(arg); | 
					
						
							|  |  |  | 			if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				return "float<f>"; | 
					
						
							|  |  |  | 			else | 
					
						
							| 
									
										
										
										
											1997-04-11 20:37:35 +00:00
										 |  |  | 				*p = (float) dval; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'd': /* double */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			double *p = va_arg(*p_va, double *); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			double dval = PyFloat_AsDouble(arg); | 
					
						
							|  |  |  | 			if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				return "float<d>"; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				*p = dval; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1996-07-21 02:27:43 +00:00
										 |  |  | #ifndef WITHOUT_COMPLEX
 | 
					
						
							| 
									
										
										
										
											1996-01-12 01:09:56 +00:00
										 |  |  | 	case 'D': /* complex double */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-07-21 02:27:43 +00:00
										 |  |  | 			Py_complex *p = va_arg(*p_va, Py_complex *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			Py_complex cval; | 
					
						
							|  |  |  | 			cval = PyComplex_AsCComplex(arg); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											1996-01-12 01:09:56 +00:00
										 |  |  | 				return "complex<D>"; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				*p = cval; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1996-07-21 02:27:43 +00:00
										 |  |  | #endif /* WITHOUT_COMPLEX */
 | 
					
						
							| 
									
										
										
										
											1996-01-12 01:09:56 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	case 'c': /* char */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			char *p = va_arg(*p_va, char *); | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			if (PyString_Check(arg) && PyString_Size(arg) == 1) | 
					
						
							|  |  |  | 				*p = PyString_AsString(arg)[0]; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				return "char"; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 's': /* string */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 			if (*format == '#') { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				void **p = (void **)va_arg(*p_va, char **); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				int *q = va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (PyString_Check(arg)) { | 
					
						
							|  |  |  | 				    *p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				    *q = PyString_GET_SIZE(arg); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (PyUnicode_Check(arg)) { | 
					
						
							|  |  |  | 				    arg = _PyUnicode_AsDefaultEncodedString( | 
					
						
							|  |  |  | 							            arg, NULL); | 
					
						
							|  |  |  | 				    if (arg == NULL) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "(unicode conversion error)"; | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 				    *p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				    *q = PyString_GET_SIZE(arg); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { /* any buffer-like object */ | 
					
						
							|  |  |  | 				    PyBufferProcs *pb = arg->ob_type->tp_as_buffer; | 
					
						
							|  |  |  | 				    int count; | 
					
						
							|  |  |  | 				    if ( pb == NULL || | 
					
						
							|  |  |  | 					 pb->bf_getreadbuffer == NULL || | 
					
						
							|  |  |  | 					 pb->bf_getsegcount == NULL ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "string or read-only buffer"; | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 				    if ( (*pb->bf_getsegcount)(arg, NULL) != 1 ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "string or single-segment read-only buffer"; | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 				    if ( (count = | 
					
						
							|  |  |  | 					  (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 ) | 
					
						
							|  |  |  | 					return "(unspecified)"; | 
					
						
							|  |  |  | 				    *q = count; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				format++; | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				char **p = va_arg(*p_va, char **); | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				if (PyString_Check(arg)) | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 				    *p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				else if (PyUnicode_Check(arg)) { | 
					
						
							| 
									
										
										
										
											2000-08-03 18:46:08 +00:00
										 |  |  | 				    arg = _PyUnicode_AsDefaultEncodedString( | 
					
						
							|  |  |  | 							            arg, NULL); | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 				    if (arg == NULL) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "(unicode conversion error)"; | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 				    *p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 				else | 
					
						
							|  |  |  | 				  return "string"; | 
					
						
							|  |  |  | 				if ((int)strlen(*p) != PyString_Size(arg)) | 
					
						
							|  |  |  | 				  return "string without null bytes"; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	case 'z': /* string, may be NULL (None) */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			if (*format == '#') { /* any buffer-like object */ | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				void **p = (void **)va_arg(*p_va, char **); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				int *q = va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (arg == Py_None) { | 
					
						
							|  |  |  | 				  *p = 0; | 
					
						
							|  |  |  | 				  *q = 0; | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else if (PyString_Check(arg)) { | 
					
						
							|  |  |  | 				    *p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				    *q = PyString_GET_SIZE(arg); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (PyUnicode_Check(arg)) { | 
					
						
							|  |  |  | 				    arg = _PyUnicode_AsDefaultEncodedString( | 
					
						
							|  |  |  | 							            arg, NULL); | 
					
						
							|  |  |  | 				    if (arg == NULL) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "(unicode conversion error)"; | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 				    *p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				    *q = PyString_GET_SIZE(arg); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { /* any buffer-like object */ | 
					
						
							|  |  |  | 				    PyBufferProcs *pb = arg->ob_type->tp_as_buffer; | 
					
						
							|  |  |  | 				    int count; | 
					
						
							|  |  |  | 				    if ( pb == NULL || | 
					
						
							|  |  |  | 					 pb->bf_getreadbuffer == NULL || | 
					
						
							|  |  |  | 					 pb->bf_getsegcount == NULL ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "string or read-only buffer"; | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 				    if ( (*pb->bf_getsegcount)(arg, NULL) != 1 ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "string or single-segment read-only buffer"; | 
					
						
							| 
									
										
										
										
											2000-09-21 21:08:30 +00:00
										 |  |  | 				    if ( (count = | 
					
						
							|  |  |  | 					  (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 ) | 
					
						
							|  |  |  | 					return "(unspecified)"; | 
					
						
							|  |  |  | 				    *q = count; | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				format++; | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				char **p = va_arg(*p_va, char **); | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				if (arg == Py_None) | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 				  *p = 0; | 
					
						
							|  |  |  | 				else if (PyString_Check(arg)) | 
					
						
							|  |  |  | 				  *p = PyString_AsString(arg); | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 				else if (PyUnicode_Check(arg)) { | 
					
						
							| 
									
										
										
										
											2000-08-03 18:46:08 +00:00
										 |  |  | 				  arg = _PyUnicode_AsDefaultEncodedString( | 
					
						
							|  |  |  | 								  arg, NULL); | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 				  if (arg == NULL) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				      return "(unicode conversion error)"; | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 				  *p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				  return "string or None"; | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 				if (*format == '#') { | 
					
						
							|  |  |  | 				  int *q = va_arg(*p_va, int *); | 
					
						
							|  |  |  | 				  if (arg == Py_None) | 
					
						
							|  |  |  | 				    *q = 0; | 
					
						
							|  |  |  | 				  else | 
					
						
							|  |  |  | 				    *q = PyString_Size(arg); | 
					
						
							|  |  |  | 				  format++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (*p != NULL && | 
					
						
							|  |  |  | 					 (int)strlen(*p) != PyString_Size(arg)) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				  return "string without null bytes or None"; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 	case 'e': /* encoded string */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			char **buffer; | 
					
						
							|  |  |  | 			const char *encoding; | 
					
						
							|  |  |  | 			PyObject *u, *s; | 
					
						
							|  |  |  | 			int size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Get 'e' parameter: the encoding name */ | 
					
						
							|  |  |  | 			encoding = (const char *)va_arg(*p_va, const char *); | 
					
						
							|  |  |  | 			if (encoding == NULL) | 
					
						
							| 
									
										
										
										
											2000-08-03 18:46:08 +00:00
										 |  |  | 			    	encoding = PyUnicode_GetDefaultEncoding(); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			/* Get 's' parameter: the output buffer to use */ | 
					
						
							|  |  |  | 			if (*format != 's') | 
					
						
							| 
									
										
										
										
											2000-03-28 02:00:29 +00:00
										 |  |  | 				return "(unknown parser marker combination)"; | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			buffer = (char **)va_arg(*p_va, char **); | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 			if (buffer == NULL) | 
					
						
							|  |  |  | 				return "(buffer is NULL)"; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/* Convert object to Unicode */ | 
					
						
							|  |  |  | 			u = PyUnicode_FromObject(arg); | 
					
						
							|  |  |  | 			if (u == NULL) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				return "string or unicode or text buffer"; | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			/* Encode object; use default error handling */ | 
					
						
							|  |  |  | 			s = PyUnicode_AsEncodedString(u, | 
					
						
							|  |  |  | 						      encoding, | 
					
						
							|  |  |  | 						      NULL); | 
					
						
							|  |  |  | 			Py_DECREF(u); | 
					
						
							|  |  |  | 			if (s == NULL) | 
					
						
							|  |  |  | 				return "(encoding failed)"; | 
					
						
							|  |  |  | 			if (!PyString_Check(s)) { | 
					
						
							|  |  |  | 				Py_DECREF(s); | 
					
						
							|  |  |  | 				return "(encoder failed to return a string)"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			size = PyString_GET_SIZE(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Write output; output is guaranteed to be
 | 
					
						
							|  |  |  | 			   0-terminated */ | 
					
						
							|  |  |  | 			if (*format == '#') {  | 
					
						
							|  |  |  | 				/* Using buffer length parameter '#':
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				   - if *buffer is NULL, a new buffer | 
					
						
							|  |  |  | 				   of the needed size is allocated and | 
					
						
							|  |  |  | 				   the data copied into it; *buffer is | 
					
						
							|  |  |  | 				   updated to point to the new buffer; | 
					
						
							|  |  |  | 				   the caller is responsible for | 
					
						
							| 
									
										
										
										
											2000-03-28 20:29:59 +00:00
										 |  |  | 				   PyMem_Free()ing it after usage | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				   - if *buffer is not NULL, the data | 
					
						
							|  |  |  | 				   is copied to *buffer; *buffer_len | 
					
						
							|  |  |  | 				   has to be set to the size of the | 
					
						
							|  |  |  | 				   buffer on input; buffer overflow is | 
					
						
							|  |  |  | 				   signalled with an error; buffer has | 
					
						
							|  |  |  | 				   to provide enough room for the | 
					
						
							|  |  |  | 				   encoded string plus the trailing | 
					
						
							|  |  |  | 				   0-byte | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				   - in both cases, *buffer_len is | 
					
						
							|  |  |  | 				   updated to the size of the buffer | 
					
						
							|  |  |  | 				   /excluding/ the trailing 0-byte | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				*/ | 
					
						
							|  |  |  | 				int *buffer_len = va_arg(*p_va, int *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				format++; | 
					
						
							|  |  |  | 				if (buffer_len == NULL) | 
					
						
							|  |  |  | 					return "(buffer_len is NULL)"; | 
					
						
							|  |  |  | 				if (*buffer == NULL) { | 
					
						
							|  |  |  | 					*buffer = PyMem_NEW(char, size + 1); | 
					
						
							|  |  |  | 					if (*buffer == NULL) { | 
					
						
							|  |  |  | 						Py_DECREF(s); | 
					
						
							|  |  |  | 						return "(memory error)"; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					if (size + 1 > *buffer_len) { | 
					
						
							|  |  |  | 						Py_DECREF(s); | 
					
						
							|  |  |  | 						return "(buffer overflow)"; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				memcpy(*buffer, | 
					
						
							|  |  |  | 				       PyString_AS_STRING(s), | 
					
						
							|  |  |  | 				       size + 1); | 
					
						
							|  |  |  | 				*buffer_len = size; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				/* Using a 0-terminated buffer:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				   - the encoded string has to be | 
					
						
							|  |  |  | 				   0-terminated for this variant to | 
					
						
							|  |  |  | 				   work; if it is not, an error raised | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				   - a new buffer of the needed size | 
					
						
							|  |  |  | 				   is allocated and the data copied | 
					
						
							|  |  |  | 				   into it; *buffer is updated to | 
					
						
							|  |  |  | 				   point to the new buffer; the caller | 
					
						
							| 
									
										
										
										
											2000-03-28 20:29:59 +00:00
										 |  |  | 				   is responsible for PyMem_Free()ing it | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 				   after usage | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				 */ | 
					
						
							| 
									
										
										
										
											2000-03-28 02:00:29 +00:00
										 |  |  | 				if ((int)strlen(PyString_AS_STRING(s)) != size) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 					return "(encoded string without NULL bytes)"; | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 				*buffer = PyMem_NEW(char, size + 1); | 
					
						
							|  |  |  | 				if (*buffer == NULL) { | 
					
						
							|  |  |  | 					Py_DECREF(s); | 
					
						
							|  |  |  | 					return "(memory error)"; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				memcpy(*buffer, | 
					
						
							|  |  |  | 				       PyString_AS_STRING(s), | 
					
						
							|  |  |  | 				       size + 1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			Py_DECREF(s); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 	case 'u': /* raw unicode buffer (Py_UNICODE *) */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (*format == '#') { /* any buffer-like object */ | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				void **p = (void **)va_arg(*p_va, char **); | 
					
						
							|  |  |  | 				PyBufferProcs *pb = arg->ob_type->tp_as_buffer; | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 				int *q = va_arg(*p_va, int *); | 
					
						
							|  |  |  | 				int count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ( pb == NULL || | 
					
						
							|  |  |  | 				     pb->bf_getreadbuffer == NULL || | 
					
						
							|  |  |  | 				     pb->bf_getsegcount == NULL ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				  return "unicode or read-only buffer"; | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 				if ( (*pb->bf_getsegcount)(arg, NULL) != 1 ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				  return "unicode or single-segment read-only buffer"; | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 				if ( (count = | 
					
						
							|  |  |  | 				      (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 ) | 
					
						
							|  |  |  | 				  return "(unspecified)"; | 
					
						
							|  |  |  | 				/* buffer interface returns bytes, we want
 | 
					
						
							|  |  |  | 				   length in characters */ | 
					
						
							|  |  |  | 				*q = count/(sizeof(Py_UNICODE));  | 
					
						
							|  |  |  | 				format++; | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				if (PyUnicode_Check(arg)) | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 				    *p = PyUnicode_AS_UNICODE(arg); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				  return "unicode"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	case 'S': /* string object */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			PyObject **p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 			if (PyString_Check(arg)) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				*p = arg; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				return "string"; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 	case 'U': /* Unicode object */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			PyObject **p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 			if (PyUnicode_Check(arg)) | 
					
						
							|  |  |  | 				*p = arg; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				return "unicode"; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	case 'O': /* object */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			PyTypeObject *type; | 
					
						
							|  |  |  | 			PyObject **p; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			if (*format == '!') { | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 				type = va_arg(*p_va, PyTypeObject*); | 
					
						
							| 
									
										
										
										
											1998-05-15 22:04:07 +00:00
										 |  |  | 				p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 				format++; | 
					
						
							|  |  |  | 				if (arg->ob_type == type) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 					*p = arg; | 
					
						
							| 
									
										
										
										
											1998-05-15 22:04:07 +00:00
										 |  |  | 				else | 
					
						
							|  |  |  | 					return type->tp_name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (*format == '?') { | 
					
						
							|  |  |  | 				inquiry pred = va_arg(*p_va, inquiry); | 
					
						
							| 
									
										
										
										
											1998-05-15 22:04:07 +00:00
										 |  |  | 				p = va_arg(*p_va, PyObject **); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				format++; | 
					
						
							| 
									
										
										
										
											1998-05-15 22:04:07 +00:00
										 |  |  | 				if ((*pred)(arg))  | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 					*p = arg; | 
					
						
							| 
									
										
										
										
											1998-05-15 22:04:07 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 					return "(unspecified)"; | 
					
						
							| 
									
										
										
										
											1998-05-15 22:04:07 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (*format == '&') { | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | 				typedef int (*converter)(PyObject *, void *); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				converter convert = va_arg(*p_va, converter); | 
					
						
							|  |  |  | 				void *addr = va_arg(*p_va, void *); | 
					
						
							|  |  |  | 				format++; | 
					
						
							|  |  |  | 				if (! (*convert)(arg, addr)) | 
					
						
							| 
									
										
										
										
											1995-01-21 14:09:37 +00:00
										 |  |  | 					return "(unspecified)"; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 				p = va_arg(*p_va, PyObject **); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				*p = arg; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	case 'w': /* memory buffer, read-write access */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			void **p = va_arg(*p_va, void **); | 
					
						
							|  |  |  | 			PyBufferProcs *pb = arg->ob_type->tp_as_buffer; | 
					
						
							|  |  |  | 			int count; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if ( pb == NULL || pb->bf_getwritebuffer == NULL || | 
					
						
							|  |  |  | 					pb->bf_getsegcount == NULL ) | 
					
						
							|  |  |  | 				return "read-write buffer"; | 
					
						
							|  |  |  | 			if ( (*pb->bf_getsegcount)(arg, NULL) != 1 ) | 
					
						
							|  |  |  | 				return "single-segment read-write buffer"; | 
					
						
							|  |  |  | 			if ( (count = pb->bf_getwritebuffer(arg, 0, p)) < 0 ) | 
					
						
							|  |  |  | 				return "(unspecified)"; | 
					
						
							|  |  |  | 			if (*format == '#') { | 
					
						
							|  |  |  | 				int *q = va_arg(*p_va, int *); | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				*q = count; | 
					
						
							|  |  |  | 				format++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1998-10-08 02:21:21 +00:00
										 |  |  | 	case 't': /* 8-bit character buffer, read-only access */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			const char **p = va_arg(*p_va, const char **); | 
					
						
							|  |  |  | 			PyBufferProcs *pb = arg->ob_type->tp_as_buffer; | 
					
						
							|  |  |  | 			int count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if ( *format++ != '#' ) | 
					
						
							|  |  |  | 				return "invalid use of 't' format character"; | 
					
						
							|  |  |  | 			if ( !PyType_HasFeature( | 
					
						
							|  |  |  | 				arg->ob_type, | 
					
						
							|  |  |  | 				Py_TPFLAGS_HAVE_GETCHARBUFFER) || | 
					
						
							|  |  |  | 			     pb == NULL || | 
					
						
							|  |  |  | 			     pb->bf_getcharbuffer == NULL || | 
					
						
							|  |  |  | 			     pb->bf_getsegcount == NULL ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				return "string or read-only character buffer"; | 
					
						
							| 
									
										
										
										
											1998-10-08 02:21:21 +00:00
										 |  |  | 			if ( (*pb->bf_getsegcount)(arg, NULL) != 1 ) | 
					
						
							| 
									
										
										
										
											2000-12-01 12:59:05 +00:00
										 |  |  | 				return "string or single-segment read-only buffer"; | 
					
						
							| 
									
										
										
										
											1998-10-08 02:21:21 +00:00
										 |  |  | 			if ( (count = pb->bf_getcharbuffer(arg, 0, p)) < 0 ) | 
					
						
							|  |  |  | 				return "(unspecified)"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			*va_arg(*p_va, int *) = count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return "impossible<bad format char>"; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	*p_format = format; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Support for keyword arguments donated by
 | 
					
						
							|  |  |  |    Geoff Philbrick <philbric@delphi.hks.com> */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | int PyArg_ParseTupleAndKeywords(PyObject *args, | 
					
						
							|  |  |  | 				PyObject *keywords, | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				char *format,  | 
					
						
							|  |  |  | 				char **kwlist, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int retval; | 
					
						
							|  |  |  | 	va_list va; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	va_start(va, kwlist); | 
					
						
							|  |  |  | 	retval = vgetargskeywords(args, keywords, format, kwlist, &va);	 | 
					
						
							|  |  |  | 	va_end(va); | 
					
						
							|  |  |  | 	return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | vgetargskeywords(PyObject *args, PyObject *keywords, char *format, | 
					
						
							|  |  |  | 	         char **kwlist, va_list *p_va) | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char msgbuf[256]; | 
					
						
							|  |  |  | 	int levels[32]; | 
					
						
							|  |  |  | 	char *fname = NULL; | 
					
						
							|  |  |  | 	char *message = NULL; | 
					
						
							|  |  |  | 	int min = -1; | 
					
						
							|  |  |  | 	int max = 0; | 
					
						
							|  |  |  | 	char *formatsave = format; | 
					
						
							|  |  |  | 	int i, len, tplen, kwlen; | 
					
						
							|  |  |  | 	char *msg, *ks, **p; | 
					
						
							|  |  |  | 	int nkwds, pos, match, converted; | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 	PyObject *key, *value; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* nested tuples cannot be parsed when using keyword arguments */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		int c = *format++; | 
					
						
							|  |  |  | 		if (c == '(') { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_SystemError, | 
					
						
							|  |  |  | 		      "tuple found in format when using keyword arguments"); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c == '\0') | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		else if (c == ':') { | 
					
						
							|  |  |  | 			fname = format; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (c == ';') { | 
					
						
							|  |  |  | 			message = format; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2000-09-08 11:49:37 +00:00
										 |  |  | 		else if (c == 'e') | 
					
						
							|  |  |  | 			; /* Pass */ | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		else if (isalpha(c)) | 
					
						
							|  |  |  | 			max++; | 
					
						
							|  |  |  | 		else if (c == '|') | 
					
						
							|  |  |  | 			min = max; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (min < 0) | 
					
						
							|  |  |  | 		min = max; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	format = formatsave; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (!PyTuple_Check(args)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_SystemError, | 
					
						
							|  |  |  | 		    "new style getargs format but argument is not a tuple"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	tplen = PyTuple_Size(args); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* do a cursory check of the keywords just to see how many we got */ | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 	if (keywords) { 	 | 
					
						
							|  |  |  | 		if (!PyDict_Check(keywords)) { | 
					
						
							| 
									
										
										
										
											2001-01-25 20:13:10 +00:00
										 |  |  | 			if (keywords == NULL) | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_SystemError, | 
					
						
							|  |  |  | 		     "NULL received when keyword dictionary expected"); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				PyErr_Format(PyExc_SystemError, | 
					
						
							|  |  |  | 		     "%s received when keyword dictionary expected", | 
					
						
							|  |  |  | 					     keywords->ob_type->tp_name); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 		kwlen = PyDict_Size(keywords); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		kwlen = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	/* make sure there are no duplicate values for an argument;
 | 
					
						
							|  |  |  | 	   its not clear when to use the term "keyword argument vs.  | 
					
						
							|  |  |  | 	   keyword parameter in messages */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (keywords) { | 
					
						
							|  |  |  | 		for (i = 0; i < tplen; i++) { | 
					
						
							|  |  |  | 			if (PyMapping_HasKeyString(keywords, kwlist[i])) { | 
					
						
							|  |  |  | 				sprintf(msgbuf, | 
					
						
							|  |  |  | 					"keyword parameter %s redefined", | 
					
						
							|  |  |  | 					kwlist[i]); | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_TypeError, msgbuf); | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	PyErr_Clear(); /* I'm not which Py functions set the error string */ | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	/* required arguments missing from args can be supplied by keyword 
 | 
					
						
							|  |  |  | 	   arguments */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	len = tplen; | 
					
						
							|  |  |  | 	if (keywords && tplen < min) { | 
					
						
							|  |  |  | 		for (i = tplen; i < min; i++) { | 
					
						
							|  |  |  | 		  if (PyMapping_HasKeyString(keywords, kwlist[i])) { | 
					
						
							|  |  |  | 				len++; | 
					
						
							|  |  |  | 		  } | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	PyErr_Clear();	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* make sure we got an acceptable number of arguments; the message
 | 
					
						
							|  |  |  | 	   is a little confusing with keywords since keyword arguments | 
					
						
							|  |  |  | 	   which are supplied, but don't match the required arguments | 
					
						
							|  |  |  | 	   are not included in the "%d given" part of the message */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (len < min || max < len) { | 
					
						
							|  |  |  | 		if (message == NULL) { | 
					
						
							|  |  |  | 			sprintf(msgbuf, | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 				"%s%s takes %s %d argument%s (%d given)", | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				fname==NULL ? "function" : fname, | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 				fname==NULL ? "" : "()", | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				min==max ? "exactly" | 
					
						
							|  |  |  | 				         : len < min ? "at least" : "at most", | 
					
						
							|  |  |  | 				len < min ? min : max, | 
					
						
							|  |  |  | 				(len < min ? min : max) == 1 ? "" : "s", | 
					
						
							|  |  |  | 				len); | 
					
						
							|  |  |  | 			message = msgbuf; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, message); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (i = 0; i < tplen; i++) { | 
					
						
							|  |  |  | 		if (*format == '|') | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 		msg = convertitem(PyTuple_GetItem(args, i), &format, p_va, | 
					
						
							|  |  |  | 				 levels, msgbuf); | 
					
						
							|  |  |  | 		if (msg) { | 
					
						
							|  |  |  | 			seterror(i+1, msg, levels, fname, message); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* handle no keyword parameters in call  */	 | 
					
						
							|  |  |  | 	   	    | 
					
						
							|  |  |  | 	if (!keywords) return 1;  | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	/* make sure the number of keywords in the keyword list matches the 
 | 
					
						
							|  |  |  | 	   number of items in the format string */ | 
					
						
							|  |  |  | 	   | 
					
						
							|  |  |  | 	nkwds = 0; | 
					
						
							|  |  |  | 	p =  kwlist; | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		if (!*(p++)) break; | 
					
						
							|  |  |  | 		nkwds++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (nkwds != max) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_SystemError, | 
					
						
							|  |  |  | 	  "number of items in format string and keyword list do not match"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	}	  	   | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	/* convert the keyword arguments; this uses the format 
 | 
					
						
							|  |  |  | 	   string where it was left after processing args */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	converted = 0; | 
					
						
							|  |  |  | 	for (i = tplen; i < nkwds; i++) { | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 		PyObject *item; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		if (*format == '|') | 
					
						
							|  |  |  | 			format++; | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 		item = PyMapping_GetItemString(keywords, kwlist[i]); | 
					
						
							|  |  |  | 		if (item != NULL) { | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			msg = convertitem(item, &format, p_va, levels, msgbuf); | 
					
						
							|  |  |  | 			if (msg) { | 
					
						
							|  |  |  | 				seterror(i+1, msg, levels, fname, message); | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			converted++; | 
					
						
							| 
									
										
										
										
											2000-12-11 20:01:55 +00:00
										 |  |  | 			Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							|  |  |  | 			msg = skipitem(&format, p_va); | 
					
						
							|  |  |  | 			if (msg) { | 
					
						
							|  |  |  | 				seterror(i+1, msg, levels, fname, message); | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* make sure there are no extraneous keyword arguments */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	pos = 0; | 
					
						
							|  |  |  | 	if (converted < kwlen) { | 
					
						
							|  |  |  | 		while (PyDict_Next(keywords, &pos, &key, &value)) { | 
					
						
							|  |  |  | 			match = 0; | 
					
						
							|  |  |  | 			ks = PyString_AsString(key); | 
					
						
							|  |  |  | 			for (i = 0; i < nkwds; i++) { | 
					
						
							|  |  |  | 				if (!strcmp(ks, kwlist[i])) { | 
					
						
							|  |  |  | 					match = 1; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!match) { | 
					
						
							|  |  |  | 				sprintf(msgbuf, | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 			"%s is an invalid keyword argument for this function", | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 					ks); | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_TypeError, msgbuf); | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | skipitem(char **p_format, va_list *p_va) | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *format = *p_format; | 
					
						
							|  |  |  | 	char c = *format++; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	switch (c) { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'b': /* byte -- very short int */ | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 	case 'B': /* byte as bitfield */ | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, char *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'h': /* short int */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, short *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 	case 'H': /* short int as bitfield */ | 
					
						
							| 
									
										
										
										
											2000-07-06 12:22:00 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			(void) va_arg(*p_va, unsigned short *); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	case 'i': /* int */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'l': /* long int */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, long *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-01-25 21:48:56 +00:00
										 |  |  | #ifdef HAVE_LONG_LONG
 | 
					
						
							| 
									
										
										
										
											1998-08-25 16:07:15 +00:00
										 |  |  | 	case 'L': /* LONG_LONG int */ | 
					
						
							| 
									
										
										
										
											1998-08-04 22:46:29 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1998-08-25 16:07:15 +00:00
										 |  |  | 			(void) va_arg(*p_va, LONG_LONG *); | 
					
						
							| 
									
										
										
										
											1998-08-04 22:46:29 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	case 'f': /* float */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, float *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'd': /* double */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, double *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | #ifndef WITHOUT_COMPLEX
 | 
					
						
							|  |  |  | 	case 'D': /* complex double */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, Py_complex *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif /* WITHOUT_COMPLEX */
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'c': /* char */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, char *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 's': /* string */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, char **); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			if (*format == '#') { | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 				(void) va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				format++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'z': /* string */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 			(void) va_arg(*p_va, char **); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			if (*format == '#') { | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 				(void) va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				format++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'S': /* string object */ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 			(void) va_arg(*p_va, PyObject **); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	case 'O': /* object */ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (*format == '!') { | 
					
						
							|  |  |  | 				format++; | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 				(void) va_arg(*p_va, PyTypeObject*); | 
					
						
							|  |  |  | 				(void) va_arg(*p_va, PyObject **); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | /* I don't know what this is for */ | 
					
						
							|  |  |  | 			else if (*format == '?') { | 
					
						
							|  |  |  | 				inquiry pred = va_arg(*p_va, inquiry); | 
					
						
							|  |  |  | 				format++; | 
					
						
							|  |  |  | 				if ((*pred)(arg)) { | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 					(void) va_arg(*p_va, PyObject **); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 			else if (*format == '&') { | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | 				typedef int (*converter)(PyObject *, void *); | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 				(void) va_arg(*p_va, converter); | 
					
						
							|  |  |  | 				(void) va_arg(*p_va, void *); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				format++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 				(void) va_arg(*p_va, PyObject **); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return "impossible<bad format char>"; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	*p_format = format; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } |