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