Commits

Armin Rigo committed 7cccdc4

Fix tests, part 1

Comments (0)

Files changed (6)

c/_cffi_backend.c

 
     for (ptypes=types; ; ptypes++) {
         if (ptypes->name == NULL) {
+#ifndef HAVE_WCHAR_H
+            if (strcmp(name, "wchar_t"))
+                PyErr_SetString(PyExc_NotImplementedError, name);
+            else
+#endif
             PyErr_SetString(PyExc_KeyError, name);
             return NULL;
         }

cffi/backend_ctypes.py

             if size == ctypes.sizeof(ctypes.c_size_t):
                 result['size_t'] = size | UNSIGNED
                 result['ssize_t'] = size
-            if size == ctypes.sizeof(ctypes.c_wchar):
-                if size < 4:
-                    result['wchar_t'] = size | UNSIGNED
-                else:
-                    result['wchar_t'] = size
         return result
 
     def load_library(self, path):
         # internals of CParser...  the following registers the
         # typedefs, because their presence or absence influences the
         # parsing itself (but what they are typedef'ed to plays no role)
-        csourcelines = []
+        csourcelines = ['typedef int wchar_t;']
         for name in sorted(self._declarations):
             if name.startswith('typedef '):
                 csourcelines.append('typedef int %s;' % (name[8:],))
         return self.name + replace_with
 
     def is_char_type(self):
-        return self.name == 'char'
+        return self.name in ('char', 'wchar_t')
     def is_signed_type(self):
         return self.is_integer_type() and not self.is_unsigned_type()
     def is_unsigned_type(self):

testing/backend_tests.py

 SIZE_OF_PTR   = ctypes.sizeof(ctypes.c_void_p)
 SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar)
 
-WCHAR_IS_UNSIGNED = (SIZE_OF_WCHAR < 4)
-
 
 class BackendTests:
 
         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, WCHAR_IS_UNSIGNED)
 
     def _test_int_type(self, ffi, c_decl, size, unsigned):
         if unsigned:
 
     def test_wchar_t(self):
         ffi = FFI(backend=self.Backend())
-        assert ffi.new("wchar_t", 'x')[0] == u'x'
+        assert ffi.new("wchar_t", u'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'
         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)])
+        p = ffi.new("wchar_t[]", [u'a', u'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'
+        p[0] = u'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")
+        p = ffi.new("wchar_t[]", u"abcd")
         assert len(p) == 5
         assert p[4] == u'\x00'
         p = ffi.new("wchar_t[]", u"a\u1234b")
         assert p[1] == unichr(0x1234)
         #
         p = ffi.new("wchar_t[]", u'\U00023456')
-        if SIZE_OF_WCHAR == 2 or sys.maxunicode == 0xffff:
+        if SIZE_OF_WCHAR == 2:
+            assert 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[0] == u'\U00023456'
             assert p[1] == u'\x00'
         #
         p = ffi.new("wchar_t[4]", u"ab")
         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"x")) == u"x"
         assert unicode(ffi.new("wchar_t", u"\x00")) == u""
-        py.test.raises(TypeError, str, ffi.new("wchar_t", u"\x00"))
+        x = ffi.new("wchar_t", u"\x00")
+        assert str(x) == repr(x)
 
     def test_string_from_char_array(self):
         ffi = FFI(backend=self.Backend())
         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"))
+        x = ffi.cast("wchar_t", "x")
+        assert str(x) == repr(x)
         #
-        p = ffi.new("wchar_t[]", "hello.")
-        p[5] = '!'
+        p = ffi.new("wchar_t[]", u"hello.")
+        p[5] = u'!'
         assert unicode(p) == u"hello!"
         p[6] = unichr(1234)
         assert unicode(p) == u"hello!\u04d2"
-        p[3] = '\x00'
+        p[3] = u'\x00'
         assert unicode(p) == u"hel"
-        py.test.raises(IndexError, "p[7] = 'X'")
+        py.test.raises(IndexError, "p[7] = u'X'")
         #
         a = ffi.new("wchar_t[]", u"hello\x00world")
         assert len(a) == 12
         # '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")
+        t = ffi.new("const wchar_t[]", u"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
+        s.name = ffi.NULL
+        assert s.name == ffi.NULL
 
     def test_voidp(self):
         ffi = FFI(backend=self.Backend())
         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("long long", ffi.cast("wchar_t", -1))
+        if SIZE_OF_WCHAR == 2:      # 2 bytes, unsigned
+            assert int(p) == 0xffff
+        else:                       # 4 bytes, signed
+            assert int(p) == -1
         p = ffi.cast("int", unichr(1234))
         assert int(p) == 1234
 

testing/test_verify.py

 all_float_types = ['float', 'double']
 
 def test_primitive_category():
-    for typename in all_integer_types + all_float_types + ['char']:
+    for typename in all_integer_types + all_float_types + ['char', 'wchar_t']:
         tp = model.PrimitiveType(typename)
-        assert tp.is_char_type() == (typename == 'char')
+        assert tp.is_char_type() == (typename in ('char', 'wchar_t'))
         assert tp.is_signed_type() == (typename in all_signed_integer_types)
         assert tp.is_unsigned_type()== (typename in all_unsigned_integer_types)
         assert tp.is_integer_type() == (typename in all_integer_types)
     assert lib.foo("A") == "B"
     py.test.raises(TypeError, lib.foo, "bar")
 
+def test_wchar_type():
+    ffi = FFI()
+    if ffi.sizeof('wchar_t') == 2:
+        uniexample1 = u'\u1234'
+        uniexample2 = u'\u1235'
+    else:
+        uniexample1 = u'\U00012345'
+        uniexample2 = u'\U00012346'
+    #
+    ffi.cdef("wchar_t foo(wchar_t);")
+    lib = ffi.verify("wchar_t foo(wchar_t x) { return x+1; }")
+    assert lib.foo(ffi.new("wchar_t[]", uniexample1)) == uniexample2
+
 def test_no_argument():
     ffi = FFI()
     ffi.cdef("int foo(void);")