From 3c9e6e9375954e9911ceddb65a98c3e58986e9a7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 24 Jun 2010 22:31:12 +0000 Subject: [PATCH] PyArg_Parse*() functions: factorize code for s/z and u/Z formats --- Lib/test/test_pyexpat.py | 2 +- Python/getargs.c | 121 ++++++++------------------------------- 2 files changed, 26 insertions(+), 97 deletions(-) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 00d92f90d8e..38983481c81 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -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') diff --git a/Python/getargs.c b/Python/getargs.c index bce99ae798e..ab95e1e547b 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -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))