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, ...)")