1import py 2import platform 3import sys, ctypes 4from cffi import FFI, CDefError, FFIError, VerificationMissing 5from testing.support import * 6 7SIZE_OF_INT = ctypes.sizeof(ctypes.c_int) 8SIZE_OF_LONG = ctypes.sizeof(ctypes.c_long) 9SIZE_OF_SHORT = ctypes.sizeof(ctypes.c_short) 10SIZE_OF_PTR = ctypes.sizeof(ctypes.c_void_p) 11SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar) 12 13def needs_dlopen_none(): 14 if sys.platform == 'win32' and sys.version_info >= (3,): 15 py.test.skip("dlopen(None) cannot work on Windows for Python 3") 16 17 18class BackendTests: 19 20 def test_integer_ranges(self): 21 ffi = FFI(backend=self.Backend()) 22 for (c_type, size) in [('char', 1), 23 ('short', 2), 24 ('short int', 2), 25 ('', 4), 26 ('int', 4), 27 ('long', SIZE_OF_LONG), 28 ('long int', SIZE_OF_LONG), 29 ('long long', 8), 30 ('long long int', 8), 31 ]: 32 for unsigned in [None, False, True]: 33 c_decl = {None: '', 34 False: 'signed ', 35 True: 'unsigned '}[unsigned] + c_type 36 if c_decl == 'char' or c_decl == '': 37 continue 38 self._test_int_type(ffi, c_decl, size, unsigned) 39 40 def test_fixedsize_int(self): 41 ffi = FFI(backend=self.Backend()) 42 for size in [1, 2, 4, 8]: 43 self._test_int_type(ffi, 'int%d_t' % (8*size), size, False) 44 self._test_int_type(ffi, 'uint%d_t' % (8*size), size, True) 45 self._test_int_type(ffi, 'intptr_t', SIZE_OF_PTR, False) 46 self._test_int_type(ffi, 'uintptr_t', SIZE_OF_PTR, True) 47 self._test_int_type(ffi, 'ptrdiff_t', SIZE_OF_PTR, False) 48 self._test_int_type(ffi, 'size_t', SIZE_OF_PTR, True) 49 self._test_int_type(ffi, 'ssize_t', SIZE_OF_PTR, False) 50 51 def _test_int_type(self, ffi, c_decl, size, unsigned): 52 if unsigned: 53 min = 0 54 max = (1 << (8*size)) - 1 55 else: 56 min = -(1 << (8*size-1)) 57 max = (1 << (8*size-1)) - 1 58 min = int(min) 59 max = int(max) 60 p = ffi.cast(c_decl, min) 61 assert p == min 62 assert hash(p) == hash(min) 63 assert bool(p) is bool(min) 64 assert int(p) == min 65 p = ffi.cast(c_decl, max) 66 assert int(p) == max 67 p = ffi.cast(c_decl, long(max)) 68 assert int(p) == max 69 q = ffi.cast(c_decl, min - 1) 70 assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max 71 q = ffi.cast(c_decl, long(min - 1)) 72 assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max 73 assert q == p 74 assert int(q) == int(p) 75 assert hash(q) == hash(p) 76 c_decl_ptr = '%s *' % c_decl 77 py.test.raises(OverflowError, ffi.new, c_decl_ptr, min - 1) 78 py.test.raises(OverflowError, ffi.new, c_decl_ptr, max + 1) 79 py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(min - 1)) 80 py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(max + 1)) 81 assert ffi.new(c_decl_ptr, min)[0] == min 82 assert ffi.new(c_decl_ptr, max)[0] == max 83 assert ffi.new(c_decl_ptr, long(min))[0] == min 84 assert ffi.new(c_decl_ptr, long(max))[0] == max 85 86 def test_new_unsupported_type(self): 87 ffi = FFI(backend=self.Backend()) 88 e = py.test.raises(TypeError, ffi.new, "int") 89 assert str(e.value) == "expected a pointer or array ctype, got 'int'" 90 91 def test_new_single_integer(self): 92 ffi = FFI(backend=self.Backend()) 93 p = ffi.new("int *") # similar to ffi.new("int[1]") 94 assert p[0] == 0 95 p[0] = -123 96 assert p[0] == -123 97 p = ffi.new("int *", -42) 98 assert p[0] == -42 99 assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT 100 101 def test_new_array_no_arg(self): 102 ffi = FFI(backend=self.Backend()) 103 p = ffi.new("int[10]") 104 # the object was zero-initialized: 105 for i in range(10): 106 assert p[i] == 0 107 108 def test_array_indexing(self): 109 ffi = FFI(backend=self.Backend()) 110 p = ffi.new("int[10]") 111 p[0] = 42 112 p[9] = 43 113 assert p[0] == 42 114 assert p[9] == 43 115 py.test.raises(IndexError, "p[10]") 116 py.test.raises(IndexError, "p[10] = 44") 117 py.test.raises(IndexError, "p[-1]") 118 py.test.raises(IndexError, "p[-1] = 44") 119 120 def test_new_array_args(self): 121 ffi = FFI(backend=self.Backend()) 122 # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" 123 # then here we must enclose the items in a list 124 p = ffi.new("int[5]", [10, 20, 30, 40, 50]) 125 assert p[0] == 10 126 assert p[1] == 20 127 assert p[2] == 30 128 assert p[3] == 40 129 assert p[4] == 50 130 p = ffi.new("int[4]", [25]) 131 assert p[0] == 25 132 assert p[1] == 0 # follow C convention rather than LuaJIT's 133 assert p[2] == 0 134 assert p[3] == 0 135 p = ffi.new("int[4]", [ffi.cast("int", -5)]) 136 assert p[0] == -5 137 assert repr(p) == "<cdata 'int[4]' owning %d bytes>" % (4*SIZE_OF_INT) 138 139 def test_new_array_varsize(self): 140 ffi = FFI(backend=self.Backend()) 141 p = ffi.new("int[]", 10) # a single integer is the length 142 assert p[9] == 0 143 py.test.raises(IndexError, "p[10]") 144 # 145 py.test.raises(TypeError, ffi.new, "int[]") 146 # 147 p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C 148 assert p[0] == -6 149 assert p[1] == -7 150 py.test.raises(IndexError, "p[2]") 151 assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT) 152 # 153 p = ffi.new("int[]", 0) 154 py.test.raises(IndexError, "p[0]") 155 py.test.raises(ValueError, ffi.new, "int[]", -1) 156 assert repr(p) == "<cdata 'int[]' owning 0 bytes>" 157 158 def test_pointer_init(self): 159 ffi = FFI(backend=self.Backend()) 160 n = ffi.new("int *", 24) 161 a = ffi.new("int *[10]", [ffi.NULL, ffi.NULL, n, n, ffi.NULL]) 162 for i in range(10): 163 if i not in (2, 3): 164 assert a[i] == ffi.NULL 165 assert a[2] == a[3] == n 166 167 def test_cannot_cast(self): 168 ffi = FFI(backend=self.Backend()) 169 a = ffi.new("short int[10]") 170 e = py.test.raises(TypeError, ffi.new, "long int **", a) 171 msg = str(e.value) 172 assert "'short[10]'" in msg and "'long *'" in msg 173 174 def test_new_pointer_to_array(self): 175 ffi = FFI(backend=self.Backend()) 176 a = ffi.new("int[4]", [100, 102, 104, 106]) 177 p = ffi.new("int **", a) 178 assert p[0] == ffi.cast("int *", a) 179 assert p[0][2] == 104 180 p = ffi.cast("int *", a) 181 assert p[0] == 100 182 assert p[1] == 102 183 assert p[2] == 104 184 assert p[3] == 106 185 # keepalive: a 186 187 def test_pointer_direct(self): 188 ffi = FFI(backend=self.Backend()) 189 p = ffi.cast("int*", 0) 190 assert p is not None 191 assert bool(p) is False 192 assert p == ffi.cast("int*", 0) 193 assert p != None 194 assert repr(p) == "<cdata 'int *' NULL>" 195 a = ffi.new("int[]", [123, 456]) 196 p = ffi.cast("int*", a) 197 assert bool(p) is True 198 assert p == ffi.cast("int*", a) 199 assert p != ffi.cast("int*", 0) 200 assert p[0] == 123 201 assert p[1] == 456 202 203 def test_repr(self): 204 typerepr = self.TypeRepr 205 ffi = FFI(backend=self.Backend()) 206 ffi.cdef("struct foo { short a, b, c; };") 207 p = ffi.cast("short unsigned int", 0) 208 assert repr(p) == "<cdata 'unsigned short' 0>" 209 assert repr(ffi.typeof(p)) == typerepr % "unsigned short" 210 p = ffi.cast("unsigned short int", 0) 211 assert repr(p) == "<cdata 'unsigned short' 0>" 212 assert repr(ffi.typeof(p)) == typerepr % "unsigned short" 213 p = ffi.cast("int*", 0) 214 assert repr(p) == "<cdata 'int *' NULL>" 215 assert repr(ffi.typeof(p)) == typerepr % "int *" 216 # 217 p = ffi.new("int*") 218 assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT 219 assert repr(ffi.typeof(p)) == typerepr % "int *" 220 p = ffi.new("int**") 221 assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR 222 assert repr(ffi.typeof(p)) == typerepr % "int * *" 223 p = ffi.new("int [2]") 224 assert repr(p) == "<cdata 'int[2]' owning %d bytes>" % (2*SIZE_OF_INT) 225 assert repr(ffi.typeof(p)) == typerepr % "int[2]" 226 p = ffi.new("int*[2][3]") 227 assert repr(p) == "<cdata 'int *[2][3]' owning %d bytes>" % ( 228 6*SIZE_OF_PTR) 229 assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]" 230 p = ffi.new("struct foo *") 231 assert repr(p) == "<cdata 'struct foo *' owning %d bytes>" % ( 232 3*SIZE_OF_SHORT) 233 assert repr(ffi.typeof(p)) == typerepr % "struct foo *" 234 # 235 q = ffi.cast("short", -123) 236 assert repr(q) == "<cdata 'short' -123>" 237 assert repr(ffi.typeof(q)) == typerepr % "short" 238 p = ffi.new("int*") 239 q = ffi.cast("short*", p) 240 assert repr(q).startswith("<cdata 'short *' 0x") 241 assert repr(ffi.typeof(q)) == typerepr % "short *" 242 p = ffi.new("int [2]") 243 q = ffi.cast("int*", p) 244 assert repr(q).startswith("<cdata 'int *' 0x") 245 assert repr(ffi.typeof(q)) == typerepr % "int *" 246 p = ffi.new("struct foo*") 247 q = ffi.cast("struct foo *", p) 248 assert repr(q).startswith("<cdata 'struct foo *' 0x") 249 assert repr(ffi.typeof(q)) == typerepr % "struct foo *" 250 prevrepr = repr(q) 251 q = q[0] 252 assert repr(q) == prevrepr.replace(' *', ' &') 253 assert repr(ffi.typeof(q)) == typerepr % "struct foo" 254 255 def test_new_array_of_array(self): 256 ffi = FFI(backend=self.Backend()) 257 p = ffi.new("int[3][4]") 258 p[0][0] = 10 259 p[2][3] = 33 260 assert p[0][0] == 10 261 assert p[2][3] == 33 262 py.test.raises(IndexError, "p[1][-1]") 263 264 def test_constructor_array_of_array(self): 265 ffi = FFI(backend=self.Backend()) 266 p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) 267 assert p[2][1] == 15 268 269 def test_new_array_of_pointer_1(self): 270 ffi = FFI(backend=self.Backend()) 271 n = ffi.new("int*", 99) 272 p = ffi.new("int*[4]") 273 p[3] = n 274 a = p[3] 275 assert repr(a).startswith("<cdata 'int *' 0x") 276 assert a[0] == 99 277 278 def test_new_array_of_pointer_2(self): 279 ffi = FFI(backend=self.Backend()) 280 n = ffi.new("int[1]", [99]) 281 p = ffi.new("int*[4]") 282 p[3] = n 283 a = p[3] 284 assert repr(a).startswith("<cdata 'int *' 0x") 285 assert a[0] == 99 286 287 def test_char(self): 288 ffi = FFI(backend=self.Backend()) 289 assert ffi.new("char*", b"\xff")[0] == b'\xff' 290 assert ffi.new("char*")[0] == b'\x00' 291 assert int(ffi.cast("char", 300)) == 300 - 256 292 assert not bool(ffi.cast("char", 0)) 293 assert bool(ffi.cast("char", 1)) 294 assert bool(ffi.cast("char", 255)) 295 py.test.raises(TypeError, ffi.new, "char*", 32) 296 py.test.raises(TypeError, ffi.new, "char*", u+"x") 297 py.test.raises(TypeError, ffi.new, "char*", b"foo") 298 # 299 p = ffi.new("char[]", [b'a', b'b', b'\x9c']) 300 assert len(p) == 3 301 assert p[0] == b'a' 302 assert p[1] == b'b' 303 assert p[2] == b'\x9c' 304 p[0] = b'\xff' 305 assert p[0] == b'\xff' 306 p = ffi.new("char[]", b"abcd") 307 assert len(p) == 5 308 assert p[4] == b'\x00' # like in C, with: char[] p = "abcd"; 309 # 310 p = ffi.new("char[4]", b"ab") 311 assert len(p) == 4 312 assert [p[i] for i in range(4)] == [b'a', b'b', b'\x00', b'\x00'] 313 p = ffi.new("char[2]", b"ab") 314 assert len(p) == 2 315 assert [p[i] for i in range(2)] == [b'a', b'b'] 316 py.test.raises(IndexError, ffi.new, "char[2]", b"abc") 317 318 def check_wchar_t(self, ffi): 319 try: 320 ffi.cast("wchar_t", 0) 321 except NotImplementedError: 322 py.test.skip("NotImplementedError: wchar_t") 323 324 def test_wchar_t(self): 325 ffi = FFI(backend=self.Backend()) 326 self.check_wchar_t(ffi) 327 assert ffi.new("wchar_t*", u+'x')[0] == u+'x' 328 assert ffi.new("wchar_t*", u+'\u1234')[0] == u+'\u1234' 329 if SIZE_OF_WCHAR > 2: 330 assert ffi.new("wchar_t*", u+'\U00012345')[0] == u+'\U00012345' 331 else: 332 py.test.raises(TypeError, ffi.new, "wchar_t*", u+'\U00012345') 333 assert ffi.new("wchar_t*")[0] == u+'\x00' 334 assert int(ffi.cast("wchar_t", 300)) == 300 335 assert not bool(ffi.cast("wchar_t", 0)) 336 assert bool(ffi.cast("wchar_t", 1)) 337 assert bool(ffi.cast("wchar_t", 65535)) 338 if SIZE_OF_WCHAR > 2: 339 assert bool(ffi.cast("wchar_t", 65536)) 340 py.test.raises(TypeError, ffi.new, "wchar_t*", 32) 341 py.test.raises(TypeError, ffi.new, "wchar_t*", "foo") 342 # 343 p = ffi.new("wchar_t[]", [u+'a', u+'b', u+'\u1234']) 344 assert len(p) == 3 345 assert p[0] == u+'a' 346 assert p[1] == u+'b' and type(p[1]) is unicode 347 assert p[2] == u+'\u1234' 348 p[0] = u+'x' 349 assert p[0] == u+'x' and type(p[0]) is unicode 350 p[1] = u+'\u1357' 351 assert p[1] == u+'\u1357' 352 p = ffi.new("wchar_t[]", u+"abcd") 353 assert len(p) == 5 354 assert p[4] == u+'\x00' 355 p = ffi.new("wchar_t[]", u+"a\u1234b") 356 assert len(p) == 4 357 assert p[1] == u+'\u1234' 358 # 359 p = ffi.new("wchar_t[]", u+'\U00023456') 360 if SIZE_OF_WCHAR == 2: 361 assert len(p) == 3 362 assert p[0] == u+'\ud84d' 363 assert p[1] == u+'\udc56' 364 assert p[2] == u+'\x00' 365 else: 366 assert len(p) == 2 367 assert p[0] == u+'\U00023456' 368 assert p[1] == u+'\x00' 369 # 370 p = ffi.new("wchar_t[4]", u+"ab") 371 assert len(p) == 4 372 assert [p[i] for i in range(4)] == [u+'a', u+'b', u+'\x00', u+'\x00'] 373 p = ffi.new("wchar_t[2]", u+"ab") 374 assert len(p) == 2 375 assert [p[i] for i in range(2)] == [u+'a', u+'b'] 376 py.test.raises(IndexError, ffi.new, "wchar_t[2]", u+"abc") 377 378 def test_none_as_null_doesnt_work(self): 379 ffi = FFI(backend=self.Backend()) 380 p = ffi.new("int*[1]") 381 assert p[0] is not None 382 assert p[0] != None 383 assert p[0] == ffi.NULL 384 assert repr(p[0]) == "<cdata 'int *' NULL>" 385 # 386 n = ffi.new("int*", 99) 387 p = ffi.new("int*[]", [n]) 388 assert p[0][0] == 99 389 py.test.raises(TypeError, "p[0] = None") 390 p[0] = ffi.NULL 391 assert p[0] == ffi.NULL 392 393 def test_float(self): 394 ffi = FFI(backend=self.Backend()) 395 p = ffi.new("float[]", [-2, -2.5]) 396 assert p[0] == -2.0 397 assert p[1] == -2.5 398 p[1] += 17.75 399 assert p[1] == 15.25 400 # 401 p = ffi.new("float*", 15.75) 402 assert p[0] == 15.75 403 py.test.raises(TypeError, int, p) 404 py.test.raises(TypeError, float, p) 405 p[0] = 0.0 406 assert bool(p) is True 407 # 408 p = ffi.new("float*", 1.1) 409 f = p[0] 410 assert f != 1.1 # because of rounding effect 411 assert abs(f - 1.1) < 1E-7 412 # 413 INF = 1E200 * 1E200 414 assert 1E200 != INF 415 p[0] = 1E200 416 assert p[0] == INF # infinite, not enough precision 417 418 def test_struct_simple(self): 419 ffi = FFI(backend=self.Backend()) 420 ffi.cdef("struct foo { int a; short b, c; };") 421 s = ffi.new("struct foo*") 422 assert s.a == s.b == s.c == 0 423 s.b = -23 424 assert s.b == -23 425 py.test.raises(OverflowError, "s.b = 32768") 426 # 427 s = ffi.new("struct foo*", [-2, -3]) 428 assert s.a == -2 429 assert s.b == -3 430 assert s.c == 0 431 py.test.raises((AttributeError, TypeError), "del s.a") 432 assert repr(s) == "<cdata 'struct foo *' owning %d bytes>" % ( 433 SIZE_OF_INT + 2 * SIZE_OF_SHORT) 434 # 435 py.test.raises(ValueError, ffi.new, "struct foo*", [1, 2, 3, 4]) 436 437 def test_constructor_struct_from_dict(self): 438 ffi = FFI(backend=self.Backend()) 439 ffi.cdef("struct foo { int a; short b, c; };") 440 s = ffi.new("struct foo*", {'b': 123, 'c': 456}) 441 assert s.a == 0 442 assert s.b == 123 443 assert s.c == 456 444 py.test.raises(KeyError, ffi.new, "struct foo*", {'d': 456}) 445 446 def test_struct_pointer(self): 447 ffi = FFI(backend=self.Backend()) 448 ffi.cdef("struct foo { int a; short b, c; };") 449 s = ffi.new("struct foo*") 450 assert s[0].a == s[0].b == s[0].c == 0 451 s[0].b = -23 452 assert s[0].b == s.b == -23 453 py.test.raises(OverflowError, "s[0].b = -32769") 454 py.test.raises(IndexError, "s[1]") 455 456 def test_struct_opaque(self): 457 ffi = FFI(backend=self.Backend()) 458 py.test.raises(TypeError, ffi.new, "struct baz*") 459 p = ffi.new("struct baz **") # this works 460 assert p[0] == ffi.NULL 461 462 def test_pointer_to_struct(self): 463 ffi = FFI(backend=self.Backend()) 464 ffi.cdef("struct foo { int a; short b, c; };") 465 s = ffi.new("struct foo *") 466 s.a = -42 467 assert s[0].a == -42 468 p = ffi.new("struct foo **", s) 469 assert p[0].a == -42 470 assert p[0][0].a == -42 471 p[0].a = -43 472 assert s.a == -43 473 assert s[0].a == -43 474 p[0][0].a = -44 475 assert s.a == -44 476 assert s[0].a == -44 477 s.a = -45 478 assert p[0].a == -45 479 assert p[0][0].a == -45 480 s[0].a = -46 481 assert p[0].a == -46 482 assert p[0][0].a == -46 483 484 def test_constructor_struct_of_array(self): 485 ffi = FFI(backend=self.Backend()) 486 ffi.cdef("struct foo { int a[2]; char b[3]; };") 487 s = ffi.new("struct foo *", [[10, 11], [b'a', b'b', b'c']]) 488 assert s.a[1] == 11 489 assert s.b[2] == b'c' 490 s.b[1] = b'X' 491 assert s.b[0] == b'a' 492 assert s.b[1] == b'X' 493 assert s.b[2] == b'c' 494 495 def test_recursive_struct(self): 496 ffi = FFI(backend=self.Backend()) 497 ffi.cdef("struct foo { int value; struct foo *next; };") 498 s = ffi.new("struct foo*") 499 t = ffi.new("struct foo*") 500 s.value = 123 501 s.next = t 502 t.value = 456 503 assert s.value == 123 504 assert s.next.value == 456 505 506 def test_union_simple(self): 507 ffi = FFI(backend=self.Backend()) 508 ffi.cdef("union foo { int a; short b, c; };") 509 u = ffi.new("union foo*") 510 assert u.a == u.b == u.c == 0 511 u.b = -23 512 assert u.b == -23 513 assert u.a != 0 514 py.test.raises(OverflowError, "u.b = 32768") 515 # 516 u = ffi.new("union foo*", [-2]) 517 assert u.a == -2 518 py.test.raises((AttributeError, TypeError), "del u.a") 519 assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT 520 521 def test_union_opaque(self): 522 ffi = FFI(backend=self.Backend()) 523 py.test.raises(TypeError, ffi.new, "union baz *") 524 u = ffi.new("union baz **") # this works 525 assert u[0] == ffi.NULL 526 527 def test_union_initializer(self): 528 ffi = FFI(backend=self.Backend()) 529 ffi.cdef("union foo { char a; int b; };") 530 py.test.raises(TypeError, ffi.new, "union foo*", b'A') 531 py.test.raises(TypeError, ffi.new, "union foo*", 5) 532 py.test.raises(ValueError, ffi.new, "union foo*", [b'A', 5]) 533 u = ffi.new("union foo*", [b'A']) 534 assert u.a == b'A' 535 py.test.raises(TypeError, ffi.new, "union foo*", [1005]) 536 u = ffi.new("union foo*", {'b': 12345}) 537 assert u.b == 12345 538 u = ffi.new("union foo*", []) 539 assert u.a == b'\x00' 540 assert u.b == 0 541 542 def test_sizeof_type(self): 543 ffi = FFI(backend=self.Backend()) 544 ffi.cdef(""" 545 struct foo { int a; short b, c, d; }; 546 union foo { int a; short b, c, d; }; 547 """) 548 for c_type, expected_size in [ 549 ('char', 1), 550 ('unsigned int', 4), 551 ('char *', SIZE_OF_PTR), 552 ('int[5]', 20), 553 ('struct foo', 12), 554 ('union foo', 4), 555 ]: 556 size = ffi.sizeof(c_type) 557 assert size == expected_size, (size, expected_size, ctype) 558 559 def test_sizeof_cdata(self): 560 ffi = FFI(backend=self.Backend()) 561 assert ffi.sizeof(ffi.new("short*")) == SIZE_OF_PTR 562 assert ffi.sizeof(ffi.cast("short", 123)) == SIZE_OF_SHORT 563 # 564 a = ffi.new("int[]", [10, 11, 12, 13, 14]) 565 assert len(a) == 5 566 assert ffi.sizeof(a) == 5 * SIZE_OF_INT 567 568 def test_string_from_char_pointer(self): 569 ffi = FFI(backend=self.Backend()) 570 x = ffi.new("char*", b"x") 571 assert str(x) == repr(x) 572 assert ffi.string(x) == b"x" 573 assert ffi.string(ffi.new("char*", b"\x00")) == b"" 574 py.test.raises(TypeError, ffi.new, "char*", unicode("foo")) 575 576 def test_unicode_from_wchar_pointer(self): 577 ffi = FFI(backend=self.Backend()) 578 self.check_wchar_t(ffi) 579 x = ffi.new("wchar_t*", u+"x") 580 assert unicode(x) == unicode(repr(x)) 581 assert ffi.string(x) == u+"x" 582 assert ffi.string(ffi.new("wchar_t*", u+"\x00")) == u+"" 583 584 def test_string_from_char_array(self): 585 ffi = FFI(backend=self.Backend()) 586 p = ffi.new("char[]", b"hello.") 587 p[5] = b'!' 588 assert ffi.string(p) == b"hello!" 589 p[6] = b'?' 590 assert ffi.string(p) == b"hello!?" 591 p[3] = b'\x00' 592 assert ffi.string(p) == b"hel" 593 assert ffi.string(p, 2) == b"he" 594 py.test.raises(IndexError, "p[7] = b'X'") 595 # 596 a = ffi.new("char[]", b"hello\x00world") 597 assert len(a) == 12 598 p = ffi.cast("char *", a) 599 assert ffi.string(p) == b'hello' 600 601 def test_string_from_wchar_array(self): 602 ffi = FFI(backend=self.Backend()) 603 self.check_wchar_t(ffi) 604 assert ffi.string(ffi.cast("wchar_t", "x")) == u+"x" 605 assert ffi.string(ffi.cast("wchar_t", u+"x")) == u+"x" 606 x = ffi.cast("wchar_t", "x") 607 assert str(x) == repr(x) 608 assert ffi.string(x) == u+"x" 609 # 610 p = ffi.new("wchar_t[]", u+"hello.") 611 p[5] = u+'!' 612 assert ffi.string(p) == u+"hello!" 613 p[6] = u+'\u04d2' 614 assert ffi.string(p) == u+"hello!\u04d2" 615 p[3] = u+'\x00' 616 assert ffi.string(p) == u+"hel" 617 assert ffi.string(p, 123) == u+"hel" 618 py.test.raises(IndexError, "p[7] = u+'X'") 619 # 620 a = ffi.new("wchar_t[]", u+"hello\x00world") 621 assert len(a) == 12 622 p = ffi.cast("wchar_t *", a) 623 assert ffi.string(p) == u+'hello' 624 assert ffi.string(p, 123) == u+'hello' 625 assert ffi.string(p, 5) == u+'hello' 626 assert ffi.string(p, 2) == u+'he' 627 628 def test_fetch_const_char_p_field(self): 629 # 'const' is ignored so far 630 ffi = FFI(backend=self.Backend()) 631 ffi.cdef("struct foo { const char *name; };") 632 t = ffi.new("const char[]", b"testing") 633 s = ffi.new("struct foo*", [t]) 634 assert type(s.name) not in (bytes, str, unicode) 635 assert ffi.string(s.name) == b"testing" 636 py.test.raises(TypeError, "s.name = None") 637 s.name = ffi.NULL 638 assert s.name == ffi.NULL 639 640 def test_fetch_const_wchar_p_field(self): 641 # 'const' is ignored so far 642 ffi = FFI(backend=self.Backend()) 643 self.check_wchar_t(ffi) 644 ffi.cdef("struct foo { const wchar_t *name; };") 645 t = ffi.new("const wchar_t[]", u+"testing") 646 s = ffi.new("struct foo*", [t]) 647 assert type(s.name) not in (bytes, str, unicode) 648 assert ffi.string(s.name) == u+"testing" 649 s.name = ffi.NULL 650 assert s.name == ffi.NULL 651 652 def test_voidp(self): 653 ffi = FFI(backend=self.Backend()) 654 py.test.raises(TypeError, ffi.new, "void*") 655 p = ffi.new("void **") 656 assert p[0] == ffi.NULL 657 a = ffi.new("int[]", [10, 11, 12]) 658 p = ffi.new("void **", a) 659 vp = p[0] 660 py.test.raises(TypeError, "vp[0]") 661 py.test.raises(TypeError, ffi.new, "short **", a) 662 # 663 ffi.cdef("struct foo { void *p; int *q; short *r; };") 664 s = ffi.new("struct foo *") 665 s.p = a # works 666 s.q = a # works 667 py.test.raises(TypeError, "s.r = a") # fails 668 b = ffi.cast("int *", a) 669 s.p = b # works 670 s.q = b # works 671 py.test.raises(TypeError, "s.r = b") # fails 672 673 def test_functionptr_simple(self): 674 ffi = FFI(backend=self.Backend()) 675 py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) 676 def cb(n): 677 return n + 1 678 cb.__qualname__ = 'cb' 679 p = ffi.callback("int(*)(int)", cb) 680 res = p(41) # calling an 'int(*)(int)', i.e. a function pointer 681 assert res == 42 and type(res) is int 682 res = p(ffi.cast("int", -41)) 683 assert res == -40 and type(res) is int 684 assert repr(p).startswith( 685 "<cdata 'int(*)(int)' calling <function cb at 0x") 686 assert ffi.typeof(p) is ffi.typeof("int(*)(int)") 687 q = ffi.new("int(**)(int)", p) 688 assert repr(q) == "<cdata 'int(* *)(int)' owning %d bytes>" % ( 689 SIZE_OF_PTR) 690 py.test.raises(TypeError, "q(43)") 691 res = q[0](43) 692 assert res == 44 693 q = ffi.cast("int(*)(int)", p) 694 assert repr(q).startswith("<cdata 'int(*)(int)' 0x") 695 res = q(45) 696 assert res == 46 697 698 def test_functionptr_advanced(self): 699 ffi = FFI(backend=self.Backend()) 700 t = ffi.typeof("int(*(*)(int))(int)") 701 assert repr(t) == self.TypeRepr % "int(*(*)(int))(int)" 702 703 def test_functionptr_voidptr_return(self): 704 ffi = FFI(backend=self.Backend()) 705 def cb(): 706 return ffi.NULL 707 p = ffi.callback("void*(*)()", cb) 708 res = p() 709 assert res is not None 710 assert res == ffi.NULL 711 int_ptr = ffi.new('int*') 712 void_ptr = ffi.cast('void*', int_ptr) 713 def cb(): 714 return void_ptr 715 p = ffi.callback("void*(*)()", cb) 716 res = p() 717 assert res == void_ptr 718 719 def test_functionptr_intptr_return(self): 720 ffi = FFI(backend=self.Backend()) 721 def cb(): 722 return ffi.NULL 723 p = ffi.callback("int*(*)()", cb) 724 res = p() 725 assert res == ffi.NULL 726 int_ptr = ffi.new('int*') 727 def cb(): 728 return int_ptr 729 p = ffi.callback("int*(*)()", cb) 730 res = p() 731 assert repr(res).startswith("<cdata 'int *' 0x") 732 assert res == int_ptr 733 int_array_ptr = ffi.new('int[1]') 734 def cb(): 735 return int_array_ptr 736 p = ffi.callback("int*(*)()", cb) 737 res = p() 738 assert repr(res).startswith("<cdata 'int *' 0x") 739 assert res == int_array_ptr 740 741 def test_functionptr_void_return(self): 742 ffi = FFI(backend=self.Backend()) 743 def foo(): 744 pass 745 foo_cb = ffi.callback("void foo()", foo) 746 result = foo_cb() 747 assert result is None 748 749 def test_char_cast(self): 750 ffi = FFI(backend=self.Backend()) 751 p = ffi.cast("int", b'\x01') 752 assert ffi.typeof(p) is ffi.typeof("int") 753 assert int(p) == 1 754 p = ffi.cast("int", ffi.cast("char", b"a")) 755 assert int(p) == ord("a") 756 p = ffi.cast("int", ffi.cast("char", b"\x80")) 757 assert int(p) == 0x80 # "char" is considered unsigned in this case 758 p = ffi.cast("int", b"\x81") 759 assert int(p) == 0x81 760 761 def test_wchar_cast(self): 762 ffi = FFI(backend=self.Backend()) 763 self.check_wchar_t(ffi) 764 p = ffi.cast("int", ffi.cast("wchar_t", u+'\u1234')) 765 assert int(p) == 0x1234 766 p = ffi.cast("long long", ffi.cast("wchar_t", -1)) 767 if SIZE_OF_WCHAR == 2: # 2 bytes, unsigned 768 assert int(p) == 0xffff 769 elif (sys.platform.startswith('linux') and 770 platform.machine().startswith('x86')): # known to be signed 771 assert int(p) == -1 772 else: # in general, it can be either signed or not 773 assert int(p) in [-1, 0xffffffff] # e.g. on arm, both cases occur 774 p = ffi.cast("int", u+'\u1234') 775 assert int(p) == 0x1234 776 777 def test_cast_array_to_charp(self): 778 ffi = FFI(backend=self.Backend()) 779 a = ffi.new("short int[]", [0x1234, 0x5678]) 780 p = ffi.cast("char*", a) 781 data = b''.join([p[i] for i in range(4)]) 782 if sys.byteorder == 'little': 783 assert data == b'\x34\x12\x78\x56' 784 else: 785 assert data == b'\x12\x34\x56\x78' 786 787 def test_cast_between_pointers(self): 788 ffi = FFI(backend=self.Backend()) 789 a = ffi.new("short int[]", [0x1234, 0x5678]) 790 p = ffi.cast("short*", a) 791 p2 = ffi.cast("int*", p) 792 q = ffi.cast("char*", p2) 793 data = b''.join([q[i] for i in range(4)]) 794 if sys.byteorder == 'little': 795 assert data == b'\x34\x12\x78\x56' 796 else: 797 assert data == b'\x12\x34\x56\x78' 798 799 def test_cast_pointer_and_int(self): 800 ffi = FFI(backend=self.Backend()) 801 a = ffi.new("short int[]", [0x1234, 0x5678]) 802 l1 = ffi.cast("intptr_t", a) 803 p = ffi.cast("short*", a) 804 l2 = ffi.cast("intptr_t", p) 805 assert int(l1) == int(l2) != 0 806 q = ffi.cast("short*", l1) 807 assert q == ffi.cast("short*", int(l1)) 808 assert q[0] == 0x1234 809 assert int(ffi.cast("intptr_t", ffi.NULL)) == 0 810 811 def test_cast_functionptr_and_int(self): 812 ffi = FFI(backend=self.Backend()) 813 def cb(n): 814 return n + 1 815 a = ffi.callback("int(*)(int)", cb) 816 p = ffi.cast("void *", a) 817 assert p 818 b = ffi.cast("int(*)(int)", p) 819 assert b(41) == 42 820 assert a == b 821 assert hash(a) == hash(b) 822 823 def test_callback_crash(self): 824 ffi = FFI(backend=self.Backend()) 825 def cb(n): 826 raise Exception 827 a = ffi.callback("int(*)(int)", cb, error=42) 828 res = a(1) # and the error reported to stderr 829 assert res == 42 830 831 def test_structptr_argument(self): 832 ffi = FFI(backend=self.Backend()) 833 ffi.cdef("struct foo_s { int a, b; };") 834 def cb(p): 835 return p[0].a * 1000 + p[0].b * 100 + p[1].a * 10 + p[1].b 836 a = ffi.callback("int(*)(struct foo_s[])", cb) 837 res = a([[5, 6], {'a': 7, 'b': 8}]) 838 assert res == 5678 839 res = a([[5], {'b': 8}]) 840 assert res == 5008 841 842 def test_array_argument_as_list(self): 843 ffi = FFI(backend=self.Backend()) 844 ffi.cdef("struct foo_s { int a, b; };") 845 seen = [] 846 def cb(argv): 847 seen.append(ffi.string(argv[0])) 848 seen.append(ffi.string(argv[1])) 849 a = ffi.callback("void(*)(char *[])", cb) 850 a([ffi.new("char[]", b"foobar"), ffi.new("char[]", b"baz")]) 851 assert seen == [b"foobar", b"baz"] 852 853 def test_cast_float(self): 854 ffi = FFI(backend=self.Backend()) 855 a = ffi.cast("float", 12) 856 assert float(a) == 12.0 857 a = ffi.cast("float", 12.5) 858 assert float(a) == 12.5 859 a = ffi.cast("float", b"A") 860 assert float(a) == ord("A") 861 a = ffi.cast("int", 12.9) 862 assert int(a) == 12 863 a = ffi.cast("char", 66.9 + 256) 864 assert ffi.string(a) == b"B" 865 # 866 a = ffi.cast("float", ffi.cast("int", 12)) 867 assert float(a) == 12.0 868 a = ffi.cast("float", ffi.cast("double", 12.5)) 869 assert float(a) == 12.5 870 a = ffi.cast("float", ffi.cast("char", b"A")) 871 assert float(a) == ord("A") 872 a = ffi.cast("int", ffi.cast("double", 12.9)) 873 assert int(a) == 12 874 a = ffi.cast("char", ffi.cast("double", 66.9 + 256)) 875 assert ffi.string(a) == b"B" 876 877 def test_enum(self): 878 ffi = FFI(backend=self.Backend()) 879 ffi.cdef("enum foo { A0, B0, CC0, D0 };") 880 assert ffi.string(ffi.cast("enum foo", 0)) == "A0" 881 assert ffi.string(ffi.cast("enum foo", 2)) == "CC0" 882 assert ffi.string(ffi.cast("enum foo", 3)) == "D0" 883 assert ffi.string(ffi.cast("enum foo", 4)) == "4" 884 ffi.cdef("enum bar { A1, B1=-2, CC1, D1, E1 };") 885 assert ffi.string(ffi.cast("enum bar", 0)) == "A1" 886 assert ffi.string(ffi.cast("enum bar", -2)) == "B1" 887 assert ffi.string(ffi.cast("enum bar", -1)) == "CC1" 888 assert ffi.string(ffi.cast("enum bar", 1)) == "E1" 889 assert ffi.cast("enum bar", -2) == ffi.cast("enum bar", -2) 890 assert ffi.cast("enum foo", 0) == ffi.cast("enum bar", 0) 891 assert ffi.cast("enum bar", 0) == ffi.cast("int", 0) 892 assert repr(ffi.cast("enum bar", -1)) == "<cdata 'enum bar' -1: CC1>" 893 assert repr(ffi.cast("enum foo", -1)) == ( # enums are unsigned, if 894 "<cdata 'enum foo' 4294967295>") # they contain no neg value 895 ffi.cdef("enum baz { A2=0x1000, B2=0x2000 };") 896 assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A2" 897 assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B2" 898 899 def test_enum_in_struct(self): 900 ffi = FFI(backend=self.Backend()) 901 ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };") 902 s = ffi.new("struct bar *") 903 s.e = 0 904 assert s.e == 0 905 s.e = 3 906 assert s.e == 3 907 assert s[0].e == 3 908 s[0].e = 2 909 assert s.e == 2 910 assert s[0].e == 2 911 s.e = ffi.cast("enum foo", -1) 912 assert s.e == 4294967295 913 assert s[0].e == 4294967295 914 s.e = s.e 915 py.test.raises(TypeError, "s.e = 'B'") 916 py.test.raises(TypeError, "s.e = '2'") 917 py.test.raises(TypeError, "s.e = '#2'") 918 py.test.raises(TypeError, "s.e = '#7'") 919 920 def test_enum_non_contiguous(self): 921 ffi = FFI(backend=self.Backend()) 922 ffi.cdef("enum foo { A, B=42, C };") 923 assert ffi.string(ffi.cast("enum foo", 0)) == "A" 924 assert ffi.string(ffi.cast("enum foo", 42)) == "B" 925 assert ffi.string(ffi.cast("enum foo", 43)) == "C" 926 invalid_value = ffi.cast("enum foo", 2) 927 assert int(invalid_value) == 2 928 assert ffi.string(invalid_value) == "2" 929 930 def test_enum_char_hex_oct(self): 931 ffi = FFI(backend=self.Backend()) 932 ffi.cdef(r"enum foo{A='!', B='\'', C=0x10, D=010, E=- 0x10, F=-010};") 933 assert ffi.string(ffi.cast("enum foo", ord('!'))) == "A" 934 assert ffi.string(ffi.cast("enum foo", ord("'"))) == "B" 935 assert ffi.string(ffi.cast("enum foo", 16)) == "C" 936 assert ffi.string(ffi.cast("enum foo", 8)) == "D" 937 assert ffi.string(ffi.cast("enum foo", -16)) == "E" 938 assert ffi.string(ffi.cast("enum foo", -8)) == "F" 939 940 def test_enum_partial(self): 941 ffi = FFI(backend=self.Backend()) 942 ffi.cdef(r"enum foo {A, ...}; enum bar { B, C };") 943 needs_dlopen_none() 944 lib = ffi.dlopen(None) 945 assert lib.B == 0 946 py.test.raises(VerificationMissing, getattr, lib, "A") 947 assert lib.C == 1 948 949 def test_array_of_struct(self): 950 ffi = FFI(backend=self.Backend()) 951 ffi.cdef("struct foo { int a, b; };") 952 s = ffi.new("struct foo[1]") 953 py.test.raises(AttributeError, 's.b') 954 py.test.raises(AttributeError, 's.b = 412') 955 s[0].b = 412 956 assert s[0].b == 412 957 py.test.raises(IndexError, 's[1]') 958 959 def test_pointer_to_array(self): 960 ffi = FFI(backend=self.Backend()) 961 p = ffi.new("int(**)[5]") 962 assert repr(p) == "<cdata 'int(* *)[5]' owning %d bytes>" % SIZE_OF_PTR 963 964 def test_iterate_array(self): 965 ffi = FFI(backend=self.Backend()) 966 a = ffi.new("char[]", b"hello") 967 assert list(a) == [b"h", b"e", b"l", b"l", b"o", b"\0"] 968 assert list(iter(a)) == [b"h", b"e", b"l", b"l", b"o", b"\0"] 969 # 970 py.test.raises(TypeError, iter, ffi.cast("char *", a)) 971 py.test.raises(TypeError, list, ffi.cast("char *", a)) 972 py.test.raises(TypeError, iter, ffi.new("int *")) 973 py.test.raises(TypeError, list, ffi.new("int *")) 974 975 def test_offsetof(self): 976 ffi = FFI(backend=self.Backend()) 977 ffi.cdef("struct foo { int a, b, c; };") 978 assert ffi.offsetof("struct foo", "a") == 0 979 assert ffi.offsetof("struct foo", "b") == 4 980 assert ffi.offsetof("struct foo", "c") == 8 981 982 def test_offsetof_nested(self): 983 ffi = FFI(backend=self.Backend()) 984 ffi.cdef("struct foo { int a, b, c; };" 985 "struct bar { struct foo d, e; };") 986 assert ffi.offsetof("struct bar", "e") == 12 987 py.test.raises(KeyError, ffi.offsetof, "struct bar", "e.a") 988 assert ffi.offsetof("struct bar", "e", "a") == 12 989 assert ffi.offsetof("struct bar", "e", "b") == 16 990 assert ffi.offsetof("struct bar", "e", "c") == 20 991 992 def test_offsetof_array(self): 993 ffi = FFI(backend=self.Backend()) 994 assert ffi.offsetof("int[]", 51) == 51 * ffi.sizeof("int") 995 assert ffi.offsetof("int *", 51) == 51 * ffi.sizeof("int") 996 ffi.cdef("struct bar { int a, b; int c[99]; };") 997 assert ffi.offsetof("struct bar", "c") == 2 * ffi.sizeof("int") 998 assert ffi.offsetof("struct bar", "c", 0) == 2 * ffi.sizeof("int") 999 assert ffi.offsetof("struct bar", "c", 51) == 53 * ffi.sizeof("int") 1000 1001 def test_alignof(self): 1002 ffi = FFI(backend=self.Backend()) 1003 ffi.cdef("struct foo { char a; short b; char c; };") 1004 assert ffi.alignof("int") == 4 1005 assert ffi.alignof("double") in (4, 8) 1006 assert ffi.alignof("struct foo") == 2 1007 1008 def test_bitfield(self): 1009 ffi = FFI(backend=self.Backend()) 1010 ffi.cdef("struct foo { int a:10, b:20, c:3; };") 1011 assert ffi.sizeof("struct foo") == 8 1012 s = ffi.new("struct foo *") 1013 s.a = 511 1014 py.test.raises(OverflowError, "s.a = 512") 1015 py.test.raises(OverflowError, "s[0].a = 512") 1016 assert s.a == 511 1017 s.a = -512 1018 py.test.raises(OverflowError, "s.a = -513") 1019 py.test.raises(OverflowError, "s[0].a = -513") 1020 assert s.a == -512 1021 s.c = 3 1022 assert s.c == 3 1023 py.test.raises(OverflowError, "s.c = 4") 1024 py.test.raises(OverflowError, "s[0].c = 4") 1025 s.c = -4 1026 assert s.c == -4 1027 1028 def test_bitfield_enum(self): 1029 ffi = FFI(backend=self.Backend()) 1030 ffi.cdef(""" 1031 typedef enum { AA, BB, CC } foo_e; 1032 typedef struct { foo_e f:2; } foo_s; 1033 """) 1034 s = ffi.new("foo_s *") 1035 s.f = 2 1036 assert s.f == 2 1037 1038 def test_anonymous_struct(self): 1039 ffi = FFI(backend=self.Backend()) 1040 ffi.cdef("typedef struct { int a; } foo_t;") 1041 ffi.cdef("typedef struct { char b, c; } bar_t;") 1042 f = ffi.new("foo_t *", [12345]) 1043 b = ffi.new("bar_t *", [b"B", b"C"]) 1044 assert f.a == 12345 1045 assert b.b == b"B" 1046 assert b.c == b"C" 1047 assert repr(b).startswith("<cdata 'bar_t *'") 1048 1049 def test_struct_with_two_usages(self): 1050 for name in ['foo_s', '']: # anonymous or not 1051 ffi = FFI(backend=self.Backend()) 1052 ffi.cdef("typedef struct %s { int a; } foo_t, *foo_p;" % name) 1053 f = ffi.new("foo_t *", [12345]) 1054 ps = ffi.new("foo_p[]", [f]) 1055 1056 def test_pointer_arithmetic(self): 1057 ffi = FFI(backend=self.Backend()) 1058 s = ffi.new("short[]", list(range(100, 110))) 1059 p = ffi.cast("short *", s) 1060 assert p[2] == 102 1061 assert p+1 == p+1 1062 assert p+1 != p+0 1063 assert p == p+0 == p-0 1064 assert (p+1)[0] == 101 1065 assert (p+19)[-10] == 109 1066 assert (p+5) - (p+1) == 4 1067 assert p == s+0 1068 assert p+1 == s+1 1069 1070 def test_pointer_comparison(self): 1071 ffi = FFI(backend=self.Backend()) 1072 s = ffi.new("short[]", list(range(100))) 1073 p = ffi.cast("short *", s) 1074 assert (p < s) is False 1075 assert (p <= s) is True 1076 assert (p == s) is True 1077 assert (p != s) is False 1078 assert (p > s) is False 1079 assert (p >= s) is True 1080 assert (s < p) is False 1081 assert (s <= p) is True 1082 assert (s == p) is True 1083 assert (s != p) is False 1084 assert (s > p) is False 1085 assert (s >= p) is True 1086 q = p + 1 1087 assert (q < s) is False 1088 assert (q <= s) is False 1089 assert (q == s) is False 1090 assert (q != s) is True 1091 assert (q > s) is True 1092 assert (q >= s) is True 1093 assert (s < q) is True 1094 assert (s <= q) is True 1095 assert (s == q) is False 1096 assert (s != q) is True 1097 assert (s > q) is False 1098 assert (s >= q) is False 1099 assert (q < p) is False 1100 assert (q <= p) is False 1101 assert (q == p) is False 1102 assert (q != p) is True 1103 assert (q > p) is True 1104 assert (q >= p) is True 1105 assert (p < q) is True 1106 assert (p <= q) is True 1107 assert (p == q) is False 1108 assert (p != q) is True 1109 assert (p > q) is False 1110 assert (p >= q) is False 1111 # 1112 assert (None == s) is False 1113 assert (None != s) is True 1114 assert (s == None) is False 1115 assert (s != None) is True 1116 assert (None == q) is False 1117 assert (None != q) is True 1118 assert (q == None) is False 1119 assert (q != None) is True 1120 1121 def test_integer_comparison(self): 1122 ffi = FFI(backend=self.Backend()) 1123 x = ffi.cast("int", 123) 1124 y = ffi.cast("int", 456) 1125 assert x < y 1126 # 1127 z = ffi.cast("double", 78.9) 1128 assert x > z 1129 assert y > z 1130 1131 def test_ffi_buffer_ptr(self): 1132 ffi = FFI(backend=self.Backend()) 1133 a = ffi.new("short *", 100) 1134 try: 1135 b = ffi.buffer(a) 1136 except NotImplementedError as e: 1137 py.test.skip(str(e)) 1138 assert type(b) is ffi.buffer 1139 content = b[:] 1140 assert len(content) == len(b) == 2 1141 if sys.byteorder == 'little': 1142 assert content == b'\x64\x00' 1143 assert b[0] == b'\x64' 1144 b[0] = b'\x65' 1145 else: 1146 assert content == b'\x00\x64' 1147 assert b[1] == b'\x64' 1148 b[1] = b'\x65' 1149 assert a[0] == 101 1150 1151 def test_ffi_buffer_array(self): 1152 ffi = FFI(backend=self.Backend()) 1153 a = ffi.new("int[]", list(range(100, 110))) 1154 try: 1155 b = ffi.buffer(a) 1156 except NotImplementedError as e: 1157 py.test.skip(str(e)) 1158 content = b[:] 1159 if sys.byteorder == 'little': 1160 assert content.startswith(b'\x64\x00\x00\x00\x65\x00\x00\x00') 1161 b[4] = b'\x45' 1162 else: 1163 assert content.startswith(b'\x00\x00\x00\x64\x00\x00\x00\x65') 1164 b[7] = b'\x45' 1165 assert len(content) == 4 * 10 1166 assert a[1] == 0x45 1167 1168 def test_ffi_buffer_ptr_size(self): 1169 ffi = FFI(backend=self.Backend()) 1170 a = ffi.new("short *", 0x4243) 1171 try: 1172 b = ffi.buffer(a, 1) 1173 except NotImplementedError as e: 1174 py.test.skip(str(e)) 1175 content = b[:] 1176 assert len(content) == 1 1177 if sys.byteorder == 'little': 1178 assert content == b'\x43' 1179 b[0] = b'\x62' 1180 assert a[0] == 0x4262 1181 else: 1182 assert content == b'\x42' 1183 b[0] = b'\x63' 1184 assert a[0] == 0x6343 1185 1186 def test_ffi_buffer_array_size(self): 1187 ffi = FFI(backend=self.Backend()) 1188 a1 = ffi.new("int[]", list(range(100, 110))) 1189 a2 = ffi.new("int[]", list(range(100, 115))) 1190 try: 1191 ffi.buffer(a1) 1192 except NotImplementedError as e: 1193 py.test.skip(str(e)) 1194 assert ffi.buffer(a1)[:] == ffi.buffer(a2, 4*10)[:] 1195 1196 def test_ffi_buffer_with_file(self): 1197 ffi = FFI(backend=self.Backend()) 1198 import tempfile, os, array 1199 fd, filename = tempfile.mkstemp() 1200 f = os.fdopen(fd, 'r+b') 1201 a = ffi.new("int[]", list(range(1005))) 1202 try: 1203 ffi.buffer(a, 512) 1204 except NotImplementedError as e: 1205 py.test.skip(str(e)) 1206 f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) 1207 f.seek(0) 1208 assert f.read() == array.array('i', range(1000)).tostring() 1209 f.seek(0) 1210 b = ffi.new("int[]", 1005) 1211 f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) 1212 assert list(a)[:1000] + [0] * (len(a)-1000) == list(b) 1213 f.close() 1214 os.unlink(filename) 1215 1216 def test_ffi_buffer_with_io(self): 1217 ffi = FFI(backend=self.Backend()) 1218 import io, array 1219 f = io.BytesIO() 1220 a = ffi.new("int[]", list(range(1005))) 1221 try: 1222 ffi.buffer(a, 512) 1223 except NotImplementedError as e: 1224 py.test.skip(str(e)) 1225 f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) 1226 f.seek(0) 1227 assert f.read() == array.array('i', range(1000)).tostring() 1228 f.seek(0) 1229 b = ffi.new("int[]", 1005) 1230 f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) 1231 assert list(a)[:1000] + [0] * (len(a)-1000) == list(b) 1232 f.close() 1233 1234 def test_ffi_buffer_comparisons(self): 1235 ffi = FFI(backend=self.Backend()) 1236 ba = bytearray(range(100, 110)) 1237 if sys.version_info >= (2, 7): 1238 assert ba == memoryview(ba) # justification for the following 1239 a = ffi.new("uint8_t[]", list(ba)) 1240 c = ffi.new("uint8_t[]", [99] + list(ba)) 1241 try: 1242 b_full = ffi.buffer(a) 1243 b_short = ffi.buffer(a, 3) 1244 b_mid = ffi.buffer(a, 6) 1245 b_other = ffi.buffer(c, 6) 1246 except NotImplementedError as e: 1247 py.test.skip(str(e)) 1248 else: 1249 content = b_full[:] 1250 assert content == b_full == ba 1251 assert b_other < b_short < b_mid < b_full 1252 assert ba > b_mid > ba[0:2] 1253 assert b_short != ba[1:4] 1254 1255 def test_array_in_struct(self): 1256 ffi = FFI(backend=self.Backend()) 1257 ffi.cdef("struct foo_s { int len; short data[5]; };") 1258 p = ffi.new("struct foo_s *") 1259 p.data[3] = 5 1260 assert p.data[3] == 5 1261 assert repr(p.data).startswith("<cdata 'short[5]' 0x") 1262 1263 def test_struct_containing_array_varsize_workaround(self): 1264 ffi = FFI(backend=self.Backend()) 1265 ffi.cdef("struct foo_s { int len; short data[0]; };") 1266 p = ffi.new("char[]", ffi.sizeof("struct foo_s") + 7 * SIZE_OF_SHORT) 1267 q = ffi.cast("struct foo_s *", p) 1268 assert q.len == 0 1269 # 'q.data' gets not a 'short[0]', but just a 'short *' instead 1270 assert repr(q.data).startswith("<cdata 'short *' 0x") 1271 assert q.data[6] == 0 1272 q.data[6] = 15 1273 assert q.data[6] == 15 1274 1275 def test_new_struct_containing_array_varsize(self): 1276 py.test.skip("later?") 1277 ffi = FFI(backend=self.Backend()) 1278 ffi.cdef("struct foo_s { int len; short data[]; };") 1279 p = ffi.new("struct foo_s *", 10) # a single integer is the length 1280 assert p.len == 0 1281 assert p.data[9] == 0 1282 py.test.raises(IndexError, "p.data[10]") 1283 1284 def test_ffi_typeof_getcname(self): 1285 ffi = FFI(backend=self.Backend()) 1286 assert ffi.getctype("int") == "int" 1287 assert ffi.getctype("int", 'x') == "int x" 1288 assert ffi.getctype("int*") == "int *" 1289 assert ffi.getctype("int*", '') == "int *" 1290 assert ffi.getctype("int*", 'x') == "int * x" 1291 assert ffi.getctype("int", '*') == "int *" 1292 assert ffi.getctype("int", ' * x ') == "int * x" 1293 assert ffi.getctype(ffi.typeof("int*"), '*') == "int * *" 1294 assert ffi.getctype("int", '[5]') == "int[5]" 1295 assert ffi.getctype("int[5]", '[6]') == "int[6][5]" 1296 assert ffi.getctype("int[5]", '(*)') == "int(*)[5]" 1297 # special-case for convenience: automatically put '()' around '*' 1298 assert ffi.getctype("int[5]", '*') == "int(*)[5]" 1299 assert ffi.getctype("int[5]", '*foo') == "int(*foo)[5]" 1300 assert ffi.getctype("int[5]", ' ** foo ') == "int(** foo)[5]" 1301 1302 def test_array_of_func_ptr(self): 1303 ffi = FFI(backend=self.Backend()) 1304 f = ffi.cast("int(*)(int)", 42) 1305 assert f != ffi.NULL 1306 py.test.raises(CDefError, ffi.cast, "int(int)", 42) 1307 py.test.raises(CDefError, ffi.new, "int([5])(int)") 1308 a = ffi.new("int(*[5])(int)", [f]) 1309 assert ffi.getctype(ffi.typeof(a)) == "int(*[5])(int)" 1310 assert len(a) == 5 1311 assert a[0] == f 1312 assert a[1] == ffi.NULL 1313 py.test.raises(TypeError, ffi.cast, "int(*)(int)[5]", 0) 1314 # 1315 def cb(n): 1316 return n + 1 1317 f = ffi.callback("int(*)(int)", cb) 1318 a = ffi.new("int(*[5])(int)", [f, f]) 1319 assert a[1](42) == 43 1320 1321 def test_callback_as_function_argument(self): 1322 # In C, function arguments can be declared with a function type, 1323 # which is automatically replaced with the ptr-to-function type. 1324 ffi = FFI(backend=self.Backend()) 1325 def cb(a, b): 1326 return chr(ord(a) + ord(b)).encode() 1327 f = ffi.callback("char cb(char, char)", cb) 1328 assert f(b'A', b'\x01') == b'B' 1329 def g(callback): 1330 return callback(b'A', b'\x01') 1331 g = ffi.callback("char g(char cb(char, char))", g) 1332 assert g(f) == b'B' 1333 1334 def test_vararg_callback(self): 1335 py.test.skip("callback with '...'") 1336 ffi = FFI(backend=self.Backend()) 1337 def cb(i, va_list): 1338 j = ffi.va_arg(va_list, "int") 1339 k = ffi.va_arg(va_list, "long long") 1340 return i * 2 + j * 3 + k * 5 1341 f = ffi.callback("long long cb(long i, ...)", cb) 1342 res = f(10, ffi.cast("int", 100), ffi.cast("long long", 1000)) 1343 assert res == 20 + 300 + 5000 1344 1345 def test_callback_decorator(self): 1346 ffi = FFI(backend=self.Backend()) 1347 # 1348 @ffi.callback("long(long, long)", error=42) 1349 def cb(a, b): 1350 return a - b 1351 # 1352 assert cb(-100, -10) == -90 1353 sz = ffi.sizeof("long") 1354 assert cb((1 << (sz*8-1)) - 1, -10) == 42 1355 1356 def test_unique_types(self): 1357 ffi1 = FFI(backend=self.Backend()) 1358 ffi2 = FFI(backend=self.Backend()) 1359 assert ffi1.typeof("char") is ffi2.typeof("char ") 1360 assert ffi1.typeof("long") is ffi2.typeof("signed long int") 1361 assert ffi1.typeof("double *") is ffi2.typeof("double*") 1362 assert ffi1.typeof("int ***") is ffi2.typeof(" int * * *") 1363 assert ffi1.typeof("int[]") is ffi2.typeof("signed int[]") 1364 assert ffi1.typeof("signed int*[17]") is ffi2.typeof("int *[17]") 1365 assert ffi1.typeof("void") is ffi2.typeof("void") 1366 assert ffi1.typeof("int(*)(int,int)") is ffi2.typeof("int(*)(int,int)") 1367 # 1368 # these depend on user-defined data, so should not be shared 1369 assert ffi1.typeof("struct foo") is not ffi2.typeof("struct foo") 1370 assert ffi1.typeof("union foo *") is not ffi2.typeof("union foo*") 1371 # the following test is an opaque enum, which we no longer support 1372 #assert ffi1.typeof("enum foo") is not ffi2.typeof("enum foo") 1373 # sanity check: twice 'ffi1' 1374 assert ffi1.typeof("struct foo*") is ffi1.typeof("struct foo *") 1375 1376 def test_anonymous_enum(self): 1377 ffi = FFI(backend=self.Backend()) 1378 ffi.cdef("typedef enum { Value0 = 0 } e, *pe;\n" 1379 "typedef enum { Value1 = 1 } e1;") 1380 assert ffi.getctype("e*") == 'e *' 1381 assert ffi.getctype("pe") == 'e *' 1382 assert ffi.getctype("e1*") == 'e1 *' 1383 1384 def test_opaque_enum(self): 1385 import warnings 1386 ffi = FFI(backend=self.Backend()) 1387 ffi.cdef("enum foo;") 1388 with warnings.catch_warnings(record=True) as log: 1389 warnings.simplefilter("always") 1390 n = ffi.cast("enum foo", -1) 1391 assert int(n) == 0xffffffff 1392 assert str(log[0].message) == ( 1393 "'enum foo' has no values explicitly defined; " 1394 "guessing that it is equivalent to 'unsigned int'") 1395 1396 def test_new_ctype(self): 1397 ffi = FFI(backend=self.Backend()) 1398 p = ffi.new("int *") 1399 py.test.raises(TypeError, ffi.new, p) 1400 p = ffi.new(ffi.typeof("int *"), 42) 1401 assert p[0] == 42 1402 1403 def test_enum_with_non_injective_mapping(self): 1404 ffi = FFI(backend=self.Backend()) 1405 ffi.cdef("enum e { AA=0, BB=0, CC=0, DD=0 };") 1406 e = ffi.cast("enum e", 0) 1407 assert ffi.string(e) == "AA" # pick the first one arbitrarily 1408 1409 def test_enum_refer_previous_enum_value(self): 1410 ffi = FFI(backend=self.Backend()) 1411 ffi.cdef("enum e { AA, BB=2, CC=4, DD=BB, EE, FF=CC, GG=FF };") 1412 assert ffi.string(ffi.cast("enum e", 2)) == "BB" 1413 assert ffi.string(ffi.cast("enum e", 3)) == "EE" 1414 assert ffi.sizeof("char[DD]") == 2 1415 assert ffi.sizeof("char[EE]") == 3 1416 assert ffi.sizeof("char[FF]") == 4 1417 assert ffi.sizeof("char[GG]") == 4 1418 1419 def test_nested_anonymous_struct(self): 1420 ffi = FFI(backend=self.Backend()) 1421 ffi.cdef(""" 1422 struct foo_s { 1423 struct { int a, b; }; 1424 union { int c, d; }; 1425 }; 1426 """) 1427 assert ffi.sizeof("struct foo_s") == 3 * SIZE_OF_INT 1428 p = ffi.new("struct foo_s *", [1, 2, 3]) 1429 assert p.a == 1 1430 assert p.b == 2 1431 assert p.c == 3 1432 assert p.d == 3 1433 p.d = 17 1434 assert p.c == 17 1435 p.b = 19 1436 assert p.a == 1 1437 assert p.b == 19 1438 assert p.c == 17 1439 assert p.d == 17 1440 p = ffi.new("struct foo_s *", {'b': 12, 'd': 14}) 1441 assert p.a == 0 1442 assert p.b == 12 1443 assert p.c == 14 1444 assert p.d == 14 1445 py.test.raises(ValueError, ffi.new, "struct foo_s *", [0, 0, 0, 0]) 1446 1447 def test_nested_field_offset_align(self): 1448 ffi = FFI(backend=self.Backend()) 1449 ffi.cdef(""" 1450 struct foo_s { 1451 struct { int a; char b; }; 1452 union { char c; }; 1453 }; 1454 """) 1455 assert ffi.offsetof("struct foo_s", "c") == 2 * SIZE_OF_INT 1456 assert ffi.sizeof("struct foo_s") == 3 * SIZE_OF_INT 1457 1458 def test_nested_anonymous_union(self): 1459 ffi = FFI(backend=self.Backend()) 1460 ffi.cdef(""" 1461 union foo_u { 1462 struct { int a, b; }; 1463 union { int c, d; }; 1464 }; 1465 """) 1466 assert ffi.sizeof("union foo_u") == 2 * SIZE_OF_INT 1467 p = ffi.new("union foo_u *", [5]) 1468 assert p.a == 5 1469 assert p.b == 0 1470 assert p.c == 5 1471 assert p.d == 5 1472 p.d = 17 1473 assert p.c == 17 1474 assert p.a == 17 1475 p.b = 19 1476 assert p.a == 17 1477 assert p.b == 19 1478 assert p.c == 17 1479 assert p.d == 17 1480 p = ffi.new("union foo_u *", {'d': 14}) 1481 assert p.a == 14 1482 assert p.b == 0 1483 assert p.c == 14 1484 assert p.d == 14 1485 p = ffi.new("union foo_u *", {'a': -63, 'b': 12}) 1486 assert p.a == -63 1487 assert p.b == 12 1488 assert p.c == -63 1489 assert p.d == -63 1490 p = ffi.new("union foo_u *", [123, 456]) 1491 assert p.a == 123 1492 assert p.b == 456 1493 assert p.c == 123 1494 assert p.d == 123 1495 py.test.raises(ValueError, ffi.new, "union foo_u *", [0, 0, 0]) 1496 1497 def test_nested_anonymous_struct_2(self): 1498 ffi = FFI(backend=self.Backend()) 1499 ffi.cdef(""" 1500 struct foo_s { 1501 int a; 1502 union { int b; union { int c, d; }; }; 1503 int e; 1504 }; 1505 """) 1506 assert ffi.sizeof("struct foo_s") == 3 * SIZE_OF_INT 1507 p = ffi.new("struct foo_s *", [11, 22, 33]) 1508 assert p.a == 11 1509 assert p.b == p.c == p.d == 22 1510 assert p.e == 33 1511 py.test.raises(ValueError, ffi.new, "struct foo_s *", [11, 22, 33, 44]) 1512 FOO = ffi.typeof("struct foo_s") 1513 fields = [(name, fld.offset, fld.flags) for (name, fld) in FOO.fields] 1514 assert fields == [ 1515 ('a', 0 * SIZE_OF_INT, 0), 1516 ('b', 1 * SIZE_OF_INT, 0), 1517 ('c', 1 * SIZE_OF_INT, 1), 1518 ('d', 1 * SIZE_OF_INT, 1), 1519 ('e', 2 * SIZE_OF_INT, 0), 1520 ] 1521 1522 def test_cast_to_array_type(self): 1523 ffi = FFI(backend=self.Backend()) 1524 p = ffi.new("int[4]", [-5]) 1525 q = ffi.cast("int[3]", p) 1526 assert q[0] == -5 1527 assert repr(q).startswith("<cdata 'int[3]' 0x") 1528 1529 def test_gc(self): 1530 ffi = FFI(backend=self.Backend()) 1531 p = ffi.new("int *", 123) 1532 seen = [] 1533 def destructor(p1): 1534 assert p1 is p 1535 assert p1[0] == 123 1536 seen.append(1) 1537 q = ffi.gc(p, destructor) 1538 assert ffi.typeof(q) is ffi.typeof(p) 1539 import gc; gc.collect() 1540 assert seen == [] 1541 del q 1542 import gc; gc.collect(); gc.collect(); gc.collect() 1543 assert seen == [1] 1544 1545 def test_gc_2(self): 1546 ffi = FFI(backend=self.Backend()) 1547 p = ffi.new("int *", 123) 1548 seen = [] 1549 q1 = ffi.gc(p, lambda p: seen.append(1)) 1550 q2 = ffi.gc(q1, lambda p: seen.append(2)) 1551 import gc; gc.collect() 1552 assert seen == [] 1553 del q1, q2 1554 import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() 1555 assert seen == [2, 1] 1556 1557 def test_gc_3(self): 1558 ffi = FFI(backend=self.Backend()) 1559 p = ffi.new("int *", 123) 1560 r = ffi.new("int *", 123) 1561 seen = [] 1562 seen_r = [] 1563 q1 = ffi.gc(p, lambda p: seen.append(1)) 1564 s1 = ffi.gc(r, lambda r: seen_r.append(4)) 1565 q2 = ffi.gc(q1, lambda p: seen.append(2)) 1566 s2 = ffi.gc(s1, lambda r: seen_r.append(5)) 1567 q3 = ffi.gc(q2, lambda p: seen.append(3)) 1568 import gc; gc.collect() 1569 assert seen == [] 1570 assert seen_r == [] 1571 del q1, q2, q3, s2, s1 1572 import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() 1573 assert seen == [3, 2, 1] 1574 assert seen_r == [5, 4] 1575 1576 def test_gc_4(self): 1577 ffi = FFI(backend=self.Backend()) 1578 p = ffi.new("int *", 123) 1579 seen = [] 1580 q1 = ffi.gc(p, lambda p: seen.append(1)) 1581 q2 = ffi.gc(q1, lambda p: seen.append(2)) 1582 q3 = ffi.gc(q2, lambda p: seen.append(3)) 1583 import gc; gc.collect() 1584 assert seen == [] 1585 del q1, q3 # q2 remains, and has a hard ref to q1 1586 import gc; gc.collect(); gc.collect(); gc.collect() 1587 assert seen == [3] 1588 1589 def test_gc_disable(self): 1590 ffi = FFI(backend=self.Backend()) 1591 p = ffi.new("int *", 123) 1592 py.test.raises(TypeError, ffi.gc, p, None) 1593 seen = [] 1594 q1 = ffi.gc(p, lambda p: seen.append(1)) 1595 q2 = ffi.gc(q1, lambda p: seen.append(2)) 1596 import gc; gc.collect() 1597 assert seen == [] 1598 assert ffi.gc(q1, None) is None 1599 del q1, q2 1600 import gc; gc.collect(); gc.collect(); gc.collect() 1601 assert seen == [2] 1602 1603 def test_gc_finite_list(self): 1604 ffi = FFI(backend=self.Backend()) 1605 p = ffi.new("int *", 123) 1606 keepalive = [] 1607 for i in range(10): 1608 keepalive.append(ffi.gc(p, lambda p: None)) 1609 del keepalive[:] 1610 import gc; gc.collect(); gc.collect() 1611 for i in range(10): 1612 keepalive.append(ffi.gc(p, lambda p: None)) 1613 1614 def test_CData_CType(self): 1615 ffi = FFI(backend=self.Backend()) 1616 assert isinstance(ffi.cast("int", 0), ffi.CData) 1617 assert isinstance(ffi.new("int *"), ffi.CData) 1618 assert not isinstance(ffi.typeof("int"), ffi.CData) 1619 assert not isinstance(ffi.cast("int", 0), ffi.CType) 1620 assert not isinstance(ffi.new("int *"), ffi.CType) 1621 1622 def test_CData_CType_2(self): 1623 ffi = FFI(backend=self.Backend()) 1624 assert isinstance(ffi.typeof("int"), ffi.CType) 1625 1626 def test_bool(self): 1627 ffi = FFI(backend=self.Backend()) 1628 assert int(ffi.cast("_Bool", 0.1)) == 1 1629 assert int(ffi.cast("_Bool", -0.0)) == 0 1630 assert int(ffi.cast("_Bool", b'\x02')) == 1 1631 assert int(ffi.cast("_Bool", b'\x00')) == 0 1632 assert int(ffi.cast("_Bool", b'\x80')) == 1 1633 assert ffi.new("_Bool *", False)[0] == 0 1634 assert ffi.new("_Bool *", 1)[0] == 1 1635 py.test.raises(OverflowError, ffi.new, "_Bool *", 2) 1636 py.test.raises(TypeError, ffi.string, ffi.cast("_Bool", 2)) 1637 1638 def test_use_own_bool(self): 1639 ffi = FFI(backend=self.Backend()) 1640 ffi.cdef("""typedef int bool;""") 1641 1642 def test_ordering_bug1(self): 1643 ffi = FFI(backend=self.Backend()) 1644 ffi.cdef(""" 1645 struct foo_s { 1646 struct bar_s *p; 1647 }; 1648 struct bar_s { 1649 struct foo_s foo; 1650 }; 1651 """) 1652 q = ffi.new("struct foo_s *") 1653 bar = ffi.new("struct bar_s *") 1654 q.p = bar 1655 assert q.p.foo.p == ffi.NULL 1656 1657 def test_ordering_bug2(self): 1658 ffi = FFI(backend=self.Backend()) 1659 ffi.cdef(""" 1660 struct bar_s; 1661 1662 struct foo_s { 1663 void (*foo)(struct bar_s[]); 1664 }; 1665 1666 struct bar_s { 1667 struct foo_s foo; 1668 }; 1669 """) 1670 q = ffi.new("struct foo_s *") 1671 1672 def test_addressof(self): 1673 ffi = FFI(backend=self.Backend()) 1674 ffi.cdef("struct foo_s { int x, y; };") 1675 p = ffi.new("struct foo_s *") 1676 a = ffi.addressof(p[0]) 1677 assert repr(a).startswith("<cdata 'struct foo_s *' 0x") 1678 assert a == p 1679 py.test.raises(TypeError, ffi.addressof, p) 1680 py.test.raises((AttributeError, TypeError), ffi.addressof, 5) 1681 py.test.raises(TypeError, ffi.addressof, ffi.cast("int", 5)) 1682 1683 def test_addressof_field(self): 1684 ffi = FFI(backend=self.Backend()) 1685 ffi.cdef("struct foo_s { int x, y; };") 1686 p = ffi.new("struct foo_s *") 1687 a = ffi.addressof(p[0], 'y') 1688 assert repr(a).startswith("<cdata 'int *' 0x") 1689 assert int(ffi.cast("uintptr_t", a)) == ( 1690 int(ffi.cast("uintptr_t", p)) + ffi.sizeof("int")) 1691 assert a == ffi.addressof(p, 'y') 1692 assert a != ffi.addressof(p, 'x') 1693 1694 def test_addressof_field_nested(self): 1695 ffi = FFI(backend=self.Backend()) 1696 ffi.cdef("struct foo_s { int x, y; };" 1697 "struct bar_s { struct foo_s a, b; };") 1698 p = ffi.new("struct bar_s *") 1699 py.test.raises(KeyError, ffi.addressof, p[0], 'b.y') 1700 a = ffi.addressof(p[0], 'b', 'y') 1701 assert int(ffi.cast("uintptr_t", a)) == ( 1702 int(ffi.cast("uintptr_t", p)) + 1703 ffi.sizeof("struct foo_s") + ffi.sizeof("int")) 1704 1705 def test_addressof_anonymous_struct(self): 1706 ffi = FFI() 1707 ffi.cdef("typedef struct { int x; } foo_t;") 1708 p = ffi.new("foo_t *") 1709 a = ffi.addressof(p[0]) 1710 assert a == p 1711 1712 def test_addressof_array(self): 1713 ffi = FFI() 1714 p = ffi.new("int[52]") 1715 p0 = ffi.addressof(p) 1716 assert p0 == p 1717 assert ffi.typeof(p0) is ffi.typeof("int(*)[52]") 1718 py.test.raises(TypeError, ffi.addressof, p0) 1719 # 1720 p1 = ffi.addressof(p, 25) 1721 assert ffi.typeof(p1) is ffi.typeof("int *") 1722 assert (p1 - p) == 25 1723 assert ffi.addressof(p, 0) == p 1724 1725 def test_addressof_pointer(self): 1726 ffi = FFI() 1727 array = ffi.new("int[50]") 1728 p = ffi.cast("int *", array) 1729 py.test.raises(TypeError, ffi.addressof, p) 1730 assert ffi.addressof(p, 0) == p 1731 assert ffi.addressof(p, 25) == p + 25 1732 assert ffi.typeof(ffi.addressof(p, 25)) == ffi.typeof(p) 1733 # 1734 ffi.cdef("struct foo { int a, b; };") 1735 array = ffi.new("struct foo[50]") 1736 p = ffi.cast("int *", array) 1737 py.test.raises(TypeError, ffi.addressof, p) 1738 assert ffi.addressof(p, 0) == p 1739 assert ffi.addressof(p, 25) == p + 25 1740 assert ffi.typeof(ffi.addressof(p, 25)) == ffi.typeof(p) 1741 1742 def test_addressof_array_in_struct(self): 1743 ffi = FFI() 1744 ffi.cdef("struct foo { int a, b; int c[50]; };") 1745 p = ffi.new("struct foo *") 1746 p1 = ffi.addressof(p, "c", 25) 1747 assert ffi.typeof(p1) is ffi.typeof("int *") 1748 assert p1 == ffi.cast("int *", p) + 27 1749 assert ffi.addressof(p, "c") == ffi.cast("int *", p) + 2 1750 assert ffi.addressof(p, "c", 0) == ffi.cast("int *", p) + 2 1751 p2 = ffi.addressof(p, 1) 1752 assert ffi.typeof(p2) is ffi.typeof("struct foo *") 1753 assert p2 == p + 1 1754 1755 def test_multiple_independent_structs(self): 1756 ffi1 = FFI(); ffi1.cdef("struct foo { int x; };") 1757 ffi2 = FFI(); ffi2.cdef("struct foo { int y, z; };") 1758 foo1 = ffi1.new("struct foo *", [10]) 1759 foo2 = ffi2.new("struct foo *", [20, 30]) 1760 assert foo1.x == 10 1761 assert foo2.y == 20 1762 assert foo2.z == 30 1763 1764 def test_missing_include(self): 1765 backend = self.Backend() 1766 ffi1 = FFI(backend=backend) 1767 ffi2 = FFI(backend=backend) 1768 ffi1.cdef("typedef signed char schar_t;") 1769 py.test.raises(CDefError, ffi2.cast, "schar_t", 142) 1770 1771 def test_include_typedef(self): 1772 backend = self.Backend() 1773 ffi1 = FFI(backend=backend) 1774 ffi2 = FFI(backend=backend) 1775 ffi1.cdef("typedef signed char schar_t;") 1776 ffi2.include(ffi1) 1777 p = ffi2.cast("schar_t", 142) 1778 assert int(p) == 142 - 256 1779 1780 def test_include_struct(self): 1781 backend = self.Backend() 1782 ffi1 = FFI(backend=backend) 1783 ffi2 = FFI(backend=backend) 1784 ffi1.cdef("struct foo { int x; };") 1785 ffi2.include(ffi1) 1786 p = ffi2.new("struct foo *", [142]) 1787 assert p.x == 142 1788 1789 def test_include_union(self): 1790 backend = self.Backend() 1791 ffi1 = FFI(backend=backend) 1792 ffi2 = FFI(backend=backend) 1793 ffi1.cdef("union foo { int x; };") 1794 ffi2.include(ffi1) 1795 p = ffi2.new("union foo *", [142]) 1796 assert p.x == 142 1797 1798 def test_include_enum(self): 1799 backend = self.Backend() 1800 ffi1 = FFI(backend=backend) 1801 ffi2 = FFI(backend=backend) 1802 ffi1.cdef("enum foo { FA, FB, FC };") 1803 ffi2.include(ffi1) 1804 p = ffi2.cast("enum foo", 1) 1805 assert ffi2.string(p) == "FB" 1806 assert ffi2.sizeof("char[FC]") == 2 1807 1808 def test_include_typedef_2(self): 1809 backend = self.Backend() 1810 ffi1 = FFI(backend=backend) 1811 ffi2 = FFI(backend=backend) 1812 ffi1.cdef("typedef struct { int x; } *foo_p;") 1813 ffi2.include(ffi1) 1814 p = ffi2.new("foo_p", [142]) 1815 assert p.x == 142 1816 1817 def test_ignore_multiple_declarations_of_constant(self): 1818 ffi = FFI(backend=self.Backend()) 1819 ffi.cdef("#define FOO 42") 1820 ffi.cdef("#define FOO 42") 1821 py.test.raises(FFIError, ffi.cdef, "#define FOO 43") 1822 1823 def test_struct_packed(self): 1824 ffi = FFI(backend=self.Backend()) 1825 ffi.cdef("struct nonpacked { char a; int b; };") 1826 ffi.cdef("struct is_packed { char a; int b; };", packed=True) 1827 ffi.cdef("struct is_packed1 { char a; int b; };", pack=1) 1828 ffi.cdef("struct is_packed2 { char a; int b; };", pack=2) 1829 ffi.cdef("struct is_packed4 { char a; int b; };", pack=4) 1830 ffi.cdef("struct is_packed8 { char a; int b; };", pack=8) 1831 assert ffi.sizeof("struct nonpacked") == 8 1832 assert ffi.sizeof("struct is_packed") == 5 1833 assert ffi.sizeof("struct is_packed1") == 5 1834 assert ffi.sizeof("struct is_packed2") == 6 1835 assert ffi.sizeof("struct is_packed4") == 8 1836 assert ffi.sizeof("struct is_packed8") == 8 1837 assert ffi.alignof("struct nonpacked") == 4 1838 assert ffi.alignof("struct is_packed") == 1 1839 assert ffi.alignof("struct is_packed1") == 1 1840 assert ffi.alignof("struct is_packed2") == 2 1841 assert ffi.alignof("struct is_packed4") == 4 1842 assert ffi.alignof("struct is_packed8") == 4 1843 for name in ['is_packed', 'is_packed1', 'is_packed2', 1844 'is_packed4', 'is_packed8']: 1845 s = ffi.new("struct %s[2]" % name) 1846 s[0].b = 42623381 1847 s[0].a = b'X' 1848 s[1].b = -4892220 1849 s[1].a = b'Y' 1850 assert s[0].b == 42623381 1851 assert s[0].a == b'X' 1852 assert s[1].b == -4892220 1853 assert s[1].a == b'Y' 1854 1855 def test_pack_valueerror(self): 1856 ffi = FFI(backend=self.Backend()) 1857 py.test.raises(ValueError, ffi.cdef, "", pack=3) 1858 py.test.raises(ValueError, ffi.cdef, "", packed=2) 1859 py.test.raises(ValueError, ffi.cdef, "", packed=True, pack=1) 1860 1861 def test_define_integer_constant(self): 1862 ffi = FFI(backend=self.Backend()) 1863 ffi.cdef(""" 1864 #define DOT_0 0 1865 #define DOT 100 1866 #define DOT_OCT 0100l 1867 #define DOT_HEX 0x100u 1868 #define DOT_HEX2 0X10 1869 #define DOT_UL 1000UL 1870 enum foo {AA, BB=DOT, CC}; 1871 """) 1872 needs_dlopen_none() 1873 lib = ffi.dlopen(None) 1874 assert ffi.string(ffi.cast("enum foo", 100)) == "BB" 1875 assert lib.DOT_0 == 0 1876 assert lib.DOT == 100 1877 assert lib.DOT_OCT == 0o100 1878 assert lib.DOT_HEX == 0x100 1879 assert lib.DOT_HEX2 == 0x10 1880 assert lib.DOT_UL == 1000 1881 1882 def test_opaque_struct_becomes_nonopaque(self): 1883 # Issue #193: if we use a struct between the first cdef() where it is 1884 # declared and another cdef() where its fields are defined, then the 1885 # definition was ignored. 1886 ffi = FFI(backend=self.Backend()) 1887 ffi.cdef("struct foo_s;") 1888 py.test.raises(TypeError, ffi.new, "struct foo_s *") 1889 ffi.cdef("struct foo_s { int x; };") 1890 ffi.new("struct foo_s *") 1891 1892 def test_ffi_self_include(self): 1893 ffi = FFI(backend=self.Backend()) 1894 py.test.raises(ValueError, ffi.include, ffi) 1895 1896 def test_anonymous_enum_include(self): 1897 ffi1 = FFI() 1898 ffi1.cdef("enum { EE1 };") 1899 ffi = FFI() 1900 ffi.include(ffi1) 1901 ffi.cdef("enum { EE2, EE3 };") 1902 needs_dlopen_none() 1903 lib = ffi.dlopen(None) 1904 assert lib.EE1 == 0 1905 assert lib.EE2 == 0 1906 assert lib.EE3 == 1 1907 1908 def test_init_once(self): 1909 def do_init(): 1910 seen.append(1) 1911 return 42 1912 ffi = FFI() 1913 seen = [] 1914 for i in range(3): 1915 res = ffi.init_once(do_init, "tag1") 1916 assert res == 42 1917 assert seen == [1] 1918 for i in range(3): 1919 res = ffi.init_once(do_init, "tag2") 1920 assert res == 42 1921 assert seen == [1, 1] 1922 1923 def test_init_once_multithread(self): 1924 import sys, time 1925 if sys.version_info < (3,): 1926 import thread 1927 else: 1928 import _thread as thread 1929 # 1930 def do_init(): 1931 seen.append('init!') 1932 time.sleep(1) 1933 seen.append('init done') 1934 return 7 1935 ffi = FFI() 1936 seen = [] 1937 for i in range(6): 1938 def f(): 1939 res = ffi.init_once(do_init, "tag") 1940 seen.append(res) 1941 thread.start_new_thread(f, ()) 1942 time.sleep(1.5) 1943 assert seen == ['init!', 'init done'] + 6 * [7] 1944 1945 def test_sizeof_struct_directly(self): 1946 # only works with the Python FFI instances 1947 ffi = FFI(backend=self.Backend()) 1948 assert ffi.sizeof("struct{int a;}") == ffi.sizeof("int") 1949 1950 def test_callback_large_struct(self): 1951 ffi = FFI(backend=self.Backend()) 1952 # more than 8 bytes 1953 ffi.cdef("struct foo_s { unsigned long a, b, c; };") 1954 # 1955 @ffi.callback("void(struct foo_s)") 1956 def cb(s): 1957 seen.append(ffi.typeof(s)) 1958 s.a += 1 1959 s.b += 2 1960 s.c += 3 1961 seen.append(s.a) 1962 seen.append(s.b) 1963 seen.append(s.c) 1964 # 1965 s1 = ffi.new("struct foo_s *", {'a': 100, 'b': 200, 'c': 300}) 1966 seen = [] 1967 cb(s1[0]) 1968 assert len(seen) == 4 1969 assert s1.a == 100 # unmodified 1970 assert s1.b == 200 1971 assert s1.c == 300 1972 assert seen[0] == ffi.typeof("struct foo_s") 1973 assert seen[1] == 101 1974 assert seen[2] == 202 1975 assert seen[3] == 303 1976 1977 def test_ffi_array_as_init(self): 1978 ffi = FFI(backend=self.Backend()) 1979 p = ffi.new("int[4]", [10, 20, 30, 400]) 1980 q = ffi.new("int[4]", p) 1981 assert list(q) == [10, 20, 30, 400] 1982 py.test.raises(TypeError, ffi.new, "int[3]", p) 1983 py.test.raises(TypeError, ffi.new, "int[5]", p) 1984 py.test.raises(TypeError, ffi.new, "int16_t[4]", p) 1985 s = ffi.new("struct {int i[4];}*", {'i': p}) 1986 assert list(s.i) == [10, 20, 30, 400] 1987 1988 def test_too_many_initializers(self): 1989 ffi = FFI(backend=self.Backend()) 1990 py.test.raises(IndexError, ffi.new, "int[4]", [10, 20, 30, 40, 50]) 1991