14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* New getargs implementation */
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h"
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <ctype.h>
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __cplusplus
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmextern "C" {
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint PyArg_Parse(PyObject *, const char *, ...);
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint PyArg_ParseTuple(PyObject *, const char *, ...);
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint PyArg_VaParse(PyObject *, const char *, va_list);
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                const char *, char **, ...);
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                const char *, char **, va_list);
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_DECLSPEC_DLL
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Export functions */
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                  const char *, char **, ...);
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                              const char *, char **, va_list);
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define FLAG_COMPAT 1
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define FLAG_SIZE_T 2
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Forward */
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int vgetargs1(PyObject *, const char *, va_list *, int);
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void seterror(int, const char *, int *, const char *, const char *);
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *convertitem(PyObject *, const char **, va_list *, int, int *,
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         char *, size_t, PyObject **);
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *converttuple(PyObject *, const char **, va_list *, int,
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          int *, char *, size_t, int, PyObject **);
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *convertsimple(PyObject *, const char **, va_list *, int, char *,
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           size_t, PyObject **);
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic Py_ssize_t convertbuffer(PyObject *, void **p, char **);
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int getbuffer(PyObject *, Py_buffer *, char**);
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int vgetargskeywords(PyObject *, PyObject *,
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            const char *, char **, va_list *, int);
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *skipitem(const char **, va_list *, int);
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyArg_Parse(PyObject *args, const char *format, ...)
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list va;
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(va, format);
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargs1(args, format, &va, FLAG_COMPAT);
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_end(va);
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyArg_Parse_SizeT(PyObject *args, char *format, ...)
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list va;
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(va, format);
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_end(va);
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyArg_ParseTuple(PyObject *args, const char *format, ...)
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list va;
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(va, format);
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargs1(args, format, &va, 0);
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_end(va);
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...)
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list va;
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(va, format);
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_end(va);
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyArg_VaParse(PyObject *args, const char *format, va_list va)
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list lva;
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef VA_LIST_IS_ARRAY
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(lva, va, sizeof(va_list));
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __va_copy
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __va_copy(lva, va);
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    lva = va;
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return vgetargs1(args, format, &lva, 0);
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list lva;
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef VA_LIST_IS_ARRAY
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(lva, va, sizeof(va_list));
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __va_copy
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __va_copy(lva, va);
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    lva = va;
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return vgetargs1(args, format, &lva, FLAG_SIZE_T);
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Handle cleanup of allocated memory in case of exception */
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcleanup_ptr(PyObject *self)
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ptr) {
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      PyMem_FREE(ptr);
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcleanup_buffer(PyObject *self)
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_buffer *ptr = (Py_buffer *)PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_BUFFER);
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ptr) {
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyBuffer_Release(ptr);
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmaddcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *cobj;
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *name;
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!*freelist) {
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *freelist = PyList_New(0);
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!*freelist) {
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            destr(ptr);
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return -1;
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (destr == cleanup_ptr) {
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else if (destr == cleanup_buffer) {
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else {
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    cobj = PyCapsule_New(ptr, name, destr);
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!cobj) {
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        destr(ptr);
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyList_Append(*freelist, cobj)) {
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(cobj);
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(cobj);
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcleanreturn(int retval, PyObject *freelist)
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (freelist && retval != 0) {
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* We were successful, reset the destructors so that they
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           don't get called. */
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t len = PyList_GET_SIZE(freelist), i;
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (i = 0; i < len; i++)
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyCapsule_SetDestructor(PyList_GET_ITEM(freelist, i), NULL);
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(freelist);
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char msgbuf[256];
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int levels[32];
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *fname = NULL;
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *message = NULL;
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int min = -1;
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int max = 0;
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int level = 0;
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int endfmt = 0;
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *formatsave = format;
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t i, len;
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *msg;
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *freelist = NULL;
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int compat = flags & FLAG_COMPAT;
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(compat || (args != (PyObject*)NULL));
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    flags = flags & ~FLAG_COMPAT;
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (endfmt == 0) {
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int c = *format++;
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        switch (c) {
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case '(':
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (level == 0)
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                max++;
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            level++;
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (level >= 30)
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_FatalError("too many tuple nesting levels "
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              "in argument format string");
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case ')':
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (level == 0)
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_FatalError("excess ')' in getargs format");
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                level--;
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case '\0':
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            endfmt = 1;
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case ':':
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            fname = format;
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            endfmt = 1;
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case ';':
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            message = format;
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            endfmt = 1;
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        default:
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (level == 0) {
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (c == 'O')
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    max++;
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else if (isalpha(Py_CHARMASK(c))) {
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if (c != 'e') /* skip encoded */
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        max++;
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                } else if (c == '|')
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    min = max;
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (level != 0)
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_FatalError(/* '(' */ "missing ')' in getargs format");
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (min < 0)
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        min = max;
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    format = formatsave;
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (compat) {
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (max == 0) {
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (args == NULL)
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 1;
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyOS_snprintf(msgbuf, sizeof(msgbuf),
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          "%.200s%s takes no arguments",
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          fname==NULL ? "function" : fname,
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          fname==NULL ? "" : "()");
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_TypeError, msgbuf);
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (min == 1 && max == 1) {
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (args == NULL) {
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyOS_snprintf(msgbuf, sizeof(msgbuf),
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "%.200s%s takes at least one argument",
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          fname==NULL ? "function" : fname,
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          fname==NULL ? "" : "()");
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_TypeError, msgbuf);
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 0;
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            msg = convertitem(args, &format, p_va, flags, levels,
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              msgbuf, sizeof(msgbuf), &freelist);
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (msg == NULL)
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return cleanreturn(1, freelist);
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            seterror(levels[0], msg, levels+1, fname, message);
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cleanreturn(0, freelist);
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_SystemError,
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "old style getargs format uses new features");
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyTuple_Check(args)) {
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_SystemError,
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "new style getargs format but argument is not a tuple");
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    len = PyTuple_GET_SIZE(args);
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (len < min || max < len) {
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (message == NULL) {
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyOS_snprintf(msgbuf, sizeof(msgbuf),
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          "%.150s%s takes %s %d argument%s "
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          "(%ld given)",
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          fname==NULL ? "function" : fname,
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          fname==NULL ? "" : "()",
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          min==max ? "exactly"
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          : len < min ? "at least" : "at most",
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          len < min ? min : max,
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          (len < min ? min : max) == 1 ? "" : "s",
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            message = msgbuf;
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_TypeError, message);
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < len; i++) {
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '|')
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          flags, levels, msgbuf,
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          sizeof(msgbuf), &freelist);
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (msg) {
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            seterror(i+1, msg, levels, fname, msg);
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cleanreturn(0, freelist);
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *format != '(' &&
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *format != '|' && *format != ':' && *format != ';') {
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_SystemError,
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "bad format string: %.200s", formatsave);
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return cleanreturn(0, freelist);
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return cleanreturn(1, freelist);
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmseterror(int iarg, const char *msg, int *levels, const char *fname,
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         const char *message)
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char buf[512];
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int i;
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *p = buf;
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyErr_Occurred())
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return;
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else if (message == NULL) {
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fname != NULL) {
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p += strlen(p);
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (iarg != 0) {
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyOS_snprintf(p, sizeof(buf) - (p - buf),
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          "argument %d", iarg);
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            i = 0;
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p += strlen(p);
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyOS_snprintf(p, sizeof(buf) - (p - buf),
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              ", item %d", levels[i]-1);
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                p += strlen(p);
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                i++;
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p += strlen(p);
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        message = buf;
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyErr_SetString(PyExc_TypeError, message);
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Convert a tuple argument.
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   On entry, *p_format points to the character _after_ the opening '('.
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   On successful exit, *p_format points to the closing ')'.
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   If successful:
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      *p_format and *p_va are updated,
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      *levels and *msgbuf are untouched,
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      and NULL is returned.
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   If the argument is invalid:
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      *p_format is unchanged,
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      *p_va is undefined,
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      *levels is a 0-terminated list of item numbers,
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      *msgbuf contains an error message, whose format is:
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     "must be <typename1>, not <typename2>", where:
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        <typename1> is the name of the expected type, and
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        <typename2> is the name of the actual type,
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm      and msgbuf is returned.
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmconverttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             int *levels, char *msgbuf, size_t bufsize, int toplevel,
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             PyObject **freelist)
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int level = 0;
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int n = 0;
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *format = *p_format;
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int i;
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (;;) {
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int c = *format++;
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (c == '(') {
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (level == 0)
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                n++;
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            level++;
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (c == ')') {
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (level == 0)
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                break;
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            level--;
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (c == ':' || c == ';' || c == '\0')
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (level == 0 && isalpha(Py_CHARMASK(c)))
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            n++;
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PySequence_Check(arg) || PyString_Check(arg)) {
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        levels[0] = 0;
4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyOS_snprintf(msgbuf, bufsize,
4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      toplevel ? "expected %d arguments, not %.50s" :
4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "must be %d-item sequence, not %.50s",
4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  n,
4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  arg == Py_None ? "None" : arg->ob_type->tp_name);
4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return msgbuf;
4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((i = PySequence_Size(arg)) != n) {
4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        levels[0] = 0;
4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyOS_snprintf(msgbuf, bufsize,
4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      toplevel ? "expected %d arguments, not %d" :
4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "must be sequence of length %d, not %d",
4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  n, i);
4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return msgbuf;
4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    format = *p_format;
4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < n; i++) {
4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char *msg;
4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *item;
4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        item = PySequence_GetItem(arg, i);
4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (item == NULL) {
4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Clear();
4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            levels[0] = i+1;
4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            levels[1] = 0;
4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strncpy(msgbuf, "is not retrievable", bufsize);
4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return msgbuf;
4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        msg = convertitem(item, &format, p_va, flags, levels+1,
4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          msgbuf, bufsize, freelist);
4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* PySequence_GetItem calls tp->sq_item, which INCREFs */
4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XDECREF(item);
4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (msg != NULL) {
4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            levels[0] = i+1;
4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return msg;
4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *p_format = format;
4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return NULL;
4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Convert a single item. */
4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *
5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmconvertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            int *levels, char *msgbuf, size_t bufsize, PyObject **freelist)
5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *msg;
5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *format = *p_format;
5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (*format == '(' /* ')' */) {
5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        format++;
5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           bufsize, 0, freelist);
5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (msg == NULL)
5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        msg = convertsimple(arg, &format, p_va, flags,
5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            msgbuf, bufsize, freelist);
5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (msg != NULL)
5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            levels[0] = 0;
5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (msg == NULL)
5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p_format = format;
5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return msg;
5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define UNICODE_DEFAULT_ENCODING(arg) \
5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyUnicode_AsDefaultEncodedString(arg, NULL)
5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Format an error message generated by convertsimple(). */
5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *
5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmconverterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(expected != NULL);
5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(arg != NULL);
5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyOS_snprintf(msgbuf, bufsize,
5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  "must be %.50s, not %.50s", expected,
5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  arg == Py_None ? "None" : arg->ob_type->tp_name);
5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return msgbuf;
5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define CONV_UNICODE "(unicode conversion error)"
5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* explicitly check for float arguments when integers are expected.  For now
5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * signal a warning.  Returns true if an exception was raised. */
5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfloat_argument_warning(PyObject *arg)
5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyFloat_Check(arg) &&
5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Warn(PyExc_DeprecationWarning,
5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                   "integer argument expected, got float" ))
5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else
5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* explicitly check for float arguments when integers are expected.  Raises
5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   TypeError and returns true for float arguments. */
5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfloat_argument_error(PyObject *arg)
5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyFloat_Check(arg)) {
5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_TypeError,
5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "integer argument expected, got float");
5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else
5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Convert a non-tuple argument.  Return NULL if conversion went OK,
5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   or a string with a message describing the failure.  The message is
5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   formatted as "must be <desired type>, not <actual type>".
5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   When failing, an exception may or may not have been raised.
5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Don't call if a tuple is expected.
5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   When you add new format codes, please don't forget poor skipitem() below.
5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/
5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *
5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmconvertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm              char *msgbuf, size_t bufsize, PyObject **freelist)
5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* For # codes */
5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define FETCH_SIZE      int *q=NULL;Py_ssize_t *q2=NULL;\
5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else q=va_arg(*p_va, int*);
5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define STORE_SIZE(s)   \
5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (flags & FLAG_SIZE_T) \
5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *q2=s; \
5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else { \
5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (INT_MAX < s) { \
5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_OverflowError, \
5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "size does not fit in an int"); \
5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("", arg, msgbuf, bufsize); \
5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } \
5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *q=s; \
5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define BUFFER_LEN      ((flags & FLAG_SIZE_T) ? *q2:*q)
6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *format = *p_format;
6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char c = *format++;
6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *uarg;
6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    switch (c) {
6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'b': { /* unsigned byte -- very short int */
6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char *p = va_arg(*p_va, char *);
6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        long ival;
6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<b>", arg, msgbuf, bufsize);
6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyInt_AsLong(arg);
6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == -1 && PyErr_Occurred())
6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<b>", arg, msgbuf, bufsize);
6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (ival < 0) {
6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_OverflowError,
6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "unsigned byte integer is less than minimum");
6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<b>", arg, msgbuf, bufsize);
6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (ival > UCHAR_MAX) {
6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_OverflowError,
6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "unsigned byte integer is greater than maximum");
6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<b>", arg, msgbuf, bufsize);
6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = (unsigned char) ival;
6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'B': {/* byte sized bitfield - both signed and unsigned
6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  values allowed */
6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char *p = va_arg(*p_va, char *);
6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        long ival;
6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<B>", arg, msgbuf, bufsize);
6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyInt_AsUnsignedLongMask(arg);
6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == -1 && PyErr_Occurred())
6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<B>", arg, msgbuf, bufsize);
6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = (unsigned char) ival;
6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'h': {/* signed short int */
6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        short *p = va_arg(*p_va, short *);
6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        long ival;
6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<h>", arg, msgbuf, bufsize);
6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyInt_AsLong(arg);
6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == -1 && PyErr_Occurred())
6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<h>", arg, msgbuf, bufsize);
6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (ival < SHRT_MIN) {
6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_OverflowError,
6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "signed short integer is less than minimum");
6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<h>", arg, msgbuf, bufsize);
6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (ival > SHRT_MAX) {
6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_OverflowError,
6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "signed short integer is greater than maximum");
6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<h>", arg, msgbuf, bufsize);
6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = (short) ival;
6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'H': { /* short int sized bitfield, both signed and
6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                   unsigned allowed */
6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned short *p = va_arg(*p_va, unsigned short *);
6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        long ival;
6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<H>", arg, msgbuf, bufsize);
6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyInt_AsUnsignedLongMask(arg);
6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == -1 && PyErr_Occurred())
6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<H>", arg, msgbuf, bufsize);
6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = (unsigned short) ival;
6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'i': {/* signed int */
6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int *p = va_arg(*p_va, int *);
6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        long ival;
6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<i>", arg, msgbuf, bufsize);
6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyInt_AsLong(arg);
6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == -1 && PyErr_Occurred())
6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<i>", arg, msgbuf, bufsize);
6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (ival > INT_MAX) {
6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_OverflowError,
6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "signed integer is greater than maximum");
6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<i>", arg, msgbuf, bufsize);
6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (ival < INT_MIN) {
6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_OverflowError,
6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "signed integer is less than minimum");
6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<i>", arg, msgbuf, bufsize);
7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = ival;
7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'I': { /* int sized bitfield, both signed and
7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                   unsigned allowed */
7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned int *p = va_arg(*p_va, unsigned int *);
7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned int ival;
7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<I>", arg, msgbuf, bufsize);
7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == (unsigned int)-1 && PyErr_Occurred())
7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<I>", arg, msgbuf, bufsize);
7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = ival;
7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'n': /* Py_ssize_t */
7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if SIZEOF_SIZE_T != SIZEOF_LONG
7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t ival;
7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<n>", arg, msgbuf, bufsize);
7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyInt_AsSsize_t(arg);
7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == -1 && PyErr_Occurred())
7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<n>", arg, msgbuf, bufsize);
7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p = ival;
7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Fall through from 'n' to 'l' if Py_ssize_t is int */
7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'l': {/* long int */
7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        long *p = va_arg(*p_va, long *);
7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        long ival;
7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_error(arg))
7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<l>", arg, msgbuf, bufsize);
7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyInt_AsLong(arg);
7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == -1 && PyErr_Occurred())
7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<l>", arg, msgbuf, bufsize);
7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = ival;
7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'k': { /* long sized bitfield */
7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned long *p = va_arg(*p_va, unsigned long *);
7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned long ival;
7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyInt_Check(arg))
7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ival = PyInt_AsUnsignedLongMask(arg);
7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (PyLong_Check(arg))
7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ival = PyLong_AsUnsignedLongMask(arg);
7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<k>", arg, msgbuf, bufsize);
7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p = ival;
7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_LONG_LONG
7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'L': {/* PY_LONG_LONG */
7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PY_LONG_LONG ival;
7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (float_argument_warning(arg))
7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("long<L>", arg, msgbuf, bufsize);
7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ival = PyLong_AsLongLong(arg);
7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("long<L>", arg, msgbuf, bufsize);
7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = ival;
7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'K': { /* long long sized bitfield */
7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        unsigned PY_LONG_LONG ival;
7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyInt_Check(arg))
7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ival = PyInt_AsUnsignedLongMask(arg);
7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (PyLong_Check(arg))
7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ival = PyLong_AsUnsignedLongLongMask(arg);
7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("integer<K>", arg, msgbuf, bufsize);
7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p = ival;
7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'f': {/* float */
7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        float *p = va_arg(*p_va, float *);
7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        double dval = PyFloat_AsDouble(arg);
7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyErr_Occurred())
7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("float<f>", arg, msgbuf, bufsize);
7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = (float) dval;
7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'd': {/* double */
8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        double *p = va_arg(*p_va, double *);
8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        double dval = PyFloat_AsDouble(arg);
8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyErr_Occurred())
8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("float<d>", arg, msgbuf, bufsize);
8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = dval;
8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef WITHOUT_COMPLEX
8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'D': {/* complex double */
8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_complex *p = va_arg(*p_va, Py_complex *);
8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_complex cval;
8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cval = PyComplex_AsCComplex(arg);
8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyErr_Occurred())
8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("complex<D>", arg, msgbuf, bufsize);
8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = cval;
8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* WITHOUT_COMPLEX */
8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'c': {/* char */
8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char *p = va_arg(*p_va, char *);
8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyString_Check(arg) && PyString_Size(arg) == 1)
8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = PyString_AS_STRING(arg)[0];
8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("char", arg, msgbuf, bufsize);
8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 's': {/* string */
8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '*') {
8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyString_Check(arg)) {
8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyBuffer_FillInfo(p, arg,
8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  1, 0);
8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyUnicode_Check(arg)) {
8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                uarg = UNICODE_DEFAULT_ENCODING(arg);
8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (uarg == NULL)
8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(CONV_UNICODE,
8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      arg, msgbuf, bufsize);
8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyBuffer_FillInfo(p, arg,
8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  1, 0);
8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else { /* any buffer-like object */
8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                char *buf;
8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (getbuffer(arg, p, &buf) < 0)
8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(buf, arg, msgbuf, bufsize);
8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (addcleanup(p, freelist, cleanup_buffer)) {
8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "(cleanup problem)",
8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else if (*format == '#') {
8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            void **p = (void **)va_arg(*p_va, char **);
8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            FETCH_SIZE;
8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyString_Check(arg)) {
8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(arg);
8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(PyString_GET_SIZE(arg));
8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyUnicode_Check(arg)) {
8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                uarg = UNICODE_DEFAULT_ENCODING(arg);
8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (uarg == NULL)
8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(CONV_UNICODE,
8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      arg, msgbuf, bufsize);
8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(uarg);
8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(PyString_GET_SIZE(uarg));
8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else { /* any buffer-like object */
8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                char *buf;
8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_ssize_t count = convertbuffer(arg, p, &buf);
8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (count < 0)
8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(buf, arg, msgbuf, bufsize);
8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(count);
8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char **p = va_arg(*p_va, char **);
8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyString_Check(arg))
8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(arg);
8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyUnicode_Check(arg)) {
8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                uarg = UNICODE_DEFAULT_ENCODING(arg);
8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (uarg == NULL)
8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(CONV_UNICODE,
8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      arg, msgbuf, bufsize);
9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(uarg);
9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("string", arg, msgbuf, bufsize);
9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("string without null bytes",
9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  arg, msgbuf, bufsize);
9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'z': {/* string, may be NULL (None) */
9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '*') {
9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (arg == Py_None)
9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyString_Check(arg)) {
9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyBuffer_FillInfo(p, arg,
9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  1, 0);
9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyUnicode_Check(arg)) {
9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                uarg = UNICODE_DEFAULT_ENCODING(arg);
9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (uarg == NULL)
9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(CONV_UNICODE,
9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      arg, msgbuf, bufsize);
9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyBuffer_FillInfo(p, arg,
9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  1, 0);
9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else { /* any buffer-like object */
9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                char *buf;
9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (getbuffer(arg, p, &buf) < 0)
9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(buf, arg, msgbuf, bufsize);
9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (addcleanup(p, freelist, cleanup_buffer)) {
9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "(cleanup problem)",
9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else if (*format == '#') { /* any buffer-like object */
9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            void **p = (void **)va_arg(*p_va, char **);
9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            FETCH_SIZE;
9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (arg == Py_None) {
9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = 0;
9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(0);
9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyString_Check(arg)) {
9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(arg);
9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(PyString_GET_SIZE(arg));
9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyUnicode_Check(arg)) {
9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                uarg = UNICODE_DEFAULT_ENCODING(arg);
9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (uarg == NULL)
9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(CONV_UNICODE,
9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      arg, msgbuf, bufsize);
9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(uarg);
9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(PyString_GET_SIZE(uarg));
9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else { /* any buffer-like object */
9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                char *buf;
9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_ssize_t count = convertbuffer(arg, p, &buf);
9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (count < 0)
9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(buf, arg, msgbuf, bufsize);
9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(count);
9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char **p = va_arg(*p_va, char **);
9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (arg == Py_None)
9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = 0;
9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyString_Check(arg))
9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(arg);
9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (PyUnicode_Check(arg)) {
9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                uarg = UNICODE_DEFAULT_ENCODING(arg);
9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (uarg == NULL)
9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(CONV_UNICODE,
9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      arg, msgbuf, bufsize);
9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyString_AS_STRING(uarg);
9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("string or None",
9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  arg, msgbuf, bufsize);
9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (*format == '#') {
9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                FETCH_SIZE;
9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                assert(0); /* XXX redundant with if-case */
9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (arg == Py_None) {
9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    STORE_SIZE(0);
9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                } else {
10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    STORE_SIZE(PyString_Size(arg));
10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                format++;
10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (*p != NULL &&
10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     (Py_ssize_t)strlen(*p) != PyString_Size(arg))
10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "string without null bytes or None",
10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'e': {/* encoded string */
10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char **buffer;
10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        const char *encoding;
10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *s;
10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t size;
10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int recode_strings;
10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Get 'e' parameter: the encoding name */
10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        encoding = (const char *)va_arg(*p_va, const char *);
10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (encoding == NULL)
10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            encoding = PyUnicode_GetDefaultEncoding();
10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Get output buffer parameter:
10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           's' (recode all objects via Unicode) or
10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           't' (only recode non-string objects)
10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        */
10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == 's')
10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            recode_strings = 1;
10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (*format == 't')
10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            recode_strings = 0;
10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr(
10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "(unknown parser marker combination)",
10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                arg, msgbuf, bufsize);
10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        buffer = (char **)va_arg(*p_va, char **);
10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        format++;
10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (buffer == NULL)
10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("(buffer is NULL)",
10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              arg, msgbuf, bufsize);
10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Encode object */
10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!recode_strings && PyString_Check(arg)) {
10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = arg;
10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_INCREF(s);
10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *u;
10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Convert object to Unicode */
10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            u = PyUnicode_FromObject(arg);
10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (u == NULL)
10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "string or unicode or text buffer",
10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Encode object; use default error handling */
10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = PyUnicode_AsEncodedString(u,
10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                          encoding,
10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                          NULL);
10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(u);
10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (s == NULL)
10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("(encoding failed)",
10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  arg, msgbuf, bufsize);
10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!PyString_Check(s)) {
10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(s);
10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "(encoder failed to return a string)",
10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("string<e>", arg, msgbuf, bufsize);
10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        size = PyString_GET_SIZE(s);
10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Write output; output is guaranteed to be 0-terminated */
10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '#') {
10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Using buffer length parameter '#':
10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               - if *buffer is NULL, a new buffer of the
10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               needed size is allocated and the data
10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               copied into it; *buffer is updated to point
10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               to the new buffer; the caller is
10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               responsible for PyMem_Free()ing it after
10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               usage
10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               - if *buffer is not NULL, the data is
10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               copied to *buffer; *buffer_len has to be
10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               set to the size of the buffer on input;
10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               buffer overflow is signalled with an error;
10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               buffer has to provide enough room for the
10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               encoded string plus the trailing 0-byte
10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               - in both cases, *buffer_len is updated to
11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               the size of the buffer /excluding/ the
11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               trailing 0-byte
11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            */
11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            FETCH_SIZE;
11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (q == NULL && q2 == NULL) {
11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(s);
11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "(buffer_len is NULL)",
11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (*buffer == NULL) {
11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *buffer = PyMem_NEW(char, size + 1);
11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (*buffer == NULL) {
11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    Py_DECREF(s);
11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(
11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "(memory error)",
11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        arg, msgbuf, bufsize);
11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (addcleanup(*buffer, freelist, cleanup_ptr)) {
11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    Py_DECREF(s);
11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(
11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "(cleanup problem)",
11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        arg, msgbuf, bufsize);
11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            } else {
11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (size + 1 > BUFFER_LEN) {
11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    Py_DECREF(s);
11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return converterr(
11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "(buffer overflow)",
11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        arg, msgbuf, bufsize);
11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            memcpy(*buffer,
11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                   PyString_AS_STRING(s),
11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                   size + 1);
11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            STORE_SIZE(size);
11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Using a 0-terminated buffer:
11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               - the encoded string has to be 0-terminated
11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               for this variant to work; if it is not, an
11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               error raised
11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               - a new buffer of the needed size is
11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               allocated and the data copied into it;
11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               *buffer is updated to point to the new
11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               buffer; the caller is responsible for
11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               PyMem_Free()ing it after usage
11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            */
11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                    != size) {
11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(s);
11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "encoded string without NULL bytes",
11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *buffer = PyMem_NEW(char, size + 1);
11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (*buffer == NULL) {
11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(s);
11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("(memory error)",
11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  arg, msgbuf, bufsize);
11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (addcleanup(*buffer, freelist, cleanup_ptr)) {
11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(s);
11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("(cleanup problem)",
11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                arg, msgbuf, bufsize);
11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            memcpy(*buffer,
11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                   PyString_AS_STRING(s),
11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                   size + 1);
11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(s);
11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'u': {/* raw unicode buffer (Py_UNICODE *) */
11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '#') { /* any buffer-like object */
11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            void **p = (void **)va_arg(*p_va, char **);
11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            FETCH_SIZE;
11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyUnicode_Check(arg)) {
11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyUnicode_AS_UNICODE(arg);
11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(PyUnicode_GET_SIZE(arg));
11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else {
11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("cannot convert raw buffers",
11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  arg, msgbuf, bufsize);
11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyUnicode_Check(arg))
11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = PyUnicode_AS_UNICODE(arg);
11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("unicode", arg, msgbuf, bufsize);
11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'S': { /* string object */
12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject **p = va_arg(*p_va, PyObject **);
12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyString_Check(arg))
12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = arg;
12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("string", arg, msgbuf, bufsize);
12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'U': { /* Unicode object */
12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject **p = va_arg(*p_va, PyObject **);
12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyUnicode_Check(arg))
12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = arg;
12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("unicode", arg, msgbuf, bufsize);
12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'O': { /* object */
12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyTypeObject *type;
12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject **p;
12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '!') {
12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            type = va_arg(*p_va, PyTypeObject*);
12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p = va_arg(*p_va, PyObject **);
12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyType_IsSubtype(arg->ob_type, type))
12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = arg;
12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(type->tp_name, arg, msgbuf, bufsize);
12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (*format == '?') {
12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            inquiry pred = va_arg(*p_va, inquiry);
12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p = va_arg(*p_va, PyObject **);
12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if ((*pred)(arg))
12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p = arg;
12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("(unspecified)",
12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  arg, msgbuf, bufsize);
12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (*format == '&') {
12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            typedef int (*converter)(PyObject *, void *);
12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            converter convert = va_arg(*p_va, converter);
12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            void *addr = va_arg(*p_va, void *);
12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (! (*convert)(arg, addr))
12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("(unspecified)",
12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  arg, msgbuf, bufsize);
12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p = va_arg(*p_va, PyObject **);
12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = arg;
12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'w': { /* memory buffer, read-write access */
12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        void **p = va_arg(*p_va, void **);
12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        void *res;
12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t count;
12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pb && pb->bf_releasebuffer && *format != '*')
12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Buffer must be released, yet caller does not use
12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               the Py_buffer protocol. */
12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("pinned buffer", arg, msgbuf, bufsize);
12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pb && pb->bf_getbuffer && *format == '*') {
12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Caller is interested in Py_buffer, and the object
12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               supports it directly. */
12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Clear();
12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("read-write buffer", arg, msgbuf, bufsize);
12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (addcleanup(p, freelist, cleanup_buffer)) {
12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr(
12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "(cleanup problem)",
12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    arg, msgbuf, bufsize);
12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return converterr("contiguous buffer", arg, msgbuf, bufsize);
12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pb == NULL ||
12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pb->bf_getwritebuffer == NULL ||
12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pb->bf_getsegcount == NULL)
12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("read-write buffer", arg, msgbuf, bufsize);
12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ((*pb->bf_getsegcount)(arg, NULL) != 1)
12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("single-segment read-write buffer",
13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              arg, msgbuf, bufsize);
13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)
13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("(unspecified)", arg, msgbuf, bufsize);
13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '*') {
13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);
13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p = res;
13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (*format == '#') {
13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                FETCH_SIZE;
13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                STORE_SIZE(count);
13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                format++;
13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 't': { /* 8-bit character buffer, read-only access */
13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char **p = va_arg(*p_va, char **);
13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t count;
13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format++ != '#')
13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr(
13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "invalid use of 't' format character",
13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                arg, msgbuf, bufsize);
13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!PyType_HasFeature(arg->ob_type,
13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pb == NULL || pb->bf_getcharbuffer == NULL ||
13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pb->bf_getsegcount == NULL)
13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr(
13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "string or read-only character buffer",
13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                arg, msgbuf, bufsize);
13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pb->bf_getsegcount(arg, NULL) != 1)
13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr(
13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "string or single-segment read-only buffer",
13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                arg, msgbuf, bufsize);
13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pb->bf_releasebuffer)
13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr(
13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "string or pinned buffer",
13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                arg, msgbuf, bufsize);
13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        count = pb->bf_getcharbuffer(arg, 0, p);
13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (count < 0)
13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return converterr("(unspecified)", arg, msgbuf, bufsize);
13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            FETCH_SIZE;
13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            STORE_SIZE(count);
13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    default:
13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *p_format = format;
13614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return NULL;
13624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
13634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic Py_ssize_t
13654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmconvertbuffer(PyObject *arg, void **p, char **errmsg)
13664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
13674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
13684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t count;
13694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pb == NULL ||
13704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pb->bf_getreadbuffer == NULL ||
13714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pb->bf_getsegcount == NULL ||
13724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pb->bf_releasebuffer != NULL) {
13734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *errmsg = "string or read-only buffer";
13744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
13754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
13774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *errmsg = "string or single-segment read-only buffer";
13784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
13794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
13814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *errmsg = "(unspecified)";
13824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return count;
13844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
13854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
13874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmgetbuffer(PyObject *arg, Py_buffer *view, char **errmsg)
13884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
13894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    void *buf;
13904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t count;
13914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
13924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pb == NULL) {
13934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *errmsg = "string or buffer";
13944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
13954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pb->bf_getbuffer) {
13974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pb->bf_getbuffer(arg, view, 0) < 0) {
13984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *errmsg = "convertible to a buffer";
13994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return -1;
14004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
14014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!PyBuffer_IsContiguous(view, 'C')) {
14024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *errmsg = "contiguous buffer";
14034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return -1;
14044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
14054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
14064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
14074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    count = convertbuffer(arg, &buf, errmsg);
14094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (count < 0) {
14104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *errmsg = "convertible to a buffer";
14114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return count;
14124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
14134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBuffer_FillInfo(view, NULL, buf, count, 1, 0);
14144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
14154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
14164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Support for keyword arguments donated by
14184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Geoff Philbrick <philbric@delphi.hks.com> */
14194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Return false (0) for error, else true. */
14214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
14224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyArg_ParseTupleAndKeywords(PyObject *args,
14234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            PyObject *keywords,
14244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            const char *format,
14254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            char **kwlist, ...)
14264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
14274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
14284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list va;
14294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((args == NULL || !PyTuple_Check(args)) ||
14314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (keywords != NULL && !PyDict_Check(keywords)) ||
14324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        format == NULL ||
14334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        kwlist == NULL)
14344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
14354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_BadInternalCall();
14364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
14374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
14384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(va, kwlist);
14404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
14414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_end(va);
14424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
14434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
14444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
14464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
14474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  PyObject *keywords,
14484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  const char *format,
14494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  char **kwlist, ...)
14504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
14514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
14524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list va;
14534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((args == NULL || !PyTuple_Check(args)) ||
14554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (keywords != NULL && !PyDict_Check(keywords)) ||
14564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        format == NULL ||
14574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        kwlist == NULL)
14584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
14594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_BadInternalCall();
14604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
14614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
14624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(va, kwlist);
14644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargskeywords(args, keywords, format,
14654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              kwlist, &va, FLAG_SIZE_T);
14664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_end(va);
14674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
14684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
14694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
14724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyArg_VaParseTupleAndKeywords(PyObject *args,
14734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              PyObject *keywords,
14744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              const char *format,
14754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              char **kwlist, va_list va)
14764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
14774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
14784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list lva;
14794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((args == NULL || !PyTuple_Check(args)) ||
14814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (keywords != NULL && !PyDict_Check(keywords)) ||
14824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        format == NULL ||
14834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        kwlist == NULL)
14844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
14854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_BadInternalCall();
14864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
14874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
14884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef VA_LIST_IS_ARRAY
14904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(lva, va, sizeof(va_list));
14914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
14924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __va_copy
14934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __va_copy(lva, va);
14944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
14954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    lva = va;
14964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
14974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
14984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
14994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
15004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
15014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
15024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
15044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
15054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    PyObject *keywords,
15064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    const char *format,
15074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    char **kwlist, va_list va)
15084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
15094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int retval;
15104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list lva;
15114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((args == NULL || !PyTuple_Check(args)) ||
15134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (keywords != NULL && !PyDict_Check(keywords)) ||
15144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        format == NULL ||
15154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        kwlist == NULL)
15164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
15174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_BadInternalCall();
15184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
15194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
15204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef VA_LIST_IS_ARRAY
15224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(lva, va, sizeof(va_list));
15234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
15244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __va_copy
15254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __va_copy(lva, va);
15264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
15274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    lva = va;
15284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
15294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
15304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    retval = vgetargskeywords(args, keywords, format,
15324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              kwlist, &lva, FLAG_SIZE_T);
15334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return retval;
15344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
15354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
15374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
15394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
15404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                 char **kwlist, va_list *p_va, int flags)
15414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
15424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char msgbuf[512];
15434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int levels[32];
15444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *fname, *msg, *custom_msg, *keyword;
15454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int min = INT_MAX;
15464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int i, len, nargs, nkeywords;
15474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *freelist = NULL, *current_arg;
15484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(args != NULL && PyTuple_Check(args));
15504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(keywords == NULL || PyDict_Check(keywords));
15514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(format != NULL);
15524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(kwlist != NULL);
15534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(p_va != NULL);
15544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* grab the function name or custom error msg first (mutually exclusive) */
15564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fname = strchr(format, ':');
15574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fname) {
15584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fname++;
15594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        custom_msg = NULL;
15604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
15614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
15624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        custom_msg = strchr(format,';');
15634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (custom_msg)
15644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            custom_msg++;
15654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
15664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* scan kwlist and get greatest possible nbr of args */
15684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (len=0; kwlist[len]; len++)
15694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        continue;
15704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    nargs = PyTuple_GET_SIZE(args);
15724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
15734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (nargs + nkeywords > len) {
15744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "
15754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "argument%s (%d given)",
15764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     (fname == NULL) ? "function" : fname,
15774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     (fname == NULL) ? "" : "()",
15784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     len,
15794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     (len == 1) ? "" : "s",
15804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     nargs + nkeywords);
15814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
15824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
15834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* convert tuple args and keyword args in same loop, using kwlist to drive process */
15854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < len; i++) {
15864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        keyword = kwlist[i];
15874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (*format == '|') {
15884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            min = i;
15894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
15904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
15914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (IS_END_OF_FORMAT(*format)) {
15924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_RuntimeError,
15934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "More keyword list entries (%d) than "
15944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "format specifiers (%d)", len, i);
15954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cleanreturn(0, freelist);
15964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
15974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        current_arg = NULL;
15984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (nkeywords) {
15994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            current_arg = PyDict_GetItemString(keywords, keyword);
16004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
16014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (current_arg) {
16024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            --nkeywords;
16034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (i < nargs) {
16044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* arg present in tuple and in dict */
16054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Format(PyExc_TypeError,
16064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "Argument given by name ('%s') "
16074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "and position (%d)",
16084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             keyword, i+1);
16094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return cleanreturn(0, freelist);
16104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
16114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
16124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (nkeywords && PyErr_Occurred())
16134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cleanreturn(0, freelist);
16144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (i < nargs)
16154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            current_arg = PyTuple_GET_ITEM(args, i);
16164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (current_arg) {
16184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            msg = convertitem(current_arg, &format, p_va, flags,
16194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                levels, msgbuf, sizeof(msgbuf), &freelist);
16204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (msg) {
16214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                seterror(i+1, msg, levels, fname, custom_msg);
16224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return cleanreturn(0, freelist);
16234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
16244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
16254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
16264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (i < min) {
16284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_TypeError, "Required argument "
16294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "'%s' (pos %d) not found",
16304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         keyword, i+1);
16314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cleanreturn(0, freelist);
16324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
16334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* current code reports success when all required args
16344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * fulfilled and no keyword args left, with no further
16354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * validation. XXX Maybe skip this in debug build ?
16364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         */
16374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!nkeywords)
16384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cleanreturn(1, freelist);
16394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* We are into optional args, skip thru to any remaining
16414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * keyword args */
16424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        msg = skipitem(&format, p_va, flags);
16434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (msg) {
16444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,
16454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         format);
16464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cleanreturn(0, freelist);
16474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
16484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!IS_END_OF_FORMAT(*format) && *format != '|') {
16514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_RuntimeError,
16524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "more argument specifiers than keyword list entries "
16534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "(remaining format:'%s')", format);
16544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return cleanreturn(0, freelist);
16554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* make sure there are no extraneous keyword arguments */
16584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (nkeywords > 0) {
16594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *key, *value;
16604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t pos = 0;
16614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        while (PyDict_Next(keywords, &pos, &key, &value)) {
16624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            int match = 0;
16634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char *ks;
16644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!PyString_Check(key)) {
16654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_TypeError,
16664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "keywords must be strings");
16674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return cleanreturn(0, freelist);
16684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
16694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ks = PyString_AsString(key);
16704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for (i = 0; i < len; i++) {
16714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (!strcmp(ks, kwlist[i])) {
16724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    match = 1;
16734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    break;
16744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
16754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
16764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!match) {
16774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Format(PyExc_TypeError,
16784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "'%s' is an invalid keyword "
16794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "argument for this function",
16804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             ks);
16814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return cleanreturn(0, freelist);
16824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
16834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
16844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return cleanreturn(1, freelist);
16874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
16884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *
16914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmskipitem(const char **p_format, va_list *p_va, int flags)
16924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
16934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const char *format = *p_format;
16944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char c = *format++;
16954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    switch (c) {
16974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* simple codes
16994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     * The individual types (second arg of va_arg) are irrelevant */
17004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'b': /* byte -- very short int */
17024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'B': /* byte as bitfield */
17034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'h': /* short int */
17044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'H': /* short int as bitfield */
17054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'i': /* int */
17064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'I': /* int sized bitfield */
17074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'l': /* long int */
17084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'k': /* long int sized bitfield */
17094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_LONG_LONG
17104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'L': /* PY_LONG_LONG */
17114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'K': /* PY_LONG_LONG sized bitfield */
17124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
17134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'f': /* float */
17144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'd': /* double */
17154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef WITHOUT_COMPLEX
17164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'D': /* complex double */
17174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
17184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'c': /* char */
17194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
17204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            (void) va_arg(*p_va, void *);
17214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
17224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'n': /* Py_ssize_t */
17254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
17264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            (void) va_arg(*p_va, Py_ssize_t *);
17274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
17284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* string codes */
17314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'e': /* string with encoding */
17334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
17344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            (void) va_arg(*p_va, const char *);
17354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!(*format == 's' || *format == 't'))
17364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* after 'e', only 's' and 't' is allowed */
17374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                goto err;
17384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
17394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* explicit fallthrough to string cases */
17404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 's': /* string */
17434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'z': /* string or None */
17444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
17454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'u': /* unicode string */
17464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
17474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 't': /* buffer, read-only */
17484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'w': /* buffer, read-write */
17494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
17504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            (void) va_arg(*p_va, char **);
17514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (*format == '#') {
17524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (flags & FLAG_SIZE_T)
17534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    (void) va_arg(*p_va, Py_ssize_t *);
17544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else
17554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    (void) va_arg(*p_va, int *);
17564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                format++;
17574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            } else if ((c == 's' || c == 'z') && *format == '*') {
17584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                format++;
17594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
17604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
17614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* object codes */
17644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'S': /* string object */
17664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
17674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'U': /* unicode string object */
17684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
17694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
17704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            (void) va_arg(*p_va, PyObject **);
17714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
17724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case 'O': /* object */
17754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
17764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (*format == '!') {
17774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                format++;
17784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (void) va_arg(*p_va, PyTypeObject*);
17794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (void) va_arg(*p_va, PyObject **);
17804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
17814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else if (*format == '&') {
17824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                typedef int (*converter)(PyObject *, void *);
17834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (void) va_arg(*p_va, converter);
17844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (void) va_arg(*p_va, void *);
17854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                format++;
17864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
17874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else {
17884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (void) va_arg(*p_va, PyObject **);
17894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
17904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
17914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case '(':           /* bypass tuple, not handled at all previously */
17944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
17954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char *msg;
17964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for (;;) {
17974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (*format==')')
17984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    break;
17994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (IS_END_OF_FORMAT(*format))
18004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return "Unmatched left paren in format "
18014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           "string";
18024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                msg = skipitem(&format, p_va, flags);
18034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (msg)
18044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return msg;
18054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
18064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            format++;
18074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
18084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
18094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case ')':
18114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return "Unmatched right paren in format string";
18124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    default:
18144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerr:
18154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return "impossible<bad format char>";
18164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *p_format = format;
18204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return NULL;
18214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
18224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
18254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
18264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
18274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t i, l;
18284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject **o;
18294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_list vargs;
18304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_STDARG_PROTOTYPES
18324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(vargs, max);
18334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
18344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_start(vargs);
18354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
18364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(min >= 0);
18384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(min <= max);
18394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyTuple_Check(args)) {
18404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_SystemError,
18414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "PyArg_UnpackTuple() argument list is not a tuple");
18424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
18434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    l = PyTuple_GET_SIZE(args);
18454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (l < min) {
18464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (name != NULL)
18474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(
18484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyExc_TypeError,
18494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "%s expected %s%zd arguments, got %zd",
18504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                name, (min == max ? "" : "at least "), min, l);
18514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
18524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(
18534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyExc_TypeError,
18544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "unpacked tuple should have %s%zd elements,"
18554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                " but has %zd",
18564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (min == max ? "" : "at least "), min, l);
18574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        va_end(vargs);
18584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
18594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (l > max) {
18614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (name != NULL)
18624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(
18634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyExc_TypeError,
18644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "%s expected %s%zd arguments, got %zd",
18654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                name, (min == max ? "" : "at most "), max, l);
18664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
18674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(
18684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyExc_TypeError,
18694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "unpacked tuple should have %s%zd elements,"
18704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                " but has %zd",
18714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (min == max ? "" : "at most "), max, l);
18724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        va_end(vargs);
18734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
18744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < l; i++) {
18764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        o = va_arg(vargs, PyObject **);
18774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *o = PyTuple_GET_ITEM(args, i);
18784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    va_end(vargs);
18804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 1;
18814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
18824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* For type constructors that don't take keyword args
18854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
18864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Sets a TypeError and returns 0 if the kwds dict is
18874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * not empty, returns 1 otherwise
18884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
18894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
18904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyArg_NoKeywords(const char *funcname, PyObject *kw)
18914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
18924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (kw == NULL)
18934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
18944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyDict_CheckExact(kw)) {
18954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_BadInternalCall();
18964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
18974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_Size(kw) == 0)
18994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
19004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
19024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    funcname);
19034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
19044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
19054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __cplusplus
19064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
19074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1908