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