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