summaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2015-05-17 10:00:14 +0200
committerArmin Rigo <arigo@tunes.org>2015-05-17 10:00:14 +0200
commit48d677b2578080c605794afd08736176b3c8f928 (patch)
tree086c5f2367dfb1989cdd41aacd675afb26bfc1e2 /testing
parentacf8dc3c0a4a389d3e89732a9fa96cff3abace83 (diff)
parentcb8e0566f3bf8f905324c6e77a00201fc6a9ab52 (diff)
downloadcffi-release-0.9.tar.gz
hg merge defaultrelease-0.9
Diffstat (limited to 'testing')
-rw-r--r--testing/backend_tests.py13
-rw-r--r--testing/test_ctypes.py3
-rw-r--r--testing/test_ffi_backend.py54
-rw-r--r--testing/test_function.py1
-rw-r--r--testing/test_verify.py79
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),