
/* New getargs implementation */

/* XXX There are several unchecked sprintf or strcat calls in this file.
   XXX The only way these can become a danger is if some C code in the
   XXX Python source (or in an extension) uses ridiculously long names
   XXX or ridiculously deep nesting in format strings. */

#include "Python.h"

#include <ctype.h>


int PyArg_Parse(PyObject *, char *, ...);
int PyArg_ParseTuple(PyObject *, char *, ...);
int PyArg_VaParse(PyObject *, char *, va_list);

int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
				char *, char **, ...);

/* Forward */
static int vgetargs1(PyObject *, char *, va_list *, int);
static void seterror(int, char *, int *, char *, char *);
static char *convertitem(PyObject *, char **, va_list *, int *, char *);
static char *converttuple(PyObject *, char **, va_list *,
			  int *, char *, int);
static char *convertsimple(PyObject *, char **, va_list *, char *);
static int convertbuffer(PyObject *, void **p, char **);

static int vgetargskeywords(PyObject *, PyObject *,
			    char *, char **, va_list *);
static char *skipitem(char **, va_list *);

int PyArg_Parse(PyObject *args, char *format, ...)
{
	int retval;
	va_list va;
	
	va_start(va, format);
	retval = vgetargs1(args, format, &va, 1);
	va_end(va);
	return retval;
}


int PyArg_ParseTuple(PyObject *args, char *format, ...)
{
	int retval;
	va_list va;
	
	va_start(va, format);
	retval = vgetargs1(args, format, &va, 0);
	va_end(va);
	return retval;
}


int
PyArg_VaParse(PyObject *args, char *format, va_list va)
{
	va_list lva;

#ifdef VA_LIST_IS_ARRAY
	memcpy(lva, va, sizeof(va_list));
#else
	lva = va;
#endif

	return vgetargs1(args, format, &lva, 0);
}


static int
vgetargs1(PyObject *args, char *format, va_list *p_va, int compat)
{
	char msgbuf[256];
	int levels[32];
	char *fname = NULL;
	char *message = NULL;
	int min = -1;
	int max = 0;
	int level = 0;
	int endfmt = 0;
	char *formatsave = format;
	int i, len;
	char *msg;
	
	assert(compat || (args != (PyObject*)NULL));

	while (endfmt == 0) {
		int c = *format++;
		switch (c) {
		case '(':
			if (level == 0)
				max++;
			level++;
			break;
		case ')':
			if (level == 0)
				Py_FatalError("excess ')' in getargs format");
			else
				level--;
			break;
		case '\0':
			endfmt = 1;
			break;
		case ':':
			fname = format;
			endfmt = 1;
			break;
		case ';':
			message = format;
			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;
			}
			break;
		}
	}
	
	if (level != 0)
		Py_FatalError(/* '(' */ "missing ')' in getargs format");
	
	if (min < 0)
		min = max;
	
	format = formatsave;
	
	if (compat) {
		if (max == 0) {
			if (args == NULL)
				return 1;
			sprintf(msgbuf, "%s%s takes no arguments",
				fname==NULL ? "function" : fname,
				fname==NULL ? "" : "()");
			PyErr_SetString(PyExc_TypeError, msgbuf);
			return 0;
		}
		else if (min == 1 && max == 1) {
			if (args == NULL) {
				sprintf(msgbuf,
					"%s%s takes at least one argument",
					fname==NULL ? "function" : fname,
					fname==NULL ? "" : "()");
				PyErr_SetString(PyExc_TypeError, msgbuf);
				return 0;
			}
			msg = convertitem(args, &format, p_va, levels, msgbuf);
			if (msg == NULL)
				return 1;
			seterror(levels[0], msg, levels+1, fname, message);
			return 0;
		}
		else {
			PyErr_SetString(PyExc_SystemError,
			    "old style getargs format uses new features");
			return 0;
		}
	}
	
	if (!PyTuple_Check(args)) {
		PyErr_SetString(PyExc_SystemError,
		    "new style getargs format but argument is not a tuple");
		return 0;
	}
	
	len = PyTuple_GET_SIZE(args);
	
	if (len < min || max < len) {
		if (message == NULL) {
			sprintf(msgbuf,
				"%s%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);
			message = msgbuf;
		}
		PyErr_SetString(PyExc_TypeError, message);
		return 0;
	}
	
	for (i = 0; i < len; i++) {
		if (*format == '|')
			format++;
		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
				  levels, msgbuf);
		if (msg) {
			seterror(i+1, msg, levels, fname, message);
			return 0;
		}
	}

	if (*format != '\0' && !isalpha((int)(*format)) &&
	    *format != '(' &&
	    *format != '|' && *format != ':' && *format != ';') {
		PyErr_Format(PyExc_SystemError,
			     "bad format string: %.200s", formatsave);
		return 0;
	}
	
	return 1;
}



static void
seterror(int iarg, char *msg, int *levels, char *fname, char *message)
{
	char buf[256];
	int i;
	char *p = buf;

	if (PyErr_Occurred())
		return;
	else if (message == NULL) {
		if (fname != NULL) {
			sprintf(p, "%s() ", fname);
			p += strlen(p);
		}
		if (iarg != 0) {
			sprintf(p, "argument %d", iarg);
			i = 0;
			p += strlen(p);
			while (levels[i] > 0) {
				sprintf(p, ", item %d", levels[i]-1);
				p += strlen(p);
				i++;
			}
		}
		else {
			sprintf(p, "argument");
			p += strlen(p);
		}
		sprintf(p, " %s", msg);
		message = buf;
	}
	PyErr_SetString(PyExc_TypeError, message);
}


/* 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:
         "must be <typename1>, not <typename2>", where:
            <typename1> is the name of the expected type, and
            <typename2> is the name of the actual type,
      and msgbuf is returned.
*/

static char *
converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels,
	     char *msgbuf, int toplevel)
{
	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++;
	}
	
	if (!PySequence_Check(arg) || PyString_Check(arg)) {
		levels[0] = 0;
		sprintf(msgbuf,
			toplevel ? "expected %d arguments, not %s" :
				   "must be %d-item sequence, not %s",
			n, arg == Py_None ? "None" : arg->ob_type->tp_name);
		return msgbuf;
	}
	
	if ((i = PySequence_Size(arg)) != n) {
		levels[0] = 0;
		sprintf(msgbuf,
			toplevel ? "expected %d arguments, not %d" :
				   "must be sequence of length %d, not %d",
			n, i);
		return msgbuf;
	}

	format = *p_format;
	for (i = 0; i < n; i++) {
		char *msg;
		PyObject *item;
		item = PySequence_GetItem(arg, i);
		msg = convertitem(item, &format, p_va, levels+1, msgbuf);
		/* PySequence_GetItem calls tp->sq_item, which INCREFs */
		Py_XDECREF(item);
		if (msg != NULL) {
			levels[0] = i+1;
			return msg;
		}
	}

	*p_format = format;
	return NULL;
}


/* Convert a single item. */

static char *
convertitem(PyObject *arg, char **p_format, va_list *p_va, int *levels,
	    char *msgbuf)
{
	char *msg;
	char *format = *p_format;
	
	if (*format == '(' /* ')' */) {
		format++;
		msg = converttuple(arg, &format, p_va, levels, msgbuf, 0);
		if (msg == NULL)
			format++;
	}
	else {
		msg = convertsimple(arg, &format, p_va, msgbuf);
		if (msg != NULL)
			levels[0] = 0;
	}
	if (msg == NULL)
		*p_format = format;
	return msg;
}



#define UNICODE_DEFAULT_ENCODING(arg) \
        _PyUnicode_AsDefaultEncodedString(arg, NULL)

/* Format an error message generated by convertsimple(). */

static char *
converterr(char *expected, PyObject *arg, char *msgbuf)
{
	assert(expected != NULL);
	assert(arg != NULL); 
	sprintf(msgbuf, "must be %.50s, not %.50s", expected,
		arg == Py_None ? "None" : arg->ob_type->tp_name);
	return msgbuf;
}

#define CONV_UNICODE "(unicode conversion error)"

/* Convert a non-tuple argument.  Return NULL if conversion went OK,
   or a string with a message describing the failure.  The message is
   formatted as "must be <desired type>, not <actual type>".
   When failing, an exception may or may not have been raised.
   Don't call if a tuple is expected. 
*/

static char *
convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf)
{
	char *format = *p_format;
	char c = *format++;
	PyObject *uarg;
	
	switch (c) {
	
	case 'b': { /* unsigned byte -- very short int */
		char *p = va_arg(*p_va, char *);
		long ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<b>", arg, msgbuf);
		else if (ival < 0) {
			PyErr_SetString(PyExc_OverflowError,
			"unsigned byte integer is less than minimum");
			return converterr("integer<b>", arg, msgbuf);
		}
		else if (ival > UCHAR_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"unsigned byte integer is greater than maximum");
			return converterr("integer<b>", arg, msgbuf);
		}
		else
			*p = (unsigned char) ival;
		break;
	}
	
	case 'B': {/* byte sized bitfield - both signed and unsigned
		      values allowed */  
		char *p = va_arg(*p_va, char *);
		long ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<b>", arg, msgbuf);
		else if (ival < SCHAR_MIN) {
			PyErr_SetString(PyExc_OverflowError,
			"byte-sized integer bitfield is less than minimum");
			return converterr("integer<B>", arg, msgbuf);
		}
		else if (ival > (int)UCHAR_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"byte-sized integer bitfield is greater than maximum");
			return converterr("integer<B>", arg, msgbuf);
		}
		else
			*p = (unsigned char) ival;
		break;
	}
	
	case 'h': {/* signed short int */
		short *p = va_arg(*p_va, short *);
		long ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<h>", arg, msgbuf);
		else if (ival < SHRT_MIN) {
			PyErr_SetString(PyExc_OverflowError,
			"signed short integer is less than minimum");
			return converterr("integer<h>", arg, msgbuf);
		}
		else if (ival > SHRT_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"signed short integer is greater than maximum");
			return converterr("integer<h>", arg, msgbuf);
		}
		else
			*p = (short) ival;
		break;
	}
	
	case 'H': { /* short int sized bitfield, both signed and
		       unsigned allowed */ 
		unsigned short *p = va_arg(*p_va, unsigned short *);
		long ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<H>", arg, msgbuf);
		else if (ival < SHRT_MIN) {
			PyErr_SetString(PyExc_OverflowError,
			"short integer bitfield is less than minimum");
			return converterr("integer<H>", arg, msgbuf);
		}
		else if (ival > USHRT_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"short integer bitfield is greater than maximum");
			return converterr("integer<H>", arg, msgbuf);
		}
		else
			*p = (unsigned short) ival;
		break;
	}
	
	case 'i': {/* signed int */
		int *p = va_arg(*p_va, int *);
		long ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<i>", arg, msgbuf);
		else if (ival > INT_MAX) {
			PyErr_SetString(PyExc_OverflowError,
				"signed integer is greater than maximum");
			return converterr("integer<i>", arg, msgbuf);
		}
		else if (ival < INT_MIN) {
			PyErr_SetString(PyExc_OverflowError,
				"signed integer is less than minimum");
			return converterr("integer<i>", arg, msgbuf);
		}
		else
			*p = ival;
		break;
	}

	case 'l': {/* long int */
		long *p = va_arg(*p_va, long *);
		long ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<l>", arg, msgbuf);
		else
			*p = ival;
		break;
	}
	
#ifdef HAVE_LONG_LONG
	case 'L': {/* LONG_LONG */
		LONG_LONG *p = va_arg( *p_va, LONG_LONG * );
		LONG_LONG ival = PyLong_AsLongLong( arg );
		if( ival == (LONG_LONG)-1 && PyErr_Occurred() ) {
			return converterr("long<L>", arg, msgbuf);
		} else {
			*p = ival;
		}
		break;
	}
#endif
	
	case 'f': {/* float */
		float *p = va_arg(*p_va, float *);
		double dval = PyFloat_AsDouble(arg);
		if (PyErr_Occurred())
			return converterr("float<f>", arg, msgbuf);
		else
			*p = (float) dval;
		break;
	}
	
	case 'd': {/* double */
		double *p = va_arg(*p_va, double *);
		double dval = PyFloat_AsDouble(arg);
		if (PyErr_Occurred())
			return converterr("float<d>", arg, msgbuf);
		else
			*p = dval;
		break;
	}
	
#ifndef WITHOUT_COMPLEX
	case 'D': {/* complex double */
		Py_complex *p = va_arg(*p_va, Py_complex *);
		Py_complex cval;
		cval = PyComplex_AsCComplex(arg);
		if (PyErr_Occurred())
			return converterr("complex<D>", arg, msgbuf);
		else
			*p = cval;
		break;
	}
#endif /* WITHOUT_COMPLEX */
	
	case 'c': {/* char */
		char *p = va_arg(*p_va, char *);
		if (PyString_Check(arg) && PyString_Size(arg) == 1)
			*p = PyString_AS_STRING(arg)[0];
		else
			return converterr("char", arg, msgbuf);
		break;
	}
	
	case 's': {/* string */
		if (*format == '#') {
			void **p = (void **)va_arg(*p_va, char **);
			int *q = va_arg(*p_va, int *);
			
			if (PyString_Check(arg)) {
				*p = PyString_AS_STRING(arg);
				*q = PyString_GET_SIZE(arg);
			}
#ifdef Py_USING_UNICODE
			else if (PyUnicode_Check(arg)) {
				uarg = UNICODE_DEFAULT_ENCODING(arg);
				if (uarg == NULL)
					return converterr(CONV_UNICODE,
							  arg, msgbuf);
				*p = PyString_AS_STRING(uarg);
				*q = PyString_GET_SIZE(uarg);
			}
#endif
			else { /* any buffer-like object */
				char *buf;
				int count = convertbuffer(arg, p, &buf);
				if (count < 0)
					return converterr(buf, arg, msgbuf);
				*q = count;
			}
			format++;
		} else {
			char **p = va_arg(*p_va, char **);
			
			if (PyString_Check(arg))
				*p = PyString_AS_STRING(arg);
#ifdef Py_USING_UNICODE
			else if (PyUnicode_Check(arg)) {
				uarg = UNICODE_DEFAULT_ENCODING(arg);
				if (uarg == NULL)
					return converterr(CONV_UNICODE,
							  arg, msgbuf);
				*p = PyString_AS_STRING(uarg);
			}
#endif
			else
				return converterr("string", arg, msgbuf);
			if ((int)strlen(*p) != PyString_Size(arg))
				return converterr("string without null bytes",
						  arg, msgbuf);
		}
		break;
	}

	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);
			}
#ifdef Py_USING_UNICODE
			else if (PyUnicode_Check(arg)) {
				uarg = UNICODE_DEFAULT_ENCODING(arg);
				if (uarg == NULL)
					return converterr(CONV_UNICODE,
							  arg, msgbuf);
				*p = PyString_AS_STRING(uarg);
				*q = PyString_GET_SIZE(uarg);
			}
#endif
			else { /* any buffer-like object */
				char *buf;
				int count = convertbuffer(arg, p, &buf);
				if (count < 0)
					return converterr(buf, arg, msgbuf);
				*q = count;
			}
			format++;
		} else {
			char **p = va_arg(*p_va, char **);
			
			if (arg == Py_None)
				*p = 0;
			else if (PyString_Check(arg))
				*p = PyString_AS_STRING(arg);
#ifdef Py_USING_UNICODE
			else if (PyUnicode_Check(arg)) {
				uarg = UNICODE_DEFAULT_ENCODING(arg);
				if (uarg == NULL)
					return converterr(CONV_UNICODE,
							  arg, msgbuf);
				*p = PyString_AS_STRING(uarg);
			}
#endif
			else
				return converterr("string or None", 
						  arg, msgbuf);
			if (*format == '#') {
				int *q = va_arg(*p_va, int *);
				if (arg == Py_None)
					*q = 0;
				else
					*q = PyString_Size(arg);
				format++;
			}
			else if (*p != NULL &&
				 (int)strlen(*p) != PyString_Size(arg))
				return converterr(
					"string without null bytes or None", 
					arg, msgbuf);
		}
		break;
	}
	
	case 'e': {/* encoded string */
		char **buffer;
		const char *encoding;
		PyObject *s;
		int size, recode_strings;

		/* Get 'e' parameter: the encoding name */
		encoding = (const char *)va_arg(*p_va, const char *);
#ifdef Py_USING_UNICODE
		if (encoding == NULL)
			encoding = PyUnicode_GetDefaultEncoding();
#endif
			
		/* 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)",
				arg, msgbuf);
		buffer = (char **)va_arg(*p_va, char **);
		format++;
		if (buffer == NULL)
			return converterr("(buffer is NULL)", 
					  arg, msgbuf);
			
		/* Encode object */
		if (!recode_strings && PyString_Check(arg)) {
			s = arg;
			Py_INCREF(s);
		}
		else {
#ifdef Py_USING_UNICODE
		    	PyObject *u;

			/* Convert object to Unicode */
			u = PyUnicode_FromObject(arg);
			if (u == NULL)
				return converterr(
					"string or unicode or text buffer", 
					arg, msgbuf);
			
			/* Encode object; use default error handling */
			s = PyUnicode_AsEncodedString(u,
						      encoding,
						      NULL);
			Py_DECREF(u);
			if (s == NULL)
				return converterr("(encoding failed)",
						  arg, msgbuf);
			if (!PyString_Check(s)) {
				Py_DECREF(s);
				return converterr(
					"(encoder failed to return a string)",
					arg, msgbuf);
			}
#else
			return converterr("string<e>", arg, msgbuf);
#endif
		}
		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 *);

			format++;
			if (buffer_len == NULL)
				return converterr(
					"(buffer_len is NULL)",
					arg, msgbuf);
			if (*buffer == NULL) {
				*buffer = PyMem_NEW(char, size + 1);
				if (*buffer == NULL) {
					Py_DECREF(s);
					return converterr(
						"(memory error)",
						arg, msgbuf);
				}
			} else {
				if (size + 1 > *buffer_len) {
					Py_DECREF(s);
					return converterr(
						"(buffer overflow)", 
						arg, msgbuf);
				}
			}
			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

			*/
			if ((int)strlen(PyString_AS_STRING(s)) != size)
				return converterr(
					"(encoded string without NULL bytes)",
					arg, msgbuf);
			*buffer = PyMem_NEW(char, size + 1);
			if (*buffer == NULL) {
				Py_DECREF(s);
				return converterr("(memory error)",
						  arg, msgbuf);
			}
			memcpy(*buffer,
			       PyString_AS_STRING(s),
			       size + 1);
		}
		Py_DECREF(s);
		break;
	}

#ifdef Py_USING_UNICODE
	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 *);
			char *buf;
			int count = convertbuffer(arg, p, &buf);

			if (count < 0)
				return converterr(buf, arg, msgbuf);
			*q = count/(sizeof(Py_UNICODE)); 
			format++;
		} else {
			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
			
			if (PyUnicode_Check(arg))
				*p = PyUnicode_AS_UNICODE(arg);
			else
				return converterr("unicode", arg, msgbuf);
		}
		break;
	}
#endif

	case 'S': { /* string object */
		PyObject **p = va_arg(*p_va, PyObject **);
		if (PyString_Check(arg))
			*p = arg;
		else
			return converterr("string", arg, msgbuf);
		break;
	}
	
#ifdef Py_USING_UNICODE
	case 'U': { /* Unicode object */
		PyObject **p = va_arg(*p_va, PyObject **);
		if (PyUnicode_Check(arg))
			*p = arg;
		else
			return converterr("unicode", arg, msgbuf);
		break;
	}
#endif
	
	case 'O': { /* object */
		PyTypeObject *type;
		PyObject **p;
		if (*format == '!') {
			type = va_arg(*p_va, PyTypeObject*);
			p = va_arg(*p_va, PyObject **);
			format++;
			if (PyType_IsSubtype(arg->ob_type, type))
				*p = arg;
			else
				return converterr(type->tp_name, arg, msgbuf);

		}
		else if (*format == '?') {
			inquiry pred = va_arg(*p_va, inquiry);
			p = va_arg(*p_va, PyObject **);
			format++;
			if ((*pred)(arg)) 
				*p = arg;
			else
				return converterr("(unspecified)", 
						  arg, msgbuf);
				
		}
		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)", 
						  arg, msgbuf);
		}
		else {
			p = va_arg(*p_va, PyObject **);
			*p = arg;
		}
		break;
	}
		
		
	case 'w': { /* memory buffer, read-write access */
		void **p = va_arg(*p_va, void **);
		PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
		int count;
			
		if (pb == NULL || 
		    pb->bf_getwritebuffer == NULL ||
		    pb->bf_getsegcount == NULL)
			return converterr("read-write buffer", arg, msgbuf);
		if ((*pb->bf_getsegcount)(arg, NULL) != 1)
			return converterr("single-segment read-write buffer", 
					  arg, msgbuf);
		if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0)
			return converterr("(unspecified)", arg, msgbuf);
		if (*format == '#') {
			int *q = va_arg(*p_va, int *);
			
			*q = count;
			format++;
		}
		break;
	}
		
	case 't': { /* 8-bit character buffer, read-only access */
		const char **p = va_arg(*p_va, const char **);
		PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
		int count;
		
		if (*format++ != '#')
			return converterr(
				"invalid use of 't' format character", 
				arg, msgbuf);
		if (!PyType_HasFeature(arg->ob_type,
				       Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
		    pb == NULL || pb->bf_getcharbuffer == NULL ||
		    pb->bf_getsegcount == NULL)
			return converterr(
				"string or read-only character buffer",
				arg, msgbuf);

		if (pb->bf_getsegcount(arg, NULL) != 1)
			return converterr(
				"string or single-segment read-only buffer",
				arg, msgbuf);

		count = pb->bf_getcharbuffer(arg, 0, p);
		if (count < 0)
			return converterr("(unspecified)", arg, msgbuf);
		*va_arg(*p_va, int *) = count;
		break;
	}

	default:
		return converterr("impossible<bad format char>", arg, msgbuf);
	
	}
	
	*p_format = format;
	return NULL;
}

int convertbuffer(PyObject *arg, void **p, char **errmsg)
{
	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;
}

/* Support for keyword arguments donated by
   Geoff Philbrick <philbric@delphi.hks.com> */

int PyArg_ParseTupleAndKeywords(PyObject *args,
				PyObject *keywords,
				char *format, 
				char **kwlist, ...)
{
	int retval;
	va_list va;
	
	va_start(va, kwlist);
	retval = vgetargskeywords(args, keywords, format, kwlist, &va);	
	va_end(va);
	return retval;
}


static int
vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
	         char **kwlist, va_list *p_va)
{
	char msgbuf[256];
	int levels[32];
	char *fname = NULL;
	char *message = NULL;
	int min = -1;
	int max = 0;
	char *formatsave = format;
	int i, len, tplen, kwlen;
	char *msg, *ks, **p;
	int nkwds, pos, match, converted;
	PyObject *key, *value;
	
	/* nested tuples cannot be parsed when using keyword arguments */
	
	for (;;) {
		int c = *format++;
		if (c == '(') {
			PyErr_SetString(PyExc_SystemError,
		      "tuple found in format when using keyword arguments");
			return 0;
		}
		else if (c == '\0')
			break;
		else if (c == ':') {
			fname = format;
			break;
		} else if (c == ';') {
			message = format;
			break;
		} else if (c == 'e')
			; /* Pass */
		else if (isalpha(c))
			max++;
		else if (c == '|')
			min = max;
	}	
	
	if (min < 0)
		min = max;
	
	format = formatsave;
	
	if (!PyTuple_Check(args)) {
		PyErr_SetString(PyExc_SystemError,
		    "new style getargs format but argument is not a tuple");
		return 0;
	}	
	
	tplen = PyTuple_GET_SIZE(args);
	
	/* do a cursory check of the keywords just to see how many we got */
	   
	if (keywords) { 	
		if (!PyDict_Check(keywords)) {
			if (keywords == NULL)
				PyErr_SetString(PyExc_SystemError,
		     "NULL received when keyword dictionary expected");
			else
				PyErr_Format(PyExc_SystemError,
		     "%s received when keyword dictionary expected",
					     keywords->ob_type->tp_name);
			return 0;
		}	
		kwlen = PyDict_Size(keywords);
	}
	else {
		kwlen = 0;
	}
			
	/* make sure there are no duplicate values for an argument;
	   its not clear when to use the term "keyword argument vs. 
	   keyword parameter in messages */
	
	if (keywords) {
		for (i = 0; i < tplen; i++) {
			if (PyMapping_HasKeyString(keywords, kwlist[i])) {
				sprintf(msgbuf,
					"keyword parameter %s redefined",
					kwlist[i]);
				PyErr_SetString(PyExc_TypeError, msgbuf);
				return 0;
			}
		}
	}
	PyErr_Clear(); /* I'm not which Py functions set the error string */
		
	/* required arguments missing from args can be supplied by keyword 
	   arguments */
	
	len = tplen;
	if (keywords && tplen < min) {
		for (i = tplen; i < min; i++) {
		  if (PyMapping_HasKeyString(keywords, kwlist[i])) {
				len++;
		  }
		}
	}
	PyErr_Clear();	
	
	/* make sure we got an acceptable number of arguments; the message
	   is a little confusing with keywords since keyword arguments
	   which are supplied, but don't match the required arguments
	   are not included in the "%d given" part of the message */

	if (len < min || max < len) {
		if (message == NULL) {
			sprintf(msgbuf,
				"%s%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);
			message = msgbuf;
		}
		PyErr_SetString(PyExc_TypeError, message);
		return 0;
	}
	
	for (i = 0; i < tplen; i++) {
		if (*format == '|')
			format++;
		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
				 levels, msgbuf);
		if (msg) {
			seterror(i+1, msg, levels, fname, message);
			return 0;
		}
	}

	/* handle no keyword parameters in call  */	
	   	   
	if (!keywords) return 1; 
		
	/* make sure the number of keywords in the keyword list matches the 
	   number of items in the format string */
	  
	nkwds = 0;
	p =  kwlist;
	for (;;) {
		if (!*(p++)) break;
		nkwds++;
	}

	if (nkwds != max) {
		PyErr_SetString(PyExc_SystemError,
	  "number of items in format string and keyword list do not match");
		return 0;
	}	  	  
			
	/* convert the keyword arguments; this uses the format 
	   string where it was left after processing args */
	
	converted = 0;
	for (i = tplen; i < nkwds; i++) {
		PyObject *item;
		if (*format == '|')
			format++;
		item = PyMapping_GetItemString(keywords, kwlist[i]);
		if (item != NULL) {
			msg = convertitem(item, &format, p_va, levels, msgbuf);
			if (msg) {
				seterror(i+1, msg, levels, fname, message);
				return 0;
			}
			converted++;
			Py_DECREF(item);
		}
		else {
			PyErr_Clear();
			msg = skipitem(&format, p_va);
			if (msg) {
				seterror(i+1, msg, levels, fname, message);
				return 0;
			}
		}
	}
	
	/* make sure there are no extraneous keyword arguments */
	
	pos = 0;
	if (converted < kwlen) {
		while (PyDict_Next(keywords, &pos, &key, &value)) {
			match = 0;
			ks = PyString_AsString(key);
			for (i = 0; i < nkwds; i++) {
				if (!strcmp(ks, kwlist[i])) {
					match = 1;
					break;
				}
			}
			if (!match) {
				sprintf(msgbuf,
			"%s is an invalid keyword argument for this function",
					ks);
				PyErr_SetString(PyExc_TypeError, msgbuf);
				return 0;
			}
		}
	}
	
	return 1;
}


static char *
skipitem(char **p_format, va_list *p_va)
{
	char *format = *p_format;
	char c = *format++;
	
	switch (c) {
	
	case 'b': /* byte -- very short int */
	case 'B': /* byte as bitfield */
		{
			(void) va_arg(*p_va, char *);
			break;
		}
	
	case 'h': /* short int */
		{
			(void) va_arg(*p_va, short *);
			break;
		}
	
	case 'H': /* short int as bitfield */
		{
			(void) va_arg(*p_va, unsigned short *);
			break;
		}
	
	case 'i': /* int */
		{
			(void) va_arg(*p_va, int *);
			break;
		}
	
	case 'l': /* long int */
		{
			(void) va_arg(*p_va, long *);
			break;
		}
	
#ifdef HAVE_LONG_LONG
	case 'L': /* LONG_LONG int */
		{
			(void) va_arg(*p_va, LONG_LONG *);
			break;
		}
#endif
	
	case 'f': /* float */
		{
			(void) va_arg(*p_va, float *);
			break;
		}
	
	case 'd': /* double */
		{
			(void) va_arg(*p_va, double *);
			break;
		}
	
#ifndef WITHOUT_COMPLEX
	case 'D': /* complex double */
		{
			(void) va_arg(*p_va, Py_complex *);
			break;
		}
#endif /* WITHOUT_COMPLEX */
	
	case 'c': /* char */
		{
			(void) va_arg(*p_va, char *);
			break;
		}
	
	case 's': /* string */
		{
			(void) va_arg(*p_va, char **);
			if (*format == '#') {
				(void) va_arg(*p_va, int *);
				format++;
			}
			break;
		}
	
	case 'z': /* string */
		{
			(void) va_arg(*p_va, char **);
			if (*format == '#') {
				(void) va_arg(*p_va, int *);
				format++;
			}
			break;
		}
	
	case 'S': /* string object */
		{
			(void) va_arg(*p_va, PyObject **);
			break;
		}
	
	case 'O': /* object */
		{
			if (*format == '!') {
				format++;
				(void) va_arg(*p_va, PyTypeObject*);
				(void) va_arg(*p_va, PyObject **);
			}
#if 0
/* I don't know what this is for */
			else if (*format == '?') {
				inquiry pred = va_arg(*p_va, inquiry);
				format++;
				if ((*pred)(arg)) {
					(void) va_arg(*p_va, PyObject **);
				}
			}
#endif
			else if (*format == '&') {
				typedef int (*converter)(PyObject *, void *);
				(void) va_arg(*p_va, converter);
				(void) va_arg(*p_va, void *);
				format++;
			}
			else {
				(void) va_arg(*p_va, PyObject **);
			}
			break;
		}
	
	default:
		return "impossible<bad format char>";
	
	}
	
	*p_format = format;
	return NULL;
}
