summaryrefslogtreecommitdiffstats
path: root/Python/getargs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/getargs.c')
-rw-r--r--Python/getargs.c514
1 files changed, 165 insertions, 349 deletions
diff --git a/Python/getargs.c b/Python/getargs.c
index 686eac5..600941d 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -105,15 +105,7 @@ PyArg_VaParse(PyObject *args, const char *format, va_list va)
{
va_list lva;
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
+ Py_VA_COPY(lva, va);
return vgetargs1(args, format, &lva, 0);
}
@@ -123,15 +115,7 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
{
va_list lva;
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
+ Py_VA_COPY(lva, va);
return vgetargs1(args, format, &lva, FLAG_SIZE_T);
}
@@ -162,10 +146,19 @@ cleanup_buffer(PyObject *self)
}
static int
-addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
+addcleanup(void *ptr, PyObject **freelist, int is_buffer)
{
PyObject *cobj;
const char *name;
+ PyCapsule_Destructor destr;
+
+ if (is_buffer) {
+ destr = cleanup_buffer;
+ name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
+ } else {
+ destr = cleanup_ptr;
+ name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
+ }
if (!*freelist) {
*freelist = PyList_New(0);
@@ -175,13 +168,6 @@ addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
}
}
- if (destr == cleanup_ptr) {
- name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
- } else if (destr == cleanup_buffer) {
- name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
- } else {
- return -1;
- }
cobj = PyCapsule_New(ptr, name, destr);
if (!cobj) {
destr(ptr);
@@ -613,8 +599,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
else q=va_arg(*p_va, int*);
-#define STORE_SIZE(s) if (flags & FLAG_SIZE_T) *q2=s; else *q=s;
+#define STORE_SIZE(s) \
+ if (flags & FLAG_SIZE_T) \
+ *q2=s; \
+ else { \
+ if (INT_MAX < s) { \
+ PyErr_SetString(PyExc_OverflowError, \
+ "size does not fit in an int"); \
+ return converterr("", arg, msgbuf, bufsize); \
+ } \
+ *q=s; \
+ }
#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q)
+#define RETURN_ERR_OCCURRED return msgbuf
const char *format = *p_format;
char c = *format++;
@@ -626,19 +623,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
char *p = va_arg(*p_va, char *);
long ival;
if (float_argument_error(arg))
- return converterr("integer<b>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- return converterr("integer<b>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else if (ival < 0) {
PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is less than minimum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
+ "unsigned byte integer is less than minimum");
+ RETURN_ERR_OCCURRED;
}
else if (ival > UCHAR_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is greater than maximum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
+ "unsigned byte integer is greater than maximum");
+ RETURN_ERR_OCCURRED;
}
else
*p = (unsigned char) ival;
@@ -650,10 +647,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
char *p = va_arg(*p_va, char *);
long ival;
if (float_argument_error(arg))
- return converterr("integer<B>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
ival = PyLong_AsUnsignedLongMask(arg);
if (ival == -1 && PyErr_Occurred())
- return converterr("integer<B>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else
*p = (unsigned char) ival;
break;
@@ -663,19 +660,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
short *p = va_arg(*p_va, short *);
long ival;
if (float_argument_error(arg))
- return converterr("integer<h>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- return converterr("integer<h>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else if (ival < SHRT_MIN) {
PyErr_SetString(PyExc_OverflowError,
- "signed short integer is less than minimum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
+ "signed short integer is less than minimum");
+ RETURN_ERR_OCCURRED;
}
else if (ival > SHRT_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "signed short integer is greater than maximum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
+ "signed short integer is greater than maximum");
+ RETURN_ERR_OCCURRED;
}
else
*p = (short) ival;
@@ -687,10 +684,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
unsigned short *p = va_arg(*p_va, unsigned short *);
long ival;
if (float_argument_error(arg))
- return converterr("integer<H>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
ival = PyLong_AsUnsignedLongMask(arg);
if (ival == -1 && PyErr_Occurred())
- return converterr("integer<H>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else
*p = (unsigned short) ival;
break;
@@ -700,19 +697,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
int *p = va_arg(*p_va, int *);
long ival;
if (float_argument_error(arg))
- return converterr("integer<i>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- return converterr("integer<i>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else if (ival > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "signed integer is greater than maximum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
+ "signed integer is greater than maximum");
+ RETURN_ERR_OCCURRED;
}
else if (ival < INT_MIN) {
PyErr_SetString(PyExc_OverflowError,
- "signed integer is less than minimum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
+ "signed integer is less than minimum");
+ RETURN_ERR_OCCURRED;
}
else
*p = ival;
@@ -724,10 +721,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
unsigned int *p = va_arg(*p_va, unsigned int *);
unsigned int ival;
if (float_argument_error(arg))
- return converterr("integer<I>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
ival = (unsigned int)PyLong_AsUnsignedLongMask(arg);
if (ival == (unsigned int)-1 && PyErr_Occurred())
- return converterr("integer<I>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else
*p = ival;
break;
@@ -739,14 +736,14 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
Py_ssize_t ival = -1;
if (float_argument_error(arg))
- return converterr("integer<n>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
iobj = PyNumber_Index(arg);
if (iobj != NULL) {
ival = PyLong_AsSsize_t(iobj);
Py_DECREF(iobj);
}
if (ival == -1 && PyErr_Occurred())
- return converterr("integer<n>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
*p = ival;
break;
}
@@ -754,10 +751,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
long *p = va_arg(*p_va, long *);
long ival;
if (float_argument_error(arg))
- return converterr("integer<l>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- return converterr("integer<l>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else
*p = ival;
break;
@@ -777,12 +774,14 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
#ifdef HAVE_LONG_LONG
case 'L': {/* PY_LONG_LONG */
PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
- PY_LONG_LONG ival = PyLong_AsLongLong( arg );
- if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
- return converterr("long<L>", arg, msgbuf, bufsize);
- } else {
+ PY_LONG_LONG ival;
+ if (float_argument_error(arg))
+ RETURN_ERR_OCCURRED;
+ ival = PyLong_AsLongLong(arg);
+ if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred())
+ RETURN_ERR_OCCURRED;
+ else
*p = ival;
- }
break;
}
@@ -802,7 +801,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
float *p = va_arg(*p_va, float *);
double dval = PyFloat_AsDouble(arg);
if (PyErr_Occurred())
- return converterr("float<f>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else
*p = (float) dval;
break;
@@ -812,24 +811,22 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
double *p = va_arg(*p_va, double *);
double dval = PyFloat_AsDouble(arg);
if (PyErr_Occurred())
- return converterr("float<d>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else
*p = dval;
break;
}
-#ifndef WITHOUT_COMPLEX
case 'D': {/* complex double */
Py_complex *p = va_arg(*p_va, Py_complex *);
Py_complex cval;
cval = PyComplex_AsCComplex(arg);
if (PyErr_Occurred())
- return converterr("complex<D>", arg, msgbuf, bufsize);
+ RETURN_ERR_OCCURRED;
else
*p = cval;
break;
}
-#endif /* WITHOUT_COMPLEX */
case 'c': {/* char */
char *p = va_arg(*p_va, char *);
@@ -850,73 +847,9 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
break;
}
- /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w', 't' codes all
+ /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
need to be cleaned up! */
- case 's': {/* text string */
- if (*format == '*') {
- Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
-
- if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- PyBuffer_FillInfo(p, arg,
- PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg),
- 1, 0);
- }
- else { /* any buffer-like object */
- char *buf;
- if (getbuffer(arg, p, &buf) < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- }
- if (addcleanup(p, freelist, cleanup_buffer)) {
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- format++;
- } else if (*format == '#') {
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
-
- if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyBytes_AS_STRING(uarg);
- STORE_SIZE(PyBytes_GET_SIZE(uarg));
- }
- else { /* any buffer-like object */
- /* XXX Really? */
- char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- STORE_SIZE(count);
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
-
- if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyBytes_AS_STRING(uarg);
- }
- else
- return converterr("string", arg, msgbuf, bufsize);
- if ((Py_ssize_t) strlen(*p) != PyBytes_GET_SIZE(uarg))
- return converterr("string without null bytes",
- arg, msgbuf, bufsize);
- }
- break;
- }
-
case 'y': {/* any buffer-like object, but not PyUnicode */
void **p = (void **)va_arg(*p_va, char **);
char *buf;
@@ -925,7 +858,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
return converterr(buf, arg, msgbuf, bufsize);
format++;
- if (addcleanup(p, freelist, cleanup_buffer)) {
+ if (addcleanup(p, freelist, 1)) {
return converterr(
"(cleanup problem)",
arg, msgbuf, bufsize);
@@ -935,19 +868,27 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
count = convertbuffer(arg, p, &buf);
if (count < 0)
return converterr(buf, arg, msgbuf, bufsize);
- else if (*format == '#') {
+ if (*format == '#') {
FETCH_SIZE;
STORE_SIZE(count);
format++;
+ } else {
+ if (strlen(*p) != count)
+ return converterr(
+ "bytes without null bytes",
+ arg, msgbuf, bufsize);
}
break;
}
- case 'z': {/* like 's' or 's#', but None is okay, stored as NULL */
+ case 's': /* text string */
+ case 'z': /* text string or None */
+ {
if (*format == '*') {
+ /* "s*" or "z*" */
Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
- if (arg == Py_None)
+ if (c == 'z' && arg == Py_None)
PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
else if (PyUnicode_Check(arg)) {
uarg = UNICODE_DEFAULT_ENCODING(arg);
@@ -963,18 +904,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if (getbuffer(arg, p, &buf) < 0)
return converterr(buf, arg, msgbuf, bufsize);
}
- if (addcleanup(p, freelist, cleanup_buffer)) {
+ if (addcleanup(p, freelist, 1)) {
return converterr(
"(cleanup problem)",
arg, msgbuf, bufsize);
}
format++;
} else if (*format == '#') { /* any buffer-like object */
+ /* "s#" or "z#" */
void **p = (void **)va_arg(*p_va, char **);
FETCH_SIZE;
- if (arg == Py_None) {
- *p = 0;
+ if (c == 'z' && arg == Py_None) {
+ *p = NULL;
STORE_SIZE(0);
}
else if (PyUnicode_Check(arg)) {
@@ -995,16 +937,12 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
}
format++;
} else {
+ /* "s" or "z" */
char **p = va_arg(*p_va, char **);
uarg = NULL;
- if (arg == Py_None)
- *p = 0;
- else if (PyBytes_Check(arg)) {
- /* Enable null byte check below */
- uarg = arg;
- *p = PyBytes_AS_STRING(arg);
- }
+ if (c == 'z' && arg == Py_None)
+ *p = NULL;
else if (PyUnicode_Check(arg)) {
uarg = UNICODE_DEFAULT_ENCODING(arg);
if (uarg == NULL)
@@ -1013,35 +951,28 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
*p = PyBytes_AS_STRING(uarg);
}
else
- return converterr("string or None",
+ return converterr(c == 'z' ? "str or None" : "str",
arg, msgbuf, bufsize);
- if (*format == '#') {
- FETCH_SIZE;
- assert(0); /* XXX redundant with if-case */
- if (arg == Py_None) {
- STORE_SIZE(0);
- }
- else {
- STORE_SIZE(PyBytes_Size(arg));
- }
- format++;
- }
- else if (*p != NULL && uarg != NULL &&
+ if (*p != NULL && uarg != NULL &&
(Py_ssize_t) strlen(*p) != PyBytes_GET_SIZE(uarg))
return converterr(
- "string without null bytes or None",
+ c == 'z' ? "str without null bytes or None"
+ : "str without null bytes",
arg, msgbuf, bufsize);
}
break;
}
- case 'Z': {/* unicode, may be NULL (None) */
+ case 'u': /* raw unicode buffer (Py_UNICODE *) */
+ case 'Z': /* raw unicode buffer or None */
+ {
if (*format == '#') { /* any buffer-like object */
+ /* "s#" or "Z#" */
Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
FETCH_SIZE;
- if (arg == Py_None) {
- *p = 0;
+ if (c == 'Z' && arg == Py_None) {
+ *p = NULL;
STORE_SIZE(0);
}
else if (PyUnicode_Check(arg)) {
@@ -1052,14 +983,20 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
return converterr("str or None", arg, msgbuf, bufsize);
format++;
} else {
+ /* "s" or "Z" */
Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
- if (arg == Py_None)
- *p = 0;
- else if (PyUnicode_Check(arg))
+ if (c == 'Z' && arg == Py_None)
+ *p = NULL;
+ else if (PyUnicode_Check(arg)) {
*p = PyUnicode_AS_UNICODE(arg);
- else
- return converterr("str or None", arg, msgbuf, bufsize);
+ if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg))
+ return converterr(
+ "str without null character or None",
+ arg, msgbuf, bufsize);
+ } else
+ return converterr(c == 'Z' ? "str or None" : "str",
+ arg, msgbuf, bufsize);
}
break;
}
@@ -1170,11 +1107,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
*buffer = PyMem_NEW(char, size + 1);
if (*buffer == NULL) {
Py_DECREF(s);
- return converterr(
- "(memory error)",
- arg, msgbuf, bufsize);
+ PyErr_NoMemory();
+ RETURN_ERR_OCCURRED;
}
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ if (addcleanup(*buffer, freelist, 0)) {
Py_DECREF(s);
return converterr(
"(cleanup problem)",
@@ -1213,10 +1149,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
*buffer = PyMem_NEW(char, size + 1);
if (*buffer == NULL) {
Py_DECREF(s);
- return converterr("(memory error)",
- arg, msgbuf, bufsize);
+ PyErr_NoMemory();
+ RETURN_ERR_OCCURRED;
}
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ if (addcleanup(*buffer, freelist, 0)) {
Py_DECREF(s);
return converterr("(cleanup problem)",
arg, msgbuf, bufsize);
@@ -1227,19 +1163,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
break;
}
- case 'u': {/* raw unicode buffer (Py_UNICODE *) */
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
- if (!PyUnicode_Check(arg))
- return converterr("str", arg, msgbuf, bufsize);
- *p = PyUnicode_AS_UNICODE(arg);
- if (*format == '#') { /* store pointer and size */
- FETCH_SIZE;
- STORE_SIZE(PyUnicode_GET_SIZE(arg));
- format++;
- }
- break;
- }
-
case 'S': { /* PyBytes object */
PyObject **p = va_arg(*p_va, PyObject **);
if (PyBytes_Check(arg))
@@ -1280,17 +1203,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
return converterr(type->tp_name, arg, msgbuf, bufsize);
}
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- p = va_arg(*p_va, PyObject **);
- format++;
- if ((*pred)(arg))
- *p = arg;
- else
- return converterr("(unspecified)",
- arg, msgbuf, bufsize);
-
- }
else if (*format == '&') {
typedef int (*converter)(PyObject *, void *);
converter convert = va_arg(*p_va, converter);
@@ -1313,96 +1225,29 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
}
- case 'w': { /* memory buffer, read-write access */
+ case 'w': { /* "w*": memory buffer, read-write access */
void **p = va_arg(*p_va, void **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
- int temp=-1;
- Py_buffer view;
-
- if (pb && pb->bf_releasebuffer && *format != '*')
- /* Buffer must be released, yet caller does not use
- the Py_buffer protocol. */
- return converterr("pinned buffer", arg, msgbuf, bufsize);
+ if (*format != '*')
+ return converterr(
+ "invalid use of 'w' format character",
+ arg, msgbuf, bufsize);
+ format++;
- if (pb && pb->bf_getbuffer && *format == '*') {
- /* Caller is interested in Py_buffer, and the object
- supports it directly. */
- format++;
- if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
- PyErr_Clear();
- return converterr("read-write buffer", arg, msgbuf, bufsize);
- }
- if (addcleanup(p, freelist, cleanup_buffer)) {
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
- return converterr("contiguous buffer", arg, msgbuf, bufsize);
- break;
- }
-
- /* Here we have processed w*, only w and w# remain. */
- if (pb == NULL ||
- pb->bf_getbuffer == NULL ||
- ((temp = PyObject_GetBuffer(arg, &view,
- PyBUF_SIMPLE)) != 0) ||
- view.readonly == 1) {
- if (temp==0) {
- PyBuffer_Release(&view);
- }
- return converterr("single-segment read-write buffer",
- arg, msgbuf, bufsize);
+ /* Caller is interested in Py_buffer, and the object
+ supports it directly. */
+ if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+ PyErr_Clear();
+ return converterr("read-write buffer", arg, msgbuf, bufsize);
}
-
- if ((count = view.len) < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
- *p = view.buf;
- if (*format == '#') {
- FETCH_SIZE;
- STORE_SIZE(count);
- format++;
+ if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) {
+ PyBuffer_Release((Py_buffer*)p);
+ return converterr("contiguous buffer", arg, msgbuf, bufsize);
}
- break;
- }
-
- /*TEO: This can be eliminated --- here only for backward
- compatibility */
- case 't': { /* 8-bit character buffer, read-only access */
- char **p = va_arg(*p_va, char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
- Py_buffer view;
-
- if (*format++ != '#')
- return converterr(
- "invalid use of 't' format character",
- arg, msgbuf, bufsize);
- if (pb == NULL || pb->bf_getbuffer == NULL)
+ if (addcleanup(p, freelist, 1)) {
return converterr(
- "bytes or read-only character buffer",
+ "(cleanup problem)",
arg, msgbuf, bufsize);
- if (pb->bf_releasebuffer)
- return converterr(
- "string or pinned buffer",
- arg, msgbuf, bufsize);
-
- if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0)
- return converterr("string or single-segment read-only buffer",
- arg, msgbuf, bufsize);
-
- count = view.len;
- *p = view.buf;
-
- PyBuffer_Release(&view);
-
- if (count < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
- {
- FETCH_SIZE;
- STORE_SIZE(count);
}
break;
}
@@ -1414,65 +1259,47 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
*p_format = format;
return NULL;
+
+#undef FETCH_SIZE
+#undef STORE_SIZE
+#undef BUFFER_LEN
+#undef RETURN_ERR_OCCURRED
}
static Py_ssize_t
convertbuffer(PyObject *arg, void **p, char **errmsg)
{
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
Py_ssize_t count;
Py_buffer view;
*errmsg = NULL;
*p = NULL;
- if (pb == NULL ||
- pb->bf_getbuffer == NULL ||
- pb->bf_releasebuffer != NULL) {
- *errmsg = "bytes or read-only buffer";
+ if (pb != NULL && pb->bf_releasebuffer != NULL) {
+ *errmsg = "read-only pinned buffer";
return -1;
}
- if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) {
- *errmsg = "bytes or single-segment read-only buffer";
+ if (getbuffer(arg, &view, errmsg) < 0)
return -1;
- }
count = view.len;
*p = view.buf;
PyBuffer_Release(&view);
return count;
}
-/* XXX for 3.x, getbuffer and convertbuffer can probably
- be merged again. */
static int
getbuffer(PyObject *arg, Py_buffer *view, char **errmsg)
{
- void *buf;
- Py_ssize_t count;
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- if (pb == NULL) {
+ if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
*errmsg = "bytes or buffer";
return -1;
}
- if (pb->bf_getbuffer) {
- if (PyObject_GetBuffer(arg, view, 0) < 0) {
- *errmsg = "convertible to a buffer";
- return -1;
- }
- if (!PyBuffer_IsContiguous(view, 'C')) {
- PyBuffer_Release(view);
- *errmsg = "contiguous buffer";
- return -1;
- }
- return 0;
- }
-
- count = convertbuffer(arg, &buf, errmsg);
- if (count < 0) {
- *errmsg = "convertible to a buffer";
- return count;
+ if (!PyBuffer_IsContiguous(view, 'C')) {
+ PyBuffer_Release(view);
+ *errmsg = "contiguous buffer";
+ return -1;
}
- PyBuffer_FillInfo(view, NULL, buf, count, 1, 0);
return 0;
}
@@ -1548,15 +1375,7 @@ PyArg_VaParseTupleAndKeywords(PyObject *args,
return 0;
}
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
+ Py_VA_COPY(lva, va);
retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
return retval;
@@ -1580,21 +1399,28 @@ _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
return 0;
}
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
+ Py_VA_COPY(lva, va);
retval = vgetargskeywords(args, keywords, format,
kwlist, &lva, FLAG_SIZE_T);
return retval;
}
+int
+PyArg_ValidateKeywordArguments(PyObject *kwargs)
+{
+ if (!PyDict_Check(kwargs)) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+ if (!_PyDict_HasOnlyStringKeys(kwargs)) {
+ PyErr_SetString(PyExc_TypeError,
+ "keyword arguments must be strings");
+ return 0;
+ }
+ return 1;
+}
+
#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
static int
@@ -1728,18 +1554,21 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
"keywords must be strings");
return cleanreturn(0, freelist);
}
+ /* check that _PyUnicode_AsString() result is not NULL */
ks = _PyUnicode_AsString(key);
- for (i = 0; i < len; i++) {
- if (!strcmp(ks, kwlist[i])) {
- match = 1;
- break;
+ if (ks != NULL) {
+ for (i = 0; i < len; i++) {
+ if (!strcmp(ks, kwlist[i])) {
+ match = 1;
+ break;
+ }
}
}
if (!match) {
PyErr_Format(PyExc_TypeError,
- "'%s' is an invalid keyword "
+ "'%U' is an invalid keyword "
"argument for this function",
- ks);
+ key);
return cleanreturn(0, freelist);
}
}
@@ -1774,9 +1603,7 @@ skipitem(const char **p_format, va_list *p_va, int flags)
#endif
case 'f': /* float */
case 'd': /* double */
-#ifndef WITHOUT_COMPLEX
case 'D': /* complex double */
-#endif
case 'c': /* char */
case 'C': /* unicode char */
{
@@ -1806,7 +1633,6 @@ skipitem(const char **p_format, va_list *p_va, int flags)
case 'z': /* string or None */
case 'y': /* bytes */
case 'u': /* unicode string */
- case 't': /* buffer, read-only */
case 'w': /* buffer, read-write */
{
(void) va_arg(*p_va, char **);
@@ -1839,16 +1665,6 @@ skipitem(const char **p_format, va_list *p_va, int flags)
(void) va_arg(*p_va, PyTypeObject*);
(void) va_arg(*p_va, PyObject **);
}
-#if 0
-/* I don't know what this is for */
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- format++;
- if ((*pred)(arg)) {
- (void) va_arg(*p_va, PyObject **);
- }
- }
-#endif
else if (*format == '&') {
typedef int (*converter)(PyObject *, void *);
(void) va_arg(*p_va, converter);