
/* 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 char *convertsimple1(PyObject *, char **, va_list *);

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;
	char *formatsave = format;
	int i, len;
	char *msg;
	
	for (;;) {
		int c = *format++;
		if (c == '(' /* ')' */) {
			if (level == 0)
				max++;
			level++;
		}
		else if (/* '(' */ c == ')') {
			if (level == 0)
				Py_FatalError(/* '(' */
				      "excess ')' in getargs format");
			else
				level--;
		}
		else if (c == '\0')
			break;
		else if (c == ':') {
			fname = format;
			break;
		}
		else if (c == ';') {
			message = format;
			break;
		}
		else if (level != 0)
			; /* Pass */
		else if (c == 'e')
			; /* Pass */
		else if (isalpha(c))
			max++;
		else if (c == '|')
			min = max;
	}
	
	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_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_GetItem(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;
}


/* Convert a non-tuple argument.  Adds to convertsimple1 functionality
   by formatting messages as "must be <desired type>, not <actual type>". */

static char *
convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf)
{
	char *msg = convertsimple1(arg, p_format, p_va);
	if (msg != NULL) {
		sprintf(msgbuf, "must be %.50s, not %.50s", msg,
			arg == Py_None ? "None" : arg->ob_type->tp_name);
		msg = msgbuf;
	}
	return msg;
}


/* Internal API needed by convertsimple1(): */
extern 
PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
				  const char *errors);

/* Convert a non-tuple argument.  Return NULL if conversion went OK,
   or a string representing the expected type if the conversion failed.
   When failing, an exception may or may not have been raised.
   Don't call if a tuple is expected. */

static char *
convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
{
	char *format = *p_format;
	char c = *format++;
	
	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 "integer<b>";
			else if (ival < 0) {
				PyErr_SetString(PyExc_OverflowError,
			      "unsigned byte integer is less than minimum");
				return "integer<b>";
			}
			else if (ival > UCHAR_MAX) {
				PyErr_SetString(PyExc_OverflowError,
			      "unsigned byte integer is greater than maximum");
				return "integer<b>";
			}
			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 "integer<b>";
			else if (ival < SCHAR_MIN) {
				PyErr_SetString(PyExc_OverflowError,
			      "byte-sized integer bitfield is less than minimum");
				return "integer<B>";
			}
			else if (ival > (int)UCHAR_MAX) {
				PyErr_SetString(PyExc_OverflowError,
			      "byte-sized integer bitfield is greater than maximum");
				return "integer<B>";
			}
			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 "integer<h>";
			else if (ival < SHRT_MIN) {
				PyErr_SetString(PyExc_OverflowError,
			      "signed short integer is less than minimum");
				return "integer<h>";
			}
			else if (ival > SHRT_MAX) {
				PyErr_SetString(PyExc_OverflowError,
			      "signed short integer is greater than maximum");
				return "integer<h>";
			}
			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 "integer<H>";
			else if (ival < SHRT_MIN) {
				PyErr_SetString(PyExc_OverflowError,
			      "short integer bitfield is less than minimum");
				return "integer<H>";
			}
			else if (ival > USHRT_MAX) {
				PyErr_SetString(PyExc_OverflowError,
			      "short integer bitfield is greater than maximum");
				return "integer<H>";
			}
			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 "integer<i>";
			else if (ival > INT_MAX) {
				PyErr_SetString(PyExc_OverflowError,
				    "signed integer is greater than maximum");
				return "integer<i>";
			}
			else if (ival < INT_MIN) {
				PyErr_SetString(PyExc_OverflowError,
				    "signed integer is less than minimum");
				return "integer<i>";
			}
			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 "integer<l>";
			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 "long<L>";
			} else {
				*p = ival;
			}
			break;
		}
#endif
	
	case 'f': /* float */
		{
			float *p = va_arg(*p_va, float *);
			double dval = PyFloat_AsDouble(arg);
			if (PyErr_Occurred())
				return "float<f>";
			else
				*p = (float) dval;
			break;
		}
	
	case 'd': /* double */
		{
			double *p = va_arg(*p_va, double *);
			double dval = PyFloat_AsDouble(arg);
			if (PyErr_Occurred())
				return "float<d>";
			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 "complex<D>";
			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_AsString(arg)[0];
			else
				return "char";
			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);
				}
				else if (PyUnicode_Check(arg)) {
				    arg = _PyUnicode_AsDefaultEncodedString(
							            arg, NULL);
				    if (arg == NULL)
					return "(unicode conversion error)";
				    *p = PyString_AS_STRING(arg);
				    *q = PyString_GET_SIZE(arg);
				}
				else { /* any buffer-like object */
				    PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
				    int count;
				    if ( pb == NULL ||
					 pb->bf_getreadbuffer == NULL ||
					 pb->bf_getsegcount == NULL )
					return "string or read-only buffer";
				    if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
					return "string or single-segment read-only buffer";
				    if ( (count =
					  (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
					return "(unspecified)";
				    *q = count;
				}
				format++;
			} else {
				char **p = va_arg(*p_va, char **);
			
				if (PyString_Check(arg))
				    *p = PyString_AS_STRING(arg);
				else if (PyUnicode_Check(arg)) {
				    arg = _PyUnicode_AsDefaultEncodedString(
							            arg, NULL);
				    if (arg == NULL)
					return "(unicode conversion error)";
				    *p = PyString_AS_STRING(arg);
				}
				else
				  return "string";
				if ((int)strlen(*p) != PyString_Size(arg))
				  return "string without null bytes";
			}
			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);
				}
				else if (PyUnicode_Check(arg)) {
				    arg = _PyUnicode_AsDefaultEncodedString(
							            arg, NULL);
				    if (arg == NULL)
					return "(unicode conversion error)";
				    *p = PyString_AS_STRING(arg);
				    *q = PyString_GET_SIZE(arg);
				}
				else { /* any buffer-like object */
				    PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
				    int count;
				    if ( pb == NULL ||
					 pb->bf_getreadbuffer == NULL ||
					 pb->bf_getsegcount == NULL )
					return "string or read-only buffer";
				    if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
					return "string or single-segment read-only buffer";
				    if ( (count =
					  (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
					return "(unspecified)";
				    *q = count;
				}
				format++;
			} else {
				char **p = va_arg(*p_va, char **);
			
				if (arg == Py_None)
				  *p = 0;
				else if (PyString_Check(arg))
				  *p = PyString_AsString(arg);
				else if (PyUnicode_Check(arg)) {
				  arg = _PyUnicode_AsDefaultEncodedString(
								  arg, NULL);
				  if (arg == NULL)
				      return "(unicode conversion error)";
				  *p = PyString_AS_STRING(arg);
				}
				else
				  return "string or None";
				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 "string without null bytes or None";
			}
			break;
		}
	
	case 'e': /* encoded string */
		{
			char **buffer;
			const char *encoding;
			PyObject *u, *s;
			int size;

			/* Get 'e' parameter: the encoding name */
			encoding = (const char *)va_arg(*p_va, const char *);
			if (encoding == NULL)
			    	encoding = PyUnicode_GetDefaultEncoding();
			
			/* Get 's' parameter: the output buffer to use */
			if (*format != 's')
				return "(unknown parser marker combination)";
			buffer = (char **)va_arg(*p_va, char **);
			format++;
			if (buffer == NULL)
				return "(buffer is NULL)";
			
			/* Convert object to Unicode */
			u = PyUnicode_FromObject(arg);
			if (u == NULL)
				return "string or unicode or text buffer";
			
			/* Encode object; use default error handling */
			s = PyUnicode_AsEncodedString(u,
						      encoding,
						      NULL);
			Py_DECREF(u);
			if (s == NULL)
				return "(encoding failed)";
			if (!PyString_Check(s)) {
				Py_DECREF(s);
				return "(encoder failed to return a string)";
			}
			size = PyString_GET_SIZE(s);

			/* Write output; output is guaranteed to be
			   0-terminated */
			if (*format == '#') { 
				/* Using buffer length parameter '#':

				   - if *buffer is NULL, a new buffer
				   of the needed size is allocated and
				   the data copied into it; *buffer is
				   updated to point to the new buffer;
				   the caller is responsible for
				   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 "(buffer_len is NULL)";
				if (*buffer == NULL) {
					*buffer = PyMem_NEW(char, size + 1);
					if (*buffer == NULL) {
						Py_DECREF(s);
						return "(memory error)";
					}
				} else {
					if (size + 1 > *buffer_len) {
						Py_DECREF(s);
						return "(buffer overflow)";
					}
				}
				memcpy(*buffer,
				       PyString_AS_STRING(s),
				       size + 1);
				*buffer_len = size;
			} else {
				/* Using a 0-terminated buffer:

				   - the encoded string has to be
				   0-terminated for this variant to
				   work; if it is not, an error raised

				   - a new buffer of the needed size
				   is allocated and the data copied
				   into it; *buffer is updated to
				   point to the new buffer; the caller
				   is responsible for PyMem_Free()ing it
				   after usage

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

	case 'u': /* raw unicode buffer (Py_UNICODE *) */
		{
			if (*format == '#') { /* any buffer-like object */
				void **p = (void **)va_arg(*p_va, char **);
				PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
				int *q = va_arg(*p_va, int *);
				int count;

				if ( pb == NULL ||
				     pb->bf_getreadbuffer == NULL ||
				     pb->bf_getsegcount == NULL )
				  return "unicode or read-only buffer";
				if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
				  return "unicode or single-segment read-only buffer";
				if ( (count =
				      (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
				  return "(unspecified)";
				/* buffer interface returns bytes, we want
				   length in characters */
				*q = count/(sizeof(Py_UNICODE)); 
				format++;
			} else {
				Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
			
				if (PyUnicode_Check(arg))
				    *p = PyUnicode_AS_UNICODE(arg);
				else
				  return "unicode";
			}
			break;
		}

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

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

			if ( *format++ != '#' )
				return "invalid use of 't' format character";
			if ( !PyType_HasFeature(
				arg->ob_type,
				Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
			     pb == NULL ||
			     pb->bf_getcharbuffer == NULL ||
			     pb->bf_getsegcount == NULL )
				return "string or read-only character buffer";
			if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
				return "string or single-segment read-only buffer";
			if ( (count = pb->bf_getcharbuffer(arg, 0, p)) < 0 )
				return "(unspecified)";

			*va_arg(*p_va, int *) = count;

			break;
		}
		
	
	default:
		return "impossible<bad format char>";
	
	}
	
	*p_format = format;
	return NULL;
}


/* 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_Size(args);
	
	/* do a cursory check of the keywords just to see how many we got */
	   
	if (keywords) { 	
		if (!PyDict_Check(keywords)) {
			PyErr_SetString(PyExc_SystemError,
	  "non-dictionary object received when keyword dictionary expected");
			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_GetItem(args, i), &format, p_va,
				 levels, msgbuf);
		if (msg) {
			seterror(i+1, msg, levels, fname, message);
			return 0;
		}
	}

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

	if (nkwds != max) {
		PyErr_SetString(PyExc_SystemError,
	  "number of items in format string and keyword list do not match");
		return 0;
	}	  	  
			
	/* convert the keyword arguments; this uses the format 
	   string where it was left after processing args */
	
	converted = 0;
	for (i = tplen; i < nkwds; i++) {
		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;
}
