1 2import sys, os, py 3from cffi import FFI, VerificationError, FFIError, CDefError 4from cffi import recompiler 5from testing.udir import udir 6from testing.support import u, long 7from testing.support import FdWriteCapture, StdErrCapture, _verify 8 9try: 10 import importlib 11except ImportError: 12 importlib = None 13 14 15def check_type_table(input, expected_output, included=None): 16 ffi = FFI() 17 if included: 18 ffi1 = FFI() 19 ffi1.cdef(included) 20 ffi.include(ffi1) 21 ffi.cdef(input) 22 recomp = recompiler.Recompiler(ffi, 'testmod') 23 recomp.collect_type_table() 24 assert ''.join(map(str, recomp.cffi_types)) == expected_output 25 26def verify(ffi, module_name, source, *args, **kwds): 27 no_cpp = kwds.pop('no_cpp', False) 28 kwds.setdefault('undef_macros', ['NDEBUG']) 29 module_name = '_CFFI_' + module_name 30 ffi.set_source(module_name, source) 31 if not os.environ.get('NO_CPP') and not no_cpp: # test the .cpp mode too 32 kwds.setdefault('source_extension', '.cpp') 33 source = 'extern "C" {\n%s\n}' % (source,) 34 elif sys.platform != 'win32': 35 # add '-Werror' to the existing 'extra_compile_args' flags 36 kwds['extra_compile_args'] = (kwds.get('extra_compile_args', []) + 37 ['-Werror']) 38 return _verify(ffi, module_name, source, *args, **kwds) 39 40def test_set_source_no_slashes(): 41 ffi = FFI() 42 py.test.raises(ValueError, ffi.set_source, "abc/def", None) 43 py.test.raises(ValueError, ffi.set_source, "abc/def", "C code") 44 45 46def test_type_table_func(): 47 check_type_table("double sin(double);", 48 "(FUNCTION 1)(PRIMITIVE 14)(FUNCTION_END 0)") 49 check_type_table("float sin(double);", 50 "(FUNCTION 3)(PRIMITIVE 14)(FUNCTION_END 0)(PRIMITIVE 13)") 51 check_type_table("float sin(void);", 52 "(FUNCTION 2)(FUNCTION_END 0)(PRIMITIVE 13)") 53 check_type_table("double sin(float); double cos(float);", 54 "(FUNCTION 3)(PRIMITIVE 13)(FUNCTION_END 0)(PRIMITIVE 14)") 55 check_type_table("double sin(float); double cos(double);", 56 "(FUNCTION 1)(PRIMITIVE 14)(FUNCTION_END 0)" # cos 57 "(FUNCTION 1)(PRIMITIVE 13)(FUNCTION_END 0)") # sin 58 check_type_table("float sin(double); float cos(float);", 59 "(FUNCTION 4)(PRIMITIVE 14)(FUNCTION_END 0)" # sin 60 "(FUNCTION 4)(PRIMITIVE 13)(FUNCTION_END 0)") # cos 61 62def test_type_table_use_noop_for_repeated_args(): 63 check_type_table("double sin(double *, double *);", 64 "(FUNCTION 4)(POINTER 4)(NOOP 1)(FUNCTION_END 0)" 65 "(PRIMITIVE 14)") 66 check_type_table("double sin(double *, double *, double);", 67 "(FUNCTION 3)(POINTER 3)(NOOP 1)(PRIMITIVE 14)" 68 "(FUNCTION_END 0)") 69 70def test_type_table_dont_use_noop_for_primitives(): 71 check_type_table("double sin(double, double);", 72 "(FUNCTION 1)(PRIMITIVE 14)(PRIMITIVE 14)(FUNCTION_END 0)") 73 74def test_type_table_funcptr_as_argument(): 75 check_type_table("int sin(double(float));", 76 "(FUNCTION 6)(PRIMITIVE 13)(FUNCTION_END 0)" 77 "(FUNCTION 7)(POINTER 0)(FUNCTION_END 0)" 78 "(PRIMITIVE 14)(PRIMITIVE 7)") 79 80def test_type_table_variadic_function(): 81 check_type_table("int sin(int, ...);", 82 "(FUNCTION 1)(PRIMITIVE 7)(FUNCTION_END 1)(POINTER 0)") 83 84def test_type_table_array(): 85 check_type_table("int a[100];", 86 "(PRIMITIVE 7)(ARRAY 0)(None 100)") 87 88def test_type_table_typedef(): 89 check_type_table("typedef int foo_t;", 90 "(PRIMITIVE 7)") 91 92def test_type_table_prebuilt_type(): 93 check_type_table("int32_t f(void);", 94 "(FUNCTION 2)(FUNCTION_END 0)(PRIMITIVE 21)") 95 96def test_type_table_struct_opaque(): 97 check_type_table("struct foo_s;", 98 "(STRUCT_UNION 0)") 99 100def test_type_table_struct(): 101 check_type_table("struct foo_s { int a; long b; };", 102 "(PRIMITIVE 7)(PRIMITIVE 9)(STRUCT_UNION 0)") 103 104def test_type_table_union(): 105 check_type_table("union foo_u { int a; long b; };", 106 "(PRIMITIVE 7)(PRIMITIVE 9)(STRUCT_UNION 0)") 107 108def test_type_table_struct_used(): 109 check_type_table("struct foo_s { int a; long b; }; int f(struct foo_s*);", 110 "(FUNCTION 3)(POINTER 5)(FUNCTION_END 0)" 111 "(PRIMITIVE 7)(PRIMITIVE 9)" 112 "(STRUCT_UNION 0)") 113 114def test_type_table_anonymous_struct_with_typedef(): 115 check_type_table("typedef struct { int a; long b; } foo_t;", 116 "(STRUCT_UNION 0)(PRIMITIVE 7)(PRIMITIVE 9)") 117 118def test_type_table_enum(): 119 check_type_table("enum foo_e { AA, BB, ... };", 120 "(ENUM 0)") 121 122def test_type_table_include_1(): 123 check_type_table("foo_t sin(foo_t);", 124 "(FUNCTION 1)(PRIMITIVE 14)(FUNCTION_END 0)", 125 included="typedef double foo_t;") 126 127def test_type_table_include_2(): 128 check_type_table("struct foo_s *sin(struct foo_s *);", 129 "(FUNCTION 1)(POINTER 3)(FUNCTION_END 0)(STRUCT_UNION 0)", 130 included="struct foo_s { int x, y; };") 131 132 133def test_math_sin(): 134 import math 135 ffi = FFI() 136 ffi.cdef("float sin(double); double cos(double);") 137 lib = verify(ffi, 'test_math_sin', '#include <math.h>') 138 assert lib.cos(1.43) == math.cos(1.43) 139 140def test_repr_lib(): 141 ffi = FFI() 142 lib = verify(ffi, 'test_repr_lib', '') 143 assert repr(lib) == "<Lib object for '_CFFI_test_repr_lib'>" 144 145def test_funcarg_ptr(): 146 ffi = FFI() 147 ffi.cdef("int foo(int *);") 148 lib = verify(ffi, 'test_funcarg_ptr', 'int foo(int *p) { return *p; }') 149 assert lib.foo([-12345]) == -12345 150 151def test_funcres_ptr(): 152 ffi = FFI() 153 ffi.cdef("int *foo(void);") 154 lib = verify(ffi, 'test_funcres_ptr', 155 'int *foo(void) { static int x=-12345; return &x; }') 156 assert lib.foo()[0] == -12345 157 158def test_global_var_array(): 159 ffi = FFI() 160 ffi.cdef("int a[100];") 161 lib = verify(ffi, 'test_global_var_array', 'int a[100] = { 9999 };') 162 lib.a[42] = 123456 163 assert lib.a[42] == 123456 164 assert lib.a[0] == 9999 165 166def test_verify_typedef(): 167 ffi = FFI() 168 ffi.cdef("typedef int **foo_t;") 169 lib = verify(ffi, 'test_verify_typedef', 'typedef int **foo_t;') 170 assert ffi.sizeof("foo_t") == ffi.sizeof("void *") 171 172def test_verify_typedef_dotdotdot(): 173 ffi = FFI() 174 ffi.cdef("typedef ... foo_t;") 175 verify(ffi, 'test_verify_typedef_dotdotdot', 'typedef int **foo_t;') 176 177def test_verify_typedef_star_dotdotdot(): 178 ffi = FFI() 179 ffi.cdef("typedef ... *foo_t;") 180 verify(ffi, 'test_verify_typedef_star_dotdotdot', 'typedef int **foo_t;') 181 182def test_global_var_int(): 183 ffi = FFI() 184 ffi.cdef("int a, b, c;") 185 lib = verify(ffi, 'test_global_var_int', 'int a = 999, b, c;') 186 assert lib.a == 999 187 lib.a -= 1001 188 assert lib.a == -2 189 lib.a = -2147483648 190 assert lib.a == -2147483648 191 py.test.raises(OverflowError, "lib.a = 2147483648") 192 py.test.raises(OverflowError, "lib.a = -2147483649") 193 lib.b = 525 # try with the first access being in setattr, too 194 assert lib.b == 525 195 py.test.raises(AttributeError, "del lib.a") 196 py.test.raises(AttributeError, "del lib.c") 197 py.test.raises(AttributeError, "del lib.foobarbaz") 198 199def test_macro(): 200 ffi = FFI() 201 ffi.cdef("#define FOOBAR ...") 202 lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") 203 assert lib.FOOBAR == -6912 204 py.test.raises(AttributeError, "lib.FOOBAR = 2") 205 206def test_macro_check_value(): 207 # the value '-0x80000000' in C sources does not have a clear meaning 208 # to me; it appears to have a different effect than '-2147483648'... 209 # Moreover, on 32-bits, -2147483648 is actually equal to 210 # -2147483648U, which in turn is equal to 2147483648U and so positive. 211 vals = ['42', '-42', '0x80000000', '-2147483648', 212 '0', '9223372036854775809ULL', 213 '-9223372036854775807LL'] 214 if sys.maxsize <= 2**32 or sys.platform == 'win32': 215 vals.remove('-2147483648') 216 ffi = FFI() 217 cdef_lines = ['#define FOO_%d_%d %s' % (i, j, vals[i]) 218 for i in range(len(vals)) 219 for j in range(len(vals))] 220 ffi.cdef('\n'.join(cdef_lines)) 221 222 verify_lines = ['#define FOO_%d_%d %s' % (i, j, vals[j]) # [j], not [i] 223 for i in range(len(vals)) 224 for j in range(len(vals))] 225 lib = verify(ffi, 'test_macro_check_value_ok', 226 '\n'.join(verify_lines)) 227 # 228 for j in range(len(vals)): 229 c_got = int(vals[j].replace('U', '').replace('L', ''), 0) 230 c_compiler_msg = str(c_got) 231 if c_got > 0: 232 c_compiler_msg += ' (0x%x)' % (c_got,) 233 # 234 for i in range(len(vals)): 235 attrname = 'FOO_%d_%d' % (i, j) 236 if i == j: 237 x = getattr(lib, attrname) 238 assert x == c_got 239 else: 240 e = py.test.raises(ffi.error, getattr, lib, attrname) 241 assert str(e.value) == ( 242 "the C compiler says '%s' is equal to " 243 "%s, but the cdef disagrees" % (attrname, c_compiler_msg)) 244 245def test_constant(): 246 ffi = FFI() 247 ffi.cdef("static const int FOOBAR;") 248 lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") 249 assert lib.FOOBAR == -6912 250 py.test.raises(AttributeError, "lib.FOOBAR = 2") 251 252def test_check_value_of_static_const(): 253 ffi = FFI() 254 ffi.cdef("static const int FOOBAR = 042;") 255 lib = verify(ffi, 'test_check_value_of_static_const', 256 "#define FOOBAR (-6912)") 257 e = py.test.raises(ffi.error, getattr, lib, 'FOOBAR') 258 assert str(e.value) == ( 259 "the C compiler says 'FOOBAR' is equal to -6912, but the cdef disagrees") 260 261def test_constant_nonint(): 262 ffi = FFI() 263 ffi.cdef("static const double FOOBAR;") 264 lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") 265 assert lib.FOOBAR == -6912.5 266 py.test.raises(AttributeError, "lib.FOOBAR = 2") 267 268def test_constant_ptr(): 269 ffi = FFI() 270 ffi.cdef("static double *const FOOBAR;") 271 lib = verify(ffi, 'test_constant_ptr', "#define FOOBAR NULL") 272 assert lib.FOOBAR == ffi.NULL 273 assert ffi.typeof(lib.FOOBAR) == ffi.typeof("double *") 274 275def test_dir(): 276 ffi = FFI() 277 ffi.cdef("int ff(int); int aa; static const int my_constant;") 278 lib = verify(ffi, 'test_dir', """ 279 #define my_constant (-45) 280 int aa; 281 int ff(int x) { return x+aa; } 282 """) 283 lib.aa = 5 284 assert dir(lib) == ['aa', 'ff', 'my_constant'] 285 # 286 aaobj = lib.__dict__['aa'] 287 assert not isinstance(aaobj, int) # some internal object instead 288 assert lib.__dict__ == { 289 'ff': lib.ff, 290 'aa': aaobj, 291 'my_constant': -45} 292 lib.__dict__['ff'] = "??" 293 assert lib.ff(10) == 15 294 295def test_verify_opaque_struct(): 296 ffi = FFI() 297 ffi.cdef("struct foo_s;") 298 lib = verify(ffi, 'test_verify_opaque_struct', "struct foo_s;") 299 assert ffi.typeof("struct foo_s").cname == "struct foo_s" 300 301def test_verify_opaque_union(): 302 ffi = FFI() 303 ffi.cdef("union foo_s;") 304 lib = verify(ffi, 'test_verify_opaque_union', "union foo_s;") 305 assert ffi.typeof("union foo_s").cname == "union foo_s" 306 307def test_verify_struct(): 308 ffi = FFI() 309 ffi.cdef("""struct foo_s { int b; short a; ...; }; 310 struct bar_s { struct foo_s *f; };""") 311 lib = verify(ffi, 'test_verify_struct', 312 """struct foo_s { short a; int b; }; 313 struct bar_s { struct foo_s *f; };""") 314 ffi.typeof("struct bar_s *") 315 p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) 316 assert p.a == -32768 317 assert p.b == -2147483648 318 py.test.raises(OverflowError, "p.a -= 1") 319 py.test.raises(OverflowError, "p.b -= 1") 320 q = ffi.new("struct bar_s *", {'f': p}) 321 assert q.f == p 322 # 323 assert ffi.offsetof("struct foo_s", "a") == 0 324 assert ffi.offsetof("struct foo_s", "b") == 4 325 assert ffi.offsetof(u+"struct foo_s", u+"b") == 4 326 # 327 py.test.raises(TypeError, ffi.addressof, p) 328 assert ffi.addressof(p[0]) == p 329 assert ffi.typeof(ffi.addressof(p[0])) is ffi.typeof("struct foo_s *") 330 assert ffi.typeof(ffi.addressof(p, "b")) is ffi.typeof("int *") 331 assert ffi.addressof(p, "b")[0] == p.b 332 333def test_verify_exact_field_offset(): 334 ffi = FFI() 335 ffi.cdef("""struct foo_s { int b; short a; };""") 336 lib = verify(ffi, 'test_verify_exact_field_offset', 337 """struct foo_s { short a; int b; };""") 338 e = py.test.raises(ffi.error, ffi.new, "struct foo_s *", []) # lazily 339 assert str(e.value) == ("struct foo_s: wrong offset for field 'b' (cdef " 340 'says 0, but C compiler says 4). fix it or use "...;" ' 341 "in the cdef for struct foo_s to make it flexible") 342 343def test_type_caching(): 344 ffi1 = FFI(); ffi1.cdef("struct foo_s;") 345 ffi2 = FFI(); ffi2.cdef("struct foo_s;") # different one! 346 lib1 = verify(ffi1, 'test_type_caching_1', 'struct foo_s;') 347 lib2 = verify(ffi2, 'test_type_caching_2', 'struct foo_s;') 348 # shared types 349 assert ffi1.typeof("long") is ffi2.typeof("long") 350 assert ffi1.typeof("long**") is ffi2.typeof("long * *") 351 assert ffi1.typeof("long(*)(int, ...)") is ffi2.typeof("long(*)(int, ...)") 352 # non-shared types 353 assert ffi1.typeof("struct foo_s") is not ffi2.typeof("struct foo_s") 354 assert ffi1.typeof("struct foo_s *") is not ffi2.typeof("struct foo_s *") 355 assert ffi1.typeof("struct foo_s*(*)()") is not ( 356 ffi2.typeof("struct foo_s*(*)()")) 357 assert ffi1.typeof("void(*)(struct foo_s*)") is not ( 358 ffi2.typeof("void(*)(struct foo_s*)")) 359 360def test_verify_enum(): 361 ffi = FFI() 362 ffi.cdef("""enum e1 { B1, A1, ... }; enum e2 { B2, A2, ... };""") 363 lib = verify(ffi, 'test_verify_enum', 364 "enum e1 { A1, B1, C1=%d };" % sys.maxsize + 365 "enum e2 { A2, B2, C2 };") 366 ffi.typeof("enum e1") 367 ffi.typeof("enum e2") 368 assert lib.A1 == 0 369 assert lib.B1 == 1 370 assert lib.A2 == 0 371 assert lib.B2 == 1 372 assert ffi.sizeof("enum e1") == ffi.sizeof("long") 373 assert ffi.sizeof("enum e2") == ffi.sizeof("int") 374 assert repr(ffi.cast("enum e1", 0)) == "<cdata 'enum e1' 0: A1>" 375 376def test_duplicate_enum(): 377 ffi = FFI() 378 ffi.cdef("enum e1 { A1, ... }; enum e2 { A1, ... };") 379 py.test.raises(VerificationError, verify, ffi, 'test_duplicate_enum', 380 "enum e1 { A1 }; enum e2 { B1 };") 381 382def test_dotdotdot_length_of_array_field(): 383 ffi = FFI() 384 ffi.cdef("struct foo_s { int a[...]; int b[...]; };") 385 verify(ffi, 'test_dotdotdot_length_of_array_field', 386 "struct foo_s { int a[42]; int b[11]; };") 387 assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 388 p = ffi.new("struct foo_s *") 389 assert p.a[41] == p.b[10] == 0 390 py.test.raises(IndexError, "p.a[42]") 391 py.test.raises(IndexError, "p.b[11]") 392 393def test_dotdotdot_global_array(): 394 ffi = FFI() 395 ffi.cdef("int aa[...]; int bb[...];") 396 lib = verify(ffi, 'test_dotdotdot_global_array', 397 "int aa[41]; int bb[12];") 398 assert ffi.sizeof(lib.aa) == 41 * 4 399 assert ffi.sizeof(lib.bb) == 12 * 4 400 assert lib.aa[40] == lib.bb[11] == 0 401 py.test.raises(IndexError, "lib.aa[41]") 402 py.test.raises(IndexError, "lib.bb[12]") 403 404def test_misdeclared_field_1(): 405 ffi = FFI() 406 ffi.cdef("struct foo_s { int a[5]; };") 407 try: 408 verify(ffi, 'test_misdeclared_field_1', 409 "struct foo_s { int a[6]; };") 410 except VerificationError: 411 pass # ok, fail during compilation already (e.g. C++) 412 else: 413 assert ffi.sizeof("struct foo_s") == 24 # found by the actual C code 414 try: 415 # lazily build the fields and boom: 416 p = ffi.new("struct foo_s *") 417 p.a 418 assert False, "should have raised" 419 except ffi.error as e: 420 assert str(e).startswith("struct foo_s: wrong size for field 'a' " 421 "(cdef says 20, but C compiler says 24)") 422 423def test_open_array_in_struct(): 424 ffi = FFI() 425 ffi.cdef("struct foo_s { int b; int a[]; };") 426 verify(ffi, 'test_open_array_in_struct', 427 "struct foo_s { int b; int a[]; };") 428 assert ffi.sizeof("struct foo_s") == 4 429 p = ffi.new("struct foo_s *", [5, [10, 20, 30, 40]]) 430 assert p.a[2] == 30 431 assert ffi.sizeof(p) == ffi.sizeof("void *") 432 assert ffi.sizeof(p[0]) == 5 * ffi.sizeof("int") 433 434def test_math_sin_type(): 435 ffi = FFI() 436 ffi.cdef("double sin(double); void *xxtestfunc();") 437 lib = verify(ffi, 'test_math_sin_type', """ 438 #include <math.h> 439 void *xxtestfunc(void) { return 0; } 440 """) 441 # 'lib.sin' is typed as a <built-in method> object on lib 442 assert ffi.typeof(lib.sin).cname == "double(*)(double)" 443 # 'x' is another <built-in method> object on lib, made very indirectly 444 x = type(lib).__dir__.__get__(lib) 445 py.test.raises(TypeError, ffi.typeof, x) 446 # 447 # present on built-in functions on CPython; must be emulated on PyPy: 448 assert lib.sin.__name__ == 'sin' 449 assert lib.sin.__module__ == '_CFFI_test_math_sin_type' 450 assert lib.sin.__doc__ == ( 451 "double sin(double);\n" 452 "\n" 453 "CFFI C function from _CFFI_test_math_sin_type.lib") 454 455 assert ffi.typeof(lib.xxtestfunc).cname == "void *(*)()" 456 assert lib.xxtestfunc.__doc__ == ( 457 "void *xxtestfunc();\n" 458 "\n" 459 "CFFI C function from _CFFI_test_math_sin_type.lib") 460 461def test_verify_anonymous_struct_with_typedef(): 462 ffi = FFI() 463 ffi.cdef("typedef struct { int a; long b; ...; } foo_t;") 464 verify(ffi, 'test_verify_anonymous_struct_with_typedef', 465 "typedef struct { long b; int hidden, a; } foo_t;") 466 p = ffi.new("foo_t *", {'b': 42}) 467 assert p.b == 42 468 assert repr(p).startswith("<cdata 'foo_t *' ") 469 470def test_verify_anonymous_struct_with_star_typedef(): 471 ffi = FFI() 472 ffi.cdef("typedef struct { int a; long b; } *foo_t;") 473 verify(ffi, 'test_verify_anonymous_struct_with_star_typedef', 474 "typedef struct { int a; long b; } *foo_t;") 475 p = ffi.new("foo_t", {'b': 42}) 476 assert p.b == 42 477 478def test_verify_anonymous_enum_with_typedef(): 479 ffi = FFI() 480 ffi.cdef("typedef enum { AA, ... } e1;") 481 lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef1', 482 "typedef enum { BB, CC, AA } e1;") 483 assert lib.AA == 2 484 assert ffi.sizeof("e1") == ffi.sizeof("int") 485 assert repr(ffi.cast("e1", 2)) == "<cdata 'e1' 2: AA>" 486 # 487 ffi = FFI() 488 ffi.cdef("typedef enum { AA=%d } e1;" % sys.maxsize) 489 lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef2', 490 "typedef enum { AA=%d } e1;" % sys.maxsize) 491 assert lib.AA == int(ffi.cast("long", sys.maxsize)) 492 assert ffi.sizeof("e1") == ffi.sizeof("long") 493 494def test_unique_types(): 495 CDEF = "struct foo_s; union foo_u; enum foo_e { AA };" 496 ffi1 = FFI(); ffi1.cdef(CDEF); verify(ffi1, "test_unique_types_1", CDEF) 497 ffi2 = FFI(); ffi2.cdef(CDEF); verify(ffi2, "test_unique_types_2", CDEF) 498 # 499 assert ffi1.typeof("char") is ffi2.typeof("char ") 500 assert ffi1.typeof("long") is ffi2.typeof("signed long int") 501 assert ffi1.typeof("double *") is ffi2.typeof("double*") 502 assert ffi1.typeof("int ***") is ffi2.typeof(" int * * *") 503 assert ffi1.typeof("int[]") is ffi2.typeof("signed int[]") 504 assert ffi1.typeof("signed int*[17]") is ffi2.typeof("int *[17]") 505 assert ffi1.typeof("void") is ffi2.typeof("void") 506 assert ffi1.typeof("int(*)(int,int)") is ffi2.typeof("int(*)(int,int)") 507 # 508 # these depend on user-defined data, so should not be shared 509 for name in ["struct foo_s", 510 "union foo_u *", 511 "enum foo_e", 512 "struct foo_s *(*)()", 513 "void(*)(struct foo_s *)", 514 "struct foo_s *(*[5])[8]", 515 ]: 516 assert ffi1.typeof(name) is not ffi2.typeof(name) 517 # sanity check: twice 'ffi1' 518 assert ffi1.typeof("struct foo_s*") is ffi1.typeof("struct foo_s *") 519 520def test_module_name_in_package(): 521 ffi = FFI() 522 ffi.cdef("int foo(int);") 523 recompiler.recompile(ffi, "test_module_name_in_package.mymod", 524 "int foo(int x) { return x + 32; }", 525 tmpdir=str(udir)) 526 old_sys_path = sys.path[:] 527 try: 528 package_dir = udir.join('test_module_name_in_package') 529 for name in os.listdir(str(udir)): 530 assert not name.startswith('test_module_name_in_package.') 531 assert os.path.isdir(str(package_dir)) 532 assert len(os.listdir(str(package_dir))) > 0 533 assert os.path.exists(str(package_dir.join('mymod.c'))) 534 package_dir.join('__init__.py').write('') 535 # 536 getattr(importlib, 'invalidate_caches', object)() 537 # 538 sys.path.insert(0, str(udir)) 539 import test_module_name_in_package.mymod 540 assert test_module_name_in_package.mymod.lib.foo(10) == 42 541 assert test_module_name_in_package.mymod.__name__ == ( 542 'test_module_name_in_package.mymod') 543 finally: 544 sys.path[:] = old_sys_path 545 546def test_bad_size_of_global_1(): 547 ffi = FFI() 548 ffi.cdef("short glob;") 549 py.test.raises(VerificationError, verify, ffi, 550 "test_bad_size_of_global_1", "long glob;") 551 552def test_bad_size_of_global_2(): 553 ffi = FFI() 554 ffi.cdef("int glob[10];") 555 py.test.raises(VerificationError, verify, ffi, 556 "test_bad_size_of_global_2", "int glob[9];") 557 558def test_unspecified_size_of_global_1(): 559 ffi = FFI() 560 ffi.cdef("int glob[];") 561 lib = verify(ffi, "test_unspecified_size_of_global_1", "int glob[10];") 562 assert ffi.typeof(lib.glob) == ffi.typeof("int *") 563 564def test_unspecified_size_of_global_2(): 565 ffi = FFI() 566 ffi.cdef("int glob[][5];") 567 lib = verify(ffi, "test_unspecified_size_of_global_2", "int glob[10][5];") 568 assert ffi.typeof(lib.glob) == ffi.typeof("int(*)[5]") 569 570def test_unspecified_size_of_global_3(): 571 ffi = FFI() 572 ffi.cdef("int glob[][...];") 573 lib = verify(ffi, "test_unspecified_size_of_global_3", "int glob[10][5];") 574 assert ffi.typeof(lib.glob) == ffi.typeof("int(*)[5]") 575 576def test_unspecified_size_of_global_4(): 577 ffi = FFI() 578 ffi.cdef("int glob[...][...];") 579 lib = verify(ffi, "test_unspecified_size_of_global_4", "int glob[10][5];") 580 assert ffi.typeof(lib.glob) == ffi.typeof("int[10][5]") 581 582def test_include_1(): 583 ffi1 = FFI() 584 ffi1.cdef("typedef double foo_t;") 585 verify(ffi1, "test_include_1_parent", "typedef double foo_t;") 586 ffi = FFI() 587 ffi.include(ffi1) 588 ffi.cdef("foo_t ff1(foo_t);") 589 lib = verify(ffi, "test_include_1", "double ff1(double x) { return 42.5; }") 590 assert lib.ff1(0) == 42.5 591 assert ffi1.typeof("foo_t") is ffi.typeof("foo_t") is ffi.typeof("double") 592 593def test_include_1b(): 594 ffi1 = FFI() 595 ffi1.cdef("int foo1(int);") 596 lib1 = verify(ffi1, "test_include_1b_parent", 597 "int foo1(int x) { return x + 10; }") 598 ffi = FFI() 599 ffi.include(ffi1) 600 ffi.cdef("int foo2(int);") 601 lib = verify(ffi, "test_include_1b", "int foo2(int x) { return x - 5; }") 602 assert lib.foo2(42) == 37 603 assert lib.foo1(42) == 52 604 assert lib.foo1 is lib1.foo1 605 606def test_include_2(): 607 ffi1 = FFI() 608 ffi1.cdef("struct foo_s { int x, y; };") 609 verify(ffi1, "test_include_2_parent", "struct foo_s { int x, y; };") 610 ffi = FFI() 611 ffi.include(ffi1) 612 ffi.cdef("struct foo_s *ff2(struct foo_s *);") 613 lib = verify(ffi, "test_include_2", 614 "struct foo_s { int x, y; }; //usually from a #include\n" 615 "struct foo_s *ff2(struct foo_s *p) { p->y++; return p; }") 616 p = ffi.new("struct foo_s *") 617 p.y = 41 618 q = lib.ff2(p) 619 assert q == p 620 assert p.y == 42 621 assert ffi1.typeof("struct foo_s") is ffi.typeof("struct foo_s") 622 623def test_include_3(): 624 ffi1 = FFI() 625 ffi1.cdef("typedef short sshort_t;") 626 verify(ffi1, "test_include_3_parent", "typedef short sshort_t;") 627 ffi = FFI() 628 ffi.include(ffi1) 629 ffi.cdef("sshort_t ff3(sshort_t);") 630 lib = verify(ffi, "test_include_3", 631 "typedef short sshort_t; //usually from a #include\n" 632 "sshort_t ff3(sshort_t x) { return x + 42; }") 633 assert lib.ff3(10) == 52 634 assert ffi.typeof(ffi.cast("sshort_t", 42)) is ffi.typeof("short") 635 assert ffi1.typeof("sshort_t") is ffi.typeof("sshort_t") 636 637def test_include_4(): 638 ffi1 = FFI() 639 ffi1.cdef("typedef struct { int x; } mystruct_t;") 640 verify(ffi1, "test_include_4_parent", 641 "typedef struct { int x; } mystruct_t;") 642 ffi = FFI() 643 ffi.include(ffi1) 644 ffi.cdef("mystruct_t *ff4(mystruct_t *);") 645 lib = verify(ffi, "test_include_4", 646 "typedef struct {int x; } mystruct_t; //usually from a #include\n" 647 "mystruct_t *ff4(mystruct_t *p) { p->x += 42; return p; }") 648 p = ffi.new("mystruct_t *", [10]) 649 q = lib.ff4(p) 650 assert q == p 651 assert p.x == 52 652 assert ffi1.typeof("mystruct_t") is ffi.typeof("mystruct_t") 653 654def test_include_5(): 655 ffi1 = FFI() 656 ffi1.cdef("typedef struct { int x[2]; int y; } *mystruct_p;") 657 verify(ffi1, "test_include_5_parent", 658 "typedef struct { int x[2]; int y; } *mystruct_p;") 659 ffi = FFI() 660 ffi.include(ffi1) 661 ffi.cdef("mystruct_p ff5(mystruct_p);") 662 lib = verify(ffi, "test_include_5", 663 "typedef struct {int x[2]; int y; } *mystruct_p; //usually #include\n" 664 "mystruct_p ff5(mystruct_p p) { p->x[1] += 42; return p; }") 665 assert ffi.alignof(ffi.typeof("mystruct_p").item) == 4 666 assert ffi1.typeof("mystruct_p") is ffi.typeof("mystruct_p") 667 p = ffi.new("mystruct_p", [[5, 10], -17]) 668 q = lib.ff5(p) 669 assert q == p 670 assert p.x[0] == 5 671 assert p.x[1] == 52 672 assert p.y == -17 673 assert ffi.alignof(ffi.typeof(p[0])) == 4 674 675def test_include_6(): 676 ffi1 = FFI() 677 ffi1.cdef("typedef ... mystruct_t;") 678 verify(ffi1, "test_include_6_parent", 679 "typedef struct _mystruct_s mystruct_t;") 680 ffi = FFI() 681 ffi.include(ffi1) 682 ffi.cdef("mystruct_t *ff6(void); int ff6b(mystruct_t *);") 683 lib = verify(ffi, "test_include_6", 684 "typedef struct _mystruct_s mystruct_t; //usually from a #include\n" 685 "struct _mystruct_s { int x; };\n" 686 "static mystruct_t result_struct = { 42 };\n" 687 "mystruct_t *ff6(void) { return &result_struct; }\n" 688 "int ff6b(mystruct_t *p) { return p->x; }") 689 p = lib.ff6() 690 assert ffi.cast("int *", p)[0] == 42 691 assert lib.ff6b(p) == 42 692 693def test_include_7(): 694 ffi1 = FFI() 695 ffi1.cdef("typedef ... mystruct_t;\n" 696 "int ff7b(mystruct_t *);") 697 verify(ffi1, "test_include_7_parent", 698 "typedef struct { int x; } mystruct_t;\n" 699 "int ff7b(mystruct_t *p) { return p->x; }") 700 ffi = FFI() 701 ffi.include(ffi1) 702 ffi.cdef("mystruct_t *ff7(void);") 703 lib = verify(ffi, "test_include_7", 704 "typedef struct { int x; } mystruct_t; //usually from a #include\n" 705 "static mystruct_t result_struct = { 42 };" 706 "mystruct_t *ff7(void) { return &result_struct; }") 707 p = lib.ff7() 708 assert ffi.cast("int *", p)[0] == 42 709 assert lib.ff7b(p) == 42 710 711def test_include_8(): 712 ffi1 = FFI() 713 ffi1.cdef("struct foo_s;") 714 verify(ffi1, "test_include_8_parent", "struct foo_s;") 715 ffi = FFI() 716 ffi.include(ffi1) 717 ffi.cdef("struct foo_s { int x, y; };") 718 verify(ffi, "test_include_8", "struct foo_s { int x, y; };") 719 e = py.test.raises(NotImplementedError, ffi.new, "struct foo_s *") 720 assert str(e.value) == ( 721 "'struct foo_s' is opaque in the ffi.include(), but no longer in " 722 "the ffi doing the include (workaround: don't use ffi.include() but" 723 " duplicate the declarations of everything using struct foo_s)") 724 725def test_unicode_libraries(): 726 try: 727 unicode 728 except NameError: 729 py.test.skip("for python 2.x") 730 # 731 import math 732 lib_m = "m" 733 if sys.platform == 'win32': 734 #there is a small chance this fails on Mingw via environ $CC 735 import distutils.ccompiler 736 if distutils.ccompiler.get_default_compiler() == 'msvc': 737 lib_m = 'msvcrt' 738 ffi = FFI() 739 ffi.cdef(unicode("float sin(double); double cos(double);")) 740 lib = verify(ffi, 'test_math_sin_unicode', unicode('#include <math.h>'), 741 libraries=[unicode(lib_m)]) 742 assert lib.cos(1.43) == math.cos(1.43) 743 744def test_incomplete_struct_as_arg(): 745 ffi = FFI() 746 ffi.cdef("struct foo_s { int x; ...; }; int f(int, struct foo_s);") 747 lib = verify(ffi, "test_incomplete_struct_as_arg", 748 "struct foo_s { int a, x, z; };\n" 749 "int f(int b, struct foo_s s) { return s.x * b; }") 750 s = ffi.new("struct foo_s *", [21]) 751 assert s.x == 21 752 assert ffi.sizeof(s[0]) == 12 753 assert ffi.offsetof(ffi.typeof(s), 'x') == 4 754 assert lib.f(2, s[0]) == 42 755 assert ffi.typeof(lib.f) == ffi.typeof("int(*)(int, struct foo_s)") 756 757def test_incomplete_struct_as_result(): 758 ffi = FFI() 759 ffi.cdef("struct foo_s { int x; ...; }; struct foo_s f(int);") 760 lib = verify(ffi, "test_incomplete_struct_as_result", 761 "struct foo_s { int a, x, z; };\n" 762 "struct foo_s f(int x) { struct foo_s r; r.x = x * 2; return r; }") 763 s = lib.f(21) 764 assert s.x == 42 765 assert ffi.typeof(lib.f) == ffi.typeof("struct foo_s(*)(int)") 766 767def test_incomplete_struct_as_both(): 768 ffi = FFI() 769 ffi.cdef("struct foo_s { int x; ...; }; struct bar_s { int y; ...; };\n" 770 "struct foo_s f(int, struct bar_s);") 771 lib = verify(ffi, "test_incomplete_struct_as_both", 772 "struct foo_s { int a, x, z; };\n" 773 "struct bar_s { int b, c, y, d; };\n" 774 "struct foo_s f(int x, struct bar_s b) {\n" 775 " struct foo_s r; r.x = x * b.y; return r;\n" 776 "}") 777 b = ffi.new("struct bar_s *", [7]) 778 s = lib.f(6, b[0]) 779 assert s.x == 42 780 assert ffi.typeof(lib.f) == ffi.typeof( 781 "struct foo_s(*)(int, struct bar_s)") 782 s = lib.f(14, {'y': -3}) 783 assert s.x == -42 784 785def test_name_of_unnamed_struct(): 786 ffi = FFI() 787 ffi.cdef("typedef struct { int x; } foo_t;\n" 788 "typedef struct { int y; } *bar_p;\n" 789 "typedef struct { int y; } **baz_pp;\n") 790 verify(ffi, "test_name_of_unnamed_struct", 791 "typedef struct { int x; } foo_t;\n" 792 "typedef struct { int y; } *bar_p;\n" 793 "typedef struct { int y; } **baz_pp;\n") 794 assert repr(ffi.typeof("foo_t")) == "<ctype 'foo_t'>" 795 assert repr(ffi.typeof("bar_p")) == "<ctype 'struct $1 *'>" 796 assert repr(ffi.typeof("baz_pp")) == "<ctype 'struct $2 * *'>" 797 798def test_address_of_global_var(): 799 ffi = FFI() 800 ffi.cdef(""" 801 long bottom, bottoms[2]; 802 long FetchRectBottom(void); 803 long FetchRectBottoms1(void); 804 #define FOOBAR 42 805 """) 806 lib = verify(ffi, "test_address_of_global_var", """ 807 long bottom, bottoms[2]; 808 long FetchRectBottom(void) { return bottom; } 809 long FetchRectBottoms1(void) { return bottoms[1]; } 810 #define FOOBAR 42 811 """) 812 lib.bottom = 300 813 assert lib.FetchRectBottom() == 300 814 lib.bottom += 1 815 assert lib.FetchRectBottom() == 301 816 lib.bottoms[1] = 500 817 assert lib.FetchRectBottoms1() == 500 818 lib.bottoms[1] += 2 819 assert lib.FetchRectBottoms1() == 502 820 # 821 p = ffi.addressof(lib, 'bottom') 822 assert ffi.typeof(p) == ffi.typeof("long *") 823 assert p[0] == 301 824 p[0] += 1 825 assert lib.FetchRectBottom() == 302 826 p = ffi.addressof(lib, 'bottoms') 827 assert ffi.typeof(p) == ffi.typeof("long(*)[2]") 828 assert p[0] == lib.bottoms 829 # 830 py.test.raises(AttributeError, ffi.addressof, lib, 'unknown_var') 831 py.test.raises(AttributeError, ffi.addressof, lib, "FOOBAR") 832 833def test_defines__CFFI_(): 834 # Check that we define the macro _CFFI_ automatically. 835 # It should be done before including Python.h, so that PyPy's Python.h 836 # can check for it. 837 ffi = FFI() 838 ffi.cdef(""" 839 #define CORRECT 1 840 """) 841 lib = verify(ffi, "test_defines__CFFI_", """ 842 #ifdef _CFFI_ 843 # define CORRECT 1 844 #endif 845 """) 846 assert lib.CORRECT == 1 847 848def test_unpack_args(): 849 ffi = FFI() 850 ffi.cdef("void foo0(void); void foo1(int); void foo2(int, int);") 851 lib = verify(ffi, "test_unpack_args", """ 852 void foo0(void) { } 853 void foo1(int x) { } 854 void foo2(int x, int y) { } 855 """) 856 assert 'foo0' in repr(lib.foo0) 857 assert 'foo1' in repr(lib.foo1) 858 assert 'foo2' in repr(lib.foo2) 859 lib.foo0() 860 lib.foo1(42) 861 lib.foo2(43, 44) 862 e1 = py.test.raises(TypeError, lib.foo0, 42) 863 e2 = py.test.raises(TypeError, lib.foo0, 43, 44) 864 e3 = py.test.raises(TypeError, lib.foo1) 865 e4 = py.test.raises(TypeError, lib.foo1, 43, 44) 866 e5 = py.test.raises(TypeError, lib.foo2) 867 e6 = py.test.raises(TypeError, lib.foo2, 42) 868 e7 = py.test.raises(TypeError, lib.foo2, 45, 46, 47) 869 assert str(e1.value) == "foo0() takes no arguments (1 given)" 870 assert str(e2.value) == "foo0() takes no arguments (2 given)" 871 assert str(e3.value) == "foo1() takes exactly one argument (0 given)" 872 assert str(e4.value) == "foo1() takes exactly one argument (2 given)" 873 assert str(e5.value) in ["foo2 expected 2 arguments, got 0", 874 "foo2() takes exactly 2 arguments (0 given)"] 875 assert str(e6.value) in ["foo2 expected 2 arguments, got 1", 876 "foo2() takes exactly 2 arguments (1 given)"] 877 assert str(e7.value) in ["foo2 expected 2 arguments, got 3", 878 "foo2() takes exactly 2 arguments (3 given)"] 879 880def test_address_of_function(): 881 ffi = FFI() 882 ffi.cdef("long myfunc(long x);") 883 lib = verify(ffi, "test_addressof_function", """ 884 char myfunc(char x) { return (char)(x + 42); } 885 """) 886 assert lib.myfunc(5) == 47 887 assert lib.myfunc(0xABC05) == 47 888 assert not isinstance(lib.myfunc, ffi.CData) 889 assert ffi.typeof(lib.myfunc) == ffi.typeof("long(*)(long)") 890 addr = ffi.addressof(lib, 'myfunc') 891 assert addr(5) == 47 892 assert addr(0xABC05) == 47 893 assert isinstance(addr, ffi.CData) 894 assert ffi.typeof(addr) == ffi.typeof("long(*)(long)") 895 896def test_address_of_function_with_struct(): 897 ffi = FFI() 898 ffi.cdef("struct foo_s { int x; }; long myfunc(struct foo_s);") 899 lib = verify(ffi, "test_addressof_function_with_struct", """ 900 struct foo_s { int x; }; 901 char myfunc(struct foo_s input) { return (char)(input.x + 42); } 902 """) 903 s = ffi.new("struct foo_s *", [5])[0] 904 assert lib.myfunc(s) == 47 905 assert not isinstance(lib.myfunc, ffi.CData) 906 assert ffi.typeof(lib.myfunc) == ffi.typeof("long(*)(struct foo_s)") 907 addr = ffi.addressof(lib, 'myfunc') 908 assert addr(s) == 47 909 assert isinstance(addr, ffi.CData) 910 assert ffi.typeof(addr) == ffi.typeof("long(*)(struct foo_s)") 911 912def test_issue198(): 913 ffi = FFI() 914 ffi.cdef(""" 915 typedef struct{...;} opaque_t; 916 const opaque_t CONSTANT; 917 int toint(opaque_t); 918 """) 919 lib = verify(ffi, 'test_issue198', """ 920 typedef int opaque_t; 921 #define CONSTANT ((opaque_t)42) 922 static int toint(opaque_t o) { return o; } 923 """) 924 def random_stuff(): 925 pass 926 assert lib.toint(lib.CONSTANT) == 42 927 random_stuff() 928 assert lib.toint(lib.CONSTANT) == 42 929 930def test_constant_is_not_a_compiler_constant(): 931 ffi = FFI() 932 ffi.cdef("static const float almost_forty_two;") 933 lib = verify(ffi, 'test_constant_is_not_a_compiler_constant', """ 934 static float f(void) { return 42.25; } 935 #define almost_forty_two (f()) 936 """) 937 assert lib.almost_forty_two == 42.25 938 939def test_constant_of_unknown_size(): 940 ffi = FFI() 941 ffi.cdef(""" 942 typedef ... opaque_t; 943 const opaque_t CONSTANT; 944 """) 945 lib = verify(ffi, 'test_constant_of_unknown_size', 946 "typedef int opaque_t;" 947 "const int CONSTANT = 42;") 948 e = py.test.raises(ffi.error, getattr, lib, 'CONSTANT') 949 assert str(e.value) == ("constant 'CONSTANT' is of " 950 "type 'opaque_t', whose size is not known") 951 952def test_variable_of_unknown_size(): 953 ffi = FFI() 954 ffi.cdef(""" 955 typedef ... opaque_t; 956 opaque_t globvar; 957 """) 958 lib = verify(ffi, 'test_variable_of_unknown_size', """ 959 typedef char opaque_t[6]; 960 opaque_t globvar = "hello"; 961 """) 962 # can't read or write it at all 963 e = py.test.raises(TypeError, getattr, lib, 'globvar') 964 assert str(e.value) in ["cdata 'opaque_t' is opaque", 965 "'opaque_t' is opaque or not completed yet"] #pypy 966 e = py.test.raises(TypeError, setattr, lib, 'globvar', []) 967 assert str(e.value) in ["'opaque_t' is opaque", 968 "'opaque_t' is opaque or not completed yet"] #pypy 969 # but we can get its address 970 p = ffi.addressof(lib, 'globvar') 971 assert ffi.typeof(p) == ffi.typeof('opaque_t *') 972 assert ffi.string(ffi.cast("char *", p), 8) == b"hello" 973 974def test_constant_of_value_unknown_to_the_compiler(): 975 extra_c_source = udir.join( 976 'extra_test_constant_of_value_unknown_to_the_compiler.c') 977 extra_c_source.write('const int external_foo = 42;\n') 978 ffi = FFI() 979 ffi.cdef("const int external_foo;") 980 lib = verify(ffi, 'test_constant_of_value_unknown_to_the_compiler', """ 981 extern const int external_foo; 982 """, sources=[str(extra_c_source)]) 983 assert lib.external_foo == 42 984 985def test_dotdot_in_source_file_names(): 986 extra_c_source = udir.join( 987 'extra_test_dotdot_in_source_file_names.c') 988 extra_c_source.write('const int external_foo = 42;\n') 989 ffi = FFI() 990 ffi.cdef("const int external_foo;") 991 lib = verify(ffi, 'test_dotdot_in_source_file_names', """ 992 extern const int external_foo; 993 """, sources=[os.path.join(os.path.dirname(str(extra_c_source)), 994 'foobar', '..', 995 os.path.basename(str(extra_c_source)))]) 996 assert lib.external_foo == 42 997 998def test_call_with_incomplete_structs(): 999 ffi = FFI() 1000 ffi.cdef("typedef struct {...;} foo_t; " 1001 "foo_t myglob; " 1002 "foo_t increment(foo_t s); " 1003 "double getx(foo_t s);") 1004 lib = verify(ffi, 'test_call_with_incomplete_structs', """ 1005 typedef double foo_t; 1006 double myglob = 42.5; 1007 double getx(double x) { return x; } 1008 double increment(double x) { return x + 1; } 1009 """) 1010 assert lib.getx(lib.myglob) == 42.5 1011 assert lib.getx(lib.increment(lib.myglob)) == 43.5 1012 1013def test_struct_array_guess_length_2(): 1014 ffi = FFI() 1015 ffi.cdef("struct foo_s { int a[...][...]; };") 1016 lib = verify(ffi, 'test_struct_array_guess_length_2', 1017 "struct foo_s { int x; int a[5][8]; int y; };") 1018 assert ffi.sizeof('struct foo_s') == 42 * ffi.sizeof('int') 1019 s = ffi.new("struct foo_s *") 1020 assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") 1021 assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') 1022 assert s.a[4][7] == 0 1023 py.test.raises(IndexError, 's.a[4][8]') 1024 py.test.raises(IndexError, 's.a[5][0]') 1025 assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") 1026 assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") 1027 1028def test_struct_array_guess_length_3(): 1029 ffi = FFI() 1030 ffi.cdef("struct foo_s { int a[][...]; };") 1031 lib = verify(ffi, 'test_struct_array_guess_length_3', 1032 "struct foo_s { int x; int a[5][7]; int y; };") 1033 assert ffi.sizeof('struct foo_s') == 37 * ffi.sizeof('int') 1034 s = ffi.new("struct foo_s *") 1035 assert ffi.typeof(s.a) == ffi.typeof("int[][7]") 1036 assert s.a[4][6] == 0 1037 py.test.raises(IndexError, 's.a[4][7]') 1038 assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") 1039 1040def test_global_var_array_2(): 1041 ffi = FFI() 1042 ffi.cdef("int a[...][...];") 1043 lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') 1044 lib.a[9][7] = 123456 1045 assert lib.a[9][7] == 123456 1046 py.test.raises(IndexError, 'lib.a[0][8]') 1047 py.test.raises(IndexError, 'lib.a[10][0]') 1048 assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") 1049 assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") 1050 1051def test_global_var_array_3(): 1052 ffi = FFI() 1053 ffi.cdef("int a[][...];") 1054 lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') 1055 lib.a[9][7] = 123456 1056 assert lib.a[9][7] == 123456 1057 py.test.raises(IndexError, 'lib.a[0][8]') 1058 assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") 1059 assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") 1060 1061def test_global_var_array_4(): 1062 ffi = FFI() 1063 ffi.cdef("int a[10][...];") 1064 lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') 1065 lib.a[9][7] = 123456 1066 assert lib.a[9][7] == 123456 1067 py.test.raises(IndexError, 'lib.a[0][8]') 1068 py.test.raises(IndexError, 'lib.a[10][8]') 1069 assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") 1070 assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") 1071 1072def test_some_integer_type(): 1073 ffi = FFI() 1074 ffi.cdef(""" 1075 typedef int... foo_t; 1076 typedef unsigned long... bar_t; 1077 typedef struct { foo_t a, b; } mystruct_t; 1078 foo_t foobar(bar_t, mystruct_t); 1079 static const bar_t mu = -20; 1080 static const foo_t nu = 20; 1081 """) 1082 lib = verify(ffi, 'test_some_integer_type', """ 1083 typedef unsigned long long foo_t; 1084 typedef short bar_t; 1085 typedef struct { foo_t a, b; } mystruct_t; 1086 static foo_t foobar(bar_t x, mystruct_t s) { 1087 return (foo_t)x + s.a + s.b; 1088 } 1089 static const bar_t mu = -20; 1090 static const foo_t nu = 20; 1091 """) 1092 assert ffi.sizeof("foo_t") == ffi.sizeof("unsigned long long") 1093 assert ffi.sizeof("bar_t") == ffi.sizeof("short") 1094 maxulonglong = 2 ** 64 - 1 1095 assert int(ffi.cast("foo_t", -1)) == maxulonglong 1096 assert int(ffi.cast("bar_t", -1)) == -1 1097 assert lib.foobar(-1, [0, 0]) == maxulonglong 1098 assert lib.foobar(2 ** 15 - 1, [0, 0]) == 2 ** 15 - 1 1099 assert lib.foobar(10, [20, 31]) == 61 1100 assert lib.foobar(0, [0, maxulonglong]) == maxulonglong 1101 py.test.raises(OverflowError, lib.foobar, 2 ** 15, [0, 0]) 1102 py.test.raises(OverflowError, lib.foobar, -(2 ** 15) - 1, [0, 0]) 1103 py.test.raises(OverflowError, ffi.new, "mystruct_t *", [0, -1]) 1104 assert lib.mu == -20 1105 assert lib.nu == 20 1106 1107def test_some_float_type(): 1108 ffi = FFI() 1109 ffi.cdef(""" 1110 typedef double... foo_t; 1111 typedef float... bar_t; 1112 foo_t sum(foo_t[]); 1113 bar_t neg(bar_t); 1114 """) 1115 lib = verify(ffi, 'test_some_float_type', """ 1116 typedef float foo_t; 1117 static foo_t sum(foo_t x[]) { return x[0] + x[1]; } 1118 typedef double bar_t; 1119 static double neg(double x) { return -x; } 1120 """) 1121 assert lib.sum([40.0, 2.25]) == 42.25 1122 assert lib.sum([12.3, 45.6]) != 12.3 + 45.6 # precision loss 1123 assert lib.neg(12.3) == -12.3 # no precision loss 1124 assert ffi.sizeof("foo_t") == ffi.sizeof("float") 1125 assert ffi.sizeof("bar_t") == ffi.sizeof("double") 1126 1127def test_some_float_invalid_1(): 1128 ffi = FFI() 1129 py.test.raises((FFIError, # with pycparser <= 2.17 1130 CDefError), # with pycparser >= 2.18 1131 ffi.cdef, "typedef long double... foo_t;") 1132 1133def test_some_float_invalid_2(): 1134 ffi = FFI() 1135 ffi.cdef("typedef double... foo_t; foo_t neg(foo_t);") 1136 lib = verify(ffi, 'test_some_float_invalid_2', """ 1137 typedef unsigned long foo_t; 1138 foo_t neg(foo_t x) { return -x; } 1139 """) 1140 e = py.test.raises(ffi.error, getattr, lib, 'neg') 1141 assert str(e.value) == ("primitive floating-point type with an unexpected " 1142 "size (or not a float type at all)") 1143 1144def test_some_float_invalid_3(): 1145 ffi = FFI() 1146 ffi.cdef("typedef double... foo_t; foo_t neg(foo_t);") 1147 lib = verify(ffi, 'test_some_float_invalid_3', """ 1148 typedef long double foo_t; 1149 foo_t neg(foo_t x) { return -x; } 1150 """) 1151 if ffi.sizeof("long double") == ffi.sizeof("double"): 1152 assert lib.neg(12.3) == -12.3 1153 else: 1154 e = py.test.raises(ffi.error, getattr, lib, 'neg') 1155 assert str(e.value) == ("primitive floating-point type is " 1156 "'long double', not supported for now with " 1157 "the syntax 'typedef double... xxx;'") 1158 1159def test_issue200(): 1160 ffi = FFI() 1161 ffi.cdef(""" 1162 typedef void (function_t)(void*); 1163 void function(void *); 1164 """) 1165 lib = verify(ffi, 'test_issue200', """ 1166 static void function(void *p) { (void)p; } 1167 """) 1168 ffi.typeof('function_t*') 1169 lib.function(ffi.NULL) 1170 # assert did not crash 1171 1172def test_alignment_of_longlong(): 1173 ffi = FFI() 1174 x1 = ffi.alignof('unsigned long long') 1175 assert x1 in [4, 8] 1176 ffi.cdef("struct foo_s { unsigned long long x; };") 1177 lib = verify(ffi, 'test_alignment_of_longlong', 1178 "struct foo_s { unsigned long long x; };") 1179 assert ffi.alignof('unsigned long long') == x1 1180 assert ffi.alignof('struct foo_s') == x1 1181 1182def test_import_from_lib(): 1183 ffi = FFI() 1184 ffi.cdef("int mybar(int); int myvar;\n#define MYFOO ...") 1185 lib = verify(ffi, 'test_import_from_lib', 1186 "#define MYFOO 42\n" 1187 "static int mybar(int x) { return x + 1; }\n" 1188 "static int myvar = -5;") 1189 assert sys.modules['_CFFI_test_import_from_lib'].lib is lib 1190 assert sys.modules['_CFFI_test_import_from_lib.lib'] is lib 1191 from _CFFI_test_import_from_lib.lib import MYFOO 1192 assert MYFOO == 42 1193 assert hasattr(lib, '__dict__') 1194 assert lib.__all__ == ['MYFOO', 'mybar'] # but not 'myvar' 1195 assert lib.__name__ == '_CFFI_test_import_from_lib.lib' 1196 assert lib.__class__ is type(sys) # !! hack for help() 1197 1198def test_macro_var_callback(): 1199 ffi = FFI() 1200 ffi.cdef("int my_value; int *(*get_my_value)(void);") 1201 lib = verify(ffi, 'test_macro_var_callback', 1202 "int *(*get_my_value)(void);\n" 1203 "#define my_value (*get_my_value())") 1204 # 1205 values = ffi.new("int[50]") 1206 def it(): 1207 for i in range(50): 1208 yield i 1209 it = it() 1210 # 1211 @ffi.callback("int *(*)(void)") 1212 def get_my_value(): 1213 for nextvalue in it: 1214 return values + nextvalue 1215 lib.get_my_value = get_my_value 1216 # 1217 values[0] = 41 1218 assert lib.my_value == 41 # [0] 1219 p = ffi.addressof(lib, 'my_value') # [1] 1220 assert p == values + 1 1221 assert p[-1] == 41 1222 assert p[+1] == 0 1223 lib.my_value = 42 # [2] 1224 assert values[2] == 42 1225 assert p[-1] == 41 1226 assert p[+1] == 42 1227 # 1228 # if get_my_value raises or returns nonsense, the exception is printed 1229 # to stderr like with any callback, but then the C expression 'my_value' 1230 # expand to '*NULL'. We assume here that '&my_value' will return NULL 1231 # without segfaulting, and check for NULL when accessing the variable. 1232 @ffi.callback("int *(*)(void)") 1233 def get_my_value(): 1234 raise LookupError 1235 lib.get_my_value = get_my_value 1236 py.test.raises(ffi.error, getattr, lib, 'my_value') 1237 py.test.raises(ffi.error, setattr, lib, 'my_value', 50) 1238 py.test.raises(ffi.error, ffi.addressof, lib, 'my_value') 1239 @ffi.callback("int *(*)(void)") 1240 def get_my_value(): 1241 return "hello" 1242 lib.get_my_value = get_my_value 1243 py.test.raises(ffi.error, getattr, lib, 'my_value') 1244 e = py.test.raises(ffi.error, setattr, lib, 'my_value', 50) 1245 assert str(e.value) == "global variable 'my_value' is at address NULL" 1246 1247def test_const_fields(): 1248 ffi = FFI() 1249 ffi.cdef("""struct foo_s { const int a; void *const b; };""") 1250 lib = verify(ffi, 'test_const_fields', """ 1251 struct foo_s { const int a; void *const b; };""") 1252 foo_s = ffi.typeof("struct foo_s") 1253 assert foo_s.fields[0][0] == 'a' 1254 assert foo_s.fields[0][1].type is ffi.typeof("int") 1255 assert foo_s.fields[1][0] == 'b' 1256 assert foo_s.fields[1][1].type is ffi.typeof("void *") 1257 1258def test_restrict_fields(): 1259 ffi = FFI() 1260 ffi.cdef("""struct foo_s { void * restrict b; };""") 1261 lib = verify(ffi, 'test_restrict_fields', """ 1262 struct foo_s { void * __restrict b; };""") 1263 foo_s = ffi.typeof("struct foo_s") 1264 assert foo_s.fields[0][0] == 'b' 1265 assert foo_s.fields[0][1].type is ffi.typeof("void *") 1266 1267def test_volatile_fields(): 1268 ffi = FFI() 1269 ffi.cdef("""struct foo_s { void * volatile b; };""") 1270 lib = verify(ffi, 'test_volatile_fields', """ 1271 struct foo_s { void * volatile b; };""") 1272 foo_s = ffi.typeof("struct foo_s") 1273 assert foo_s.fields[0][0] == 'b' 1274 assert foo_s.fields[0][1].type is ffi.typeof("void *") 1275 1276def test_const_array_fields(): 1277 ffi = FFI() 1278 ffi.cdef("""struct foo_s { const int a[4]; };""") 1279 lib = verify(ffi, 'test_const_array_fields', """ 1280 struct foo_s { const int a[4]; };""") 1281 foo_s = ffi.typeof("struct foo_s") 1282 assert foo_s.fields[0][0] == 'a' 1283 assert foo_s.fields[0][1].type is ffi.typeof("int[4]") 1284 1285def test_const_array_fields_varlength(): 1286 ffi = FFI() 1287 ffi.cdef("""struct foo_s { const int a[]; ...; };""") 1288 lib = verify(ffi, 'test_const_array_fields_varlength', """ 1289 struct foo_s { const int a[4]; };""") 1290 foo_s = ffi.typeof("struct foo_s") 1291 assert foo_s.fields[0][0] == 'a' 1292 assert foo_s.fields[0][1].type is ffi.typeof("int[]") 1293 1294def test_const_array_fields_unknownlength(): 1295 ffi = FFI() 1296 ffi.cdef("""struct foo_s { const int a[...]; ...; };""") 1297 lib = verify(ffi, 'test_const_array_fields_unknownlength', """ 1298 struct foo_s { const int a[4]; };""") 1299 foo_s = ffi.typeof("struct foo_s") 1300 assert foo_s.fields[0][0] == 'a' 1301 assert foo_s.fields[0][1].type is ffi.typeof("int[4]") 1302 1303def test_const_function_args(): 1304 ffi = FFI() 1305 ffi.cdef("""int foobar(const int a, const int *b, const int c[]);""") 1306 lib = verify(ffi, 'test_const_function_args', """ 1307 int foobar(const int a, const int *b, const int c[]) { 1308 return a + *b + *c; 1309 } 1310 """) 1311 assert lib.foobar(100, ffi.new("int *", 40), ffi.new("int *", 2)) == 142 1312 1313def test_const_function_type_args(): 1314 ffi = FFI() 1315 ffi.cdef("""int (*foobar)(const int a, const int *b, const int c[]);""") 1316 lib = verify(ffi, 'test_const_function_type_args', """ 1317 int (*foobar)(const int a, const int *b, const int c[]); 1318 """) 1319 t = ffi.typeof(lib.foobar) 1320 assert t.args[0] is ffi.typeof("int") 1321 assert t.args[1] is ffi.typeof("int *") 1322 assert t.args[2] is ffi.typeof("int *") 1323 1324def test_const_constant(): 1325 ffi = FFI() 1326 ffi.cdef("""struct foo_s { int x,y; }; const struct foo_s myfoo;""") 1327 lib = verify(ffi, 'test_const_constant', """ 1328 struct foo_s { int x,y; }; const struct foo_s myfoo = { 40, 2 }; 1329 """) 1330 assert lib.myfoo.x == 40 1331 assert lib.myfoo.y == 2 1332 1333def test_const_via_typedef(): 1334 ffi = FFI() 1335 ffi.cdef("""typedef const int const_t; const_t aaa;""") 1336 lib = verify(ffi, 'test_const_via_typedef', """ 1337 typedef const int const_t; 1338 #define aaa 42 1339 """) 1340 assert lib.aaa == 42 1341 py.test.raises(AttributeError, "lib.aaa = 43") 1342 1343def test_win32_calling_convention_0(): 1344 ffi = FFI() 1345 ffi.cdef(""" 1346 int call1(int(__cdecl *cb)(int)); 1347 int (*const call2)(int(__stdcall *cb)(int)); 1348 """) 1349 lib = verify(ffi, 'test_win32_calling_convention_0', r""" 1350 #ifndef _MSC_VER 1351 # define __stdcall /* nothing */ 1352 #endif 1353 int call1(int(*cb)(int)) { 1354 int i, result = 0; 1355 //printf("call1: cb = %p\n", cb); 1356 for (i = 0; i < 1000; i++) 1357 result += cb(i); 1358 //printf("result = %d\n", result); 1359 return result; 1360 } 1361 int call2(int(__stdcall *cb)(int)) { 1362 int i, result = 0; 1363 //printf("call2: cb = %p\n", cb); 1364 for (i = 0; i < 1000; i++) 1365 result += cb(-i); 1366 //printf("result = %d\n", result); 1367 return result; 1368 } 1369 """) 1370 @ffi.callback("int(int)") 1371 def cb1(x): 1372 return x * 2 1373 @ffi.callback("int __stdcall(int)") 1374 def cb2(x): 1375 return x * 3 1376 res = lib.call1(cb1) 1377 assert res == 500*999*2 1378 assert res == ffi.addressof(lib, 'call1')(cb1) 1379 res = lib.call2(cb2) 1380 assert res == -500*999*3 1381 assert res == ffi.addressof(lib, 'call2')(cb2) 1382 if sys.platform == 'win32' and not sys.maxsize > 2**32: 1383 assert '__stdcall' in str(ffi.typeof(cb2)) 1384 assert '__stdcall' not in str(ffi.typeof(cb1)) 1385 py.test.raises(TypeError, lib.call1, cb2) 1386 py.test.raises(TypeError, lib.call2, cb1) 1387 else: 1388 assert '__stdcall' not in str(ffi.typeof(cb2)) 1389 assert ffi.typeof(cb2) is ffi.typeof(cb1) 1390 1391def test_win32_calling_convention_1(): 1392 ffi = FFI() 1393 ffi.cdef(""" 1394 int __cdecl call1(int(__cdecl *cb)(int)); 1395 int __stdcall call2(int(__stdcall *cb)(int)); 1396 int (__cdecl *const cb1)(int); 1397 int (__stdcall *const cb2)(int); 1398 """) 1399 lib = verify(ffi, 'test_win32_calling_convention_1', r""" 1400 #ifndef _MSC_VER 1401 # define __cdecl 1402 # define __stdcall 1403 #endif 1404 int __cdecl cb1(int x) { return x * 2; } 1405 int __stdcall cb2(int x) { return x * 3; } 1406 1407 int __cdecl call1(int(__cdecl *cb)(int)) { 1408 int i, result = 0; 1409 //printf("here1\n"); 1410 //printf("cb = %p, cb1 = %p\n", cb, (void *)cb1); 1411 for (i = 0; i < 1000; i++) 1412 result += cb(i); 1413 //printf("result = %d\n", result); 1414 return result; 1415 } 1416 int __stdcall call2(int(__stdcall *cb)(int)) { 1417 int i, result = 0; 1418 //printf("here1\n"); 1419 //printf("cb = %p, cb2 = %p\n", cb, (void *)cb2); 1420 for (i = 0; i < 1000; i++) 1421 result += cb(-i); 1422 //printf("result = %d\n", result); 1423 return result; 1424 } 1425 """) 1426 #print '<<< cb1 =', ffi.addressof(lib, 'cb1') 1427 ptr_call1 = ffi.addressof(lib, 'call1') 1428 assert lib.call1(ffi.addressof(lib, 'cb1')) == 500*999*2 1429 assert ptr_call1(ffi.addressof(lib, 'cb1')) == 500*999*2 1430 #print '<<< cb2 =', ffi.addressof(lib, 'cb2') 1431 ptr_call2 = ffi.addressof(lib, 'call2') 1432 assert lib.call2(ffi.addressof(lib, 'cb2')) == -500*999*3 1433 assert ptr_call2(ffi.addressof(lib, 'cb2')) == -500*999*3 1434 #print '<<< done' 1435 1436def test_win32_calling_convention_2(): 1437 # any mistake in the declaration of plain function (including the 1438 # precise argument types and, here, the calling convention) are 1439 # automatically corrected. But this does not apply to the 'cb' 1440 # function pointer argument. 1441 ffi = FFI() 1442 ffi.cdef(""" 1443 int __stdcall call1(int(__cdecl *cb)(int)); 1444 int __cdecl call2(int(__stdcall *cb)(int)); 1445 int (__cdecl *const cb1)(int); 1446 int (__stdcall *const cb2)(int); 1447 """) 1448 lib = verify(ffi, 'test_win32_calling_convention_2', """ 1449 #ifndef _MSC_VER 1450 # define __cdecl 1451 # define __stdcall 1452 #endif 1453 int __cdecl call1(int(__cdecl *cb)(int)) { 1454 int i, result = 0; 1455 for (i = 0; i < 1000; i++) 1456 result += cb(i); 1457 return result; 1458 } 1459 int __stdcall call2(int(__stdcall *cb)(int)) { 1460 int i, result = 0; 1461 for (i = 0; i < 1000; i++) 1462 result += cb(-i); 1463 return result; 1464 } 1465 int __cdecl cb1(int x) { return x * 2; } 1466 int __stdcall cb2(int x) { return x * 3; } 1467 """) 1468 ptr_call1 = ffi.addressof(lib, 'call1') 1469 ptr_call2 = ffi.addressof(lib, 'call2') 1470 if sys.platform == 'win32' and not sys.maxsize > 2**32: 1471 py.test.raises(TypeError, lib.call1, ffi.addressof(lib, 'cb2')) 1472 py.test.raises(TypeError, ptr_call1, ffi.addressof(lib, 'cb2')) 1473 py.test.raises(TypeError, lib.call2, ffi.addressof(lib, 'cb1')) 1474 py.test.raises(TypeError, ptr_call2, ffi.addressof(lib, 'cb1')) 1475 assert lib.call1(ffi.addressof(lib, 'cb1')) == 500*999*2 1476 assert ptr_call1(ffi.addressof(lib, 'cb1')) == 500*999*2 1477 assert lib.call2(ffi.addressof(lib, 'cb2')) == -500*999*3 1478 assert ptr_call2(ffi.addressof(lib, 'cb2')) == -500*999*3 1479 1480def test_win32_calling_convention_3(): 1481 ffi = FFI() 1482 ffi.cdef(""" 1483 struct point { int x, y; }; 1484 1485 int (*const cb1)(struct point); 1486 int (__stdcall *const cb2)(struct point); 1487 1488 struct point __stdcall call1(int(*cb)(struct point)); 1489 struct point call2(int(__stdcall *cb)(struct point)); 1490 """) 1491 lib = verify(ffi, 'test_win32_calling_convention_3', r""" 1492 #ifndef _MSC_VER 1493 # define __cdecl 1494 # define __stdcall 1495 #endif 1496 struct point { int x, y; }; 1497 int cb1(struct point pt) { return pt.x + 10 * pt.y; } 1498 int __stdcall cb2(struct point pt) { return pt.x + 100 * pt.y; } 1499 struct point __stdcall call1(int(__cdecl *cb)(struct point)) { 1500 int i; 1501 struct point result = { 0, 0 }; 1502 //printf("here1\n"); 1503 //printf("cb = %p, cb1 = %p\n", cb, (void *)cb1); 1504 for (i = 0; i < 1000; i++) { 1505 struct point p = { i, -i }; 1506 int r = cb(p); 1507 result.x += r; 1508 result.y -= r; 1509 } 1510 return result; 1511 } 1512 struct point __cdecl call2(int(__stdcall *cb)(struct point)) { 1513 int i; 1514 struct point result = { 0, 0 }; 1515 for (i = 0; i < 1000; i++) { 1516 struct point p = { -i, i }; 1517 int r = cb(p); 1518 result.x += r; 1519 result.y -= r; 1520 } 1521 return result; 1522 } 1523 """) 1524 ptr_call1 = ffi.addressof(lib, 'call1') 1525 ptr_call2 = ffi.addressof(lib, 'call2') 1526 if sys.platform == 'win32' and not sys.maxsize > 2**32: 1527 py.test.raises(TypeError, lib.call1, ffi.addressof(lib, 'cb2')) 1528 py.test.raises(TypeError, ptr_call1, ffi.addressof(lib, 'cb2')) 1529 py.test.raises(TypeError, lib.call2, ffi.addressof(lib, 'cb1')) 1530 py.test.raises(TypeError, ptr_call2, ffi.addressof(lib, 'cb1')) 1531 pt = lib.call1(ffi.addressof(lib, 'cb1')) 1532 assert (pt.x, pt.y) == (-9*500*999, 9*500*999) 1533 pt = ptr_call1(ffi.addressof(lib, 'cb1')) 1534 assert (pt.x, pt.y) == (-9*500*999, 9*500*999) 1535 pt = lib.call2(ffi.addressof(lib, 'cb2')) 1536 assert (pt.x, pt.y) == (99*500*999, -99*500*999) 1537 pt = ptr_call2(ffi.addressof(lib, 'cb2')) 1538 assert (pt.x, pt.y) == (99*500*999, -99*500*999) 1539 1540def test_extern_python_1(): 1541 import warnings 1542 ffi = FFI() 1543 with warnings.catch_warnings(record=True) as log: 1544 ffi.cdef(""" 1545 extern "Python" { 1546 int bar(int, int); 1547 void baz(int, int); 1548 int bok(void); 1549 void boz(void); 1550 } 1551 """) 1552 assert len(log) == 0, "got a warning: %r" % (log,) 1553 lib = verify(ffi, 'test_extern_python_1', """ 1554 static void baz(int, int); /* forward */ 1555 """) 1556 assert ffi.typeof(lib.bar) == ffi.typeof("int(*)(int, int)") 1557 with FdWriteCapture() as f: 1558 res = lib.bar(4, 5) 1559 assert res == 0 1560 assert f.getvalue() == ( 1561 b"extern \"Python\": function _CFFI_test_extern_python_1.bar() called, " 1562 b"but no code was attached " 1563 b"to it yet with @ffi.def_extern(). Returning 0.\n") 1564 1565 @ffi.def_extern("bar") 1566 def my_bar(x, y): 1567 seen.append(("Bar", x, y)) 1568 return x * y 1569 assert my_bar != lib.bar 1570 seen = [] 1571 res = lib.bar(6, 7) 1572 assert seen == [("Bar", 6, 7)] 1573 assert res == 42 1574 1575 def baz(x, y): 1576 seen.append(("Baz", x, y)) 1577 baz1 = ffi.def_extern()(baz) 1578 assert baz1 is baz 1579 seen = [] 1580 baz(long(40), long(4)) 1581 res = lib.baz(long(50), long(8)) 1582 assert res is None 1583 assert seen == [("Baz", 40, 4), ("Baz", 50, 8)] 1584 assert type(seen[0][1]) is type(seen[0][2]) is long 1585 assert type(seen[1][1]) is type(seen[1][2]) is int 1586 1587 @ffi.def_extern(name="bok") 1588 def bokk(): 1589 seen.append("Bok") 1590 return 42 1591 seen = [] 1592 assert lib.bok() == 42 1593 assert seen == ["Bok"] 1594 1595 @ffi.def_extern() 1596 def boz(): 1597 seen.append("Boz") 1598 seen = [] 1599 assert lib.boz() is None 1600 assert seen == ["Boz"] 1601 1602def test_extern_python_bogus_name(): 1603 ffi = FFI() 1604 ffi.cdef("int abc;") 1605 lib = verify(ffi, 'test_extern_python_bogus_name', "int abc;") 1606 def fn(): 1607 pass 1608 py.test.raises(ffi.error, ffi.def_extern("unknown_name"), fn) 1609 py.test.raises(ffi.error, ffi.def_extern("abc"), fn) 1610 assert lib.abc == 0 1611 e = py.test.raises(ffi.error, ffi.def_extern("abc"), fn) 1612 assert str(e.value) == ("ffi.def_extern('abc'): no 'extern \"Python\"' " 1613 "function with this name") 1614 e = py.test.raises(ffi.error, ffi.def_extern(), fn) 1615 assert str(e.value) == ("ffi.def_extern('fn'): no 'extern \"Python\"' " 1616 "function with this name") 1617 # 1618 py.test.raises(TypeError, ffi.def_extern(42), fn) 1619 py.test.raises((TypeError, AttributeError), ffi.def_extern(), "foo") 1620 class X: 1621 pass 1622 x = X() 1623 x.__name__ = x 1624 py.test.raises(TypeError, ffi.def_extern(), x) 1625 1626def test_extern_python_bogus_result_type(): 1627 ffi = FFI() 1628 ffi.cdef("""extern "Python" void bar(int);""") 1629 lib = verify(ffi, 'test_extern_python_bogus_result_type', "") 1630 # 1631 @ffi.def_extern() 1632 def bar(n): 1633 return n * 10 1634 with StdErrCapture() as f: 1635 res = lib.bar(321) 1636 assert res is None 1637 assert f.getvalue() == ( 1638 "From cffi callback %r:\n" % (bar,) + 1639 "Trying to convert the result back to C:\n" 1640 "TypeError: callback with the return type 'void' must return None\n") 1641 1642def test_extern_python_redefine(): 1643 ffi = FFI() 1644 ffi.cdef("""extern "Python" int bar(int);""") 1645 lib = verify(ffi, 'test_extern_python_redefine', "") 1646 # 1647 @ffi.def_extern() 1648 def bar(n): 1649 return n * 10 1650 assert lib.bar(42) == 420 1651 # 1652 @ffi.def_extern() 1653 def bar(n): 1654 return -n 1655 assert lib.bar(42) == -42 1656 1657def test_extern_python_struct(): 1658 ffi = FFI() 1659 ffi.cdef(""" 1660 struct foo_s { int a, b, c; }; 1661 extern "Python" int bar(int, struct foo_s, int); 1662 extern "Python" { struct foo_s baz(int, int); 1663 struct foo_s bok(void); } 1664 """) 1665 lib = verify(ffi, 'test_extern_python_struct', 1666 "struct foo_s { int a, b, c; };") 1667 # 1668 @ffi.def_extern() 1669 def bar(x, s, z): 1670 return x + s.a + s.b + s.c + z 1671 res = lib.bar(1000, [1001, 1002, 1004], 1008) 1672 assert res == 5015 1673 # 1674 @ffi.def_extern() 1675 def baz(x, y): 1676 return [x + y, x - y, x * y] 1677 res = lib.baz(1000, 42) 1678 assert res.a == 1042 1679 assert res.b == 958 1680 assert res.c == 42000 1681 # 1682 @ffi.def_extern() 1683 def bok(): 1684 return [10, 20, 30] 1685 res = lib.bok() 1686 assert [res.a, res.b, res.c] == [10, 20, 30] 1687 1688def test_extern_python_long_double(): 1689 ffi = FFI() 1690 ffi.cdef(""" 1691 extern "Python" int bar(int, long double, int); 1692 extern "Python" long double baz(int, int); 1693 extern "Python" long double bok(void); 1694 """) 1695 lib = verify(ffi, 'test_extern_python_long_double', "") 1696 # 1697 @ffi.def_extern() 1698 def bar(x, l, z): 1699 seen.append((x, l, z)) 1700 return 6 1701 seen = [] 1702 lib.bar(10, 3.5, 20) 1703 expected = ffi.cast("long double", 3.5) 1704 assert repr(seen) == repr([(10, expected, 20)]) 1705 # 1706 @ffi.def_extern() 1707 def baz(x, z): 1708 assert x == 10 and z == 20 1709 return expected 1710 res = lib.baz(10, 20) 1711 assert repr(res) == repr(expected) 1712 # 1713 @ffi.def_extern() 1714 def bok(): 1715 return expected 1716 res = lib.bok() 1717 assert repr(res) == repr(expected) 1718 1719def test_extern_python_signature(): 1720 ffi = FFI() 1721 lib = verify(ffi, 'test_extern_python_signature', "") 1722 py.test.raises(TypeError, ffi.def_extern(425), None) 1723 py.test.raises(TypeError, ffi.def_extern, 'a', 'b', 'c', 'd') 1724 1725def test_extern_python_errors(): 1726 ffi = FFI() 1727 ffi.cdef(""" 1728 extern "Python" int bar(int); 1729 """) 1730 lib = verify(ffi, 'test_extern_python_errors', "") 1731 1732 seen = [] 1733 def oops(*args): 1734 seen.append(args) 1735 1736 @ffi.def_extern(onerror=oops) 1737 def bar(x): 1738 return x + "" 1739 assert lib.bar(10) == 0 1740 1741 @ffi.def_extern(name="bar", onerror=oops, error=-66) 1742 def bar2(x): 1743 return x + "" 1744 assert lib.bar(10) == -66 1745 1746 assert len(seen) == 2 1747 exc, val, tb = seen[0] 1748 assert exc is TypeError 1749 assert isinstance(val, TypeError) 1750 assert tb.tb_frame.f_code.co_name == "bar" 1751 exc, val, tb = seen[1] 1752 assert exc is TypeError 1753 assert isinstance(val, TypeError) 1754 assert tb.tb_frame.f_code.co_name == "bar2" 1755 # 1756 # a case where 'onerror' is not callable 1757 py.test.raises(TypeError, ffi.def_extern(name='bar', onerror=42), 1758 lambda x: x) 1759 1760def test_extern_python_stdcall(): 1761 ffi = FFI() 1762 ffi.cdef(""" 1763 extern "Python" int __stdcall foo(int); 1764 extern "Python" int WINAPI bar(int); 1765 int (__stdcall * mycb1)(int); 1766 int indirect_call(int); 1767 """) 1768 lib = verify(ffi, 'test_extern_python_stdcall', """ 1769 #ifndef _MSC_VER 1770 # define __stdcall 1771 #endif 1772 static int (__stdcall * mycb1)(int); 1773 static int indirect_call(int x) { 1774 return mycb1(x); 1775 } 1776 """) 1777 # 1778 @ffi.def_extern() 1779 def foo(x): 1780 return x + 42 1781 @ffi.def_extern() 1782 def bar(x): 1783 return x + 43 1784 assert lib.foo(100) == 142 1785 assert lib.bar(100) == 143 1786 lib.mycb1 = lib.foo 1787 assert lib.mycb1(200) == 242 1788 assert lib.indirect_call(300) == 342 1789 1790def test_extern_python_plus_c(): 1791 ffi = FFI() 1792 ffi.cdef(""" 1793 extern "Python+C" int foo(int); 1794 extern "C +\tPython" int bar(int); 1795 int call_me(int); 1796 """) 1797 lib = verify(ffi, 'test_extern_python_plus_c', """ 1798 int foo(int); 1799 #ifdef __GNUC__ 1800 __attribute__((visibility("hidden"))) 1801 #endif 1802 int bar(int); 1803 1804 static int call_me(int x) { 1805 return foo(x) - bar(x); 1806 } 1807 """) 1808 # 1809 @ffi.def_extern() 1810 def foo(x): 1811 return x * 42 1812 @ffi.def_extern() 1813 def bar(x): 1814 return x * 63 1815 assert lib.foo(100) == 4200 1816 assert lib.bar(100) == 6300 1817 assert lib.call_me(100) == -2100 1818 1819def test_introspect_function(): 1820 ffi = FFI() 1821 ffi.cdef("float f1(double);") 1822 lib = verify(ffi, 'test_introspect_function', """ 1823 float f1(double x) { return x; } 1824 """) 1825 assert dir(lib) == ['f1'] 1826 FUNC = ffi.typeof(lib.f1) 1827 assert FUNC.kind == 'function' 1828 assert FUNC.args[0].cname == 'double' 1829 assert FUNC.result.cname == 'float' 1830 assert ffi.typeof(ffi.addressof(lib, 'f1')) is FUNC 1831 1832def test_introspect_global_var(): 1833 ffi = FFI() 1834 ffi.cdef("float g1;") 1835 lib = verify(ffi, 'test_introspect_global_var', """ 1836 float g1; 1837 """) 1838 assert dir(lib) == ['g1'] 1839 FLOATPTR = ffi.typeof(ffi.addressof(lib, 'g1')) 1840 assert FLOATPTR.kind == 'pointer' 1841 assert FLOATPTR.item.cname == 'float' 1842 1843def test_introspect_global_var_array(): 1844 ffi = FFI() 1845 ffi.cdef("float g1[100];") 1846 lib = verify(ffi, 'test_introspect_global_var_array', """ 1847 float g1[100]; 1848 """) 1849 assert dir(lib) == ['g1'] 1850 FLOATARRAYPTR = ffi.typeof(ffi.addressof(lib, 'g1')) 1851 assert FLOATARRAYPTR.kind == 'pointer' 1852 assert FLOATARRAYPTR.item.kind == 'array' 1853 assert FLOATARRAYPTR.item.length == 100 1854 assert ffi.typeof(lib.g1) is FLOATARRAYPTR.item 1855 1856def test_introspect_integer_const(): 1857 ffi = FFI() 1858 ffi.cdef("#define FOO 42") 1859 lib = verify(ffi, 'test_introspect_integer_const', """ 1860 #define FOO 42 1861 """) 1862 assert dir(lib) == ['FOO'] 1863 assert lib.FOO == ffi.integer_const('FOO') == 42 1864 1865def test_introspect_typedef(): 1866 ffi = FFI() 1867 ffi.cdef("typedef int foo_t;") 1868 lib = verify(ffi, 'test_introspect_typedef', """ 1869 typedef int foo_t; 1870 """) 1871 assert ffi.list_types() == (['foo_t'], [], []) 1872 assert ffi.typeof('foo_t').kind == 'primitive' 1873 assert ffi.typeof('foo_t').cname == 'int' 1874 1875def test_introspect_typedef_multiple(): 1876 ffi = FFI() 1877 ffi.cdef("typedef signed char a_t, c_t, g_t, b_t;") 1878 lib = verify(ffi, 'test_introspect_typedef_multiple', """ 1879 typedef signed char a_t, c_t, g_t, b_t; 1880 """) 1881 assert ffi.list_types() == (['a_t', 'b_t', 'c_t', 'g_t'], [], []) 1882 1883def test_introspect_struct(): 1884 ffi = FFI() 1885 ffi.cdef("struct foo_s { int a; };") 1886 lib = verify(ffi, 'test_introspect_struct', """ 1887 struct foo_s { int a; }; 1888 """) 1889 assert ffi.list_types() == ([], ['foo_s'], []) 1890 assert ffi.typeof('struct foo_s').kind == 'struct' 1891 assert ffi.typeof('struct foo_s').cname == 'struct foo_s' 1892 1893def test_introspect_union(): 1894 ffi = FFI() 1895 ffi.cdef("union foo_s { int a; };") 1896 lib = verify(ffi, 'test_introspect_union', """ 1897 union foo_s { int a; }; 1898 """) 1899 assert ffi.list_types() == ([], [], ['foo_s']) 1900 assert ffi.typeof('union foo_s').kind == 'union' 1901 assert ffi.typeof('union foo_s').cname == 'union foo_s' 1902 1903def test_introspect_struct_and_typedef(): 1904 ffi = FFI() 1905 ffi.cdef("typedef struct { int a; } foo_t;") 1906 lib = verify(ffi, 'test_introspect_struct_and_typedef', """ 1907 typedef struct { int a; } foo_t; 1908 """) 1909 assert ffi.list_types() == (['foo_t'], [], []) 1910 assert ffi.typeof('foo_t').kind == 'struct' 1911 assert ffi.typeof('foo_t').cname == 'foo_t' 1912 1913def test_introspect_included_type(): 1914 SOURCE = """ 1915 typedef signed char schar_t; 1916 struct sint_t { int x; }; 1917 """ 1918 ffi1 = FFI() 1919 ffi1.cdef(SOURCE) 1920 ffi2 = FFI() 1921 ffi2.include(ffi1) 1922 verify(ffi1, "test_introspect_included_type_parent", SOURCE) 1923 verify(ffi2, "test_introspect_included_type", SOURCE) 1924 assert ffi1.list_types() == ffi2.list_types() == ( 1925 ['schar_t'], ['sint_t'], []) 1926 1927def test_introspect_order(): 1928 ffi = FFI() 1929 ffi.cdef("union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb;") 1930 ffi.cdef("union CFFIg { int a; }; typedef struct CFFIcc { int a; } CFFIbbb;") 1931 ffi.cdef("union CFFIaa { int a; }; typedef struct CFFIa { int a; } CFFIbb;") 1932 verify(ffi, "test_introspect_order", """ 1933 union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb; 1934 union CFFIg { int a; }; typedef struct CFFIcc { int a; } CFFIbbb; 1935 union CFFIaa { int a; }; typedef struct CFFIa { int a; } CFFIbb; 1936 """) 1937 assert ffi.list_types() == (['CFFIb', 'CFFIbb', 'CFFIbbb'], 1938 ['CFFIa', 'CFFIcc', 'CFFIccc'], 1939 ['CFFIaa', 'CFFIaaa', 'CFFIg']) 1940 1941def test_bool_in_cpp(): 1942 # this works when compiled as C, but in cffi < 1.7 it fails as C++ 1943 ffi = FFI() 1944 ffi.cdef("bool f(void);") 1945 lib = verify(ffi, "test_bool_in_cpp", "char f(void) { return 2; }") 1946 assert lib.f() is True 1947 1948def test_bool_in_cpp_2(): 1949 ffi = FFI() 1950 ffi.cdef('int add(int a, int b);') 1951 lib = verify(ffi, "test_bool_bug_cpp", ''' 1952 typedef bool _Bool; /* there is a Windows header with this line */ 1953 int add(int a, int b) 1954 { 1955 return a + b; 1956 }''', source_extension='.cpp') 1957 c = lib.add(2, 3) 1958 assert c == 5 1959 1960def test_struct_field_opaque(): 1961 ffi = FFI() 1962 ffi.cdef("struct a { struct b b; };") 1963 e = py.test.raises(TypeError, verify, 1964 ffi, "test_struct_field_opaque", "?") 1965 assert str(e.value) == ("struct a: field 'a.b' is of an opaque" 1966 " type (not declared in cdef())") 1967 ffi = FFI() 1968 ffi.cdef("struct a { struct b b[2]; };") 1969 e = py.test.raises(TypeError, verify, 1970 ffi, "test_struct_field_opaque", "?") 1971 assert str(e.value) == ("struct a: field 'a.b' is of an opaque" 1972 " type (not declared in cdef())") 1973 ffi = FFI() 1974 ffi.cdef("struct a { struct b b[]; };") 1975 e = py.test.raises(TypeError, verify, 1976 ffi, "test_struct_field_opaque", "?") 1977 assert str(e.value) == ("struct a: field 'a.b' is of an opaque" 1978 " type (not declared in cdef())") 1979 1980def test_function_arg_opaque(): 1981 py.test.skip("can currently declare a function with an opaque struct " 1982 "as argument, but AFAICT it's impossible to call it later") 1983 1984def test_function_returns_opaque(): 1985 ffi = FFI() 1986 ffi.cdef("struct a foo(int);") 1987 e = py.test.raises(TypeError, verify, 1988 ffi, "test_function_returns_opaque", "?") 1989 assert str(e.value) == ("function foo: 'struct a' is used as result type," 1990 " but is opaque") 1991 1992def test_function_returns_union(): 1993 ffi = FFI() 1994 ffi.cdef("union u1 { int a, b; }; union u1 f1(int);") 1995 lib = verify(ffi, "test_function_returns_union", """ 1996 union u1 { int a, b; }; 1997 static union u1 f1(int x) { union u1 u; u.b = x; return u; } 1998 """) 1999 assert lib.f1(51).a == 51 2000 2001def test_function_returns_partial_struct(): 2002 ffi = FFI() 2003 ffi.cdef("struct aaa { int a; ...; }; struct aaa f1(int);") 2004 lib = verify(ffi, "test_function_returns_partial_struct", """ 2005 struct aaa { int b, a, c; }; 2006 static struct aaa f1(int x) { struct aaa s = {0}; s.a = x; return s; } 2007 """) 2008 assert lib.f1(52).a == 52 2009 2010def test_function_returns_float_complex(): 2011 if sys.platform == 'win32': 2012 py.test.skip("MSVC may not support _Complex") 2013 ffi = FFI() 2014 ffi.cdef("float _Complex f1(float a, float b);"); 2015 lib = verify(ffi, "test_function_returns_float_complex", """ 2016 #include <complex.h> 2017 static float _Complex f1(float a, float b) { return a + I*2.0*b; } 2018 """, no_cpp=True) # <complex.h> fails on some systems with C++ 2019 result = lib.f1(1.25, 5.1) 2020 assert type(result) == complex 2021 assert result.real == 1.25 # exact 2022 assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-5) # inexact 2023 2024def test_function_returns_double_complex(): 2025 if sys.platform == 'win32': 2026 py.test.skip("MSVC may not support _Complex") 2027 ffi = FFI() 2028 ffi.cdef("double _Complex f1(double a, double b);"); 2029 lib = verify(ffi, "test_function_returns_double_complex", """ 2030 #include <complex.h> 2031 static double _Complex f1(double a, double b) { return a + I*2.0*b; } 2032 """, no_cpp=True) # <complex.h> fails on some systems with C++ 2033 result = lib.f1(1.25, 5.1) 2034 assert type(result) == complex 2035 assert result.real == 1.25 # exact 2036 assert result.imag == 2*5.1 # exact 2037 2038def test_function_argument_float_complex(): 2039 if sys.platform == 'win32': 2040 py.test.skip("MSVC may not support _Complex") 2041 ffi = FFI() 2042 ffi.cdef("float f1(float _Complex x);"); 2043 lib = verify(ffi, "test_function_argument_float_complex", """ 2044 #include <complex.h> 2045 static float f1(float _Complex x) { return cabsf(x); } 2046 """, no_cpp=True) # <complex.h> fails on some systems with C++ 2047 x = complex(12.34, 56.78) 2048 result = lib.f1(x) 2049 assert abs(result - abs(x)) < 1e-5 2050 2051def test_function_argument_double_complex(): 2052 if sys.platform == 'win32': 2053 py.test.skip("MSVC may not support _Complex") 2054 ffi = FFI() 2055 ffi.cdef("double f1(double _Complex);"); 2056 lib = verify(ffi, "test_function_argument_double_complex", """ 2057 #include <complex.h> 2058 static double f1(double _Complex x) { return cabs(x); } 2059 """, no_cpp=True) # <complex.h> fails on some systems with C++ 2060 x = complex(12.34, 56.78) 2061 result = lib.f1(x) 2062 assert abs(result - abs(x)) < 1e-11 2063 2064def test_typedef_array_dotdotdot(): 2065 ffi = FFI() 2066 ffi.cdef(""" 2067 typedef int foo_t[...], bar_t[...]; 2068 int gv[...]; 2069 typedef int mat_t[...][...]; 2070 typedef int vmat_t[][...]; 2071 """) 2072 lib = verify(ffi, "test_typedef_array_dotdotdot", """ 2073 typedef int foo_t[50], bar_t[50]; 2074 int gv[23]; 2075 typedef int mat_t[6][7]; 2076 typedef int vmat_t[][8]; 2077 """) 2078 assert ffi.sizeof("foo_t") == 50 * ffi.sizeof("int") 2079 assert ffi.sizeof("bar_t") == 50 * ffi.sizeof("int") 2080 assert len(ffi.new("foo_t")) == 50 2081 assert len(ffi.new("bar_t")) == 50 2082 assert ffi.sizeof(lib.gv) == 23 * ffi.sizeof("int") 2083 assert ffi.sizeof("mat_t") == 6 * 7 * ffi.sizeof("int") 2084 assert len(ffi.new("mat_t")) == 6 2085 assert len(ffi.new("mat_t")[3]) == 7 2086 py.test.raises(ffi.error, ffi.sizeof, "vmat_t") 2087 p = ffi.new("vmat_t", 4) 2088 assert ffi.sizeof(p[3]) == 8 * ffi.sizeof("int") 2089 2090def test_call_with_custom_field_pos(): 2091 ffi = FFI() 2092 ffi.cdef(""" 2093 struct foo { int x; ...; }; 2094 struct foo f(void); 2095 struct foo g(int, ...); 2096 """) 2097 lib = verify(ffi, "test_call_with_custom_field_pos", """ 2098 struct foo { int y, x; }; 2099 struct foo f(void) { 2100 struct foo s = { 40, 200 }; 2101 return s; 2102 } 2103 struct foo g(int a, ...) { return f(); } 2104 """) 2105 assert lib.f().x == 200 2106 e = py.test.raises(NotImplementedError, lib.g, 0) 2107 assert str(e.value) == ( 2108 'ctype \'struct foo\' not supported as return value. It is a ' 2109 'struct declared with "...;", but the C calling convention may ' 2110 'depend on the missing fields; or, it contains anonymous ' 2111 'struct/unions. Such structs are only supported ' 2112 'as return value if the function is \'API mode\' and non-variadic ' 2113 '(i.e. declared inside ffibuilder.cdef()+ffibuilder.set_source() ' 2114 'and not taking a final \'...\' argument)') 2115 2116def test_call_with_nested_anonymous_struct(): 2117 if sys.platform == 'win32': 2118 py.test.skip("needs a GCC extension") 2119 ffi = FFI() 2120 ffi.cdef(""" 2121 struct foo { int a; union { int b, c; }; }; 2122 struct foo f(void); 2123 struct foo g(int, ...); 2124 """) 2125 lib = verify(ffi, "test_call_with_nested_anonymous_struct", """ 2126 struct foo { int a; union { int b, c; }; }; 2127 struct foo f(void) { 2128 struct foo s = { 40 }; 2129 s.b = 200; 2130 return s; 2131 } 2132 struct foo g(int a, ...) { return f(); } 2133 """) 2134 assert lib.f().b == 200 2135 e = py.test.raises(NotImplementedError, lib.g, 0) 2136 assert str(e.value) == ( 2137 'ctype \'struct foo\' not supported as return value. It is a ' 2138 'struct declared with "...;", but the C calling convention may ' 2139 'depend on the missing fields; or, it contains anonymous ' 2140 'struct/unions. Such structs are only supported ' 2141 'as return value if the function is \'API mode\' and non-variadic ' 2142 '(i.e. declared inside ffibuilder.cdef()+ffibuilder.set_source() ' 2143 'and not taking a final \'...\' argument)') 2144 2145def test_call_with_bitfield(): 2146 ffi = FFI() 2147 ffi.cdef(""" 2148 struct foo { int x:5; }; 2149 struct foo f(void); 2150 struct foo g(int, ...); 2151 """) 2152 lib = verify(ffi, "test_call_with_bitfield", """ 2153 struct foo { int x:5; }; 2154 struct foo f(void) { 2155 struct foo s = { 11 }; 2156 return s; 2157 } 2158 struct foo g(int a, ...) { return f(); } 2159 """) 2160 assert lib.f().x == 11 2161 e = py.test.raises(NotImplementedError, lib.g, 0) 2162 assert str(e.value) == ( 2163 "ctype 'struct foo' not supported as return value. It is a struct " 2164 "with bit fields, which libffi does not support. Such structs are " 2165 "only supported as return value if the function is 'API mode' and " 2166 "non-variadic (i.e. declared inside ffibuilder.cdef()+ffibuilder." 2167 "set_source() and not taking a final '...' argument)") 2168 2169def test_call_with_zero_length_field(): 2170 if sys.platform == 'win32': 2171 py.test.skip("zero-length field not supported by MSVC") 2172 ffi = FFI() 2173 ffi.cdef(""" 2174 struct foo { int a; int x[0]; }; 2175 struct foo f(void); 2176 struct foo g(int, ...); 2177 """) 2178 lib = verify(ffi, "test_call_with_zero_length_field", """ 2179 struct foo { int a; int x[0]; }; 2180 struct foo f(void) { 2181 struct foo s = { 42 }; 2182 return s; 2183 } 2184 struct foo g(int a, ...) { return f(); } 2185 """) 2186 assert lib.f().a == 42 2187 e = py.test.raises(NotImplementedError, lib.g, 0) 2188 assert str(e.value) == ( 2189 "ctype 'struct foo' not supported as return value. It is a " 2190 "struct with a zero-length array, which libffi does not support." 2191 " Such structs are only supported as return value if the function is " 2192 "'API mode' and non-variadic (i.e. declared inside ffibuilder.cdef()" 2193 "+ffibuilder.set_source() and not taking a final '...' argument)") 2194 2195def test_call_with_union(): 2196 ffi = FFI() 2197 ffi.cdef(""" 2198 union foo { int a; char b; }; 2199 union foo f(void); 2200 union foo g(int, ...); 2201 """) 2202 lib = verify(ffi, "test_call_with_union", """ 2203 union foo { int a; char b; }; 2204 union foo f(void) { 2205 union foo s = { 42 }; 2206 return s; 2207 } 2208 union foo g(int a, ...) { return f(); } 2209 """) 2210 assert lib.f().a == 42 2211 e = py.test.raises(NotImplementedError, lib.g, 0) 2212 assert str(e.value) == ( 2213 "ctype 'union foo' not supported as return value by libffi. " 2214 "Unions are only supported as return value if the function is " 2215 "'API mode' and non-variadic (i.e. declared inside ffibuilder.cdef()" 2216 "+ffibuilder.set_source() and not taking a final '...' argument)") 2217 2218def test_call_with_packed_struct(): 2219 if sys.platform == 'win32': 2220 py.test.skip("needs a GCC extension") 2221 ffi = FFI() 2222 ffi.cdef(""" 2223 struct foo { char y; int x; }; 2224 struct foo f(void); 2225 struct foo g(int, ...); 2226 """, packed=True) 2227 lib = verify(ffi, "test_call_with_packed_struct", """ 2228 struct foo { char y; int x; } __attribute__((packed)); 2229 struct foo f(void) { 2230 struct foo s = { 40, 200 }; 2231 return s; 2232 } 2233 struct foo g(int a, ...) { 2234 struct foo s = { 41, 201 }; 2235 return s; 2236 } 2237 """) 2238 assert ord(lib.f().y) == 40 2239 assert lib.f().x == 200 2240 e = py.test.raises(NotImplementedError, lib.g, 0) 2241 assert str(e.value) == ( 2242 "ctype 'struct foo' not supported as return value. It is a " 2243 "'packed' structure, with a different layout than expected by libffi." 2244 " Such structs are only supported as return value if the function is " 2245 "'API mode' and non-variadic (i.e. declared inside ffibuilder.cdef()" 2246 "+ffibuilder.set_source() and not taking a final '...' argument)") 2247 2248def test_pack_not_supported(): 2249 ffi = FFI() 2250 ffi.cdef("""struct foo { char y; int x; };""", pack=2) 2251 py.test.raises(NotImplementedError, verify, 2252 ffi, "test_pack_not_supported", "") 2253 2254def test_gcc_visibility_hidden(): 2255 if sys.platform == 'win32': 2256 py.test.skip("test for gcc/clang") 2257 ffi = FFI() 2258 ffi.cdef(""" 2259 int f(int); 2260 """) 2261 lib = verify(ffi, "test_gcc_visibility_hidden", """ 2262 int f(int a) { return a + 40; } 2263 """, extra_compile_args=['-fvisibility=hidden']) 2264 assert lib.f(2) == 42 2265 2266def test_override_default_definition(): 2267 ffi = FFI() 2268 ffi.cdef("typedef long int16_t, char16_t;") 2269 lib = verify(ffi, "test_override_default_definition", "") 2270 assert ffi.typeof("int16_t") is ffi.typeof("char16_t") is ffi.typeof("long") 2271 2272def test_char16_char32_type(no_cpp=False): 2273 if no_cpp is False and sys.platform == "win32": 2274 py.test.skip("aaaaaaa why do modern MSVC compilers still define " 2275 "a very old __cplusplus value") 2276 ffi = FFI() 2277 ffi.cdef(""" 2278 char16_t foo_2bytes(char16_t); 2279 char32_t foo_4bytes(char32_t); 2280 """) 2281 lib = verify(ffi, "test_char16_char32_type" + no_cpp * "_nocpp", """ 2282 #if !defined(__cplusplus) || (!defined(_LIBCPP_VERSION) && __cplusplus < 201103L) 2283 typedef uint_least16_t char16_t; 2284 typedef uint_least32_t char32_t; 2285 #endif 2286 2287 char16_t foo_2bytes(char16_t a) { return (char16_t)(a + 42); } 2288 char32_t foo_4bytes(char32_t a) { return (char32_t)(a + 42); } 2289 """, no_cpp=no_cpp) 2290 assert lib.foo_2bytes(u+'\u1234') == u+'\u125e' 2291 assert lib.foo_4bytes(u+'\u1234') == u+'\u125e' 2292 assert lib.foo_4bytes(u+'\U00012345') == u+'\U0001236f' 2293 py.test.raises(TypeError, lib.foo_2bytes, u+'\U00012345') 2294 py.test.raises(TypeError, lib.foo_2bytes, 1234) 2295 py.test.raises(TypeError, lib.foo_4bytes, 1234) 2296 2297def test_char16_char32_plain_c(): 2298 test_char16_char32_type(no_cpp=True) 2299 2300def test_loader_spec(): 2301 ffi = FFI() 2302 lib = verify(ffi, "test_loader_spec", "") 2303 if sys.version_info < (3,): 2304 assert not hasattr(lib, '__loader__') 2305 assert not hasattr(lib, '__spec__') 2306 else: 2307 assert lib.__loader__ is None 2308 assert lib.__spec__ is None 2309 2310def test_realize_struct_error(): 2311 ffi = FFI() 2312 ffi.cdef("""typedef ... foo_t; struct foo_s { void (*x)(foo_t); };""") 2313 lib = verify(ffi, "test_realize_struct_error", """ 2314 typedef int foo_t; struct foo_s { void (*x)(foo_t); }; 2315 """) 2316 py.test.raises(TypeError, ffi.new, "struct foo_s *") 2317