/***********************************************************
Copyright (c) 2000, BeOpen.com.
Copyright (c) 1995-2000, Corporation for National Research Initiatives.
Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
All rights reserved.

See the file "Misc/COPYRIGHT" for information on usage and
redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
******************************************************************/

/* 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>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif


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 requires no arguments",
				fname==NULL ? "function" : fname);
			PyErr_SetString(PyExc_TypeError, msgbuf);
			return 0;
		}
		else if (min == 1 && max == 1) {
			if (args == NULL) {
				sprintf(msgbuf,
					"%s requires at least one argument",
					fname==NULL ? "function" : fname);
				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 requires %s %d argument%s; %d given",
				fname==NULL ? "function" : fname,
				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;
	if (iarg == 0 && message == NULL)
		message = msg;
	else if (message == NULL) {
		if (fname != NULL) {
			sprintf(p, "%s, ", fname);
			p += strlen(p);
		}
		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++;
		}
		sprintf(p, ": expected %s found", 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:
         "<typename1>, <typename2>", where:
            <typename1> is the name of the expected type, and
            <typename2> is the name of the actual type,
         (so you can surround it by "expected ... found"),
      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)) {
		levels[0] = 0;
		sprintf(msgbuf,
			toplevel ? "%d arguments, %s" : "%d-sequence, %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 ? "%d arguments, %d" : "%d-sequence, %d-sequence",
		    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 appending ", <actual argument type>" to error message. */

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, "%.50s, %.50s", msg,
			arg == Py_None ? "None" : arg->ob_type->tp_name);
		msg = msgbuf;
	}
	return msg;
}


/* Internal API needed by convertsimple1(): */
extern 
PyObject *_PyUnicode_AsUTF8String(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 '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': /* unsigned short int */
		{
			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 < 0) {
				PyErr_SetString(PyExc_OverflowError,
			      "unsigned short integer is less than minimum");
				return "integer<H>";
			}
			else if (ival > USHRT_MAX) {
				PyErr_SetString(PyExc_OverflowError,
			      "unsigned short integer 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 == '#') { /* 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 "read-only buffer";
				if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
				  return "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_AsUTF8String(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 **);
				PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
				int *q = va_arg(*p_va, int *);
				int count;

				if (arg == Py_None) {
				  *p = 0;
				  *q = 0;
				} else {
				  if ( pb == NULL ||
				       pb->bf_getreadbuffer == NULL ||
				       pb->bf_getsegcount == NULL )
				    return "read-only buffer";
				  if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
				  return "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_AsUTF8String(arg, NULL);
				  if (arg == NULL)
				      return "unicode conversion error";
				  *p = PyString_AS_STRING(arg);
				}
				else
				  return "None or string";
				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 "None or string without null bytes";
			}
			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)
				return "(encoding is NULL)";
			
			/* 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, 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 "read-only buffer";
				if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
				  return "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 "read-only character buffer";
			if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
				return "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 (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 requires %s %d argument%s; %d given",
				fname==NULL ? "function" : fname,
				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++;
		}
		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 */
		{
			(void) va_arg(*p_va, char *);
			break;
		}
	
	case 'h': /* short int */
		{
			(void) va_arg(*p_va, short *);
			break;
		}
	
	case 'H': /* unsigned short int */
		{
			(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;
}
