]> granicus.if.org Git - python/commitdiff
Fixed "u#" parser marker to pass through Unicode objects as-is without
authorMarc-André Lemburg <mal@egenix.com>
Wed, 9 Jan 2002 16:21:27 +0000 (16:21 +0000)
committerMarc-André Lemburg <mal@egenix.com>
Wed, 9 Jan 2002 16:21:27 +0000 (16:21 +0000)
going through the buffer interface API.

Added tests for this to the _testcapi module and updated docs.

Doc/ext/extending.tex
Misc/NEWS
Modules/_testcapimodule.c
Python/getargs.c

index 0051a0222f81b1da8579bbc2626bba716b13497b..d77a7142d2864ac851c63fc258c6bbcdcb6747c4 100644 (file)
@@ -669,6 +669,8 @@ address you pass.
 \item[\samp{u\#} (Unicode object) {[Py_UNICODE *, int]}]
 This variant on \samp{u} stores into two C variables, the first one
 a pointer to a Unicode data buffer, the second one its length.
+Non-Unicode objects are handled by interpreting their read buffer
+pointer as pointer to a Py_UNICODE array.
 
 \item[\samp{es} (string, Unicode object or character buffer compatible
 object) {[const char *encoding, char **buffer]}]
index 1912dc2c9737dfd7f260df97556c8c8d2de7cb29..4429f8e04ad8a10f722b84fe4d8707a07776bb48 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -28,6 +28,9 @@ Build
 
 C API
 
+- The "u#" parser marker will now pass through Unicode object as-is
+  without going through the buffer API.
+
 - The enumerators of cmp_op have been renamed to use the prefix PyCmp_.
 
 - An old #define of ANY as void has been removed from pyport.h.  This
index 0f5fa7c5d17ec80cd23b36a780af13630925faa8..824ae87473dc2b9ab27b36d408bf2cb02bd30c14 100644 (file)
@@ -307,6 +307,53 @@ test_L_code(PyObject *self, PyObject *args)
 
 #endif /* ifdef HAVE_LONG_LONG */
 
+#ifdef Py_USING_UNICODE
+
+/* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case
+   of an error.
+*/
+static PyObject *
+test_u_code(PyObject *self, PyObject *args)
+{
+       PyObject *tuple, *obj;
+       Py_UNICODE *value;
+       int len;
+
+        if (!PyArg_ParseTuple(args, ":test_u_code"))
+                return NULL;
+
+        tuple = PyTuple_New(1);
+        if (tuple == NULL)
+               return NULL;
+
+        obj = PyUnicode_Decode("test", strlen("test"),
+                              "ascii", NULL);
+        if (obj == NULL)
+               return NULL;
+
+        PyTuple_SET_ITEM(tuple, 0, obj);
+
+        value = 0;
+        if (PyArg_ParseTuple(tuple, "u:test_u_code", &value) < 0)
+               return NULL;
+        if (value != PyUnicode_AS_UNICODE(obj))
+               return raiseTestError("test_u_code",
+                       "u code returned wrong value for u'test'");
+        value = 0;
+        if (PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len) < 0)
+               return NULL;
+        if (value != PyUnicode_AS_UNICODE(obj) ||
+           len != PyUnicode_GET_SIZE(obj))
+               return raiseTestError("test_u_code",
+                       "u# code returned wrong values for u'test'");
+       
+       Py_DECREF(tuple);
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+#endif
+
 static PyObject *
 raise_exception(PyObject *self, PyObject *args)
 {
@@ -342,6 +389,9 @@ static PyMethodDef TestMethods[] = {
 #ifdef HAVE_LONG_LONG
        {"test_longlong_api",   test_longlong_api,      METH_VARARGS},
        {"test_L_code",         test_L_code,            METH_VARARGS},
+#endif
+#ifdef Py_USING_UNICODE
+       {"test_u_code",         test_u_code,            METH_VARARGS},
 #endif
        {NULL, NULL} /* sentinel */
 };
index 9df2a2e56672dda3af83ae6b801bc291f5e21924..411c69543d6c3489e5fa8fd3230f772160335474 100644 (file)
@@ -838,16 +838,20 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
                if (*format == '#') { /* any buffer-like object */
                        void **p = (void **)va_arg(*p_va, char **);
                        int *q = va_arg(*p_va, int *);
+                       if (PyUnicode_Check(arg)) {
+                               *p = PyUnicode_AS_UNICODE(arg);
+                               *q = PyUnicode_GET_SIZE(arg);
+                       }
+                       else {
                        char *buf;
                        int count = convertbuffer(arg, p, &buf);
-
                        if (count < 0)
                                return converterr(buf, arg, msgbuf, bufsize);
                        *q = count/(sizeof(Py_UNICODE)); 
+                       }
                        format++;
                } else {
                        Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
-                       
                        if (PyUnicode_Check(arg))
                                *p = PyUnicode_AS_UNICODE(arg);
                        else