PyArg_Parse*() functions: factorize code for s/z and u/Z formats

This commit is contained in:
Victor Stinner 2010-06-24 22:31:12 +00:00
parent 4aae1ebab2
commit 3c9e6e9375
2 changed files with 26 additions and 97 deletions

View File

@ -184,7 +184,7 @@ class NamespaceSeparatorTest(unittest.TestCase):
self.fail()
except TypeError as e:
self.assertEquals(str(e),
'ParserCreate() argument 2 must be string or None, not int')
'ParserCreate() argument 2 must be str or None, not int')
try:
expat.ParserCreate(namespace_separator='too long')

View File

@ -853,70 +853,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
/* 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;
@ -948,11 +884,14 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
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);
@ -975,11 +914,12 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
}
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)) {
@ -1000,11 +940,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;
if (c == 'z' && arg == Py_None)
*p = NULL;
else if (PyUnicode_Check(arg)) {
uarg = UNICODE_DEFAULT_ENCODING(arg);
if (uarg == NULL)
@ -1013,24 +954,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 (*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)) {
@ -1041,10 +986,11 @@ 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;
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))
@ -1052,7 +998,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
"str without null character or None",
arg, msgbuf, bufsize);
} else
return converterr("str or None", arg, msgbuf, bufsize);
return converterr(c == 'Z' ? "str or None" : "str",
arg, msgbuf, bufsize);
}
break;
}
@ -1222,24 +1169,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++;
} else {
if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg))
return converterr(
"str without null character",
arg, msgbuf, bufsize);
}
break;
}
case 'S': { /* PyBytes object */
PyObject **p = va_arg(*p_va, PyObject **);
if (PyBytes_Check(arg))