summaryrefslogtreecommitdiffstats
path: root/Python/getargs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/getargs.c')
-rw-r--r--Python/getargs.c745
1 files changed, 429 insertions, 316 deletions
diff --git a/Python/getargs.c b/Python/getargs.c
index 600941d..a6cebbc 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -105,7 +105,15 @@ PyArg_VaParse(PyObject *args, const char *format, va_list va)
{
va_list lva;
- Py_VA_COPY(lva, va);
+#ifdef VA_LIST_IS_ARRAY
+ memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(lva, va);
+#else
+ lva = va;
+#endif
+#endif
return vgetargs1(args, format, &lva, 0);
}
@@ -115,7 +123,15 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
{
va_list lva;
- Py_VA_COPY(lva, va);
+#ifdef VA_LIST_IS_ARRAY
+ memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(lva, va);
+#else
+ lva = va;
+#endif
+#endif
return vgetargs1(args, format, &lva, FLAG_SIZE_T);
}
@@ -125,14 +141,13 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
#define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"
#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
-#define GETARGS_CAPSULE_NAME_CLEANUP_CONVERT "getargs.cleanup_convert"
static void
cleanup_ptr(PyObject *self)
{
void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);
if (ptr) {
- PyMem_FREE(ptr);
+ PyMem_FREE(ptr);
}
}
@@ -146,19 +161,10 @@ cleanup_buffer(PyObject *self)
}
static int
-addcleanup(void *ptr, PyObject **freelist, int is_buffer)
+addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
{
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);
@@ -168,6 +174,13 @@ addcleanup(void *ptr, PyObject **freelist, int is_buffer)
}
}
+ 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);
@@ -181,46 +194,6 @@ addcleanup(void *ptr, PyObject **freelist, int is_buffer)
return 0;
}
-static void
-cleanup_convert(PyObject *self)
-{
- typedef int (*destr_t)(PyObject *, void *);
- destr_t destr = (destr_t)PyCapsule_GetContext(self);
- void *ptr = PyCapsule_GetPointer(self,
- GETARGS_CAPSULE_NAME_CLEANUP_CONVERT);
- if (ptr && destr)
- destr(NULL, ptr);
-}
-
-static int
-addcleanup_convert(void *ptr, PyObject **freelist, int (*destr)(PyObject*,void*))
-{
- PyObject *cobj;
- if (!*freelist) {
- *freelist = PyList_New(0);
- if (!*freelist) {
- destr(NULL, ptr);
- return -1;
- }
- }
- cobj = PyCapsule_New(ptr, GETARGS_CAPSULE_NAME_CLEANUP_CONVERT,
- cleanup_convert);
- if (!cobj) {
- destr(NULL, ptr);
- return -1;
- }
- if (PyCapsule_SetContext(cobj, destr) == -1) {
- /* This really should not happen. */
- Py_FatalError("capsule refused setting of context.");
- }
- if (PyList_Append(*freelist, cobj)) {
- Py_DECREF(cobj); /* This will also call destr. */
- return -1;
- }
- Py_DECREF(cobj);
- return 0;
-}
-
static int
cleanreturn(int retval, PyObject *freelist)
{
@@ -475,7 +448,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
n++;
}
- if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
+ if (!PySequence_Check(arg) || PyString_Check(arg)) {
levels[0] = 0;
PyOS_snprintf(msgbuf, bufsize,
toplevel ? "expected %d arguments, not %.50s" :
@@ -568,14 +541,27 @@ converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
#define CONV_UNICODE "(unicode conversion error)"
-/* Explicitly check for float arguments when integers are expected.
- Return 1 for error, 0 if ok. */
+/* explicitly check for float arguments when integers are expected. For now
+ * signal a warning. Returns true if an exception was raised. */
+static int
+float_argument_warning(PyObject *arg)
+{
+ if (PyFloat_Check(arg) &&
+ PyErr_Warn(PyExc_DeprecationWarning,
+ "integer argument expected, got float" ))
+ return 1;
+ else
+ return 0;
+}
+
+/* explicitly check for float arguments when integers are expected. Raises
+ TypeError and returns true for float arguments. */
static int
float_argument_error(PyObject *arg)
{
if (PyFloat_Check(arg)) {
PyErr_SetString(PyExc_TypeError,
- "integer argument expected, got float" );
+ "integer argument expected, got float");
return 1;
}
else
@@ -611,11 +597,12 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
*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++;
+#ifdef Py_USING_UNICODE
PyObject *uarg;
+#endif
switch (c) {
@@ -623,19 +610,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_ERR_OCCURRED;
- ival = PyLong_AsLong(arg);
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<b>", arg, msgbuf, bufsize);
else if (ival < 0) {
PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is less than minimum");
- RETURN_ERR_OCCURRED;
+ "unsigned byte integer is less than minimum");
+ return converterr("integer<b>", arg, msgbuf, bufsize);
}
else if (ival > UCHAR_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is greater than maximum");
- RETURN_ERR_OCCURRED;
+ "unsigned byte integer is greater than maximum");
+ return converterr("integer<b>", arg, msgbuf, bufsize);
}
else
*p = (unsigned char) ival;
@@ -647,10 +634,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_ERR_OCCURRED;
- ival = PyLong_AsUnsignedLongMask(arg);
+ return converterr("integer<B>", arg, msgbuf, bufsize);
+ ival = PyInt_AsUnsignedLongMask(arg);
if (ival == -1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<B>", arg, msgbuf, bufsize);
else
*p = (unsigned char) ival;
break;
@@ -660,19 +647,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_ERR_OCCURRED;
- ival = PyLong_AsLong(arg);
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<h>", arg, msgbuf, bufsize);
else if (ival < SHRT_MIN) {
PyErr_SetString(PyExc_OverflowError,
- "signed short integer is less than minimum");
- RETURN_ERR_OCCURRED;
+ "signed short integer is less than minimum");
+ return converterr("integer<h>", arg, msgbuf, bufsize);
}
else if (ival > SHRT_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "signed short integer is greater than maximum");
- RETURN_ERR_OCCURRED;
+ "signed short integer is greater than maximum");
+ return converterr("integer<h>", arg, msgbuf, bufsize);
}
else
*p = (short) ival;
@@ -684,10 +671,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_ERR_OCCURRED;
- ival = PyLong_AsUnsignedLongMask(arg);
+ return converterr("integer<H>", arg, msgbuf, bufsize);
+ ival = PyInt_AsUnsignedLongMask(arg);
if (ival == -1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<H>", arg, msgbuf, bufsize);
else
*p = (unsigned short) ival;
break;
@@ -697,19 +684,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_ERR_OCCURRED;
- ival = PyLong_AsLong(arg);
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<i>", arg, msgbuf, bufsize);
else if (ival > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "signed integer is greater than maximum");
- RETURN_ERR_OCCURRED;
+ "signed integer is greater than maximum");
+ return converterr("integer<i>", arg, msgbuf, bufsize);
}
else if (ival < INT_MIN) {
PyErr_SetString(PyExc_OverflowError,
- "signed integer is less than minimum");
- RETURN_ERR_OCCURRED;
+ "signed integer is less than minimum");
+ return converterr("integer<i>", arg, msgbuf, bufsize);
}
else
*p = ival;
@@ -721,40 +708,38 @@ 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_ERR_OCCURRED;
- ival = (unsigned int)PyLong_AsUnsignedLongMask(arg);
+ return converterr("integer<I>", arg, msgbuf, bufsize);
+ ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
if (ival == (unsigned int)-1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<I>", arg, msgbuf, bufsize);
else
*p = ival;
break;
}
case 'n': /* Py_ssize_t */
+#if SIZEOF_SIZE_T != SIZEOF_LONG
{
- PyObject *iobj;
Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
- Py_ssize_t ival = -1;
+ Py_ssize_t ival;
if (float_argument_error(arg))
- RETURN_ERR_OCCURRED;
- iobj = PyNumber_Index(arg);
- if (iobj != NULL) {
- ival = PyLong_AsSsize_t(iobj);
- Py_DECREF(iobj);
- }
+ return converterr("integer<n>", arg, msgbuf, bufsize);
+ ival = PyInt_AsSsize_t(arg);
if (ival == -1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<n>", arg, msgbuf, bufsize);
*p = ival;
break;
}
+#endif
+ /* Fall through from 'n' to 'l' if Py_ssize_t is int */
case 'l': {/* long int */
long *p = va_arg(*p_va, long *);
long ival;
if (float_argument_error(arg))
- RETURN_ERR_OCCURRED;
- ival = PyLong_AsLong(arg);
+ return converterr("integer<l>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
+ return converterr("integer<l>", arg, msgbuf, bufsize);
else
*p = ival;
break;
@@ -763,7 +748,9 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
case 'k': { /* long sized bitfield */
unsigned long *p = va_arg(*p_va, unsigned long *);
unsigned long ival;
- if (PyLong_Check(arg))
+ if (PyInt_Check(arg))
+ ival = PyInt_AsUnsignedLongMask(arg);
+ else if (PyLong_Check(arg))
ival = PyLong_AsUnsignedLongMask(arg);
else
return converterr("integer<k>", arg, msgbuf, bufsize);
@@ -775,20 +762,23 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
case 'L': {/* PY_LONG_LONG */
PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
PY_LONG_LONG ival;
- if (float_argument_error(arg))
- RETURN_ERR_OCCURRED;
+ if (float_argument_warning(arg))
+ return converterr("long<L>", arg, msgbuf, bufsize);
ival = PyLong_AsLongLong(arg);
- if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred())
- RETURN_ERR_OCCURRED;
- else
+ if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
+ return converterr("long<L>", arg, msgbuf, bufsize);
+ } else {
*p = ival;
+ }
break;
}
case 'K': { /* long long sized bitfield */
unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
unsigned PY_LONG_LONG ival;
- if (PyLong_Check(arg))
+ if (PyInt_Check(arg))
+ ival = PyInt_AsUnsignedLongMask(arg);
+ else if (PyLong_Check(arg))
ival = PyLong_AsUnsignedLongLongMask(arg);
else
return converterr("integer<K>", arg, msgbuf, bufsize);
@@ -801,7 +791,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_ERR_OCCURRED;
+ return converterr("float<f>", arg, msgbuf, bufsize);
else
*p = (float) dval;
break;
@@ -811,124 +801,170 @@ 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_ERR_OCCURRED;
+ return converterr("float<d>", arg, msgbuf, bufsize);
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_ERR_OCCURRED;
+ return converterr("complex<D>", arg, msgbuf, bufsize);
else
*p = cval;
break;
}
+#endif /* WITHOUT_COMPLEX */
case 'c': {/* char */
char *p = va_arg(*p_va, char *);
- if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
- *p = PyBytes_AS_STRING(arg)[0];
+ if (PyString_Check(arg) && PyString_Size(arg) == 1)
+ *p = PyString_AS_STRING(arg)[0];
else
- return converterr("a byte string of length 1", arg, msgbuf, bufsize);
+ return converterr("char", arg, msgbuf, bufsize);
break;
}
- case 'C': {/* unicode char */
- int *p = va_arg(*p_va, int *);
- if (PyUnicode_Check(arg) &&
- PyUnicode_GET_SIZE(arg) == 1)
- *p = PyUnicode_AS_UNICODE(arg)[0];
- else
- return converterr("a unicode character", arg, msgbuf, bufsize);
- break;
- }
-
- /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
- need to be cleaned up! */
-
- case 'y': {/* any buffer-like object, but not PyUnicode */
- void **p = (void **)va_arg(*p_va, char **);
- char *buf;
- Py_ssize_t count;
+ case 's': {/* string */
if (*format == '*') {
- if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- format++;
- if (addcleanup(p, freelist, 1)) {
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (PyString_Check(arg)) {
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
+ 1, 0);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
+ 1, 0);
+ }
+#endif
+ 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);
}
- break;
- }
- count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- if (*format == '#') {
+ format++;
+ } else if (*format == '#') {
+ void **p = (void **)va_arg(*p_va, char **);
FETCH_SIZE;
- STORE_SIZE(count);
+
+ if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ STORE_SIZE(PyString_GET_SIZE(arg));
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ STORE_SIZE(PyString_GET_SIZE(uarg));
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ Py_ssize_t count = convertbuffer(arg, p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ STORE_SIZE(count);
+ }
format++;
} else {
- if (strlen(*p) != count)
- return converterr(
- "bytes without null bytes",
- arg, msgbuf, bufsize);
+ char **p = va_arg(*p_va, char **);
+
+ if (PyString_Check(arg))
+ *p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ }
+#endif
+ else
+ return converterr("string", arg, msgbuf, bufsize);
+ if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
+ return converterr("string without null bytes",
+ arg, msgbuf, bufsize);
}
break;
}
- case 's': /* text string */
- case 'z': /* text string or None */
- {
+ case 'z': {/* string, may be NULL (None) */
if (*format == '*') {
- /* "s*" or "z*" */
Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
- if (c == 'z' && arg == Py_None)
+ if (arg == Py_None)
PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
+ else if (PyString_Check(arg)) {
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
+ 1, 0);
+ }
+#ifdef Py_USING_UNICODE
else 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),
+ PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
1, 0);
}
+#endif
else { /* any buffer-like object */
char *buf;
if (getbuffer(arg, p, &buf) < 0)
return converterr(buf, arg, msgbuf, bufsize);
}
- if (addcleanup(p, freelist, 1)) {
+ if (addcleanup(p, freelist, cleanup_buffer)) {
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 (c == 'z' && arg == Py_None) {
- *p = NULL;
+ if (arg == Py_None) {
+ *p = 0;
STORE_SIZE(0);
}
+ else if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ STORE_SIZE(PyString_GET_SIZE(arg));
+ }
+#ifdef Py_USING_UNICODE
else 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));
+ *p = PyString_AS_STRING(uarg);
+ STORE_SIZE(PyString_GET_SIZE(uarg));
}
+#endif
else { /* any buffer-like object */
- /* XXX Really? */
char *buf;
Py_ssize_t count = convertbuffer(arg, p, &buf);
if (count < 0)
@@ -937,82 +973,56 @@ 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 (c == 'z' && arg == Py_None)
- *p = NULL;
+ if (arg == Py_None)
+ *p = 0;
+ else if (PyString_Check(arg))
+ *p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(arg)) {
uarg = UNICODE_DEFAULT_ENCODING(arg);
if (uarg == NULL)
return converterr(CONV_UNICODE,
arg, msgbuf, bufsize);
- *p = PyBytes_AS_STRING(uarg);
+ *p = PyString_AS_STRING(uarg);
}
+#endif
else
- return converterr(c == 'z' ? "str or None" : "str",
+ return converterr("string or None",
arg, msgbuf, bufsize);
- if (*p != NULL && uarg != NULL &&
- (Py_ssize_t) strlen(*p) != PyBytes_GET_SIZE(uarg))
+ if (*format == '#') {
+ FETCH_SIZE;
+ assert(0); /* XXX redundant with if-case */
+ if (arg == Py_None) {
+ STORE_SIZE(0);
+ } else {
+ STORE_SIZE(PyString_Size(arg));
+ }
+ format++;
+ }
+ else if (*p != NULL &&
+ (Py_ssize_t)strlen(*p) != PyString_Size(arg))
return converterr(
- c == 'z' ? "str without null bytes or None"
- : "str without null bytes",
+ "string without null bytes or None",
arg, msgbuf, bufsize);
}
break;
}
- 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 (c == 'Z' && arg == Py_None) {
- *p = NULL;
- STORE_SIZE(0);
- }
- else if (PyUnicode_Check(arg)) {
- *p = PyUnicode_AS_UNICODE(arg);
- STORE_SIZE(PyUnicode_GET_SIZE(arg));
- }
- else
- return converterr("str or None", arg, msgbuf, bufsize);
- format++;
- } else {
- /* "s" or "Z" */
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
-
- if (c == 'Z' && arg == Py_None)
- *p = NULL;
- else if (PyUnicode_Check(arg)) {
- *p = PyUnicode_AS_UNICODE(arg);
- 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;
- }
-
case 'e': {/* encoded string */
char **buffer;
const char *encoding;
PyObject *s;
- int recode_strings;
Py_ssize_t size;
- const char *ptr;
+ int recode_strings;
/* Get 'e' parameter: the encoding name */
encoding = (const char *)va_arg(*p_va, const char *);
+#ifdef Py_USING_UNICODE
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
+#endif
/* Get output buffer parameter:
's' (recode all objects via Unicode) or
@@ -1033,15 +1043,12 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
arg, msgbuf, bufsize);
/* Encode object */
- if (!recode_strings &&
- (PyBytes_Check(arg) || PyByteArray_Check(arg))) {
+ if (!recode_strings && PyString_Check(arg)) {
s = arg;
Py_INCREF(s);
- if (PyObject_AsCharBuffer(s, &ptr, &size) < 0)
- return converterr("(AsCharBuffer failed)",
- arg, msgbuf, bufsize);
}
else {
+#ifdef Py_USING_UNICODE
PyObject *u;
/* Convert object to Unicode */
@@ -1059,17 +1066,17 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if (s == NULL)
return converterr("(encoding failed)",
arg, msgbuf, bufsize);
- if (!PyBytes_Check(s)) {
+ if (!PyString_Check(s)) {
Py_DECREF(s);
return converterr(
- "(encoder failed to return bytes)",
+ "(encoder failed to return a string)",
arg, msgbuf, bufsize);
}
- size = PyBytes_GET_SIZE(s);
- ptr = PyBytes_AS_STRING(s);
- if (ptr == NULL)
- ptr = "";
+#else
+ return converterr("string<e>", arg, msgbuf, bufsize);
+#endif
}
+ size = PyString_GET_SIZE(s);
/* Write output; output is guaranteed to be 0-terminated */
if (*format == '#') {
@@ -1107,10 +1114,11 @@ 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);
- PyErr_NoMemory();
- RETURN_ERR_OCCURRED;
+ return converterr(
+ "(memory error)",
+ arg, msgbuf, bufsize);
}
- if (addcleanup(*buffer, freelist, 0)) {
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
Py_DECREF(s);
return converterr(
"(cleanup problem)",
@@ -1124,7 +1132,9 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
arg, msgbuf, bufsize);
}
}
- memcpy(*buffer, ptr, size+1);
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
STORE_SIZE(size);
} else {
/* Using a 0-terminated buffer:
@@ -1140,7 +1150,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
PyMem_Free()ing it after usage
*/
- if ((Py_ssize_t)strlen(ptr) != size) {
+ if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
+ != size) {
Py_DECREF(s);
return converterr(
"encoded string without NULL bytes",
@@ -1149,46 +1160,66 @@ 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);
- PyErr_NoMemory();
- RETURN_ERR_OCCURRED;
+ return converterr("(memory error)",
+ arg, msgbuf, bufsize);
}
- if (addcleanup(*buffer, freelist, 0)) {
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
Py_DECREF(s);
return converterr("(cleanup problem)",
arg, msgbuf, bufsize);
}
- memcpy(*buffer, ptr, size+1);
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
}
Py_DECREF(s);
break;
}
- case 'S': { /* PyBytes object */
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyBytes_Check(arg))
- *p = arg;
- else
- return converterr("bytes", arg, msgbuf, bufsize);
+#ifdef Py_USING_UNICODE
+ case 'u': {/* raw unicode buffer (Py_UNICODE *) */
+ if (*format == '#') { /* any buffer-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ FETCH_SIZE;
+ if (PyUnicode_Check(arg)) {
+ *p = PyUnicode_AS_UNICODE(arg);
+ STORE_SIZE(PyUnicode_GET_SIZE(arg));
+ }
+ else {
+ return converterr("cannot convert raw buffers",
+ arg, msgbuf, bufsize);
+ }
+ format++;
+ } else {
+ Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+ if (PyUnicode_Check(arg))
+ *p = PyUnicode_AS_UNICODE(arg);
+ else
+ return converterr("unicode", arg, msgbuf, bufsize);
+ }
break;
}
+#endif
- case 'Y': { /* PyByteArray object */
+ case 'S': { /* string object */
PyObject **p = va_arg(*p_va, PyObject **);
- if (PyByteArray_Check(arg))
+ if (PyString_Check(arg))
*p = arg;
else
- return converterr("bytearray", arg, msgbuf, bufsize);
+ return converterr("string", arg, msgbuf, bufsize);
break;
}
- case 'U': { /* PyUnicode object */
+#ifdef Py_USING_UNICODE
+ case 'U': { /* Unicode object */
PyObject **p = va_arg(*p_va, PyObject **);
if (PyUnicode_Check(arg))
*p = arg;
else
- return converterr("str", arg, msgbuf, bufsize);
+ return converterr("unicode", arg, msgbuf, bufsize);
break;
}
+#endif
case 'O': { /* object */
PyTypeObject *type;
@@ -1203,19 +1234,25 @@ 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);
void *addr = va_arg(*p_va, void *);
- int res;
format++;
- if (! (res = (*convert)(arg, addr)))
+ if (! (*convert)(arg, addr))
return converterr("(unspecified)",
arg, msgbuf, bufsize);
- if (res == Py_CLEANUP_SUPPORTED &&
- addcleanup_convert(addr, freelist, convert) == -1)
- return converterr("(cleanup problem)",
- arg, msgbuf, bufsize);
}
else {
p = va_arg(*p_va, PyObject **);
@@ -1225,29 +1262,92 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
}
- case 'w': { /* "w*": memory buffer, read-write access */
+ case 'w': { /* memory buffer, read-write access */
void **p = va_arg(*p_va, void **);
+ void *res;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ Py_ssize_t count;
- if (*format != '*')
- return converterr(
- "invalid use of 'w' format character",
- arg, msgbuf, bufsize);
- format++;
+ 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);
- /* Caller is interested in Py_buffer, and the object
- supports it directly. */
- if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
- PyErr_Clear();
+ if (pb && pb->bf_getbuffer && *format == '*') {
+ /* Caller is interested in Py_buffer, and the object
+ supports it directly. */
+ format++;
+ if (pb->bf_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;
+ }
+
+ if (pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL)
return converterr("read-write buffer", arg, msgbuf, bufsize);
+ if ((*pb->bf_getsegcount)(arg, NULL) != 1)
+ return converterr("single-segment read-write buffer",
+ arg, msgbuf, bufsize);
+ if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)
+ return converterr("(unspecified)", arg, msgbuf, bufsize);
+ if (*format == '*') {
+ PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);
+ format++;
}
- if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) {
- PyBuffer_Release((Py_buffer*)p);
- return converterr("contiguous buffer", arg, msgbuf, bufsize);
+ else {
+ *p = res;
+ if (*format == '#') {
+ FETCH_SIZE;
+ STORE_SIZE(count);
+ format++;
+ }
}
- if (addcleanup(p, freelist, 1)) {
+ break;
+ }
+
+ 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;
+
+ if (*format++ != '#')
+ return converterr(
+ "invalid use of 't' format character",
+ arg, msgbuf, bufsize);
+ if (!PyType_HasFeature(arg->ob_type,
+ Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
+ pb == NULL || pb->bf_getcharbuffer == NULL ||
+ pb->bf_getsegcount == NULL)
+ return converterr(
+ "string or read-only character buffer",
+ arg, msgbuf, bufsize);
+
+ if (pb->bf_getsegcount(arg, NULL) != 1)
+ return converterr(
+ "string or single-segment read-only buffer",
+ arg, msgbuf, bufsize);
+
+ if (pb->bf_releasebuffer)
return converterr(
- "(cleanup problem)",
+ "string or pinned buffer",
arg, msgbuf, bufsize);
+
+ count = pb->bf_getcharbuffer(arg, 0, p);
+ if (count < 0)
+ return converterr("(unspecified)", arg, msgbuf, bufsize);
+ {
+ FETCH_SIZE;
+ STORE_SIZE(count);
}
break;
}
@@ -1259,47 +1359,58 @@ 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 = Py_TYPE(arg)->tp_as_buffer;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
Py_ssize_t count;
- Py_buffer view;
-
- *errmsg = NULL;
- *p = NULL;
- if (pb != NULL && pb->bf_releasebuffer != NULL) {
- *errmsg = "read-only pinned buffer";
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL ||
+ pb->bf_releasebuffer != NULL) {
+ *errmsg = "string or read-only buffer";
return -1;
}
-
- if (getbuffer(arg, &view, errmsg) < 0)
+ if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
+ *errmsg = "string or single-segment read-only buffer";
return -1;
- count = view.len;
- *p = view.buf;
- PyBuffer_Release(&view);
+ }
+ if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
+ *errmsg = "(unspecified)";
+ }
return count;
}
static int
getbuffer(PyObject *arg, Py_buffer *view, char **errmsg)
{
- if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
- *errmsg = "bytes or buffer";
+ void *buf;
+ Py_ssize_t count;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ if (pb == NULL) {
+ *errmsg = "string or buffer";
return -1;
}
- if (!PyBuffer_IsContiguous(view, 'C')) {
- PyBuffer_Release(view);
- *errmsg = "contiguous buffer";
- return -1;
+ if (pb->bf_getbuffer) {
+ if (pb->bf_getbuffer(arg, view, 0) < 0) {
+ *errmsg = "convertible to a buffer";
+ return -1;
+ }
+ if (!PyBuffer_IsContiguous(view, 'C')) {
+ *errmsg = "contiguous buffer";
+ return -1;
+ }
+ return 0;
}
+
+ count = convertbuffer(arg, &buf, errmsg);
+ if (count < 0) {
+ *errmsg = "convertible to a buffer";
+ return count;
+ }
+ PyBuffer_FillInfo(view, arg, buf, count, 1, 0);
return 0;
}
@@ -1375,7 +1486,15 @@ PyArg_VaParseTupleAndKeywords(PyObject *args,
return 0;
}
- Py_VA_COPY(lva, va);
+#ifdef VA_LIST_IS_ARRAY
+ memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(lva, va);
+#else
+ lva = va;
+#endif
+#endif
retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
return retval;
@@ -1399,28 +1518,21 @@ _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
return 0;
}
- Py_VA_COPY(lva, va);
+#ifdef VA_LIST_IS_ARRAY
+ memcpy(lva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(lva, va);
+#else
+ lva = va;
+#endif
+#endif
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
@@ -1549,26 +1661,23 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
while (PyDict_Next(keywords, &pos, &key, &value)) {
int match = 0;
char *ks;
- if (!PyUnicode_Check(key)) {
+ if (!PyString_Check(key)) {
PyErr_SetString(PyExc_TypeError,
"keywords must be strings");
return cleanreturn(0, freelist);
}
- /* check that _PyUnicode_AsString() result is not NULL */
- ks = _PyUnicode_AsString(key);
- if (ks != NULL) {
- for (i = 0; i < len; i++) {
- if (!strcmp(ks, kwlist[i])) {
- match = 1;
- break;
- }
+ ks = PyString_AsString(key);
+ for (i = 0; i < len; i++) {
+ if (!strcmp(ks, kwlist[i])) {
+ match = 1;
+ break;
}
}
if (!match) {
PyErr_Format(PyExc_TypeError,
- "'%U' is an invalid keyword "
+ "'%s' is an invalid keyword "
"argument for this function",
- key);
+ ks);
return cleanreturn(0, freelist);
}
}
@@ -1603,9 +1712,10 @@ 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 */
{
(void) va_arg(*p_va, void *);
break;
@@ -1631,8 +1741,10 @@ skipitem(const char **p_format, va_list *p_va, int flags)
case 's': /* string */
case 'z': /* string or None */
- case 'y': /* bytes */
+#ifdef Py_USING_UNICODE
case 'u': /* unicode string */
+#endif
+ case 't': /* buffer, read-only */
case 'w': /* buffer, read-write */
{
(void) va_arg(*p_va, char **);
@@ -1642,7 +1754,7 @@ skipitem(const char **p_format, va_list *p_va, int flags)
else
(void) va_arg(*p_va, int *);
format++;
- } else if ((c == 's' || c == 'z' || c == 'y') && *format == '*') {
+ } else if ((c == 's' || c == 'z') && *format == '*') {
format++;
}
break;
@@ -1651,8 +1763,9 @@ skipitem(const char **p_format, va_list *p_va, int flags)
/* object codes */
case 'S': /* string object */
- case 'Y': /* string object */
+#ifdef Py_USING_UNICODE
case 'U': /* unicode string object */
+#endif
{
(void) va_arg(*p_va, PyObject **);
break;