+++ /dev/null
-\r
-/* New getargs implementation */\r
-\r
-#include "Python.h"\r
-\r
-#include <ctype.h>\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-int PyArg_Parse(PyObject *, const char *, ...);\r
-int PyArg_ParseTuple(PyObject *, const char *, ...);\r
-int PyArg_VaParse(PyObject *, const char *, va_list);\r
-\r
-int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,\r
- const char *, char **, ...);\r
-int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,\r
- const char *, char **, va_list);\r
-\r
-#ifdef HAVE_DECLSPEC_DLL\r
-/* Export functions */\r
-PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);\r
-PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);\r
-PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,\r
- const char *, char **, ...);\r
-PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);\r
-PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);\r
-PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,\r
- const char *, char **, va_list);\r
-#endif\r
-\r
-#define FLAG_COMPAT 1\r
-#define FLAG_SIZE_T 2\r
-\r
-\r
-/* Forward */\r
-static int vgetargs1(PyObject *, const char *, va_list *, int);\r
-static void seterror(int, const char *, int *, const char *, const char *);\r
-static char *convertitem(PyObject *, const char **, va_list *, int, int *,\r
- char *, size_t, PyObject **);\r
-static char *converttuple(PyObject *, const char **, va_list *, int,\r
- int *, char *, size_t, int, PyObject **);\r
-static char *convertsimple(PyObject *, const char **, va_list *, int, char *,\r
- size_t, PyObject **);\r
-static Py_ssize_t convertbuffer(PyObject *, void **p, char **);\r
-static int getbuffer(PyObject *, Py_buffer *, char**);\r
-\r
-static int vgetargskeywords(PyObject *, PyObject *,\r
- const char *, char **, va_list *, int);\r
-static char *skipitem(const char **, va_list *, int);\r
-\r
-int\r
-PyArg_Parse(PyObject *args, const char *format, ...)\r
-{\r
- int retval;\r
- va_list va;\r
-\r
- va_start(va, format);\r
- retval = vgetargs1(args, format, &va, FLAG_COMPAT);\r
- va_end(va);\r
- return retval;\r
-}\r
-\r
-int\r
-_PyArg_Parse_SizeT(PyObject *args, char *format, ...)\r
-{\r
- int retval;\r
- va_list va;\r
-\r
- va_start(va, format);\r
- retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);\r
- va_end(va);\r
- return retval;\r
-}\r
-\r
-\r
-int\r
-PyArg_ParseTuple(PyObject *args, const char *format, ...)\r
-{\r
- int retval;\r
- va_list va;\r
-\r
- va_start(va, format);\r
- retval = vgetargs1(args, format, &va, 0);\r
- va_end(va);\r
- return retval;\r
-}\r
-\r
-int\r
-_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...)\r
-{\r
- int retval;\r
- va_list va;\r
-\r
- va_start(va, format);\r
- retval = vgetargs1(args, format, &va, FLAG_SIZE_T);\r
- va_end(va);\r
- return retval;\r
-}\r
-\r
-\r
-int\r
-PyArg_VaParse(PyObject *args, const char *format, va_list va)\r
-{\r
- va_list lva;\r
-\r
-#ifdef VA_LIST_IS_ARRAY\r
- memcpy(lva, va, sizeof(va_list));\r
-#else\r
-#ifdef __va_copy\r
- __va_copy(lva, va);\r
-#else\r
- lva = va;\r
-#endif\r
-#endif\r
-\r
- return vgetargs1(args, format, &lva, 0);\r
-}\r
-\r
-int\r
-_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)\r
-{\r
- va_list lva;\r
-\r
-#ifdef VA_LIST_IS_ARRAY\r
- memcpy(lva, va, sizeof(va_list));\r
-#else\r
-#ifdef __va_copy\r
- __va_copy(lva, va);\r
-#else\r
- lva = va;\r
-#endif\r
-#endif\r
-\r
- return vgetargs1(args, format, &lva, FLAG_SIZE_T);\r
-}\r
-\r
-\r
-/* Handle cleanup of allocated memory in case of exception */\r
-\r
-#define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"\r
-#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"\r
-\r
-static void\r
-cleanup_ptr(PyObject *self)\r
-{\r
- void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);\r
- if (ptr) {\r
- PyMem_FREE(ptr);\r
- }\r
-}\r
-\r
-static void\r
-cleanup_buffer(PyObject *self)\r
-{\r
- Py_buffer *ptr = (Py_buffer *)PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_BUFFER);\r
- if (ptr) {\r
- PyBuffer_Release(ptr);\r
- }\r
-}\r
-\r
-static int\r
-addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)\r
-{\r
- PyObject *cobj;\r
- const char *name;\r
-\r
- if (!*freelist) {\r
- *freelist = PyList_New(0);\r
- if (!*freelist) {\r
- destr(ptr);\r
- return -1;\r
- }\r
- }\r
-\r
- if (destr == cleanup_ptr) {\r
- name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;\r
- } else if (destr == cleanup_buffer) {\r
- name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;\r
- } else {\r
- return -1;\r
- }\r
- cobj = PyCapsule_New(ptr, name, destr);\r
- if (!cobj) {\r
- destr(ptr);\r
- return -1;\r
- }\r
- if (PyList_Append(*freelist, cobj)) {\r
- Py_DECREF(cobj);\r
- return -1;\r
- }\r
- Py_DECREF(cobj);\r
- return 0;\r
-}\r
-\r
-static int\r
-cleanreturn(int retval, PyObject *freelist)\r
-{\r
- if (freelist && retval != 0) {\r
- /* We were successful, reset the destructors so that they\r
- don't get called. */\r
- Py_ssize_t len = PyList_GET_SIZE(freelist), i;\r
- for (i = 0; i < len; i++)\r
- PyCapsule_SetDestructor(PyList_GET_ITEM(freelist, i), NULL);\r
- }\r
- Py_XDECREF(freelist);\r
- return retval;\r
-}\r
-\r
-\r
-static int\r
-vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)\r
-{\r
- char msgbuf[256];\r
- int levels[32];\r
- const char *fname = NULL;\r
- const char *message = NULL;\r
- int min = -1;\r
- int max = 0;\r
- int level = 0;\r
- int endfmt = 0;\r
- const char *formatsave = format;\r
- Py_ssize_t i, len;\r
- char *msg;\r
- PyObject *freelist = NULL;\r
- int compat = flags & FLAG_COMPAT;\r
-\r
- assert(compat || (args != (PyObject*)NULL));\r
- flags = flags & ~FLAG_COMPAT;\r
-\r
- while (endfmt == 0) {\r
- int c = *format++;\r
- switch (c) {\r
- case '(':\r
- if (level == 0)\r
- max++;\r
- level++;\r
- if (level >= 30)\r
- Py_FatalError("too many tuple nesting levels "\r
- "in argument format string");\r
- break;\r
- case ')':\r
- if (level == 0)\r
- Py_FatalError("excess ')' in getargs format");\r
- else\r
- level--;\r
- break;\r
- case '\0':\r
- endfmt = 1;\r
- break;\r
- case ':':\r
- fname = format;\r
- endfmt = 1;\r
- break;\r
- case ';':\r
- message = format;\r
- endfmt = 1;\r
- break;\r
- default:\r
- if (level == 0) {\r
- if (c == 'O')\r
- max++;\r
- else if (isalpha(Py_CHARMASK(c))) {\r
- if (c != 'e') /* skip encoded */\r
- max++;\r
- } else if (c == '|')\r
- min = max;\r
- }\r
- break;\r
- }\r
- }\r
-\r
- if (level != 0)\r
- Py_FatalError(/* '(' */ "missing ')' in getargs format");\r
-\r
- if (min < 0)\r
- min = max;\r
-\r
- format = formatsave;\r
-\r
- if (compat) {\r
- if (max == 0) {\r
- if (args == NULL)\r
- return 1;\r
- PyOS_snprintf(msgbuf, sizeof(msgbuf),\r
- "%.200s%s takes no arguments",\r
- fname==NULL ? "function" : fname,\r
- fname==NULL ? "" : "()");\r
- PyErr_SetString(PyExc_TypeError, msgbuf);\r
- return 0;\r
- }\r
- else if (min == 1 && max == 1) {\r
- if (args == NULL) {\r
- PyOS_snprintf(msgbuf, sizeof(msgbuf),\r
- "%.200s%s takes at least one argument",\r
- fname==NULL ? "function" : fname,\r
- fname==NULL ? "" : "()");\r
- PyErr_SetString(PyExc_TypeError, msgbuf);\r
- return 0;\r
- }\r
- msg = convertitem(args, &format, p_va, flags, levels,\r
- msgbuf, sizeof(msgbuf), &freelist);\r
- if (msg == NULL)\r
- return cleanreturn(1, freelist);\r
- seterror(levels[0], msg, levels+1, fname, message);\r
- return cleanreturn(0, freelist);\r
- }\r
- else {\r
- PyErr_SetString(PyExc_SystemError,\r
- "old style getargs format uses new features");\r
- return 0;\r
- }\r
- }\r
-\r
- if (!PyTuple_Check(args)) {\r
- PyErr_SetString(PyExc_SystemError,\r
- "new style getargs format but argument is not a tuple");\r
- return 0;\r
- }\r
-\r
- len = PyTuple_GET_SIZE(args);\r
-\r
- if (len < min || max < len) {\r
- if (message == NULL) {\r
- PyOS_snprintf(msgbuf, sizeof(msgbuf),\r
- "%.150s%s takes %s %d argument%s "\r
- "(%ld given)",\r
- fname==NULL ? "function" : fname,\r
- fname==NULL ? "" : "()",\r
- min==max ? "exactly"\r
- : len < min ? "at least" : "at most",\r
- len < min ? min : max,\r
- (len < min ? min : max) == 1 ? "" : "s",\r
- Py_SAFE_DOWNCAST(len, Py_ssize_t, long));\r
- message = msgbuf;\r
- }\r
- PyErr_SetString(PyExc_TypeError, message);\r
- return 0;\r
- }\r
-\r
- for (i = 0; i < len; i++) {\r
- if (*format == '|')\r
- format++;\r
- msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,\r
- flags, levels, msgbuf,\r
- sizeof(msgbuf), &freelist);\r
- if (msg) {\r
- seterror(i+1, msg, levels, fname, msg);\r
- return cleanreturn(0, freelist);\r
- }\r
- }\r
-\r
- if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&\r
- *format != '(' &&\r
- *format != '|' && *format != ':' && *format != ';') {\r
- PyErr_Format(PyExc_SystemError,\r
- "bad format string: %.200s", formatsave);\r
- return cleanreturn(0, freelist);\r
- }\r
-\r
- return cleanreturn(1, freelist);\r
-}\r
-\r
-\r
-\r
-static void\r
-seterror(int iarg, const char *msg, int *levels, const char *fname,\r
- const char *message)\r
-{\r
- char buf[512];\r
- int i;\r
- char *p = buf;\r
-\r
- if (PyErr_Occurred())\r
- return;\r
- else if (message == NULL) {\r
- if (fname != NULL) {\r
- PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);\r
- p += strlen(p);\r
- }\r
- if (iarg != 0) {\r
- PyOS_snprintf(p, sizeof(buf) - (p - buf),\r
- "argument %d", iarg);\r
- i = 0;\r
- p += strlen(p);\r
- while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {\r
- PyOS_snprintf(p, sizeof(buf) - (p - buf),\r
- ", item %d", levels[i]-1);\r
- p += strlen(p);\r
- i++;\r
- }\r
- }\r
- else {\r
- PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");\r
- p += strlen(p);\r
- }\r
- PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);\r
- message = buf;\r
- }\r
- PyErr_SetString(PyExc_TypeError, message);\r
-}\r
-\r
-\r
-/* Convert a tuple argument.\r
- On entry, *p_format points to the character _after_ the opening '('.\r
- On successful exit, *p_format points to the closing ')'.\r
- If successful:\r
- *p_format and *p_va are updated,\r
- *levels and *msgbuf are untouched,\r
- and NULL is returned.\r
- If the argument is invalid:\r
- *p_format is unchanged,\r
- *p_va is undefined,\r
- *levels is a 0-terminated list of item numbers,\r
- *msgbuf contains an error message, whose format is:\r
- "must be <typename1>, not <typename2>", where:\r
- <typename1> is the name of the expected type, and\r
- <typename2> is the name of the actual type,\r
- and msgbuf is returned.\r
-*/\r
-\r
-static char *\r
-converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,\r
- int *levels, char *msgbuf, size_t bufsize, int toplevel,\r
- PyObject **freelist)\r
-{\r
- int level = 0;\r
- int n = 0;\r
- const char *format = *p_format;\r
- int i;\r
-\r
- for (;;) {\r
- int c = *format++;\r
- if (c == '(') {\r
- if (level == 0)\r
- n++;\r
- level++;\r
- }\r
- else if (c == ')') {\r
- if (level == 0)\r
- break;\r
- level--;\r
- }\r
- else if (c == ':' || c == ';' || c == '\0')\r
- break;\r
- else if (level == 0 && isalpha(Py_CHARMASK(c)))\r
- n++;\r
- }\r
-\r
- if (!PySequence_Check(arg) || PyString_Check(arg)) {\r
- levels[0] = 0;\r
- PyOS_snprintf(msgbuf, bufsize,\r
- toplevel ? "expected %d arguments, not %.50s" :\r
- "must be %d-item sequence, not %.50s",\r
- n,\r
- arg == Py_None ? "None" : arg->ob_type->tp_name);\r
- return msgbuf;\r
- }\r
-\r
- if ((i = PySequence_Size(arg)) != n) {\r
- levels[0] = 0;\r
- PyOS_snprintf(msgbuf, bufsize,\r
- toplevel ? "expected %d arguments, not %d" :\r
- "must be sequence of length %d, not %d",\r
- n, i);\r
- return msgbuf;\r
- }\r
-\r
- format = *p_format;\r
- for (i = 0; i < n; i++) {\r
- char *msg;\r
- PyObject *item;\r
- item = PySequence_GetItem(arg, i);\r
- if (item == NULL) {\r
- PyErr_Clear();\r
- levels[0] = i+1;\r
- levels[1] = 0;\r
- strncpy(msgbuf, "is not retrievable", bufsize);\r
- return msgbuf;\r
- }\r
- msg = convertitem(item, &format, p_va, flags, levels+1,\r
- msgbuf, bufsize, freelist);\r
- /* PySequence_GetItem calls tp->sq_item, which INCREFs */\r
- Py_XDECREF(item);\r
- if (msg != NULL) {\r
- levels[0] = i+1;\r
- return msg;\r
- }\r
- }\r
-\r
- *p_format = format;\r
- return NULL;\r
-}\r
-\r
-\r
-/* Convert a single item. */\r
-\r
-static char *\r
-convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,\r
- int *levels, char *msgbuf, size_t bufsize, PyObject **freelist)\r
-{\r
- char *msg;\r
- const char *format = *p_format;\r
-\r
- if (*format == '(' /* ')' */) {\r
- format++;\r
- msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,\r
- bufsize, 0, freelist);\r
- if (msg == NULL)\r
- format++;\r
- }\r
- else {\r
- msg = convertsimple(arg, &format, p_va, flags,\r
- msgbuf, bufsize, freelist);\r
- if (msg != NULL)\r
- levels[0] = 0;\r
- }\r
- if (msg == NULL)\r
- *p_format = format;\r
- return msg;\r
-}\r
-\r
-\r
-\r
-#define UNICODE_DEFAULT_ENCODING(arg) \\r
- _PyUnicode_AsDefaultEncodedString(arg, NULL)\r
-\r
-/* Format an error message generated by convertsimple(). */\r
-\r
-static char *\r
-converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)\r
-{\r
- assert(expected != NULL);\r
- assert(arg != NULL);\r
- PyOS_snprintf(msgbuf, bufsize,\r
- "must be %.50s, not %.50s", expected,\r
- arg == Py_None ? "None" : arg->ob_type->tp_name);\r
- return msgbuf;\r
-}\r
-\r
-#define CONV_UNICODE "(unicode conversion error)"\r
-\r
-/* explicitly check for float arguments when integers are expected. For now\r
- * signal a warning. Returns true if an exception was raised. */\r
-static int\r
-float_argument_warning(PyObject *arg)\r
-{\r
- if (PyFloat_Check(arg) &&\r
- PyErr_Warn(PyExc_DeprecationWarning,\r
- "integer argument expected, got float" ))\r
- return 1;\r
- else\r
- return 0;\r
-}\r
-\r
-/* explicitly check for float arguments when integers are expected. Raises\r
- TypeError and returns true for float arguments. */\r
-static int\r
-float_argument_error(PyObject *arg)\r
-{\r
- if (PyFloat_Check(arg)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "integer argument expected, got float");\r
- return 1;\r
- }\r
- else\r
- return 0;\r
-}\r
-\r
-/* Convert a non-tuple argument. Return NULL if conversion went OK,\r
- or a string with a message describing the failure. The message is\r
- formatted as "must be <desired type>, not <actual type>".\r
- When failing, an exception may or may not have been raised.\r
- Don't call if a tuple is expected.\r
-\r
- When you add new format codes, please don't forget poor skipitem() below.\r
-*/\r
-\r
-static char *\r
-convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,\r
- char *msgbuf, size_t bufsize, PyObject **freelist)\r
-{\r
- /* For # codes */\r
-#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\\r
- if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \\r
- else q=va_arg(*p_va, int*);\r
-#define STORE_SIZE(s) \\r
- if (flags & FLAG_SIZE_T) \\r
- *q2=s; \\r
- else { \\r
- if (INT_MAX < s) { \\r
- PyErr_SetString(PyExc_OverflowError, \\r
- "size does not fit in an int"); \\r
- return converterr("", arg, msgbuf, bufsize); \\r
- } \\r
- *q=s; \\r
- }\r
-#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q)\r
-\r
- const char *format = *p_format;\r
- char c = *format++;\r
-#ifdef Py_USING_UNICODE\r
- PyObject *uarg;\r
-#endif\r
-\r
- switch (c) {\r
-\r
- case 'b': { /* unsigned byte -- very short int */\r
- char *p = va_arg(*p_va, char *);\r
- long ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<b>", arg, msgbuf, bufsize);\r
- ival = PyInt_AsLong(arg);\r
- if (ival == -1 && PyErr_Occurred())\r
- return converterr("integer<b>", arg, msgbuf, bufsize);\r
- else if (ival < 0) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "unsigned byte integer is less than minimum");\r
- return converterr("integer<b>", arg, msgbuf, bufsize);\r
- }\r
- else if (ival > UCHAR_MAX) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "unsigned byte integer is greater than maximum");\r
- return converterr("integer<b>", arg, msgbuf, bufsize);\r
- }\r
- else\r
- *p = (unsigned char) ival;\r
- break;\r
- }\r
-\r
- case 'B': {/* byte sized bitfield - both signed and unsigned\r
- values allowed */\r
- char *p = va_arg(*p_va, char *);\r
- long ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<B>", arg, msgbuf, bufsize);\r
- ival = PyInt_AsUnsignedLongMask(arg);\r
- if (ival == -1 && PyErr_Occurred())\r
- return converterr("integer<B>", arg, msgbuf, bufsize);\r
- else\r
- *p = (unsigned char) ival;\r
- break;\r
- }\r
-\r
- case 'h': {/* signed short int */\r
- short *p = va_arg(*p_va, short *);\r
- long ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<h>", arg, msgbuf, bufsize);\r
- ival = PyInt_AsLong(arg);\r
- if (ival == -1 && PyErr_Occurred())\r
- return converterr("integer<h>", arg, msgbuf, bufsize);\r
- else if (ival < SHRT_MIN) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "signed short integer is less than minimum");\r
- return converterr("integer<h>", arg, msgbuf, bufsize);\r
- }\r
- else if (ival > SHRT_MAX) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "signed short integer is greater than maximum");\r
- return converterr("integer<h>", arg, msgbuf, bufsize);\r
- }\r
- else\r
- *p = (short) ival;\r
- break;\r
- }\r
-\r
- case 'H': { /* short int sized bitfield, both signed and\r
- unsigned allowed */\r
- unsigned short *p = va_arg(*p_va, unsigned short *);\r
- long ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<H>", arg, msgbuf, bufsize);\r
- ival = PyInt_AsUnsignedLongMask(arg);\r
- if (ival == -1 && PyErr_Occurred())\r
- return converterr("integer<H>", arg, msgbuf, bufsize);\r
- else\r
- *p = (unsigned short) ival;\r
- break;\r
- }\r
-\r
- case 'i': {/* signed int */\r
- int *p = va_arg(*p_va, int *);\r
- long ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<i>", arg, msgbuf, bufsize);\r
- ival = PyInt_AsLong(arg);\r
- if (ival == -1 && PyErr_Occurred())\r
- return converterr("integer<i>", arg, msgbuf, bufsize);\r
- else if (ival > INT_MAX) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "signed integer is greater than maximum");\r
- return converterr("integer<i>", arg, msgbuf, bufsize);\r
- }\r
- else if (ival < INT_MIN) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "signed integer is less than minimum");\r
- return converterr("integer<i>", arg, msgbuf, bufsize);\r
- }\r
- else\r
- *p = ival;\r
- break;\r
- }\r
-\r
- case 'I': { /* int sized bitfield, both signed and\r
- unsigned allowed */\r
- unsigned int *p = va_arg(*p_va, unsigned int *);\r
- unsigned int ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<I>", arg, msgbuf, bufsize);\r
- ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);\r
- if (ival == (unsigned int)-1 && PyErr_Occurred())\r
- return converterr("integer<I>", arg, msgbuf, bufsize);\r
- else\r
- *p = ival;\r
- break;\r
- }\r
-\r
- case 'n': /* Py_ssize_t */\r
-#if SIZEOF_SIZE_T != SIZEOF_LONG\r
- {\r
- Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);\r
- Py_ssize_t ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<n>", arg, msgbuf, bufsize);\r
- ival = PyInt_AsSsize_t(arg);\r
- if (ival == -1 && PyErr_Occurred())\r
- return converterr("integer<n>", arg, msgbuf, bufsize);\r
- *p = ival;\r
- break;\r
- }\r
-#endif\r
- /* Fall through from 'n' to 'l' if Py_ssize_t is int */\r
- case 'l': {/* long int */\r
- long *p = va_arg(*p_va, long *);\r
- long ival;\r
- if (float_argument_error(arg))\r
- return converterr("integer<l>", arg, msgbuf, bufsize);\r
- ival = PyInt_AsLong(arg);\r
- if (ival == -1 && PyErr_Occurred())\r
- return converterr("integer<l>", arg, msgbuf, bufsize);\r
- else\r
- *p = ival;\r
- break;\r
- }\r
-\r
- case 'k': { /* long sized bitfield */\r
- unsigned long *p = va_arg(*p_va, unsigned long *);\r
- unsigned long ival;\r
- if (PyInt_Check(arg))\r
- ival = PyInt_AsUnsignedLongMask(arg);\r
- else if (PyLong_Check(arg))\r
- ival = PyLong_AsUnsignedLongMask(arg);\r
- else\r
- return converterr("integer<k>", arg, msgbuf, bufsize);\r
- *p = ival;\r
- break;\r
- }\r
-\r
-#ifdef HAVE_LONG_LONG\r
- case 'L': {/* PY_LONG_LONG */\r
- PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );\r
- PY_LONG_LONG ival;\r
- if (float_argument_warning(arg))\r
- return converterr("long<L>", arg, msgbuf, bufsize);\r
- ival = PyLong_AsLongLong(arg);\r
- if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {\r
- return converterr("long<L>", arg, msgbuf, bufsize);\r
- } else {\r
- *p = ival;\r
- }\r
- break;\r
- }\r
-\r
- case 'K': { /* long long sized bitfield */\r
- unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);\r
- unsigned PY_LONG_LONG ival;\r
- if (PyInt_Check(arg))\r
- ival = PyInt_AsUnsignedLongMask(arg);\r
- else if (PyLong_Check(arg))\r
- ival = PyLong_AsUnsignedLongLongMask(arg);\r
- else\r
- return converterr("integer<K>", arg, msgbuf, bufsize);\r
- *p = ival;\r
- break;\r
- }\r
-#endif\r
-\r
- case 'f': {/* float */\r
- float *p = va_arg(*p_va, float *);\r
- double dval = PyFloat_AsDouble(arg);\r
- if (PyErr_Occurred())\r
- return converterr("float<f>", arg, msgbuf, bufsize);\r
- else\r
- *p = (float) dval;\r
- break;\r
- }\r
-\r
- case 'd': {/* double */\r
- double *p = va_arg(*p_va, double *);\r
- double dval = PyFloat_AsDouble(arg);\r
- if (PyErr_Occurred())\r
- return converterr("float<d>", arg, msgbuf, bufsize);\r
- else\r
- *p = dval;\r
- break;\r
- }\r
-\r
-#ifndef WITHOUT_COMPLEX\r
- case 'D': {/* complex double */\r
- Py_complex *p = va_arg(*p_va, Py_complex *);\r
- Py_complex cval;\r
- cval = PyComplex_AsCComplex(arg);\r
- if (PyErr_Occurred())\r
- return converterr("complex<D>", arg, msgbuf, bufsize);\r
- else\r
- *p = cval;\r
- break;\r
- }\r
-#endif /* WITHOUT_COMPLEX */\r
-\r
- case 'c': {/* char */\r
- char *p = va_arg(*p_va, char *);\r
- if (PyString_Check(arg) && PyString_Size(arg) == 1)\r
- *p = PyString_AS_STRING(arg)[0];\r
- else\r
- return converterr("char", arg, msgbuf, bufsize);\r
- break;\r
- }\r
-\r
- case 's': {/* string */\r
- if (*format == '*') {\r
- Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);\r
-\r
- if (PyString_Check(arg)) {\r
- PyBuffer_FillInfo(p, arg,\r
- PyString_AS_STRING(arg), PyString_GET_SIZE(arg),\r
- 1, 0);\r
- }\r
-#ifdef Py_USING_UNICODE\r
- else if (PyUnicode_Check(arg)) {\r
- uarg = UNICODE_DEFAULT_ENCODING(arg);\r
- if (uarg == NULL)\r
- return converterr(CONV_UNICODE,\r
- arg, msgbuf, bufsize);\r
- PyBuffer_FillInfo(p, arg,\r
- PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),\r
- 1, 0);\r
- }\r
-#endif\r
- else { /* any buffer-like object */\r
- char *buf;\r
- if (getbuffer(arg, p, &buf) < 0)\r
- return converterr(buf, arg, msgbuf, bufsize);\r
- }\r
- if (addcleanup(p, freelist, cleanup_buffer)) {\r
- return converterr(\r
- "(cleanup problem)",\r
- arg, msgbuf, bufsize);\r
- }\r
- format++;\r
- } else if (*format == '#') {\r
- void **p = (void **)va_arg(*p_va, char **);\r
- FETCH_SIZE;\r
-\r
- if (PyString_Check(arg)) {\r
- *p = PyString_AS_STRING(arg);\r
- STORE_SIZE(PyString_GET_SIZE(arg));\r
- }\r
-#ifdef Py_USING_UNICODE\r
- else if (PyUnicode_Check(arg)) {\r
- uarg = UNICODE_DEFAULT_ENCODING(arg);\r
- if (uarg == NULL)\r
- return converterr(CONV_UNICODE,\r
- arg, msgbuf, bufsize);\r
- *p = PyString_AS_STRING(uarg);\r
- STORE_SIZE(PyString_GET_SIZE(uarg));\r
- }\r
-#endif\r
- else { /* any buffer-like object */\r
- char *buf;\r
- Py_ssize_t count = convertbuffer(arg, p, &buf);\r
- if (count < 0)\r
- return converterr(buf, arg, msgbuf, bufsize);\r
- STORE_SIZE(count);\r
- }\r
- format++;\r
- } else {\r
- char **p = va_arg(*p_va, char **);\r
-\r
- if (PyString_Check(arg))\r
- *p = PyString_AS_STRING(arg);\r
-#ifdef Py_USING_UNICODE\r
- else if (PyUnicode_Check(arg)) {\r
- uarg = UNICODE_DEFAULT_ENCODING(arg);\r
- if (uarg == NULL)\r
- return converterr(CONV_UNICODE,\r
- arg, msgbuf, bufsize);\r
- *p = PyString_AS_STRING(uarg);\r
- }\r
-#endif\r
- else\r
- return converterr("string", arg, msgbuf, bufsize);\r
- if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))\r
- return converterr("string without null bytes",\r
- arg, msgbuf, bufsize);\r
- }\r
- break;\r
- }\r
-\r
- case 'z': {/* string, may be NULL (None) */\r
- if (*format == '*') {\r
- Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);\r
-\r
- if (arg == Py_None)\r
- PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);\r
- else if (PyString_Check(arg)) {\r
- PyBuffer_FillInfo(p, arg,\r
- PyString_AS_STRING(arg), PyString_GET_SIZE(arg),\r
- 1, 0);\r
- }\r
-#ifdef Py_USING_UNICODE\r
- else if (PyUnicode_Check(arg)) {\r
- uarg = UNICODE_DEFAULT_ENCODING(arg);\r
- if (uarg == NULL)\r
- return converterr(CONV_UNICODE,\r
- arg, msgbuf, bufsize);\r
- PyBuffer_FillInfo(p, arg,\r
- PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),\r
- 1, 0);\r
- }\r
-#endif\r
- else { /* any buffer-like object */\r
- char *buf;\r
- if (getbuffer(arg, p, &buf) < 0)\r
- return converterr(buf, arg, msgbuf, bufsize);\r
- }\r
- if (addcleanup(p, freelist, cleanup_buffer)) {\r
- return converterr(\r
- "(cleanup problem)",\r
- arg, msgbuf, bufsize);\r
- }\r
- format++;\r
- } else if (*format == '#') { /* any buffer-like object */\r
- void **p = (void **)va_arg(*p_va, char **);\r
- FETCH_SIZE;\r
-\r
- if (arg == Py_None) {\r
- *p = 0;\r
- STORE_SIZE(0);\r
- }\r
- else if (PyString_Check(arg)) {\r
- *p = PyString_AS_STRING(arg);\r
- STORE_SIZE(PyString_GET_SIZE(arg));\r
- }\r
-#ifdef Py_USING_UNICODE\r
- else if (PyUnicode_Check(arg)) {\r
- uarg = UNICODE_DEFAULT_ENCODING(arg);\r
- if (uarg == NULL)\r
- return converterr(CONV_UNICODE,\r
- arg, msgbuf, bufsize);\r
- *p = PyString_AS_STRING(uarg);\r
- STORE_SIZE(PyString_GET_SIZE(uarg));\r
- }\r
-#endif\r
- else { /* any buffer-like object */\r
- char *buf;\r
- Py_ssize_t count = convertbuffer(arg, p, &buf);\r
- if (count < 0)\r
- return converterr(buf, arg, msgbuf, bufsize);\r
- STORE_SIZE(count);\r
- }\r
- format++;\r
- } else {\r
- char **p = va_arg(*p_va, char **);\r
-\r
- if (arg == Py_None)\r
- *p = 0;\r
- else if (PyString_Check(arg))\r
- *p = PyString_AS_STRING(arg);\r
-#ifdef Py_USING_UNICODE\r
- else if (PyUnicode_Check(arg)) {\r
- uarg = UNICODE_DEFAULT_ENCODING(arg);\r
- if (uarg == NULL)\r
- return converterr(CONV_UNICODE,\r
- arg, msgbuf, bufsize);\r
- *p = PyString_AS_STRING(uarg);\r
- }\r
-#endif\r
- else\r
- return converterr("string or None",\r
- arg, msgbuf, bufsize);\r
- if (*format == '#') {\r
- FETCH_SIZE;\r
- assert(0); /* XXX redundant with if-case */\r
- if (arg == Py_None) {\r
- STORE_SIZE(0);\r
- } else {\r
- STORE_SIZE(PyString_Size(arg));\r
- }\r
- format++;\r
- }\r
- else if (*p != NULL &&\r
- (Py_ssize_t)strlen(*p) != PyString_Size(arg))\r
- return converterr(\r
- "string without null bytes or None",\r
- arg, msgbuf, bufsize);\r
- }\r
- break;\r
- }\r
-\r
- case 'e': {/* encoded string */\r
- char **buffer;\r
- const char *encoding;\r
- PyObject *s;\r
- Py_ssize_t size;\r
- int recode_strings;\r
-\r
- /* Get 'e' parameter: the encoding name */\r
- encoding = (const char *)va_arg(*p_va, const char *);\r
-#ifdef Py_USING_UNICODE\r
- if (encoding == NULL)\r
- encoding = PyUnicode_GetDefaultEncoding();\r
-#endif\r
-\r
- /* Get output buffer parameter:\r
- 's' (recode all objects via Unicode) or\r
- 't' (only recode non-string objects)\r
- */\r
- if (*format == 's')\r
- recode_strings = 1;\r
- else if (*format == 't')\r
- recode_strings = 0;\r
- else\r
- return converterr(\r
- "(unknown parser marker combination)",\r
- arg, msgbuf, bufsize);\r
- buffer = (char **)va_arg(*p_va, char **);\r
- format++;\r
- if (buffer == NULL)\r
- return converterr("(buffer is NULL)",\r
- arg, msgbuf, bufsize);\r
-\r
- /* Encode object */\r
- if (!recode_strings && PyString_Check(arg)) {\r
- s = arg;\r
- Py_INCREF(s);\r
- }\r
- else {\r
-#ifdef Py_USING_UNICODE\r
- PyObject *u;\r
-\r
- /* Convert object to Unicode */\r
- u = PyUnicode_FromObject(arg);\r
- if (u == NULL)\r
- return converterr(\r
- "string or unicode or text buffer",\r
- arg, msgbuf, bufsize);\r
-\r
- /* Encode object; use default error handling */\r
- s = PyUnicode_AsEncodedString(u,\r
- encoding,\r
- NULL);\r
- Py_DECREF(u);\r
- if (s == NULL)\r
- return converterr("(encoding failed)",\r
- arg, msgbuf, bufsize);\r
- if (!PyString_Check(s)) {\r
- Py_DECREF(s);\r
- return converterr(\r
- "(encoder failed to return a string)",\r
- arg, msgbuf, bufsize);\r
- }\r
-#else\r
- return converterr("string<e>", arg, msgbuf, bufsize);\r
-#endif\r
- }\r
- size = PyString_GET_SIZE(s);\r
-\r
- /* Write output; output is guaranteed to be 0-terminated */\r
- if (*format == '#') {\r
- /* Using buffer length parameter '#':\r
-\r
- - if *buffer is NULL, a new buffer of the\r
- needed size is allocated and the data\r
- copied into it; *buffer is updated to point\r
- to the new buffer; the caller is\r
- responsible for PyMem_Free()ing it after\r
- usage\r
-\r
- - if *buffer is not NULL, the data is\r
- copied to *buffer; *buffer_len has to be\r
- set to the size of the buffer on input;\r
- buffer overflow is signalled with an error;\r
- buffer has to provide enough room for the\r
- encoded string plus the trailing 0-byte\r
-\r
- - in both cases, *buffer_len is updated to\r
- the size of the buffer /excluding/ the\r
- trailing 0-byte\r
-\r
- */\r
- FETCH_SIZE;\r
-\r
- format++;\r
- if (q == NULL && q2 == NULL) {\r
- Py_DECREF(s);\r
- return converterr(\r
- "(buffer_len is NULL)",\r
- arg, msgbuf, bufsize);\r
- }\r
- if (*buffer == NULL) {\r
- *buffer = PyMem_NEW(char, size + 1);\r
- if (*buffer == NULL) {\r
- Py_DECREF(s);\r
- return converterr(\r
- "(memory error)",\r
- arg, msgbuf, bufsize);\r
- }\r
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {\r
- Py_DECREF(s);\r
- return converterr(\r
- "(cleanup problem)",\r
- arg, msgbuf, bufsize);\r
- }\r
- } else {\r
- if (size + 1 > BUFFER_LEN) {\r
- Py_DECREF(s);\r
- return converterr(\r
- "(buffer overflow)",\r
- arg, msgbuf, bufsize);\r
- }\r
- }\r
- memcpy(*buffer,\r
- PyString_AS_STRING(s),\r
- size + 1);\r
- STORE_SIZE(size);\r
- } else {\r
- /* Using a 0-terminated buffer:\r
-\r
- - the encoded string has to be 0-terminated\r
- for this variant to work; if it is not, an\r
- error raised\r
-\r
- - a new buffer of the needed size is\r
- allocated and the data copied into it;\r
- *buffer is updated to point to the new\r
- buffer; the caller is responsible for\r
- PyMem_Free()ing it after usage\r
-\r
- */\r
- if ((Py_ssize_t)strlen(PyString_AS_STRING(s))\r
- != size) {\r
- Py_DECREF(s);\r
- return converterr(\r
- "encoded string without NULL bytes",\r
- arg, msgbuf, bufsize);\r
- }\r
- *buffer = PyMem_NEW(char, size + 1);\r
- if (*buffer == NULL) {\r
- Py_DECREF(s);\r
- return converterr("(memory error)",\r
- arg, msgbuf, bufsize);\r
- }\r
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {\r
- Py_DECREF(s);\r
- return converterr("(cleanup problem)",\r
- arg, msgbuf, bufsize);\r
- }\r
- memcpy(*buffer,\r
- PyString_AS_STRING(s),\r
- size + 1);\r
- }\r
- Py_DECREF(s);\r
- break;\r
- }\r
-\r
-#ifdef Py_USING_UNICODE\r
- case 'u': {/* raw unicode buffer (Py_UNICODE *) */\r
- if (*format == '#') { /* any buffer-like object */\r
- void **p = (void **)va_arg(*p_va, char **);\r
- FETCH_SIZE;\r
- if (PyUnicode_Check(arg)) {\r
- *p = PyUnicode_AS_UNICODE(arg);\r
- STORE_SIZE(PyUnicode_GET_SIZE(arg));\r
- }\r
- else {\r
- return converterr("cannot convert raw buffers",\r
- arg, msgbuf, bufsize);\r
- }\r
- format++;\r
- } else {\r
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);\r
- if (PyUnicode_Check(arg))\r
- *p = PyUnicode_AS_UNICODE(arg);\r
- else\r
- return converterr("unicode", arg, msgbuf, bufsize);\r
- }\r
- break;\r
- }\r
-#endif\r
-\r
- case 'S': { /* string object */\r
- PyObject **p = va_arg(*p_va, PyObject **);\r
- if (PyString_Check(arg))\r
- *p = arg;\r
- else\r
- return converterr("string", arg, msgbuf, bufsize);\r
- break;\r
- }\r
-\r
-#ifdef Py_USING_UNICODE\r
- case 'U': { /* Unicode object */\r
- PyObject **p = va_arg(*p_va, PyObject **);\r
- if (PyUnicode_Check(arg))\r
- *p = arg;\r
- else\r
- return converterr("unicode", arg, msgbuf, bufsize);\r
- break;\r
- }\r
-#endif\r
-\r
- case 'O': { /* object */\r
- PyTypeObject *type;\r
- PyObject **p;\r
- if (*format == '!') {\r
- type = va_arg(*p_va, PyTypeObject*);\r
- p = va_arg(*p_va, PyObject **);\r
- format++;\r
- if (PyType_IsSubtype(arg->ob_type, type))\r
- *p = arg;\r
- else\r
- return converterr(type->tp_name, arg, msgbuf, bufsize);\r
-\r
- }\r
- else if (*format == '?') {\r
- inquiry pred = va_arg(*p_va, inquiry);\r
- p = va_arg(*p_va, PyObject **);\r
- format++;\r
- if ((*pred)(arg))\r
- *p = arg;\r
- else\r
- return converterr("(unspecified)",\r
- arg, msgbuf, bufsize);\r
-\r
- }\r
- else if (*format == '&') {\r
- typedef int (*converter)(PyObject *, void *);\r
- converter convert = va_arg(*p_va, converter);\r
- void *addr = va_arg(*p_va, void *);\r
- format++;\r
- if (! (*convert)(arg, addr))\r
- return converterr("(unspecified)",\r
- arg, msgbuf, bufsize);\r
- }\r
- else {\r
- p = va_arg(*p_va, PyObject **);\r
- *p = arg;\r
- }\r
- break;\r
- }\r
-\r
-\r
- case 'w': { /* memory buffer, read-write access */\r
- void **p = va_arg(*p_va, void **);\r
- void *res;\r
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;\r
- Py_ssize_t count;\r
-\r
- if (pb && pb->bf_releasebuffer && *format != '*')\r
- /* Buffer must be released, yet caller does not use\r
- the Py_buffer protocol. */\r
- return converterr("pinned buffer", arg, msgbuf, bufsize);\r
-\r
- if (pb && pb->bf_getbuffer && *format == '*') {\r
- /* Caller is interested in Py_buffer, and the object\r
- supports it directly. */\r
- format++;\r
- if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {\r
- PyErr_Clear();\r
- return converterr("read-write buffer", arg, msgbuf, bufsize);\r
- }\r
- if (addcleanup(p, freelist, cleanup_buffer)) {\r
- return converterr(\r
- "(cleanup problem)",\r
- arg, msgbuf, bufsize);\r
- }\r
- if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))\r
- return converterr("contiguous buffer", arg, msgbuf, bufsize);\r
- break;\r
- }\r
-\r
- if (pb == NULL ||\r
- pb->bf_getwritebuffer == NULL ||\r
- pb->bf_getsegcount == NULL)\r
- return converterr("read-write buffer", arg, msgbuf, bufsize);\r
- if ((*pb->bf_getsegcount)(arg, NULL) != 1)\r
- return converterr("single-segment read-write buffer",\r
- arg, msgbuf, bufsize);\r
- if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)\r
- return converterr("(unspecified)", arg, msgbuf, bufsize);\r
- if (*format == '*') {\r
- PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);\r
- format++;\r
- }\r
- else {\r
- *p = res;\r
- if (*format == '#') {\r
- FETCH_SIZE;\r
- STORE_SIZE(count);\r
- format++;\r
- }\r
- }\r
- break;\r
- }\r
-\r
- case 't': { /* 8-bit character buffer, read-only access */\r
- char **p = va_arg(*p_va, char **);\r
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;\r
- Py_ssize_t count;\r
-\r
- if (*format++ != '#')\r
- return converterr(\r
- "invalid use of 't' format character",\r
- arg, msgbuf, bufsize);\r
- if (!PyType_HasFeature(arg->ob_type,\r
- Py_TPFLAGS_HAVE_GETCHARBUFFER) ||\r
- pb == NULL || pb->bf_getcharbuffer == NULL ||\r
- pb->bf_getsegcount == NULL)\r
- return converterr(\r
- "string or read-only character buffer",\r
- arg, msgbuf, bufsize);\r
-\r
- if (pb->bf_getsegcount(arg, NULL) != 1)\r
- return converterr(\r
- "string or single-segment read-only buffer",\r
- arg, msgbuf, bufsize);\r
-\r
- if (pb->bf_releasebuffer)\r
- return converterr(\r
- "string or pinned buffer",\r
- arg, msgbuf, bufsize);\r
-\r
- count = pb->bf_getcharbuffer(arg, 0, p);\r
- if (count < 0)\r
- return converterr("(unspecified)", arg, msgbuf, bufsize);\r
- {\r
- FETCH_SIZE;\r
- STORE_SIZE(count);\r
- }\r
- break;\r
- }\r
-\r
- default:\r
- return converterr("impossible<bad format char>", arg, msgbuf, bufsize);\r
-\r
- }\r
-\r
- *p_format = format;\r
- return NULL;\r
-}\r
-\r
-static Py_ssize_t\r
-convertbuffer(PyObject *arg, void **p, char **errmsg)\r
-{\r
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;\r
- Py_ssize_t count;\r
- if (pb == NULL ||\r
- pb->bf_getreadbuffer == NULL ||\r
- pb->bf_getsegcount == NULL ||\r
- pb->bf_releasebuffer != NULL) {\r
- *errmsg = "string or read-only buffer";\r
- return -1;\r
- }\r
- if ((*pb->bf_getsegcount)(arg, NULL) != 1) {\r
- *errmsg = "string or single-segment read-only buffer";\r
- return -1;\r
- }\r
- if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {\r
- *errmsg = "(unspecified)";\r
- }\r
- return count;\r
-}\r
-\r
-static int\r
-getbuffer(PyObject *arg, Py_buffer *view, char **errmsg)\r
-{\r
- void *buf;\r
- Py_ssize_t count;\r
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;\r
- if (pb == NULL) {\r
- *errmsg = "string or buffer";\r
- return -1;\r
- }\r
- if (pb->bf_getbuffer) {\r
- if (pb->bf_getbuffer(arg, view, 0) < 0) {\r
- *errmsg = "convertible to a buffer";\r
- return -1;\r
- }\r
- if (!PyBuffer_IsContiguous(view, 'C')) {\r
- *errmsg = "contiguous buffer";\r
- return -1;\r
- }\r
- return 0;\r
- }\r
-\r
- count = convertbuffer(arg, &buf, errmsg);\r
- if (count < 0) {\r
- *errmsg = "convertible to a buffer";\r
- return count;\r
- }\r
- PyBuffer_FillInfo(view, arg, buf, count, 1, 0);\r
- return 0;\r
-}\r
-\r
-/* Support for keyword arguments donated by\r
- Geoff Philbrick <philbric@delphi.hks.com> */\r
-\r
-/* Return false (0) for error, else true. */\r
-int\r
-PyArg_ParseTupleAndKeywords(PyObject *args,\r
- PyObject *keywords,\r
- const char *format,\r
- char **kwlist, ...)\r
-{\r
- int retval;\r
- va_list va;\r
-\r
- if ((args == NULL || !PyTuple_Check(args)) ||\r
- (keywords != NULL && !PyDict_Check(keywords)) ||\r
- format == NULL ||\r
- kwlist == NULL)\r
- {\r
- PyErr_BadInternalCall();\r
- return 0;\r
- }\r
-\r
- va_start(va, kwlist);\r
- retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);\r
- va_end(va);\r
- return retval;\r
-}\r
-\r
-int\r
-_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,\r
- PyObject *keywords,\r
- const char *format,\r
- char **kwlist, ...)\r
-{\r
- int retval;\r
- va_list va;\r
-\r
- if ((args == NULL || !PyTuple_Check(args)) ||\r
- (keywords != NULL && !PyDict_Check(keywords)) ||\r
- format == NULL ||\r
- kwlist == NULL)\r
- {\r
- PyErr_BadInternalCall();\r
- return 0;\r
- }\r
-\r
- va_start(va, kwlist);\r
- retval = vgetargskeywords(args, keywords, format,\r
- kwlist, &va, FLAG_SIZE_T);\r
- va_end(va);\r
- return retval;\r
-}\r
-\r
-\r
-int\r
-PyArg_VaParseTupleAndKeywords(PyObject *args,\r
- PyObject *keywords,\r
- const char *format,\r
- char **kwlist, va_list va)\r
-{\r
- int retval;\r
- va_list lva;\r
-\r
- if ((args == NULL || !PyTuple_Check(args)) ||\r
- (keywords != NULL && !PyDict_Check(keywords)) ||\r
- format == NULL ||\r
- kwlist == NULL)\r
- {\r
- PyErr_BadInternalCall();\r
- return 0;\r
- }\r
-\r
-#ifdef VA_LIST_IS_ARRAY\r
- memcpy(lva, va, sizeof(va_list));\r
-#else\r
-#ifdef __va_copy\r
- __va_copy(lva, va);\r
-#else\r
- lva = va;\r
-#endif\r
-#endif\r
-\r
- retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);\r
- return retval;\r
-}\r
-\r
-int\r
-_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,\r
- PyObject *keywords,\r
- const char *format,\r
- char **kwlist, va_list va)\r
-{\r
- int retval;\r
- va_list lva;\r
-\r
- if ((args == NULL || !PyTuple_Check(args)) ||\r
- (keywords != NULL && !PyDict_Check(keywords)) ||\r
- format == NULL ||\r
- kwlist == NULL)\r
- {\r
- PyErr_BadInternalCall();\r
- return 0;\r
- }\r
-\r
-#ifdef VA_LIST_IS_ARRAY\r
- memcpy(lva, va, sizeof(va_list));\r
-#else\r
-#ifdef __va_copy\r
- __va_copy(lva, va);\r
-#else\r
- lva = va;\r
-#endif\r
-#endif\r
-\r
- retval = vgetargskeywords(args, keywords, format,\r
- kwlist, &lva, FLAG_SIZE_T);\r
- return retval;\r
-}\r
-\r
-#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')\r
-\r
-static int\r
-vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,\r
- char **kwlist, va_list *p_va, int flags)\r
-{\r
- char msgbuf[512];\r
- int levels[32];\r
- const char *fname, *msg, *custom_msg, *keyword;\r
- int min = INT_MAX;\r
- int i, len, nargs, nkeywords;\r
- PyObject *freelist = NULL, *current_arg;\r
-\r
- assert(args != NULL && PyTuple_Check(args));\r
- assert(keywords == NULL || PyDict_Check(keywords));\r
- assert(format != NULL);\r
- assert(kwlist != NULL);\r
- assert(p_va != NULL);\r
-\r
- /* grab the function name or custom error msg first (mutually exclusive) */\r
- fname = strchr(format, ':');\r
- if (fname) {\r
- fname++;\r
- custom_msg = NULL;\r
- }\r
- else {\r
- custom_msg = strchr(format,';');\r
- if (custom_msg)\r
- custom_msg++;\r
- }\r
-\r
- /* scan kwlist and get greatest possible nbr of args */\r
- for (len=0; kwlist[len]; len++)\r
- continue;\r
-\r
- nargs = PyTuple_GET_SIZE(args);\r
- nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);\r
- if (nargs + nkeywords > len) {\r
- PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "\r
- "argument%s (%d given)",\r
- (fname == NULL) ? "function" : fname,\r
- (fname == NULL) ? "" : "()",\r
- len,\r
- (len == 1) ? "" : "s",\r
- nargs + nkeywords);\r
- return 0;\r
- }\r
-\r
- /* convert tuple args and keyword args in same loop, using kwlist to drive process */\r
- for (i = 0; i < len; i++) {\r
- keyword = kwlist[i];\r
- if (*format == '|') {\r
- min = i;\r
- format++;\r
- }\r
- if (IS_END_OF_FORMAT(*format)) {\r
- PyErr_Format(PyExc_RuntimeError,\r
- "More keyword list entries (%d) than "\r
- "format specifiers (%d)", len, i);\r
- return cleanreturn(0, freelist);\r
- }\r
- current_arg = NULL;\r
- if (nkeywords) {\r
- current_arg = PyDict_GetItemString(keywords, keyword);\r
- }\r
- if (current_arg) {\r
- --nkeywords;\r
- if (i < nargs) {\r
- /* arg present in tuple and in dict */\r
- PyErr_Format(PyExc_TypeError,\r
- "Argument given by name ('%s') "\r
- "and position (%d)",\r
- keyword, i+1);\r
- return cleanreturn(0, freelist);\r
- }\r
- }\r
- else if (nkeywords && PyErr_Occurred())\r
- return cleanreturn(0, freelist);\r
- else if (i < nargs)\r
- current_arg = PyTuple_GET_ITEM(args, i);\r
-\r
- if (current_arg) {\r
- msg = convertitem(current_arg, &format, p_va, flags,\r
- levels, msgbuf, sizeof(msgbuf), &freelist);\r
- if (msg) {\r
- seterror(i+1, msg, levels, fname, custom_msg);\r
- return cleanreturn(0, freelist);\r
- }\r
- continue;\r
- }\r
-\r
- if (i < min) {\r
- PyErr_Format(PyExc_TypeError, "Required argument "\r
- "'%s' (pos %d) not found",\r
- keyword, i+1);\r
- return cleanreturn(0, freelist);\r
- }\r
- /* current code reports success when all required args\r
- * fulfilled and no keyword args left, with no further\r
- * validation. XXX Maybe skip this in debug build ?\r
- */\r
- if (!nkeywords)\r
- return cleanreturn(1, freelist);\r
-\r
- /* We are into optional args, skip thru to any remaining\r
- * keyword args */\r
- msg = skipitem(&format, p_va, flags);\r
- if (msg) {\r
- PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,\r
- format);\r
- return cleanreturn(0, freelist);\r
- }\r
- }\r
-\r
- if (!IS_END_OF_FORMAT(*format) && *format != '|') {\r
- PyErr_Format(PyExc_RuntimeError,\r
- "more argument specifiers than keyword list entries "\r
- "(remaining format:'%s')", format);\r
- return cleanreturn(0, freelist);\r
- }\r
-\r
- /* make sure there are no extraneous keyword arguments */\r
- if (nkeywords > 0) {\r
- PyObject *key, *value;\r
- Py_ssize_t pos = 0;\r
- while (PyDict_Next(keywords, &pos, &key, &value)) {\r
- int match = 0;\r
- char *ks;\r
- if (!PyString_Check(key)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "keywords must be strings");\r
- return cleanreturn(0, freelist);\r
- }\r
- ks = PyString_AsString(key);\r
- for (i = 0; i < len; i++) {\r
- if (!strcmp(ks, kwlist[i])) {\r
- match = 1;\r
- break;\r
- }\r
- }\r
- if (!match) {\r
- PyErr_Format(PyExc_TypeError,\r
- "'%s' is an invalid keyword "\r
- "argument for this function",\r
- ks);\r
- return cleanreturn(0, freelist);\r
- }\r
- }\r
- }\r
-\r
- return cleanreturn(1, freelist);\r
-}\r
-\r
-\r
-static char *\r
-skipitem(const char **p_format, va_list *p_va, int flags)\r
-{\r
- const char *format = *p_format;\r
- char c = *format++;\r
-\r
- switch (c) {\r
-\r
- /* simple codes\r
- * The individual types (second arg of va_arg) are irrelevant */\r
-\r
- case 'b': /* byte -- very short int */\r
- case 'B': /* byte as bitfield */\r
- case 'h': /* short int */\r
- case 'H': /* short int as bitfield */\r
- case 'i': /* int */\r
- case 'I': /* int sized bitfield */\r
- case 'l': /* long int */\r
- case 'k': /* long int sized bitfield */\r
-#ifdef HAVE_LONG_LONG\r
- case 'L': /* PY_LONG_LONG */\r
- case 'K': /* PY_LONG_LONG sized bitfield */\r
-#endif\r
- case 'f': /* float */\r
- case 'd': /* double */\r
-#ifndef WITHOUT_COMPLEX\r
- case 'D': /* complex double */\r
-#endif\r
- case 'c': /* char */\r
- {\r
- (void) va_arg(*p_va, void *);\r
- break;\r
- }\r
-\r
- case 'n': /* Py_ssize_t */\r
- {\r
- (void) va_arg(*p_va, Py_ssize_t *);\r
- break;\r
- }\r
-\r
- /* string codes */\r
-\r
- case 'e': /* string with encoding */\r
- {\r
- (void) va_arg(*p_va, const char *);\r
- if (!(*format == 's' || *format == 't'))\r
- /* after 'e', only 's' and 't' is allowed */\r
- goto err;\r
- format++;\r
- /* explicit fallthrough to string cases */\r
- }\r
-\r
- case 's': /* string */\r
- case 'z': /* string or None */\r
-#ifdef Py_USING_UNICODE\r
- case 'u': /* unicode string */\r
-#endif\r
- case 't': /* buffer, read-only */\r
- case 'w': /* buffer, read-write */\r
- {\r
- (void) va_arg(*p_va, char **);\r
- if (*format == '#') {\r
- if (flags & FLAG_SIZE_T)\r
- (void) va_arg(*p_va, Py_ssize_t *);\r
- else\r
- (void) va_arg(*p_va, int *);\r
- format++;\r
- } else if ((c == 's' || c == 'z') && *format == '*') {\r
- format++;\r
- }\r
- break;\r
- }\r
-\r
- /* object codes */\r
-\r
- case 'S': /* string object */\r
-#ifdef Py_USING_UNICODE\r
- case 'U': /* unicode string object */\r
-#endif\r
- {\r
- (void) va_arg(*p_va, PyObject **);\r
- break;\r
- }\r
-\r
- case 'O': /* object */\r
- {\r
- if (*format == '!') {\r
- format++;\r
- (void) va_arg(*p_va, PyTypeObject*);\r
- (void) va_arg(*p_va, PyObject **);\r
- }\r
- else if (*format == '&') {\r
- typedef int (*converter)(PyObject *, void *);\r
- (void) va_arg(*p_va, converter);\r
- (void) va_arg(*p_va, void *);\r
- format++;\r
- }\r
- else {\r
- (void) va_arg(*p_va, PyObject **);\r
- }\r
- break;\r
- }\r
-\r
- case '(': /* bypass tuple, not handled at all previously */\r
- {\r
- char *msg;\r
- for (;;) {\r
- if (*format==')')\r
- break;\r
- if (IS_END_OF_FORMAT(*format))\r
- return "Unmatched left paren in format "\r
- "string";\r
- msg = skipitem(&format, p_va, flags);\r
- if (msg)\r
- return msg;\r
- }\r
- format++;\r
- break;\r
- }\r
-\r
- case ')':\r
- return "Unmatched right paren in format string";\r
-\r
- default:\r
-err:\r
- return "impossible<bad format char>";\r
-\r
- }\r
-\r
- *p_format = format;\r
- return NULL;\r
-}\r
-\r
-\r
-int\r
-PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)\r
-{\r
- Py_ssize_t i, l;\r
- PyObject **o;\r
- va_list vargs;\r
-\r
-#ifdef HAVE_STDARG_PROTOTYPES\r
- va_start(vargs, max);\r
-#else\r
- va_start(vargs);\r
-#endif\r
-\r
- assert(min >= 0);\r
- assert(min <= max);\r
- if (!PyTuple_Check(args)) {\r
- va_end(vargs);\r
- PyErr_SetString(PyExc_SystemError,\r
- "PyArg_UnpackTuple() argument list is not a tuple");\r
- return 0;\r
- }\r
- l = PyTuple_GET_SIZE(args);\r
- if (l < min) {\r
- if (name != NULL)\r
- PyErr_Format(\r
- PyExc_TypeError,\r
- "%s expected %s%zd arguments, got %zd",\r
- name, (min == max ? "" : "at least "), min, l);\r
- else\r
- PyErr_Format(\r
- PyExc_TypeError,\r
- "unpacked tuple should have %s%zd elements,"\r
- " but has %zd",\r
- (min == max ? "" : "at least "), min, l);\r
- va_end(vargs);\r
- return 0;\r
- }\r
- if (l > max) {\r
- if (name != NULL)\r
- PyErr_Format(\r
- PyExc_TypeError,\r
- "%s expected %s%zd arguments, got %zd",\r
- name, (min == max ? "" : "at most "), max, l);\r
- else\r
- PyErr_Format(\r
- PyExc_TypeError,\r
- "unpacked tuple should have %s%zd elements,"\r
- " but has %zd",\r
- (min == max ? "" : "at most "), max, l);\r
- va_end(vargs);\r
- return 0;\r
- }\r
- for (i = 0; i < l; i++) {\r
- o = va_arg(vargs, PyObject **);\r
- *o = PyTuple_GET_ITEM(args, i);\r
- }\r
- va_end(vargs);\r
- return 1;\r
-}\r
-\r
-\r
-/* For type constructors that don't take keyword args\r
- *\r
- * Sets a TypeError and returns 0 if the kwds dict is\r
- * not empty, returns 1 otherwise\r
- */\r
-int\r
-_PyArg_NoKeywords(const char *funcname, PyObject *kw)\r
-{\r
- if (kw == NULL)\r
- return 1;\r
- if (!PyDict_CheckExact(kw)) {\r
- PyErr_BadInternalCall();\r
- return 0;\r
- }\r
- if (PyDict_Size(kw) == 0)\r
- return 1;\r
-\r
- PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",\r
- funcname);\r
- return 0;\r
-}\r
-#ifdef __cplusplus\r
-};\r
-#endif\r