| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* New getargs implementation */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 *); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | static char *convertitem(PyObject *, char **, va_list *, int *, char *,  | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			 size_t, PyObject **); | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | static char *converttuple(PyObject *, char **, va_list *, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			  int *, char *, size_t, int, PyObject **); | 
					
						
							|  |  |  | static char *convertsimple(PyObject *, char **, va_list *, char *, | 
					
						
							|  |  |  | 			   size_t, PyObject **); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | static int convertbuffer(PyObject *, void **p, char **); | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int vgetargskeywords(PyObject *, PyObject *, | 
					
						
							|  |  |  | 			    char *, char **, va_list *); | 
					
						
							|  |  |  | static char *skipitem(char **, va_list *); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-23 14:41:08 +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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-23 14:41:08 +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)); | 
					
						
							| 
									
										
										
										
											2002-07-28 10:23:27 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #ifdef __va_copy
 | 
					
						
							|  |  |  | 	__va_copy(lva, va); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	lva = va; | 
					
						
							| 
									
										
										
										
											2002-07-28 10:23:27 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return vgetargs1(args, format, &lva, 0); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | /* Handle cleanup of allocated memory in case of exception */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | addcleanup(void *ptr, PyObject **freelist) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *cobj; | 
					
						
							|  |  |  | 	if (!*freelist) { | 
					
						
							|  |  |  | 		*freelist = PyList_New(0); | 
					
						
							|  |  |  | 		if (!*freelist) { | 
					
						
							|  |  |  | 			PyMem_FREE(ptr); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	cobj = PyCObject_FromVoidPtr(ptr, NULL); | 
					
						
							|  |  |  | 	if (!cobj) { | 
					
						
							|  |  |  | 		PyMem_FREE(ptr); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(PyList_Append(*freelist, cobj)) { | 
					
						
							|  |  |  |                 PyMem_FREE(ptr); | 
					
						
							|  |  |  | 		Py_DECREF(cobj); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |         Py_DECREF(cobj); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | cleanreturn(int retval, PyObject *freelist) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(freelist) { | 
					
						
							|  |  |  | 		if((retval) == 0) { | 
					
						
							|  |  |  | 			int len = PyList_GET_SIZE(freelist), i; | 
					
						
							|  |  |  | 			for (i = 0; i < len; i++) | 
					
						
							|  |  |  |                                 PyMem_FREE(PyCObject_AsVoidPtr( | 
					
						
							|  |  |  |                                 		PyList_GET_ITEM(freelist, i))); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_DECREF(freelist); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 	int endfmt = 0; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	char *formatsave = format; | 
					
						
							|  |  |  | 	int i, len; | 
					
						
							|  |  |  | 	char *msg; | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 	PyObject *freelist = NULL; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-02-12 22:13:26 +00:00
										 |  |  | 	assert(compat || (args != (PyObject*)NULL)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 	while (endfmt == 0) { | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		int c = *format++; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 		switch (c) { | 
					
						
							|  |  |  | 		case '(': | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			if (level == 0) | 
					
						
							|  |  |  | 				max++; | 
					
						
							|  |  |  | 			level++; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case ')': | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			if (level == 0) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 				Py_FatalError("excess ')' in getargs format"); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				level--; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 		case '\0': | 
					
						
							|  |  |  | 			endfmt = 1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case ':': | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			fname = format; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 			endfmt = 1; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 		case ';': | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			message = format; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:46:19 +00:00
										 |  |  | 			endfmt = 1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			if (level == 0) { | 
					
						
							|  |  |  | 				if (c == 'O') | 
					
						
							|  |  |  | 					max++; | 
					
						
							|  |  |  | 				else if (isalpha(c)) { | 
					
						
							|  |  |  | 					if (c != 'e') /* skip encoded */ | 
					
						
							|  |  |  | 						max++; | 
					
						
							|  |  |  | 				} else if (c == '|') | 
					
						
							|  |  |  | 					min = max; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	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-11-28 20:29:22 +00:00
										 |  |  | 			PyOS_snprintf(msgbuf, sizeof(msgbuf), | 
					
						
							|  |  |  | 				      "%.200s%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) { | 
					
						
							| 
									
										
										
										
											2001-11-28 20:29:22 +00:00
										 |  |  | 				PyOS_snprintf(msgbuf, sizeof(msgbuf), | 
					
						
							|  |  |  | 				      "%.200s%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; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			msg = convertitem(args, &format, p_va, levels, msgbuf, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 					  sizeof(msgbuf), &freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			if (msg == NULL) | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				return cleanreturn(1, freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			seterror(levels[0], msg, levels+1, fname, message); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-18 20:57:38 +00:00
										 |  |  | 	len = PyTuple_GET_SIZE(args); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (len < min || max < len) { | 
					
						
							|  |  |  | 		if (message == NULL) { | 
					
						
							| 
									
										
										
										
											2001-11-28 20:29:22 +00:00
										 |  |  | 			PyOS_snprintf(msgbuf, sizeof(msgbuf), | 
					
						
							|  |  |  | 				      "%.150s%s takes %s %d argument%s " | 
					
						
							|  |  |  | 				      "(%d given)", | 
					
						
							|  |  |  | 				      fname==NULL ? "function" : fname, | 
					
						
							|  |  |  | 				      fname==NULL ? "" : "()", | 
					
						
							|  |  |  | 				      min==max ? "exactly" | 
					
						
							|  |  |  | 				      : len < min ? "at least" : "at most", | 
					
						
							|  |  |  | 				      len < min ? min : max, | 
					
						
							|  |  |  | 				      (len < min ? min : max) == 1 ? "" : "s", | 
					
						
							|  |  |  | 				      len); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			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++; | 
					
						
							| 
									
										
										
										
											2001-05-18 20:57:38 +00:00
										 |  |  | 		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				  levels, msgbuf, sizeof(msgbuf), &freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		if (msg) { | 
					
						
							|  |  |  | 			seterror(i+1, msg, levels, fname, message); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 		return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1997-12-09 20:36:39 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 	return cleanreturn(1, freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2001-11-28 11:47:00 +00:00
										 |  |  | 	char buf[512]; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	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-11-28 21:46:59 +00:00
										 |  |  | 			PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			p += strlen(p); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 		if (iarg != 0) { | 
					
						
							| 
									
										
										
										
											2001-12-03 00:43:33 +00:00
										 |  |  | 			PyOS_snprintf(p, sizeof(buf) - (p - buf), | 
					
						
							| 
									
										
										
										
											2001-11-28 21:46:59 +00:00
										 |  |  | 				      "argument %d", iarg); | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 			i = 0; | 
					
						
							|  |  |  | 			p += strlen(p); | 
					
						
							| 
									
										
										
										
											2001-11-28 11:47:00 +00:00
										 |  |  | 			while (levels[i] > 0 && (int)(p-buf) < 220) { | 
					
						
							| 
									
										
										
										
											2001-11-28 21:46:59 +00:00
										 |  |  | 				PyOS_snprintf(p, sizeof(buf) - (buf - p), | 
					
						
							|  |  |  | 					      ", item %d", levels[i]-1); | 
					
						
							| 
									
										
										
										
											2001-01-15 22:14:16 +00:00
										 |  |  | 				p += strlen(p); | 
					
						
							|  |  |  | 				i++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2001-12-03 00:43:33 +00:00
										 |  |  | 			PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument"); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			p += strlen(p); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-12-03 00:43:33 +00:00
										 |  |  | 		PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", 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, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 	     char *msgbuf, size_t bufsize, int toplevel, PyObject **freelist) | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 		PyOS_snprintf(msgbuf, bufsize, | 
					
						
							| 
									
										
										
										
											2001-11-28 20:29:22 +00:00
										 |  |  | 			      toplevel ? "expected %d arguments, not %.50s" : | 
					
						
							|  |  |  | 			              "must be %d-item sequence, not %.50s", | 
					
						
							|  |  |  | 			      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; | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 		PyOS_snprintf(msgbuf, bufsize, | 
					
						
							| 
									
										
										
										
											2001-11-28 20:29:22 +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); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 		msg = convertitem(item, &format, p_va, levels+1, msgbuf, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				  bufsize, freelist); | 
					
						
							| 
									
										
										
										
											1999-02-17 23:16:43 +00:00
										 |  |  | 		/* 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, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 	    char *msgbuf, size_t bufsize, PyObject **freelist) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *msg; | 
					
						
							|  |  |  | 	char *format = *p_format; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (*format == '(' /* ')' */) { | 
					
						
							|  |  |  | 		format++; | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 		msg = converttuple(arg, &format, p_va, levels, msgbuf,  | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				   bufsize, 0, freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		if (msg == NULL) | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 		msg = convertsimple(arg, &format, p_va, msgbuf, bufsize, | 
					
						
							|  |  |  | 				    freelist); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		if (msg != NULL) | 
					
						
							|  |  |  | 			levels[0] = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (msg == NULL) | 
					
						
							|  |  |  | 		*p_format = format; | 
					
						
							|  |  |  | 	return msg; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define UNICODE_DEFAULT_ENCODING(arg) \
 | 
					
						
							|  |  |  |         _PyUnicode_AsDefaultEncodedString(arg, NULL) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Format an error message generated by convertsimple(). */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | converterr(char *expected, PyObject *arg, char *msgbuf, size_t bufsize) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 	assert(expected != NULL); | 
					
						
							|  |  |  | 	assert(arg != NULL);  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 	PyOS_snprintf(msgbuf, bufsize, | 
					
						
							|  |  |  | 		      "must be %.50s, not %.50s", expected, | 
					
						
							|  |  |  | 		      arg == Py_None ? "None" : arg->ob_type->tp_name); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	return msgbuf; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | #define CONV_UNICODE "(unicode conversion error)"
 | 
					
						
							| 
									
										
										
										
											2000-04-27 20:13:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-04 20:59:40 +00:00
										 |  |  | /* explicitly check for float arguments when integers are expected.  For now
 | 
					
						
							|  |  |  |  * signal a warning.  Returns true if an exception was raised. */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | float_argument_error(PyObject *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (PyFloat_Check(arg) && | 
					
						
							|  |  |  | 	    PyErr_Warn(PyExc_DeprecationWarning, | 
					
						
							|  |  |  | 		       "integer argument expected, got float" )) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | /* Convert a non-tuple argument.  Return NULL if conversion went OK,
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  |    or a string with a message describing the failure.  The message is | 
					
						
							|  |  |  |    formatted as "must be <desired type>, not <actual type>". | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  |    When failing, an exception may or may not have been raised. | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  |    Don't call if a tuple is expected.  | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 	      size_t bufsize, PyObject **freelist) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *format = *p_format; | 
					
						
							|  |  |  | 	char c = *format++; | 
					
						
							| 
									
										
										
										
											2002-11-21 20:23:11 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 	PyObject *uarg; | 
					
						
							| 
									
										
										
										
											2002-11-21 20:23:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	switch (c) { | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'b': { /* unsigned byte -- very short int */ | 
					
						
							|  |  |  | 		char *p = va_arg(*p_va, char *); | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		long ival; | 
					
						
							| 
									
										
										
										
											2003-02-04 20:59:40 +00:00
										 |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		ival = PyInt_AsLong(arg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<b>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else if (ival < 0) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  | 			"unsigned byte integer is less than minimum"); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<b>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (ival > UCHAR_MAX) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  | 			"unsigned byte integer is greater than maximum"); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<b>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			*p = (unsigned char) ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'B': {/* byte sized bitfield - both signed and unsigned
 | 
					
						
							|  |  |  | 		      values allowed */   | 
					
						
							|  |  |  | 		char *p = va_arg(*p_va, char *); | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		long ival; | 
					
						
							| 
									
										
										
										
											2003-02-04 20:59:40 +00:00
										 |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-04-17 18:55:45 +00:00
										 |  |  | 		ival = PyInt_AsUnsignedLongMask(arg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<B>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			*p = (unsigned char) ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-05 21:29:58 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2003-04-18 00:12:30 +00:00
										 |  |  | 	case 'h': {/* signed short int */ | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		short *p = va_arg(*p_va, short *); | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		long ival; | 
					
						
							| 
									
										
										
										
											2003-02-04 20:59:40 +00:00
										 |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		ival = PyInt_AsLong(arg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<h>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2003-04-18 00:12:30 +00:00
										 |  |  | 		else if (ival < SHRT_MIN) { | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2003-04-18 00:12:30 +00:00
										 |  |  | 			"signed short integer is less than minimum"); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<h>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-04-18 00:12:30 +00:00
										 |  |  | 		else if (ival > SHRT_MAX) { | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			PyErr_SetString(PyExc_OverflowError, | 
					
						
							| 
									
										
										
										
											2003-04-18 00:12:30 +00:00
										 |  |  | 			"signed short integer is greater than maximum"); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<h>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			*p = (short) ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'H': { /* short int sized bitfield, both signed and
 | 
					
						
							|  |  |  | 		       unsigned allowed */  | 
					
						
							|  |  |  | 		unsigned short *p = va_arg(*p_va, unsigned short *); | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		long ival; | 
					
						
							| 
									
										
										
										
											2003-02-04 20:59:40 +00:00
										 |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-04-17 18:55:45 +00:00
										 |  |  | 		ival = PyInt_AsUnsignedLongMask(arg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<H>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			*p = (unsigned short) ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-07-06 12:22:00 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'i': {/* signed int */ | 
					
						
							|  |  |  | 		int *p = va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		long ival; | 
					
						
							| 
									
										
										
										
											2003-02-04 20:59:40 +00:00
										 |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		ival = PyInt_AsLong(arg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<i>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else if (ival > INT_MAX) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  | 				"signed integer is greater than maximum"); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<i>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (ival < INT_MIN) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  | 				"signed integer is less than minimum"); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<i>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			*p = ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-17 18:55:45 +00:00
										 |  |  | 	case 'I': { /* int sized bitfield, both signed and
 | 
					
						
							|  |  |  | 		       unsigned allowed */  | 
					
						
							|  |  |  | 		unsigned int *p = va_arg(*p_va, unsigned int *); | 
					
						
							|  |  |  | 		unsigned int ival; | 
					
						
							|  |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		ival = PyInt_AsUnsignedLongMask(arg); | 
					
						
							|  |  |  | 		if (ival == -1 && PyErr_Occurred()) | 
					
						
							|  |  |  | 			return converterr("integer<I>", arg, msgbuf, bufsize); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			*p = ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'l': {/* long int */ | 
					
						
							|  |  |  | 		long *p = va_arg(*p_va, long *); | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		long ival; | 
					
						
							| 
									
										
										
										
											2003-02-04 20:59:40 +00:00
										 |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2003-01-24 22:15:21 +00:00
										 |  |  | 		ival = PyInt_AsLong(arg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (ival == -1 && PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("integer<l>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			*p = ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-04-17 18:55:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case 'k': { /* long sized bitfield */ | 
					
						
							|  |  |  | 		unsigned long *p = va_arg(*p_va, unsigned long *); | 
					
						
							|  |  |  | 		unsigned long ival; | 
					
						
							|  |  |  | 		if (PyInt_Check(arg)) | 
					
						
							|  |  |  | 			ival = PyInt_AsUnsignedLongMask(arg); | 
					
						
							|  |  |  | 		else if (PyLong_Check(arg)) | 
					
						
							|  |  |  | 			ival = PyLong_AsUnsignedLongMask(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return converterr("integer<k>", arg, msgbuf, bufsize); | 
					
						
							|  |  |  | 		*p = ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1999-01-25 21:48:56 +00:00
										 |  |  | #ifdef HAVE_LONG_LONG
 | 
					
						
							| 
									
										
										
										
											2003-03-29 10:06:18 +00:00
										 |  |  | 	case 'L': {/* PY_LONG_LONG */ | 
					
						
							|  |  |  | 		PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * ); | 
					
						
							|  |  |  | 		PY_LONG_LONG ival = PyLong_AsLongLong( arg ); | 
					
						
							|  |  |  | 		if( ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) { | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("long<L>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			*p = ival; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-04-17 18:55:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case 'K': { /* long long sized bitfield */ | 
					
						
							|  |  |  | 		unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *); | 
					
						
							|  |  |  | 		unsigned PY_LONG_LONG ival; | 
					
						
							|  |  |  | 		if (float_argument_error(arg)) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		if (PyInt_Check(arg)) | 
					
						
							|  |  |  | 			ival = PyInt_AsUnsignedLongMask(arg); | 
					
						
							|  |  |  | 		else if (PyLong_Check(arg)) | 
					
						
							|  |  |  | 			ival = PyLong_AsUnsignedLongLongMask(arg); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return converterr("integer<K>", arg, msgbuf, bufsize); | 
					
						
							|  |  |  | 		*p = ival; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1998-08-04 22:46:29 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'f': {/* float */ | 
					
						
							|  |  |  | 		float *p = va_arg(*p_va, float *); | 
					
						
							|  |  |  | 		double dval = PyFloat_AsDouble(arg); | 
					
						
							|  |  |  | 		if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("float<f>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			*p = (float) dval; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'd': {/* double */ | 
					
						
							|  |  |  | 		double *p = va_arg(*p_va, double *); | 
					
						
							|  |  |  | 		double dval = PyFloat_AsDouble(arg); | 
					
						
							|  |  |  | 		if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("float<d>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			*p = dval; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1996-07-21 02:27:43 +00:00
										 |  |  | #ifndef WITHOUT_COMPLEX
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'D': {/* complex double */ | 
					
						
							|  |  |  | 		Py_complex *p = va_arg(*p_va, Py_complex *); | 
					
						
							|  |  |  | 		Py_complex cval; | 
					
						
							|  |  |  | 		cval = PyComplex_AsCComplex(arg); | 
					
						
							|  |  |  | 		if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("complex<D>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			*p = cval; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1996-07-21 02:27:43 +00:00
										 |  |  | #endif /* WITHOUT_COMPLEX */
 | 
					
						
							| 
									
										
										
										
											1996-01-12 01:09:56 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'c': {/* char */ | 
					
						
							|  |  |  | 		char *p = va_arg(*p_va, char *); | 
					
						
							|  |  |  | 		if (PyString_Check(arg) && PyString_Size(arg) == 1) | 
					
						
							| 
									
										
										
										
											2001-10-10 02:51:57 +00:00
										 |  |  | 			*p = PyString_AS_STRING(arg)[0]; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("char", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 's': {/* string */ | 
					
						
							|  |  |  | 		if (*format == '#') { | 
					
						
							|  |  |  | 			void **p = (void **)va_arg(*p_va, char **); | 
					
						
							|  |  |  | 			int *q = va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			if (PyString_Check(arg)) { | 
					
						
							|  |  |  | 				*p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				*q = PyString_GET_SIZE(arg); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else if (PyUnicode_Check(arg)) { | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				uarg = UNICODE_DEFAULT_ENCODING(arg); | 
					
						
							|  |  |  | 				if (uarg == NULL) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					return converterr(CONV_UNICODE, | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 							  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				*p = PyString_AS_STRING(uarg); | 
					
						
							|  |  |  | 				*q = PyString_GET_SIZE(uarg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else { /* any buffer-like object */ | 
					
						
							|  |  |  | 				char *buf; | 
					
						
							|  |  |  | 				int count = convertbuffer(arg, p, &buf); | 
					
						
							|  |  |  | 				if (count < 0) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					return converterr(buf, arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				*q = count; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			char **p = va_arg(*p_va, char **); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (PyString_Check(arg)) | 
					
						
							|  |  |  | 				*p = PyString_AS_STRING(arg); | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else if (PyUnicode_Check(arg)) { | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				uarg = UNICODE_DEFAULT_ENCODING(arg); | 
					
						
							|  |  |  | 				if (uarg == NULL) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					return converterr(CONV_UNICODE, | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 							  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				*p = PyString_AS_STRING(uarg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				return converterr("string", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			if ((int)strlen(*p) != PyString_Size(arg)) | 
					
						
							|  |  |  | 				return converterr("string without null bytes", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'z': {/* string, may be NULL (None) */ | 
					
						
							|  |  |  | 		if (*format == '#') { /* any buffer-like object */ | 
					
						
							|  |  |  | 			void **p = (void **)va_arg(*p_va, char **); | 
					
						
							|  |  |  | 			int *q = va_arg(*p_va, int *); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (arg == Py_None) { | 
					
						
							|  |  |  | 				*p = 0; | 
					
						
							|  |  |  | 				*q = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else if (PyString_Check(arg)) { | 
					
						
							|  |  |  | 				*p = PyString_AS_STRING(arg); | 
					
						
							|  |  |  | 				*q = PyString_GET_SIZE(arg); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else if (PyUnicode_Check(arg)) { | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				uarg = UNICODE_DEFAULT_ENCODING(arg); | 
					
						
							|  |  |  | 				if (uarg == NULL) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					return converterr(CONV_UNICODE, | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 							  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				*p = PyString_AS_STRING(uarg); | 
					
						
							|  |  |  | 				*q = PyString_GET_SIZE(uarg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else { /* any buffer-like object */ | 
					
						
							|  |  |  | 				char *buf; | 
					
						
							|  |  |  | 				int count = convertbuffer(arg, p, &buf); | 
					
						
							|  |  |  | 				if (count < 0) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					return converterr(buf, arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				*q = count; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			char **p = va_arg(*p_va, char **); | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			if (arg == Py_None) | 
					
						
							|  |  |  | 				*p = 0; | 
					
						
							|  |  |  | 			else if (PyString_Check(arg)) | 
					
						
							| 
									
										
										
										
											2001-10-10 02:51:08 +00:00
										 |  |  | 				*p = PyString_AS_STRING(arg); | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else if (PyUnicode_Check(arg)) { | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				uarg = UNICODE_DEFAULT_ENCODING(arg); | 
					
						
							|  |  |  | 				if (uarg == NULL) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					return converterr(CONV_UNICODE, | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 							  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-09-10 01:54:43 +00:00
										 |  |  | 				*p = PyString_AS_STRING(uarg); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				return converterr("string or None",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			if (*format == '#') { | 
					
						
							|  |  |  | 				int *q = va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											2000-05-08 14:02:41 +00:00
										 |  |  | 				if (arg == Py_None) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					*q = 0; | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					*q = PyString_Size(arg); | 
					
						
							|  |  |  | 				format++; | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else if (*p != NULL && | 
					
						
							|  |  |  | 				 (int)strlen(*p) != PyString_Size(arg)) | 
					
						
							|  |  |  | 				return converterr( | 
					
						
							|  |  |  | 					"string without null bytes or None",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'e': {/* encoded string */ | 
					
						
							|  |  |  | 		char **buffer; | 
					
						
							|  |  |  | 		const char *encoding; | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | 		PyObject *s; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		int size, recode_strings; | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		/* Get 'e' parameter: the encoding name */ | 
					
						
							|  |  |  | 		encoding = (const char *)va_arg(*p_va, const char *); | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (encoding == NULL) | 
					
						
							|  |  |  | 			encoding = PyUnicode_GetDefaultEncoding(); | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		/* Get output buffer parameter:
 | 
					
						
							|  |  |  | 		   's' (recode all objects via Unicode) or | 
					
						
							|  |  |  | 		   't' (only recode non-string objects)  | 
					
						
							|  |  |  | 		*/ | 
					
						
							|  |  |  | 		if (*format == 's') | 
					
						
							|  |  |  | 			recode_strings = 1; | 
					
						
							|  |  |  | 		else if (*format == 't') | 
					
						
							|  |  |  | 			recode_strings = 0; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return converterr( | 
					
						
							|  |  |  | 				"(unknown parser marker combination)", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		buffer = (char **)va_arg(*p_va, char **); | 
					
						
							|  |  |  | 		format++; | 
					
						
							|  |  |  | 		if (buffer == NULL) | 
					
						
							|  |  |  | 			return converterr("(buffer is NULL)",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		/* Encode object */ | 
					
						
							|  |  |  | 		if (!recode_strings && PyString_Check(arg)) { | 
					
						
							|  |  |  | 			s = arg; | 
					
						
							|  |  |  | 			Py_INCREF(s); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							|  |  |  | 		    	PyObject *u; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			/* Convert object to Unicode */ | 
					
						
							|  |  |  | 			u = PyUnicode_FromObject(arg); | 
					
						
							|  |  |  | 			if (u == NULL) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				return converterr( | 
					
						
							|  |  |  | 					"string or unicode or text buffer",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				return converterr("(encoding failed)", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			if (!PyString_Check(s)) { | 
					
						
							|  |  |  | 				Py_DECREF(s); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				return converterr( | 
					
						
							|  |  |  | 					"(encoder failed to return a string)", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("string<e>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		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 PyMem_Free()ing it after | 
					
						
							|  |  |  | 			   usage  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			   - 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 *); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			format++; | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			if (buffer_len == NULL) { | 
					
						
							|  |  |  | 				Py_DECREF(s); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				return converterr( | 
					
						
							|  |  |  | 					"(buffer_len is NULL)", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			if (*buffer == NULL) { | 
					
						
							|  |  |  | 				*buffer = PyMem_NEW(char, size + 1); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 				if (*buffer == NULL) { | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					Py_DECREF(s); | 
					
						
							|  |  |  | 					return converterr( | 
					
						
							|  |  |  | 						"(memory error)", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				if(addcleanup(*buffer, freelist)) { | 
					
						
							|  |  |  | 					Py_DECREF(s); | 
					
						
							|  |  |  | 					return converterr( | 
					
						
							|  |  |  | 						"(cleanup problem)", | 
					
						
							|  |  |  | 						arg, msgbuf, bufsize); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				if (size + 1 > *buffer_len) { | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 					Py_DECREF(s); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 					return converterr( | 
					
						
							|  |  |  | 						"(buffer overflow)",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			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 is responsible for | 
					
						
							|  |  |  | 			   PyMem_Free()ing it after usage | 
					
						
							| 
									
										
										
										
											2000-03-24 22:14:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			*/ | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			if ((int)strlen(PyString_AS_STRING(s)) != size) { | 
					
						
							|  |  |  | 				Py_DECREF(s); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				return converterr( | 
					
						
							|  |  |  | 					"(encoded string without NULL bytes)", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			*buffer = PyMem_NEW(char, size + 1); | 
					
						
							|  |  |  | 			if (*buffer == NULL) { | 
					
						
							|  |  |  | 				Py_DECREF(s); | 
					
						
							|  |  |  | 				return converterr("(memory error)", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			if(addcleanup(*buffer, freelist)) { | 
					
						
							|  |  |  | 				Py_DECREF(s); | 
					
						
							|  |  |  | 				return converterr("(cleanup problem)", | 
					
						
							|  |  |  | 						arg, msgbuf, bufsize); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			memcpy(*buffer, | 
					
						
							|  |  |  | 			       PyString_AS_STRING(s), | 
					
						
							|  |  |  | 			       size + 1); | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		Py_DECREF(s); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-05-03 15:17:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'u': {/* raw unicode buffer (Py_UNICODE *) */ | 
					
						
							|  |  |  | 		if (*format == '#') { /* any buffer-like object */ | 
					
						
							|  |  |  | 			void **p = (void **)va_arg(*p_va, char **); | 
					
						
							|  |  |  | 			int *q = va_arg(*p_va, int *); | 
					
						
							| 
									
										
										
										
											2002-01-09 16:21:27 +00:00
										 |  |  | 			if (PyUnicode_Check(arg)) { | 
					
						
							|  |  |  | 			    	*p = PyUnicode_AS_UNICODE(arg); | 
					
						
							|  |  |  | 				*q = PyUnicode_GET_SIZE(arg); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			char *buf; | 
					
						
							|  |  |  | 			int count = convertbuffer(arg, p, &buf); | 
					
						
							|  |  |  | 			if (count < 0) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				return converterr(buf, arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			*q = count/(sizeof(Py_UNICODE));  | 
					
						
							| 
									
										
										
										
											2002-01-09 16:21:27 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			format++; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); | 
					
						
							|  |  |  | 			if (PyUnicode_Check(arg)) | 
					
						
							|  |  |  | 				*p = PyUnicode_AS_UNICODE(arg); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				return converterr("unicode", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case 'S': { /* string object */ | 
					
						
							|  |  |  | 		PyObject **p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 		if (PyString_Check(arg)) | 
					
						
							|  |  |  | 			*p = arg; | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("string", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #ifdef Py_USING_UNICODE
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 'U': { /* Unicode object */ | 
					
						
							|  |  |  | 		PyObject **p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 		if (PyUnicode_Check(arg)) | 
					
						
							|  |  |  | 			*p = arg; | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("unicode", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-08-17 18:39:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	case 'O': { /* object */ | 
					
						
							|  |  |  | 		PyTypeObject *type; | 
					
						
							|  |  |  | 		PyObject **p; | 
					
						
							|  |  |  | 		if (*format == '!') { | 
					
						
							|  |  |  | 			type = va_arg(*p_va, PyTypeObject*); | 
					
						
							|  |  |  | 			p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 			format++; | 
					
						
							| 
									
										
										
										
											2001-08-28 16:37:51 +00:00
										 |  |  | 			if (PyType_IsSubtype(arg->ob_type, type)) | 
					
						
							| 
									
										
										
										
											2000-03-10 23:02:17 +00:00
										 |  |  | 				*p = arg; | 
					
						
							|  |  |  | 			else | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				return converterr(type->tp_name, arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											1998-05-15 22:04:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (*format == '?') { | 
					
						
							|  |  |  | 			inquiry pred = va_arg(*p_va, inquiry); | 
					
						
							|  |  |  | 			p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 			if ((*pred)(arg))  | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 				*p = arg; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				return converterr("(unspecified)",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 				 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (*format == '&') { | 
					
						
							|  |  |  | 			typedef int (*converter)(PyObject *, void *); | 
					
						
							|  |  |  | 			converter convert = va_arg(*p_va, converter); | 
					
						
							|  |  |  | 			void *addr = va_arg(*p_va, void *); | 
					
						
							|  |  |  | 			format++; | 
					
						
							|  |  |  | 			if (! (*convert)(arg, addr)) | 
					
						
							|  |  |  | 				return converterr("(unspecified)",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 						  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		else { | 
					
						
							|  |  |  | 			p = va_arg(*p_va, PyObject **); | 
					
						
							|  |  |  | 			*p = arg; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +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; | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (pb == NULL ||  | 
					
						
							|  |  |  | 		    pb->bf_getwritebuffer == NULL || | 
					
						
							|  |  |  | 		    pb->bf_getsegcount == NULL) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("read-write buffer", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if ((*pb->bf_getsegcount)(arg, NULL) != 1) | 
					
						
							|  |  |  | 			return converterr("single-segment read-write buffer",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 					  arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("(unspecified)", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (*format == '#') { | 
					
						
							|  |  |  | 			int *q = va_arg(*p_va, int *); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			*q = count; | 
					
						
							|  |  |  | 			format++; | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-05 22:15:02 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 	case 't': { /* 8-bit character buffer, read-only access */ | 
					
						
							|  |  |  | 		const char **p = va_arg(*p_va, const char **); | 
					
						
							| 
									
										
										
										
											2001-10-11 14:40:37 +00:00
										 |  |  | 		PyBufferProcs *pb = arg->ob_type->tp_as_buffer; | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		int count; | 
					
						
							| 
									
										
										
										
											1998-10-08 02:21:21 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (*format++ != '#') | 
					
						
							|  |  |  | 			return converterr( | 
					
						
							|  |  |  | 				"invalid use of 't' format character",  | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (!PyType_HasFeature(arg->ob_type, | 
					
						
							| 
									
										
										
										
											2001-10-11 14:40:37 +00:00
										 |  |  | 				       Py_TPFLAGS_HAVE_GETCHARBUFFER) || | 
					
						
							|  |  |  | 		    pb == NULL || pb->bf_getcharbuffer == NULL || | 
					
						
							|  |  |  | 		    pb->bf_getsegcount == NULL) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 			return converterr( | 
					
						
							|  |  |  | 				"string or read-only character buffer", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-11 14:40:37 +00:00
										 |  |  | 		if (pb->bf_getsegcount(arg, NULL) != 1) | 
					
						
							|  |  |  | 			return converterr( | 
					
						
							|  |  |  | 				"string or single-segment read-only buffer", | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 				arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-10-11 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		count = pb->bf_getcharbuffer(arg, 0, p); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		if (count < 0) | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			return converterr("(unspecified)", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | 		*va_arg(*p_va, int *) = count; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 		return converterr("impossible<bad format char>", arg, msgbuf, bufsize); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:42:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	*p_format = format; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-23 14:41:08 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | convertbuffer(PyObject *arg, void **p, char **errmsg) | 
					
						
							| 
									
										
										
										
											2001-05-29 17:37:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyBufferProcs *pb = arg->ob_type->tp_as_buffer; | 
					
						
							|  |  |  | 	int count; | 
					
						
							|  |  |  | 	if (pb == NULL || | 
					
						
							|  |  |  | 	    pb->bf_getreadbuffer == NULL || | 
					
						
							|  |  |  | 	    pb->bf_getsegcount == NULL) { | 
					
						
							|  |  |  | 		*errmsg = "string or read-only buffer"; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((*pb->bf_getsegcount)(arg, NULL) != 1) { | 
					
						
							|  |  |  | 		*errmsg = "string or single-segment read-only buffer"; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) { | 
					
						
							|  |  |  | 		*errmsg = "(unspecified)"; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return count; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Support for keyword arguments donated by
 | 
					
						
							|  |  |  |    Geoff Philbrick <philbric@delphi.hks.com> */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | /* Return false (0) for error, else true. */ | 
					
						
							| 
									
										
										
										
											2001-10-23 14:41:08 +00:00
										 |  |  | int | 
					
						
							|  |  |  | PyArg_ParseTupleAndKeywords(PyObject *args, | 
					
						
							|  |  |  | 			    PyObject *keywords, | 
					
						
							|  |  |  | 			    char *format,  | 
					
						
							|  |  |  | 			    char **kwlist, ...) | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int retval; | 
					
						
							|  |  |  | 	va_list va; | 
					
						
							| 
									
										
										
										
											2001-10-27 03:58:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if ((args == NULL || !PyTuple_Check(args)) || | 
					
						
							|  |  |  | 	    (keywords != NULL && !PyDict_Check(keywords)) || | 
					
						
							|  |  |  | 	    format == NULL || | 
					
						
							|  |  |  | 	    kwlist == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2001-10-27 03:58:40 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2001-10-27 06:53:00 +00:00
										 |  |  | 	char msgbuf[512]; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	int levels[32]; | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 	char *fname, *message; | 
					
						
							|  |  |  | 	int min, max; | 
					
						
							| 
									
										
										
										
											2001-10-27 04:38:11 +00:00
										 |  |  | 	char *formatsave; | 
					
						
							| 
									
										
										
										
											2001-10-27 07:00:56 +00:00
										 |  |  | 	int i, len, nargs, nkeywords; | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 	char *msg, **p; | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 	PyObject *freelist = NULL; | 
					
						
							| 
									
										
										
										
											2001-10-27 00:17:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-27 03:58:40 +00:00
										 |  |  | 	assert(args != NULL && PyTuple_Check(args)); | 
					
						
							|  |  |  | 	assert(keywords == NULL || PyDict_Check(keywords)); | 
					
						
							|  |  |  | 	assert(format != NULL); | 
					
						
							|  |  |  | 	assert(kwlist != NULL); | 
					
						
							|  |  |  | 	assert(p_va != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 	/* Search the format:
 | 
					
						
							|  |  |  | 	   message <- error msg, if any (else NULL). | 
					
						
							| 
									
										
										
										
											2001-11-29 03:26:37 +00:00
										 |  |  | 	   fname <- routine name, if any (else NULL). | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 	   min <- # of required arguments, or -1 if all are required. | 
					
						
							|  |  |  | 	   max <- most arguments (required + optional). | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 	   Check that kwlist has a non-NULL entry for each arg. | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 	   Raise error if a tuple arg spec is found. | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 	fname = message = NULL; | 
					
						
							| 
									
										
										
										
											2001-10-27 04:38:11 +00:00
										 |  |  | 	formatsave = format; | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 	p = kwlist; | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 	min = -1; | 
					
						
							|  |  |  | 	max = 0; | 
					
						
							|  |  |  | 	while ((i = *format++) != '\0') { | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 		if (isalpha(i) && i != 'e') { | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 			max++; | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 			if (*p == NULL) { | 
					
						
							| 
									
										
										
										
											2001-11-29 03:26:37 +00:00
										 |  |  | 				PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  | 					"more argument specifiers than " | 
					
						
							|  |  |  | 					"keyword list entries"); | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 				return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			p++; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 		else if (i == '|') | 
					
						
							|  |  |  | 			min = max; | 
					
						
							|  |  |  | 		else if (i == ':') { | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			fname = format; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (i == ';') { | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			message = format; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (i == '(') { | 
					
						
							| 
									
										
										
										
											2001-11-29 03:26:37 +00:00
										 |  |  | 			PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  | 				"tuple found in format when using keyword " | 
					
						
							|  |  |  | 				"arguments"); | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	format = formatsave; | 
					
						
							|  |  |  | 	if (*p != NULL) { | 
					
						
							| 
									
										
										
										
											2001-11-29 03:26:37 +00:00
										 |  |  | 		PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  | 			"more keyword list entries than " | 
					
						
							|  |  |  | 			"argument specifiers"); | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 	if (min < 0) { | 
					
						
							|  |  |  | 		/* All arguments are required. */ | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		min = max; | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-27 04:38:11 +00:00
										 |  |  | 	nargs = PyTuple_GET_SIZE(args); | 
					
						
							| 
									
										
										
										
											2001-10-27 04:45:34 +00:00
										 |  |  | 	nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); | 
					
						
							| 
									
										
										
										
											2001-10-27 04:26:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	/* 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 */ | 
					
						
							| 
									
										
										
										
											2001-10-27 05:07:41 +00:00
										 |  |  | 	if (nkeywords > 0) { | 
					
						
							| 
									
										
										
										
											2001-10-27 04:38:11 +00:00
										 |  |  | 		for (i = 0; i < nargs; i++) { | 
					
						
							| 
									
										
										
										
											2001-10-27 00:46:09 +00:00
										 |  |  | 			char *thiskw = kwlist[i]; | 
					
						
							|  |  |  | 			if (thiskw == NULL) | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2001-10-27 05:50:39 +00:00
										 |  |  | 			if (PyDict_GetItemString(keywords, thiskw)) { | 
					
						
							| 
									
										
										
										
											2001-10-27 05:07:41 +00:00
										 |  |  | 				PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 					"keyword parameter '%s' was given " | 
					
						
							|  |  |  | 					"by position and by name", | 
					
						
							| 
									
										
										
										
											2001-10-27 00:46:09 +00:00
										 |  |  | 					thiskw); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-10-27 06:14:32 +00:00
										 |  |  | 			else if (PyErr_Occurred()) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-10-27 05:30:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	/* required arguments missing from args can be supplied by keyword 
 | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 	   arguments; set len to the number of posiitional arguments, and, | 
					
						
							|  |  |  | 	   if that's less than the minimum required, add in the number of | 
					
						
							|  |  |  | 	   required arguments that are supplied by keywords */ | 
					
						
							| 
									
										
										
										
											2001-10-27 04:38:11 +00:00
										 |  |  | 	len = nargs; | 
					
						
							| 
									
										
										
										
											2001-10-27 06:42:16 +00:00
										 |  |  | 	if (nkeywords > 0 && nargs < min) { | 
					
						
							| 
									
										
										
										
											2001-10-27 04:38:11 +00:00
										 |  |  | 		for (i = nargs; i < min; i++) { | 
					
						
							| 
									
										
										
										
											2001-10-27 05:50:39 +00:00
										 |  |  | 			if (PyDict_GetItemString(keywords, kwlist[i])) | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				len++; | 
					
						
							| 
									
										
										
										
											2001-10-27 06:14:32 +00:00
										 |  |  | 			else if (PyErr_Occurred()) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-10-27 06:14:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	/* 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) { | 
					
						
							| 
									
										
										
										
											2001-11-28 20:29:22 +00:00
										 |  |  | 			PyOS_snprintf(msgbuf, sizeof(msgbuf), | 
					
						
							|  |  |  | 				      "%.200s%s takes %s %d argument%s " | 
					
						
							|  |  |  | 				      "(%d given)", | 
					
						
							|  |  |  | 				      fname==NULL ? "function" : fname, | 
					
						
							|  |  |  | 				      fname==NULL ? "" : "()", | 
					
						
							|  |  |  | 				      min==max ? "exactly" | 
					
						
							|  |  |  | 			              : len < min ? "at least" : "at most", | 
					
						
							|  |  |  | 				      len < min ? min : max, | 
					
						
							|  |  |  | 				      (len < min ? min : max) == 1 ? "" : "s", | 
					
						
							|  |  |  | 				      len); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			message = msgbuf; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, message); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* convert the positional arguments */ | 
					
						
							| 
									
										
										
										
											2001-10-27 04:38:11 +00:00
										 |  |  | 	for (i = 0; i < nargs; i++) { | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		if (*format == '|') | 
					
						
							|  |  |  | 			format++; | 
					
						
							| 
									
										
										
										
											2001-05-18 20:57:38 +00:00
										 |  |  | 		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				  levels, msgbuf, sizeof(msgbuf), &freelist); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		if (msg) { | 
					
						
							|  |  |  | 			seterror(i+1, msg, levels, fname, message); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 	/* handle no keyword parameters in call */	 | 
					
						
							| 
									
										
										
										
											2001-10-27 05:07:41 +00:00
										 |  |  | 	if (nkeywords == 0) | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 		return cleanreturn(1, freelist); | 
					
						
							| 
									
										
										
										
											2001-10-27 05:07:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	/* convert the keyword arguments; this uses the format 
 | 
					
						
							|  |  |  | 	   string where it was left after processing args */ | 
					
						
							| 
									
										
										
										
											2001-10-27 07:00:56 +00:00
										 |  |  | 	for (i = nargs; i < max; i++) { | 
					
						
							| 
									
										
										
										
											1997-04-29 20:08:16 +00:00
										 |  |  | 		PyObject *item; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		if (*format == '|') | 
					
						
							|  |  |  | 			format++; | 
					
						
							| 
									
										
										
										
											2001-10-27 05:50:39 +00:00
										 |  |  | 		item = PyDict_GetItemString(keywords, kwlist[i]); | 
					
						
							| 
									
										
										
										
											1996-12-05 23:27:02 +00:00
										 |  |  | 		if (item != NULL) { | 
					
						
							| 
									
										
										
										
											2001-10-27 05:50:39 +00:00
										 |  |  | 			Py_INCREF(item); | 
					
						
							| 
									
										
										
										
											2001-11-28 22:14:37 +00:00
										 |  |  | 			msg = convertitem(item, &format, p_va, levels, msgbuf, | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 					  sizeof(msgbuf), &freelist); | 
					
						
							| 
									
										
										
										
											2001-10-27 05:50:39 +00:00
										 |  |  | 			Py_DECREF(item); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			if (msg) { | 
					
						
							|  |  |  | 				seterror(i+1, msg, levels, fname, message); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 			--nkeywords; | 
					
						
							|  |  |  | 			if (nkeywords == 0) | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-10-27 06:14:32 +00:00
										 |  |  | 		else if (PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 			return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		else { | 
					
						
							|  |  |  | 			msg = skipitem(&format, p_va); | 
					
						
							|  |  |  | 			if (msg) { | 
					
						
							|  |  |  | 				seterror(i+1, msg, levels, fname, message); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-10-27 05:07:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 	/* make sure there are no extraneous keyword arguments */ | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 	if (nkeywords > 0) { | 
					
						
							|  |  |  | 		PyObject *key, *value; | 
					
						
							|  |  |  | 		int pos = 0; | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 		while (PyDict_Next(keywords, &pos, &key, &value)) { | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 			int match = 0; | 
					
						
							| 
									
										
										
										
											2002-04-04 16:22:30 +00:00
										 |  |  | 			char *ks; | 
					
						
							|  |  |  | 			if (!PyString_Check(key)) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_TypeError,  | 
					
						
							|  |  |  | 					        "keywords must be strings"); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											2002-04-04 16:22:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			ks = PyString_AsString(key); | 
					
						
							| 
									
										
										
										
											2001-10-27 07:00:56 +00:00
										 |  |  | 			for (i = 0; i < max; i++) { | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 				if (!strcmp(ks, kwlist[i])) { | 
					
						
							|  |  |  | 					match = 1; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!match) { | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 				PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 					     "'%s' is an invalid keyword " | 
					
						
							|  |  |  | 					     "argument for this function", | 
					
						
							|  |  |  | 					     ks); | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 				return cleanreturn(0, freelist); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-10-27 07:25:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-03 10:00:22 +00:00
										 |  |  | 	return cleanreturn(1, freelist); | 
					
						
							| 
									
										
										
										
											1996-08-19 19:32:04 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2003-03-29 10:06:18 +00:00
										 |  |  | 	case 'L': /* PY_LONG_LONG int */ | 
					
						
							| 
									
										
										
										
											1998-08-04 22:46:29 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2003-03-29 10:06:18 +00:00
										 |  |  | 			(void) va_arg(*p_va, PY_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; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2001-10-23 21:09:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | PyArg_UnpackTuple(PyObject *args, char *name, int min, int max, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, l; | 
					
						
							|  |  |  | 	PyObject **o; | 
					
						
							|  |  |  | 	va_list vargs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_STDARG_PROTOTYPES
 | 
					
						
							|  |  |  | 	va_start(vargs, max); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	va_start(vargs); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert(min >= 0); | 
					
						
							|  |  |  | 	assert(min <= max); | 
					
						
							|  |  |  | 	if (!PyTuple_Check(args)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_SystemError, | 
					
						
							|  |  |  | 		    "PyArg_UnpackTuple() argument list is not a tuple"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	l = PyTuple_GET_SIZE(args); | 
					
						
							|  |  |  | 	if (l < min) { | 
					
						
							|  |  |  | 		if (name != NULL) | 
					
						
							|  |  |  | 			PyErr_Format( | 
					
						
							|  |  |  | 			    PyExc_TypeError, | 
					
						
							|  |  |  | 			    "%s expected %s%d arguments, got %d",  | 
					
						
							|  |  |  | 			    name, (min == max ? "" : "at least "), min, l); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			PyErr_Format( | 
					
						
							|  |  |  | 			    PyExc_TypeError, | 
					
						
							|  |  |  | 			    "unpacked tuple should have %s%d elements," | 
					
						
							|  |  |  | 			    " but has %d",  | 
					
						
							|  |  |  | 			    (min == max ? "" : "at least "), min, l); | 
					
						
							|  |  |  | 		va_end(vargs); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (l > max) { | 
					
						
							|  |  |  | 		if (name != NULL) | 
					
						
							|  |  |  | 			PyErr_Format( | 
					
						
							|  |  |  | 			    PyExc_TypeError, | 
					
						
							|  |  |  | 			    "%s expected %s%d arguments, got %d",  | 
					
						
							|  |  |  | 			    name, (min == max ? "" : "at most "), max, l); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			PyErr_Format( | 
					
						
							|  |  |  | 			    PyExc_TypeError, | 
					
						
							|  |  |  | 			    "unpacked tuple should have %s%d elements," | 
					
						
							|  |  |  | 			    " but has %d",  | 
					
						
							|  |  |  | 			    (min == max ? "" : "at most "), max, l); | 
					
						
							|  |  |  | 		va_end(vargs); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (i = 0; i < l; i++) { | 
					
						
							|  |  |  | 		o = va_arg(vargs, PyObject **); | 
					
						
							|  |  |  | 		*o = PyTuple_GET_ITEM(args, i); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	va_end(vargs); | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } |