[pypy-commit] cffi wchar_t: in-progress

arigo noreply at buildbot.pypy.org
Mon Jul 9 16:59:11 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: wchar_t
Changeset: r607:94a8888f3d84
Date: 2012-07-09 16:17 +0200
http://bitbucket.org/cffi/cffi/changeset/94a8888f3d84/

Log:	in-progress

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -886,6 +886,7 @@
             if (res < 0)
                 return -1;
             data[0] = res;
+            return 0;
         }
 #ifdef HAVE_WCHAR_H
         else {
@@ -893,9 +894,9 @@
             if (res == (wchar_t)-1 && PyErr_Occurred())
                 return -1;
             *(wchar_t *)data = res;
+            return 0;
         }
 #endif
-        return 0;
     }
     if (ct->ct_flags & (CT_STRUCT|CT_UNION)) {
 
@@ -1169,34 +1170,35 @@
 static PyObject *cdata_unicode(CDataObject *cd)
 {
     if (cd->c_type->ct_flags & CT_PRIMITIVE_CHAR &&
-        cd->c_type->ct_size > sizeof(char)) {
+        cd->c_type->ct_size == sizeof(wchar_t)) {
         return _my_PyUnicode_FromWideChar((wchar_t *)cd->c_data, 1);
     }
     else if (cd->c_type->ct_itemdescr != NULL &&
              cd->c_type->ct_itemdescr->ct_flags & CT_PRIMITIVE_CHAR &&
-             cd->c_type->ct_itemdescr->ct_size > sizeof(char)) {
+             cd->c_type->ct_itemdescr->ct_size == sizeof(wchar_t)) {
         Py_ssize_t length;
+        const wchar_t *start = (wchar_t *)cd->c_data;
 
         if (cd->c_type->ct_flags & CT_ARRAY) {
-            const wchar_t *start = (wchar_t *)cd->c_data;
             const Py_ssize_t lenmax = get_array_length(cd);
             length = 0;
             while (length < lenmax && start[length])
                 length++;
         }
         else {
-            abort();
             if (cd->c_data == NULL) {
                 PyObject *s = cdata_repr(cd);
                 if (s != NULL) {
                     PyErr_Format(PyExc_RuntimeError,
-                                 "cannot use str() on %s",
+                                 "cannot use unicode() on %s",
                                  PyString_AS_STRING(s));
                     Py_DECREF(s);
                 }
                 return NULL;
             }
-            length = strlen(cd->c_data);
+            length = 0;
+            while (start[length])
+                length++;
         }
 
         return _my_PyUnicode_FromWideChar((wchar_t *)cd->c_data, length);
@@ -1257,7 +1259,12 @@
         return convert_to_object(cd->c_data, cd->c_type);
     }
     else if (cd->c_type->ct_flags & CT_PRIMITIVE_CHAR) {
-        return PyInt_FromLong((unsigned char)cd->c_data[0]);
+        if (cd->c_type->ct_size == sizeof(char))
+            return PyInt_FromLong((unsigned char)cd->c_data[0]);
+#ifdef HAVE_WCHAR_H
+        else
+            return PyInt_FromLong((long)*(wchar_t *)cd->c_data);
+#endif
     }
     else if (cd->c_type->ct_flags & CT_PRIMITIVE_FLOAT) {
         PyObject *o = convert_to_object(cd->c_data, cd->c_type);
@@ -1657,12 +1664,27 @@
             argtype = (CTypeDescrObject *)PyTuple_GET_ITEM(fvarargs, i);
 
         if ((argtype->ct_flags & CT_POINTER) &&
-            (argtype->ct_itemdescr->ct_flags & CT_PRIMITIVE_CHAR) &&
-            PyString_Check(obj)) {
-            /* special case: Python string -> cdata 'char *' */
-            *(char **)data = PyString_AS_STRING(obj);
+            (argtype->ct_itemdescr->ct_flags & CT_PRIMITIVE_CHAR)) {
+            if (argtype->ct_itemdescr->ct_size == sizeof(char)) {
+                if (PyString_Check(obj)) {
+                    /* special case: Python string -> cdata 'char *' */
+                    *(char **)data = PyString_AS_STRING(obj);
+                    continue;
+                }
+            }
+#ifdef HAVE_WCHAR_H
+            else {
+                if (PyUnicode_Check(obj)) {
+                    /* Python Unicode string -> cdata 'wchar_t *':
+                       not supported yet */
+                    PyErr_SetString(PyExc_NotImplementedError,
+                        "automatic unicode-to-'wchar_t *' conversion");
+                    goto error;
+                }
+            }
+#endif
         }
-        else if (convert_from_object(data, argtype, obj) < 0)
+        if (convert_from_object(data, argtype, obj) < 0)
             goto error;
     }
 
@@ -1975,7 +1997,7 @@
             }
             else if (PyUnicode_Check(init)) {
                 /* from a unicode, we add the null terminator */
-                explicitlength = PyUnicode_GET_SIZE(init) + 1;
+                explicitlength = _my_PyUnicode_SizeAsWideChar(init) + 1;
             }
             else {
                 explicitlength = PyNumber_AsSsize_t(init, PyExc_OverflowError);
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1324,8 +1324,9 @@
     assert unicode(a) == u'hello \u1234 world!'
     assert str(a) == repr(a)
     assert a[6] == u'\u1234'
-    a[6] = '-'
-    assert str(a) == 'hello - world'
+    a[6] = u'-'
+    assert unicode(a) == 'hello - world!'
+    assert str(a) == repr(a)
     #
     if wchar4:
         u = u'\U00012345\U00012346\U00012347'
@@ -1341,29 +1342,29 @@
     #
     w = cast(BWChar, 'a')
     assert repr(w) == "<cdata 'wchar_t' u'a'>"
-    assert str(w) == 'a'
+    assert str(w) == repr(w)
     assert unicode(w) == u'a'
+    assert int(w) == ord('a')
     w = cast(BWChar, 0x1234)
     assert repr(w) == "<cdata 'wchar_t' u'\u1234'>"
-    py.test.raises(xxUnicodeEncodeError, str, w)
+    assert str(w) == repr(w)
     assert unicode(w) == u'\u1234'
     assert int(w) == 0x1234
     #
+    a = newp(BWCharArray, u'hello - world')
     p = cast(BWCharP, a)
-    assert str(p) == 'hello - world'
     assert unicode(p) == u'hello - world'
     p[6] = u'\u2345'
-    py.test.raises(xxUnicodeEncodeError, str, p)
     assert unicode(p) == u'hello \u2345 world'
     #
     s = newp(BStructPtr, [u'\u1234', p])
     assert s.a1 == u'\u1234'
     assert s.a2 == p
-    py.test.raises(xxUnicodeEncodeError, str, s.a2)
+    assert str(s.a2) == repr(s.a2)
     assert unicode(s.a2) == u'hello \u2345 world'
     #
     q = cast(BWCharP, 0)
-    py.test.raises(RuntimeError, str, q)
+    assert str(q) == repr(q)
     py.test.raises(RuntimeError, unicode, q)
     #
     BInt = new_primitive_type("int")
@@ -1372,7 +1373,8 @@
         return len(unicode(p))
     BFunc = new_function_type((BWCharP,), BInt, False)
     f = callback(BFunc, cb, -42)
-    assert f(u'a\u1234b') == 3
+    #assert f(u'a\u1234b') == 3    -- not implemented
+    py.test.raises(NotImplementedError, f, u'a\u1234b')
 
 def test_keepalive_struct():
     # exception to the no-keepalive rule: p=newp(BStructPtr) returns a


More information about the pypy-commit mailing list