Author: Armin Rigo <ar...@tunes.org>
Branch: wchar_t
Changeset: r480:41bf8ed262e9
Date: 2012-06-20 19:31 +0200
http://bitbucket.org/cffi/cffi/changeset/41bf8ed262e9/

Log:    Start by writing tests.

diff --git a/c/_ffi_backend.c b/c/_ffi_backend.c
--- a/c/_ffi_backend.c
+++ b/c/_ffi_backend.c
@@ -1794,7 +1794,7 @@
             return NULL;
         }
         if (ctitem->ct_flags & CT_PRIMITIVE_CHAR)
-            datasize += sizeof(char);  /* forcefully add a null character */
+            datasize *= 2;   /* forcefully add another character: a null */
     }
     else if (ct->ct_flags & CT_ARRAY) {
         dataoffset = offsetof(CDataObject_with_alignment, alignment);
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -222,8 +222,8 @@
             if size == ctypes.sizeof(ctypes.c_size_t):
                 result['size_t'] = size | UNSIGNED
                 result['ssize_t'] = size
-            #if size == ctypes.sizeof(ctypes.c_wchar):
-            #    result['wchar_t'] = size | UNSIGNED
+            if size == ctypes.sizeof(ctypes.c_wchar):
+                result['wchar_t'] = size | UNSIGNED
         return result
 
     def load_library(self, path):
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -6,7 +6,7 @@
 SIZE_OF_LONG  = ctypes.sizeof(ctypes.c_long)
 SIZE_OF_SHORT = ctypes.sizeof(ctypes.c_short)
 SIZE_OF_PTR   = ctypes.sizeof(ctypes.c_void_p)
-#SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar)
+SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar)
 
 
 class BackendTests:
@@ -41,7 +41,7 @@
         self._test_int_type(ffi, 'ptrdiff_t', SIZE_OF_PTR, False)
         self._test_int_type(ffi, 'size_t', SIZE_OF_PTR, True)
         self._test_int_type(ffi, 'ssize_t', SIZE_OF_PTR, False)
-        #self._test_int_type(ffi, 'wchar_t', SIZE_OF_WCHAR, True)
+        self._test_int_type(ffi, 'wchar_t', SIZE_OF_WCHAR, True)
 
     def _test_int_type(self, ffi, c_decl, size, unsigned):
         if unsigned:
@@ -272,8 +272,9 @@
         assert ffi.new("char", "\xff")[0] == '\xff'
         assert ffi.new("char")[0] == '\x00'
         assert int(ffi.cast("char", 300)) == 300 - 256
-        assert bool(ffi.new("char"))
+        assert bool(ffi.cast("char", 0))
         py.test.raises(TypeError, ffi.new, "char", 32)
+        py.test.raises(TypeError, ffi.new, "char", u"x")
         py.test.raises(TypeError, ffi.new, "char", "foo")
         #
         p = ffi.new("char[]", ['a', 'b', '\x9c'])
@@ -295,6 +296,55 @@
         assert [p[i] for i in range(2)] == ['a', 'b']
         py.test.raises(IndexError, ffi.new, "char[2]", "abc")
 
+    def test_wchar_t(self):
+        ffi = FFI(backend=self.Backend())
+        assert ffi.new("wchar_t", 'x')[0] == u'x'
+        assert ffi.new("wchar_t", unichr(1234))[0] == unichr(1234)
+        if SIZE_OF_WCHAR > 2:
+            assert ffi.new("wchar_t", u'\U00012345')[0] == u'\U00012345'
+        else:
+            py.test.raises(TypeError, ffi.new, "wchar_t", u'\U00012345')
+        assert ffi.new("wchar_t")[0] == u'\x00'
+        assert int(ffi.cast("wchar_t", 300)) == 300
+        assert bool(ffi.cast("wchar_t", 0))
+        py.test.raises(TypeError, ffi.new, "wchar_t", 32)
+        py.test.raises(TypeError, ffi.new, "wchar_t", "foo")
+        #
+        p = ffi.new("wchar_t[]", [u'a', 'b', unichr(1234)])
+        assert len(p) == 3
+        assert p[0] == u'a'
+        assert p[1] == u'b' and type(p[1]) is unicode
+        assert p[2] == unichr(1234)
+        p[0] = 'x'
+        assert p[0] == u'x' and type(p[0]) is unicode
+        p[1] = unichr(1357)
+        assert p[1] == unichr(1357)
+        p = ffi.new("wchar_t[]", "abcd")
+        assert len(p) == 5
+        assert p[4] == u'\x00'
+        p = ffi.new("wchar_t[]", u"a\u1234b")
+        assert len(p) == 4
+        assert p[1] == unichr(0x1234)
+        #
+        p = ffi.new("wchar_t[]", u'\U00023456')
+        if SIZE_OF_WCHAR == 2 or sys.maxunicode == 0xffff:
+            assert len(p) == 3
+            assert p[0] == u'\ud84d'
+            assert p[1] == u'\udc56'
+            assert p[2] == u'\x00'
+        else:
+            assert len(p) == 2
+            assert p[0] == unichr(0x23456)
+            assert p[1] == u'\x00'
+        #
+        p = ffi.new("wchar_t[4]", u"ab")
+        assert len(p) == 4
+        assert [p[i] for i in range(4)] == [u'a', u'b', u'\x00', u'\x00']
+        p = ffi.new("wchar_t[2]", u"ab")
+        assert len(p) == 2
+        assert [p[i] for i in range(2)] == [u'a', u'b']
+        py.test.raises(IndexError, ffi.new, "wchar_t[2]", u"abc")
+
     def test_none_as_null(self):
         ffi = FFI(backend=self.Backend())
         p = ffi.new("int*[1]")
@@ -470,6 +520,10 @@
         ffi = FFI(backend=self.Backend())
         assert str(ffi.new("char", "x")) == "x"
         assert str(ffi.new("char", "\x00")) == ""
+        #
+        assert unicode(ffi.new("wchar_t", "x")) == u"x"
+        assert unicode(ffi.new("wchar_t", u"\x00")) == u""
+        py.test.raises(TypeError, str, ffi.new("wchar_t", u"\x00"))
 
     def test_string_from_char_array(self):
         ffi = FFI(backend=self.Backend())
@@ -488,6 +542,26 @@
         p = ffi.cast("char *", a)
         assert str(p) == 'hello'
 
+    def test_string_from_wchar_array(self):
+        ffi = FFI(backend=self.Backend())
+        assert unicode(ffi.cast("wchar_t", "x")) == u"x"
+        assert unicode(ffi.cast("wchar_t", u"x")) == u"x"
+        py.test.raises(TypeError, str, ffi.cast("wchar_t", "x"))
+        #
+        p = ffi.new("wchar_t[]", "hello.")
+        p[5] = '!'
+        assert unicode(p) == u"hello!"
+        p[6] = unichr(1234)
+        assert unicode(p) == u"hello!\u04d2"
+        p[3] = '\x00'
+        assert unicode(p) == u"hel"
+        py.test.raises(IndexError, "p[7] = 'X'")
+        #
+        a = ffi.new("wchar_t[]", u"hello\x00world")
+        assert len(a) == 12
+        p = ffi.cast("wchar_t *", a)
+        assert unicode(p) == u'hello'
+
     def test_fetch_const_char_p_field(self):
         # 'const' is ignored so far
         ffi = FFI(backend=self.Backend())
@@ -499,6 +573,17 @@
         s.name = None
         assert s.name is None
 
+    def test_fetch_const_wchar_p_field(self):
+        # 'const' is ignored so far
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("struct foo { const wchar_t *name; };")
+        t = ffi.new("const wchar_t[]", "testing")
+        s = ffi.new("struct foo", [t])
+        assert type(s.name) not in (str, unicode)
+        assert unicode(s.name) == u"testing"
+        s.name = None
+        assert s.name is None
+
     def test_voidp(self):
         ffi = FFI(backend=self.Backend())
         py.test.raises(TypeError, ffi.new, "void")
@@ -607,6 +692,12 @@
         assert int(p) == 0x80     # "char" is considered unsigned in this case
         p = ffi.cast("int", "\x81")
         assert int(p) == 0x81
+        p = ffi.cast("int", ffi.cast("wchar_t", unichr(1234)))
+        assert int(p) == 1234
+        p = ffi.cast("long long", ffi.cast("wchar_t", -1)) # wchar_t->unsigned
+        assert int(p) == (256 ** SIZE_OF_WCHAR) - 1
+        p = ffi.cast("int", unichr(1234))
+        assert int(p) == 1234
 
     def test_cast_array_to_charp(self):
         ffi = FFI(backend=self.Backend())
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to