diff options
| author | Armin Rigo <arigo@tunes.org> | 2015-05-17 10:00:14 +0200 |
|---|---|---|
| committer | Armin Rigo <arigo@tunes.org> | 2015-05-17 10:00:14 +0200 |
| commit | 48d677b2578080c605794afd08736176b3c8f928 (patch) | |
| tree | 086c5f2367dfb1989cdd41aacd675afb26bfc1e2 /testing | |
| parent | acf8dc3c0a4a389d3e89732a9fa96cff3abace83 (diff) | |
| parent | cb8e0566f3bf8f905324c6e77a00201fc6a9ab52 (diff) | |
| download | cffi-release-0.9.tar.gz | |
hg merge defaultrelease-0.9
Diffstat (limited to 'testing')
| -rw-r--r-- | testing/backend_tests.py | 13 | ||||
| -rw-r--r-- | testing/test_ctypes.py | 3 | ||||
| -rw-r--r-- | testing/test_ffi_backend.py | 54 | ||||
| -rw-r--r-- | testing/test_function.py | 1 | ||||
| -rw-r--r-- | testing/test_verify.py | 79 |
5 files changed, 134 insertions, 16 deletions
diff --git a/testing/backend_tests.py b/testing/backend_tests.py index d4e8cf6..d3b5ca1 100644 --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -1388,6 +1388,17 @@ class BackendTests: assert p.c == 14 assert p.d == 14 + def test_nested_field_offset_align(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { + struct { int a; char b; }; + union { char c; }; + }; + """) + assert ffi.offsetof("struct foo_s", "c") == 2 * SIZE_OF_INT + assert ffi.sizeof("struct foo_s") == 3 * SIZE_OF_INT + def test_nested_anonymous_union(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" @@ -1692,5 +1703,3 @@ class BackendTests: assert lib.DOT_HEX == 0x100 assert lib.DOT_HEX2 == 0x10 assert lib.DOT_UL == 1000 - - diff --git a/testing/test_ctypes.py b/testing/test_ctypes.py index 23e88b1..d2b53ed 100644 --- a/testing/test_ctypes.py +++ b/testing/test_ctypes.py @@ -28,6 +28,9 @@ class TestCTypes(backend_tests.BackendTests): def test_nested_anonymous_struct(self): py.test.skip("ctypes backend: not supported: nested anonymous struct") + def test_nested_field_offset_align(self): + py.test.skip("ctypes backend: not supported: nested anonymous struct") + def test_nested_anonymous_union(self): py.test.skip("ctypes backend: not supported: nested anonymous union") diff --git a/testing/test_ffi_backend.py b/testing/test_ffi_backend.py index 7cb5eee..4ea8b69 100644 --- a/testing/test_ffi_backend.py +++ b/testing/test_ffi_backend.py @@ -222,3 +222,57 @@ class TestBitfield: assert ffi.typeof(c) is ffi.typeof("char[]") ffi.cast("unsigned short *", c)[1] += 500 assert list(a) == [10000, 20500, 30000] + + def test_all_primitives(self): + ffi = FFI() + for name in [ + "char", + "short", + "int", + "long", + "long long", + "signed char", + "unsigned char", + "unsigned short", + "unsigned int", + "unsigned long", + "unsigned long long", + "float", + "double", + "long double", + "wchar_t", + "_Bool", + "int8_t", + "uint8_t", + "int16_t", + "uint16_t", + "int32_t", + "uint32_t", + "int64_t", + "uint64_t", + "int_least8_t", + "uint_least8_t", + "int_least16_t", + "uint_least16_t", + "int_least32_t", + "uint_least32_t", + "int_least64_t", + "uint_least64_t", + "int_fast8_t", + "uint_fast8_t", + "int_fast16_t", + "uint_fast16_t", + "int_fast32_t", + "uint_fast32_t", + "int_fast64_t", + "uint_fast64_t", + "intptr_t", + "uintptr_t", + "intmax_t", + "uintmax_t", + "ptrdiff_t", + "size_t", + "ssize_t", + ]: + x = ffi.sizeof(name) + assert 1 <= x <= 16 diff --git a/testing/test_function.py b/testing/test_function.py index 8edd4ae..d87bafb 100644 --- a/testing/test_function.py +++ b/testing/test_function.py @@ -292,7 +292,6 @@ class TestFunction(object): assert ffi.string(a) == b'4.4.4.4' def test_function_typedef(self): - py.test.skip("using really obscure C syntax") ffi = FFI(backend=self.Backend()) ffi.cdef(""" typedef double func_t(double); diff --git a/testing/test_verify.py b/testing/test_verify.py index 6a4400f..6a07168 100644 --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -657,9 +657,9 @@ def test_global_constants(): # case the 'static' is completely ignored. ffi.cdef("static const int AA, BB, CC, DD;") lib = ffi.verify("#define AA 42\n" - "#define BB (-43)\n" - "#define CC (22*2)\n" - "#define DD ((unsigned int)142)\n") + "#define BB (-43) // blah\n" + "#define CC (22*2) /* foobar */\n" + "#define DD ((unsigned int)142) /* foo\nbar */\n") assert lib.AA == 42 assert lib.BB == -43 assert lib.CC == 44 @@ -1197,6 +1197,15 @@ def test_typedef_enum_as_function_result(): """) assert lib.foo_func(lib.BB) == lib.BB == 2 +def test_function_typedef(): + ffi = FFI() + ffi.cdef(""" + typedef double func_t(double); + func_t sin; + """) + lib = ffi.verify('#include <math.h>', libraries=lib_m) + assert lib.sin(1.23) == math.sin(1.23) + def test_callback_calling_convention(): py.test.skip("later") if sys.platform != 'win32': @@ -1217,11 +1226,11 @@ def test_callback_calling_convention(): xxx def test_opaque_integer_as_function_result(): - import platform - if platform.machine().startswith('sparc'): - py.test.skip('Breaks horribly on sparc (SIGILL + corrupted stack)') - elif platform.machine() == 'mips64' and sys.maxsize > 2**32: - py.test.skip('Segfaults on mips64el') + #import platform + #if platform.machine().startswith('sparc'): + # py.test.skip('Breaks horribly on sparc (SIGILL + corrupted stack)') + #elif platform.machine() == 'mips64' and sys.maxsize > 2**32: + # py.test.skip('Segfaults on mips64el') # XXX bad abuse of "struct { ...; }". It only works a bit by chance # anyway. XXX think about something better :-( ffi = FFI() @@ -1236,11 +1245,45 @@ def test_opaque_integer_as_function_result(): h = lib.foo() assert ffi.sizeof(h) == ffi.sizeof("short") +def test_return_partial_struct(): + ffi = FFI() + ffi.cdef(""" + typedef struct { int x; ...; } foo_t; + foo_t foo(void); + """) + lib = ffi.verify(""" + typedef struct { int y, x; } foo_t; + foo_t foo(void) { foo_t r = { 45, 81 }; return r; } + """) + h = lib.foo() + assert ffi.sizeof(h) == 2 * ffi.sizeof("int") + assert h.x == 81 + +def test_take_and_return_partial_structs(): + ffi = FFI() + ffi.cdef(""" + typedef struct { int x; ...; } foo_t; + foo_t foo(foo_t, foo_t); + """) + lib = ffi.verify(""" + typedef struct { int y, x; } foo_t; + foo_t foo(foo_t a, foo_t b) { + foo_t r = { 100, a.x * 5 + b.x * 7 }; + return r; + } + """) + args = ffi.new("foo_t[3]") + args[0].x = 1000 + args[2].x = -498 + h = lib.foo(args[0], args[2]) + assert ffi.sizeof(h) == 2 * ffi.sizeof("int") + assert h.x == 1000 * 5 - 498 * 7 + def test_cannot_name_struct_type(): ffi = FFI() - ffi.cdef("typedef struct { int x; } *sp; void foo(sp);") + ffi.cdef("typedef struct { int x; } **sp; void foo(sp);") e = py.test.raises(VerificationError, ffi.verify, - "typedef struct { int x; } *sp; void foo(sp);") + "typedef struct { int x; } **sp; void foo(sp x) { }") assert 'in argument of foo: unknown type name' in str(e.value) def test_dont_check_unnamable_fields(): @@ -1637,9 +1680,8 @@ def test_struct_returned_by_func(): e = py.test.raises(TypeError, ffi.verify, "typedef struct { int x; } foo_t; " "foo_t myfunc(void) { foo_t x = { 42 }; return x; }") - assert str(e.value) in [ - "function myfunc: 'foo_t' is used as result type, but is opaque", - "function myfunc: result type 'foo_t' is opaque"] + assert str(e.value) == ( + "function myfunc: 'foo_t' is used as result type, but is opaque") def test_include(): ffi1 = FFI() @@ -1667,6 +1709,17 @@ def test_include_enum(): res = lib2.myfunc(lib2.AA) assert res == 2 +def test_named_pointer_as_argument(): + ffi = FFI() + ffi.cdef("typedef struct { int x; } *mystruct_p;\n" + "mystruct_p ff5a(mystruct_p);") + lib = ffi.verify("typedef struct { int x; } *mystruct_p;\n" + "mystruct_p ff5a(mystruct_p p) { p->x += 40; return p; }") + p = ffi.new("mystruct_p", [-2]) + q = lib.ff5a(p) + assert q == p + assert p.x == 38 + def test_enum_size(): cases = [('123', 4, 4294967295), ('4294967295U', 4, 4294967295), |
