1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
import py, sys
from cffi import cffi_opcode
def check(input, expected_output=None, expected_ffi_error=False):
import _cffi_backend
ffi = _cffi_backend.FFI()
if not expected_ffi_error:
ct = ffi.typeof(input)
assert isinstance(ct, ffi.CType)
assert ct.cname == (expected_output or input)
else:
e = py.test.raises(ffi.error, ffi.typeof, input)
if isinstance(expected_ffi_error, str):
assert str(e.value) == expected_ffi_error
def test_void():
check("void", "void")
check(" void ", "void")
def test_int_star():
check("int")
check("int *")
check("int*", "int *")
check("long int", "long")
check("long")
def test_noop():
check("int(*)", "int *")
def test_array():
check("int[6]")
def test_funcptr():
check("int(*)(long)")
check("int(long)", expected_ffi_error="the type 'int(long)' is a"
" function type, not a pointer-to-function type")
check("int(void)", expected_ffi_error="the type 'int()' is a"
" function type, not a pointer-to-function type")
def test_funcptr_rewrite_args():
check("int(*)(int(int))", "int(*)(int(*)(int))")
check("int(*)(long[])", "int(*)(long *)")
check("int(*)(long[5])", "int(*)(long *)")
def test_all_primitives():
for name in cffi_opcode.PRIMITIVE_TO_INDEX:
check(name, name)
def check_func(input, expected_output=None):
import _cffi_backend
ffi = _cffi_backend.FFI()
ct = ffi.typeof(ffi.callback(input, lambda: None))
assert isinstance(ct, ffi.CType)
if sys.platform != 'win32' or sys.maxsize > 2**32:
expected_output = expected_output.replace('__stdcall *', '*')
assert ct.cname == expected_output
def test_funcptr_stdcall():
check_func("int(int)", "int(*)(int)")
check_func("int foobar(int)", "int(*)(int)")
check_func("int __stdcall(int)", "int(__stdcall *)(int)")
check_func("int __stdcall foobar(int)", "int(__stdcall *)(int)")
check_func("void __cdecl(void)", "void(*)()")
check_func("void __cdecl foobar(void)", "void(*)()")
check_func("void __stdcall(void)", "void(__stdcall *)()")
check_func("void __stdcall foobar(long, short)",
"void(__stdcall *)(long, short)")
check_func("void(void __cdecl(void), void __stdcall(void))",
"void(*)(void(*)(), void(__stdcall *)())")
def test_variadic_overrides_stdcall():
check("void (__stdcall*)(int, ...)", "void(*)(int, ...)")
|