• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import os, sys, math, py
2import pytest
3from cffi import FFI, FFIError, VerificationError, VerificationMissing, model
4from cffi import CDefError
5from cffi import recompiler
6from testing.support import *
7from testing.support import _verify, extra_compile_args
8import _cffi_backend
9
10lib_m = ['m']
11if sys.platform == 'win32':
12    #there is a small chance this fails on Mingw via environ $CC
13    import distutils.ccompiler
14    if distutils.ccompiler.get_default_compiler() == 'msvc':
15        lib_m = ['msvcrt']
16
17class FFI(FFI):
18    error = _cffi_backend.FFI.error
19    _extra_compile_args = extra_compile_args
20    _verify_counter = 0
21
22    def verify(self, preamble='', *args, **kwds):
23        # HACK to reuse the tests from ../cffi0/test_verify.py
24        FFI._verify_counter += 1
25        module_name = 'verify%d' % FFI._verify_counter
26        try:
27            del self._assigned_source
28        except AttributeError:
29            pass
30        self.set_source(module_name, preamble)
31        return _verify(self, module_name, preamble, *args,
32                       extra_compile_args=self._extra_compile_args, **kwds)
33
34class FFI_warnings_not_error(FFI):
35    _extra_compile_args = []
36
37
38def test_missing_function(ffi=None):
39    # uses the FFI hacked above with '-Werror'
40    if ffi is None:
41        ffi = FFI()
42    ffi.cdef("void some_completely_unknown_function();")
43    try:
44        lib = ffi.verify()
45    except (VerificationError, OSError, ImportError):
46        pass     # expected case: we get a VerificationError
47    else:
48        # but depending on compiler and loader details, maybe
49        # 'lib' could actually be imported but will fail if we
50        # actually try to call the unknown function...  Hard
51        # to test anything more.
52        pass
53
54def test_missing_function_import_error():
55    # uses the original FFI that just gives a warning during compilation
56    test_missing_function(ffi=FFI_warnings_not_error())
57
58def test_simple_case():
59    ffi = FFI()
60    ffi.cdef("double sin(double x);")
61    lib = ffi.verify('#include <math.h>', libraries=lib_m)
62    assert lib.sin(1.23) == math.sin(1.23)
63
64def _Wconversion(cdef, source, **kargs):
65    if sys.platform in ('win32', 'darwin'):
66        py.test.skip("needs GCC")
67    ffi = FFI()
68    ffi.cdef(cdef)
69    py.test.raises(VerificationError, ffi.verify, source, **kargs)
70    extra_compile_args_orig = extra_compile_args[:]
71    extra_compile_args.remove('-Wconversion')
72    try:
73        lib = ffi.verify(source, **kargs)
74    finally:
75        extra_compile_args[:] = extra_compile_args_orig
76    return lib
77
78def test_Wconversion_unsigned():
79    _Wconversion("unsigned foo(void);",
80                 "int foo(void) { return -1;}")
81
82def test_Wconversion_integer():
83    _Wconversion("short foo(void);",
84                 "long long foo(void) { return 1<<sizeof(short);}")
85
86def test_Wconversion_floating():
87    lib = _Wconversion("float sin(double);",
88                       "#include <math.h>", libraries=lib_m)
89    res = lib.sin(1.23)
90    assert res != math.sin(1.23)     # not exact, because of double->float
91    assert abs(res - math.sin(1.23)) < 1E-5
92
93def test_Wconversion_float2int():
94    _Wconversion("int sinf(float);",
95                 "#include <math.h>", libraries=lib_m)
96
97def test_Wconversion_double2int():
98    _Wconversion("int sin(double);",
99                 "#include <math.h>", libraries=lib_m)
100
101def test_rounding_1():
102    ffi = FFI()
103    ffi.cdef("double sinf(float x);")
104    lib = ffi.verify('#include <math.h>', libraries=lib_m)
105    res = lib.sinf(1.23)
106    assert res != math.sin(1.23)     # not exact, because of double->float
107    assert abs(res - math.sin(1.23)) < 1E-5
108
109def test_rounding_2():
110    ffi = FFI()
111    ffi.cdef("double sin(float x);")
112    lib = ffi.verify('#include <math.h>', libraries=lib_m)
113    res = lib.sin(1.23)
114    assert res != math.sin(1.23)     # not exact, because of double->float
115    assert abs(res - math.sin(1.23)) < 1E-5
116
117def test_strlen_exact():
118    ffi = FFI()
119    ffi.cdef("size_t strlen(const char *s);")
120    lib = ffi.verify("#include <string.h>")
121    assert lib.strlen(b"hi there!") == 9
122
123def test_strlen_approximate():
124    lib = _Wconversion("int strlen(char *s);",
125                       "#include <string.h>")
126    assert lib.strlen(b"hi there!") == 9
127
128def test_return_approximate():
129    for typename in ['short', 'int', 'long', 'long long']:
130        ffi = FFI()
131        ffi.cdef("%s foo(signed char x);" % typename)
132        lib = ffi.verify("signed char foo(signed char x) { return x;}")
133        assert lib.foo(-128) == -128
134        assert lib.foo(+127) == +127
135
136def test_strlen_array_of_char():
137    ffi = FFI()
138    ffi.cdef("size_t strlen(char[]);")
139    lib = ffi.verify("#include <string.h>")
140    assert lib.strlen(b"hello") == 5
141
142def test_longdouble():
143    ffi = FFI()
144    ffi.cdef("long double sinl(long double x);")
145    lib = ffi.verify('#include <math.h>', libraries=lib_m)
146    for input in [1.23,
147                  ffi.cast("double", 1.23),
148                  ffi.cast("long double", 1.23)]:
149        x = lib.sinl(input)
150        assert repr(x).startswith("<cdata 'long double'")
151        assert (float(x) - math.sin(1.23)) < 1E-10
152
153def test_longdouble_precision():
154    # Test that we don't loose any precision of 'long double' when
155    # passing through Python and CFFI.
156    ffi = FFI()
157    ffi.cdef("long double step1(long double x);")
158    SAME_SIZE = ffi.sizeof("long double") == ffi.sizeof("double")
159    lib = ffi.verify("""
160        long double step1(long double x)
161        {
162            return 4*x-x*x;
163        }
164    """)
165    def do(cast_to_double):
166        x = 0.9789
167        for i in range(10000):
168            x = lib.step1(x)
169            if cast_to_double:
170                x = float(x)
171        return float(x)
172
173    more_precise = do(False)
174    less_precise = do(True)
175    if SAME_SIZE:
176        assert more_precise == less_precise
177    else:
178        assert abs(more_precise - less_precise) > 0.1
179        # Check the particular results on Intel
180        import platform
181        if (platform.machine().startswith('i386') or
182            platform.machine().startswith('i486') or
183            platform.machine().startswith('i586') or
184            platform.machine().startswith('i686') or
185            platform.machine().startswith('x86')):
186            assert abs(more_precise - 0.656769) < 0.001
187            assert abs(less_precise - 3.99091) < 0.001
188        else:
189            py.test.skip("don't know the very exact precision of 'long double'")
190
191
192all_primitive_types = model.PrimitiveType.ALL_PRIMITIVE_TYPES
193if sys.platform == 'win32':
194    all_primitive_types = all_primitive_types.copy()
195    del all_primitive_types['ssize_t']
196all_integer_types = sorted(tp for tp in all_primitive_types
197                           if all_primitive_types[tp] == 'i')
198all_float_types = sorted(tp for tp in all_primitive_types
199                            if all_primitive_types[tp] == 'f')
200
201def all_signed_integer_types(ffi):
202    return [x for x in all_integer_types if int(ffi.cast(x, -1)) < 0]
203
204def all_unsigned_integer_types(ffi):
205    return [x for x in all_integer_types if int(ffi.cast(x, -1)) > 0]
206
207
208def test_primitive_category():
209    for typename in all_primitive_types:
210        tp = model.PrimitiveType(typename)
211        C = tp.is_char_type()
212        F = tp.is_float_type()
213        X = tp.is_complex_type()
214        I = tp.is_integer_type()
215        assert C == (typename in ('char', 'wchar_t', 'char16_t', 'char32_t'))
216        assert F == (typename in ('float', 'double', 'long double'))
217        assert X == (typename in ('float _Complex', 'double _Complex'))
218        assert I + F + C + X == 1      # one and only one of them is true
219
220def test_all_integer_and_float_types():
221    typenames = []
222    for typename in all_primitive_types:
223        if (all_primitive_types[typename] == 'c' or
224            all_primitive_types[typename] == 'j' or    # complex
225            typename == '_Bool' or typename == 'long double'):
226            pass
227        else:
228            typenames.append(typename)
229    #
230    ffi = FFI()
231    ffi.cdef('\n'.join(["%s foo_%s(%s);" % (tp, tp.replace(' ', '_'), tp)
232                       for tp in typenames]))
233    lib = ffi.verify('\n'.join(["%s foo_%s(%s x) { return (%s)(x+1); }" %
234                                (tp, tp.replace(' ', '_'), tp, tp)
235                                for tp in typenames]))
236    for typename in typenames:
237        foo = getattr(lib, 'foo_%s' % typename.replace(' ', '_'))
238        assert foo(42) == 43
239        if sys.version < '3':
240            assert foo(long(44)) == 45
241        assert foo(ffi.cast(typename, 46)) == 47
242        py.test.raises(TypeError, foo, ffi.NULL)
243        #
244        # check for overflow cases
245        if all_primitive_types[typename] == 'f':
246            continue
247        for value in [-2**80, -2**40, -2**20, -2**10, -2**5, -1,
248                      2**5, 2**10, 2**20, 2**40, 2**80]:
249            overflows = int(ffi.cast(typename, value)) != value
250            if overflows:
251                py.test.raises(OverflowError, foo, value)
252            else:
253                assert foo(value) == value + 1
254
255def test_var_signed_integer_types():
256    ffi = FFI()
257    lst = all_signed_integer_types(ffi)
258    csource = "\n".join(["static %s somevar_%s;" % (tp, tp.replace(' ', '_'))
259                         for tp in lst])
260    ffi.cdef(csource)
261    lib = ffi.verify(csource)
262    for tp in lst:
263        varname = 'somevar_%s' % tp.replace(' ', '_')
264        sz = ffi.sizeof(tp)
265        max = (1 << (8*sz-1)) - 1
266        min = -(1 << (8*sz-1))
267        setattr(lib, varname, max)
268        assert getattr(lib, varname) == max
269        setattr(lib, varname, min)
270        assert getattr(lib, varname) == min
271        py.test.raises(OverflowError, setattr, lib, varname, max+1)
272        py.test.raises(OverflowError, setattr, lib, varname, min-1)
273
274def test_var_unsigned_integer_types():
275    ffi = FFI()
276    lst = all_unsigned_integer_types(ffi)
277    csource = "\n".join(["static %s somevar_%s;" % (tp, tp.replace(' ', '_'))
278                         for tp in lst])
279    ffi.cdef(csource)
280    lib = ffi.verify(csource)
281    for tp in lst:
282        varname = 'somevar_%s' % tp.replace(' ', '_')
283        sz = ffi.sizeof(tp)
284        if tp != '_Bool':
285            max = (1 << (8*sz)) - 1
286        else:
287            max = 1
288        setattr(lib, varname, max)
289        assert getattr(lib, varname) == max
290        setattr(lib, varname, 0)
291        assert getattr(lib, varname) == 0
292        py.test.raises(OverflowError, setattr, lib, varname, max+1)
293        py.test.raises(OverflowError, setattr, lib, varname, -1)
294
295def test_fn_signed_integer_types():
296    ffi = FFI()
297    lst = all_signed_integer_types(ffi)
298    cdefsrc = "\n".join(["%s somefn_%s(%s);" % (tp, tp.replace(' ', '_'), tp)
299                         for tp in lst])
300    ffi.cdef(cdefsrc)
301    verifysrc = "\n".join(["%s somefn_%s(%s x) { return x; }" %
302                           (tp, tp.replace(' ', '_'), tp) for tp in lst])
303    lib = ffi.verify(verifysrc)
304    for tp in lst:
305        fnname = 'somefn_%s' % tp.replace(' ', '_')
306        sz = ffi.sizeof(tp)
307        max = (1 << (8*sz-1)) - 1
308        min = -(1 << (8*sz-1))
309        fn = getattr(lib, fnname)
310        assert fn(max) == max
311        assert fn(min) == min
312        py.test.raises(OverflowError, fn, max + 1)
313        py.test.raises(OverflowError, fn, min - 1)
314
315def test_fn_unsigned_integer_types():
316    ffi = FFI()
317    lst = all_unsigned_integer_types(ffi)
318    cdefsrc = "\n".join(["%s somefn_%s(%s);" % (tp, tp.replace(' ', '_'), tp)
319                         for tp in lst])
320    ffi.cdef(cdefsrc)
321    verifysrc = "\n".join(["%s somefn_%s(%s x) { return x; }" %
322                           (tp, tp.replace(' ', '_'), tp) for tp in lst])
323    lib = ffi.verify(verifysrc)
324    for tp in lst:
325        fnname = 'somefn_%s' % tp.replace(' ', '_')
326        sz = ffi.sizeof(tp)
327        if tp != '_Bool':
328            max = (1 << (8*sz)) - 1
329        else:
330            max = 1
331        fn = getattr(lib, fnname)
332        assert fn(max) == max
333        assert fn(0) == 0
334        py.test.raises(OverflowError, fn, max + 1)
335        py.test.raises(OverflowError, fn, -1)
336
337def test_char_type():
338    ffi = FFI()
339    ffi.cdef("char foo(char);")
340    lib = ffi.verify("char foo(char x) { return ++x; }")
341    assert lib.foo(b"A") == b"B"
342    py.test.raises(TypeError, lib.foo, b"bar")
343    py.test.raises(TypeError, lib.foo, "bar")
344
345def test_wchar_type():
346    ffi = FFI()
347    if ffi.sizeof('wchar_t') == 2:
348        uniexample1 = u+'\u1234'
349        uniexample2 = u+'\u1235'
350    else:
351        uniexample1 = u+'\U00012345'
352        uniexample2 = u+'\U00012346'
353    #
354    ffi.cdef("wchar_t foo(wchar_t);")
355    lib = ffi.verify("wchar_t foo(wchar_t x) { return x+1; }")
356    assert lib.foo(uniexample1) == uniexample2
357
358def test_no_argument():
359    ffi = FFI()
360    ffi.cdef("int foo(void);")
361    lib = ffi.verify("int foo(void) { return 42; }")
362    assert lib.foo() == 42
363
364def test_two_arguments():
365    ffi = FFI()
366    ffi.cdef("int foo(int, int);")
367    lib = ffi.verify("int foo(int a, int b) { return a - b; }")
368    assert lib.foo(40, -2) == 42
369
370def test_macro():
371    ffi = FFI()
372    ffi.cdef("int foo(int, int);")
373    lib = ffi.verify("#define foo(a, b) ((a) * (b))")
374    assert lib.foo(-6, -7) == 42
375
376def test_ptr():
377    ffi = FFI()
378    ffi.cdef("int *foo(int *);")
379    lib = ffi.verify("int *foo(int *a) { return a; }")
380    assert lib.foo(ffi.NULL) == ffi.NULL
381    p = ffi.new("int *", 42)
382    q = ffi.new("int *", 42)
383    assert lib.foo(p) == p
384    assert lib.foo(q) != p
385
386def test_bogus_ptr():
387    ffi = FFI()
388    ffi.cdef("int *foo(int *);")
389    lib = ffi.verify("int *foo(int *a) { return a; }")
390    py.test.raises(TypeError, lib.foo, ffi.new("short *", 42))
391
392
393def test_verify_typedefs():
394    py.test.skip("ignored so far")
395    types = ['signed char', 'unsigned char', 'int', 'long']
396    for cdefed in types:
397        for real in types:
398            ffi = FFI()
399            ffi.cdef("typedef %s foo_t;" % cdefed)
400            if cdefed == real:
401                ffi.verify("typedef %s foo_t;" % real)
402            else:
403                py.test.raises(VerificationError, ffi.verify,
404                               "typedef %s foo_t;" % real)
405
406def test_nondecl_struct():
407    ffi = FFI()
408    ffi.cdef("typedef struct foo_s foo_t; int bar(foo_t *);")
409    lib = ffi.verify("typedef struct foo_s foo_t;\n"
410                     "int bar(foo_t *f) { (void)f; return 42; }\n")
411    assert lib.bar(ffi.NULL) == 42
412
413def test_ffi_full_struct():
414    def check(verified_code):
415        ffi = FFI()
416        ffi.cdef("struct foo_s { char x; int y; long *z; };")
417        ffi.verify(verified_code)
418        ffi.new("struct foo_s *", {})
419
420    check("struct foo_s { char x; int y; long *z; };")
421    #
422    if sys.platform != 'win32':  # XXX fixme: only gives warnings
423        py.test.raises(VerificationError, check,
424            "struct foo_s { char x; int y; int *z; };")
425    #
426    py.test.raises(VerificationError, check,
427        "struct foo_s { int y; long *z; };")     # cdef'ed field x is missing
428    #
429    e = py.test.raises(FFI.error, check,
430                       "struct foo_s { int y; char x; long *z; };")
431    assert str(e.value).startswith(
432        "struct foo_s: wrong offset for field 'x'"
433        " (cdef says 0, but C compiler says 4)")
434    #
435    e = py.test.raises(FFI.error, check,
436        "struct foo_s { char x; int y; long *z; char extra; };")
437    assert str(e.value).startswith(
438        "struct foo_s: wrong total size"
439        " (cdef says %d, but C compiler says %d)" % (
440            8 + FFI().sizeof('long *'),
441            8 + FFI().sizeof('long *') * 2))
442    #
443    # a corner case that we cannot really detect, but where it has no
444    # bad consequences: the size is the same, but there is an extra field
445    # that replaces what is just padding in our declaration above
446    check("struct foo_s { char x, extra; int y; long *z; };")
447    #
448    e = py.test.raises(FFI.error, check,
449        "struct foo_s { char x; short pad; short y; long *z; };")
450    assert str(e.value).startswith(
451        "struct foo_s: wrong size for field 'y'"
452        " (cdef says 4, but C compiler says 2)")
453
454def test_ffi_nonfull_struct():
455    ffi = FFI()
456    ffi.cdef("""
457    struct foo_s {
458       int x;
459       ...;
460    };
461    """)
462    py.test.raises(VerificationMissing, ffi.sizeof, 'struct foo_s')
463    py.test.raises(VerificationMissing, ffi.offsetof, 'struct foo_s', 'x')
464    py.test.raises(VerificationMissing, ffi.new, 'struct foo_s *')
465    ffi.verify("""
466    struct foo_s {
467       int a, b, x, c, d, e;
468    };
469    """)
470    assert ffi.sizeof('struct foo_s') == 6 * ffi.sizeof('int')
471    assert ffi.offsetof('struct foo_s', 'x') == 2 * ffi.sizeof('int')
472
473def test_ffi_nonfull_alignment():
474    ffi = FFI()
475    ffi.cdef("struct foo_s { char x; ...; };")
476    ffi.verify("struct foo_s { int a, b; char x; };")
477    assert ffi.sizeof('struct foo_s') == 3 * ffi.sizeof('int')
478    assert ffi.alignof('struct foo_s') == ffi.sizeof('int')
479
480def _check_field_match(typename, real, expect_mismatch):
481    ffi = FFI()
482    testing_by_size = (expect_mismatch == 'by_size')
483    if testing_by_size:
484        expect_mismatch = ffi.sizeof(typename) != ffi.sizeof(real)
485    ffi.cdef("struct foo_s { %s x; ...; };" % typename)
486    try:
487        ffi.verify("struct foo_s { %s x; };" % real)
488        ffi.new("struct foo_s *", [])  # because some mismatches show up lazily
489    except (VerificationError, ffi.error):
490        if not expect_mismatch:
491            if testing_by_size and typename != real:
492                print("ignoring mismatch between %s* and %s* even though "
493                      "they have the same size" % (typename, real))
494                return
495            raise AssertionError("unexpected mismatch: %s should be accepted "
496                                 "as equal to %s" % (typename, real))
497    else:
498        if expect_mismatch:
499            raise AssertionError("mismatch not detected: "
500                                 "%s != %s" % (typename, real))
501
502def test_struct_bad_sized_integer():
503    for typename in ['int8_t', 'int16_t', 'int32_t', 'int64_t']:
504        for real in ['int8_t', 'int16_t', 'int32_t', 'int64_t']:
505            _check_field_match(typename, real, "by_size")
506
507def test_struct_bad_sized_float():
508    for typename in all_float_types:
509        for real in all_float_types:
510            _check_field_match(typename, real, "by_size")
511
512def test_struct_signedness_ignored():
513    _check_field_match("int", "unsigned int", expect_mismatch=False)
514    _check_field_match("unsigned short", "signed short", expect_mismatch=False)
515
516def test_struct_float_vs_int():
517    if sys.platform == 'win32':
518        py.test.skip("XXX fixme: only gives warnings")
519    ffi = FFI()
520    for typename in all_signed_integer_types(ffi):
521        for real in all_float_types:
522            _check_field_match(typename, real, expect_mismatch=True)
523    for typename in all_float_types:
524        for real in all_signed_integer_types(ffi):
525            _check_field_match(typename, real, expect_mismatch=True)
526
527def test_struct_array_field():
528    ffi = FFI()
529    ffi.cdef("struct foo_s { int a[17]; ...; };")
530    ffi.verify("struct foo_s { int x; int a[17]; int y; };")
531    assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
532    s = ffi.new("struct foo_s *")
533    assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
534
535def test_struct_array_no_length():
536    ffi = FFI()
537    ffi.cdef("struct foo_s { int a[]; int y; ...; };\n"
538             "int bar(struct foo_s *);\n")
539    lib = ffi.verify("struct foo_s { int x; int a[17]; int y; };\n"
540                     "int bar(struct foo_s *f) { return f->a[14]; }\n")
541    assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
542    s = ffi.new("struct foo_s *")
543    assert ffi.typeof(s.a) is ffi.typeof('int[]')   # implicit max length
544    assert len(s.a) == 18  # max length, computed from the size and start offset
545    s.a[14] = 4242
546    assert lib.bar(s) == 4242
547    # with no declared length, out-of-bound accesses are not detected
548    s.a[17] = -521
549    assert s.y == s.a[17] == -521
550    #
551    s = ffi.new("struct foo_s *", {'a': list(range(17))})
552    assert s.a[16] == 16
553    # overflows at construction time not detected either
554    s = ffi.new("struct foo_s *", {'a': list(range(18))})
555    assert s.y == s.a[17] == 17
556
557def test_struct_array_guess_length():
558    ffi = FFI()
559    ffi.cdef("struct foo_s { int a[...]; };")
560    ffi.verify("struct foo_s { int x; int a[17]; int y; };")
561    assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
562    s = ffi.new("struct foo_s *")
563    assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
564    with pytest.raises(IndexError):
565        s.a[17]
566
567def test_struct_array_c99_1():
568    if sys.platform == 'win32':
569        py.test.skip("requires C99")
570    ffi = FFI()
571    ffi.cdef("struct foo_s { int x; int a[]; };")
572    ffi.verify("struct foo_s { int x; int a[]; };")
573    assert ffi.sizeof('struct foo_s') == 1 * ffi.sizeof('int')
574    s = ffi.new("struct foo_s *", [424242, 4])
575    assert ffi.sizeof(ffi.typeof(s[0])) == 1 * ffi.sizeof('int')
576    assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
577    # ^^^ explanation: if you write in C: "char x[5];", then
578    # "sizeof(x)" will evaluate to 5.  The behavior above is
579    # a generalization of that to "struct foo_s[len(a)=5] x;"
580    # if you could do that in C.
581    assert s.a[3] == 0
582    s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
583    assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
584    assert s.a[3] == -10
585    s = ffi.new("struct foo_s *")
586    assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
587    s = ffi.new("struct foo_s *", [424242])
588    assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
589
590def test_struct_array_c99_2():
591    if sys.platform == 'win32':
592        py.test.skip("requires C99")
593    ffi = FFI()
594    ffi.cdef("struct foo_s { int x; int a[]; ...; };")
595    ffi.verify("struct foo_s { int x, y; int a[]; };")
596    assert ffi.sizeof('struct foo_s') == 2 * ffi.sizeof('int')
597    s = ffi.new("struct foo_s *", [424242, 4])
598    assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
599    assert s.a[3] == 0
600    s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
601    assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
602    assert s.a[3] == -10
603    s = ffi.new("struct foo_s *")
604    assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
605    s = ffi.new("struct foo_s *", [424242])
606    assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
607
608def test_struct_ptr_to_array_field():
609    ffi = FFI()
610    ffi.cdef("struct foo_s { int (*a)[17]; ...; }; struct bar_s { ...; };")
611    ffi.verify("struct foo_s { int x; int (*a)[17]; int y; };\n"
612               "struct bar_s { int x; int *a; int y; };")
613    assert ffi.sizeof('struct foo_s') == ffi.sizeof("struct bar_s")
614    s = ffi.new("struct foo_s *")
615    assert ffi.sizeof(s.a) == ffi.sizeof('int(*)[17]') == ffi.sizeof("int *")
616
617def test_struct_with_bitfield_exact():
618    ffi = FFI()
619    ffi.cdef("struct foo_s { int a:2, b:3; };")
620    ffi.verify("struct foo_s { int a:2, b:3; };")
621    s = ffi.new("struct foo_s *")
622    s.b = 3
623    with pytest.raises(OverflowError):
624        s.b = 4
625    assert s.b == 3
626
627def test_struct_with_bitfield_enum():
628    ffi = FFI()
629    code = """
630        typedef enum { AA, BB, CC } foo_e;
631        typedef struct { foo_e f:2; } foo_s;
632    """
633    ffi.cdef(code)
634    ffi.verify(code)
635    s = ffi.new("foo_s *")
636    s.f = 1
637    assert s.f == 1
638    if int(ffi.cast("foo_e", -1)) < 0:
639        two = -2
640    else:
641        two = 2
642    s.f = two
643    assert s.f == two
644
645def test_unsupported_struct_with_bitfield_ellipsis():
646    ffi = FFI()
647    py.test.raises(NotImplementedError, ffi.cdef,
648                   "struct foo_s { int a:2, b:3; ...; };")
649
650def test_global_constants():
651    ffi = FFI()
652    # use 'static const int', as generally documented, although in this
653    # case the 'static' is completely ignored.
654    ffi.cdef("static const int AA, BB, CC, DD;")
655    lib = ffi.verify("#define AA 42\n"
656                     "#define BB (-43)   // blah\n"
657                     "#define CC (22*2)  /* foobar */\n"
658                     "#define DD ((unsigned int)142)  /* foo\nbar */\n")
659    assert lib.AA == 42
660    assert lib.BB == -43
661    assert lib.CC == 44
662    assert lib.DD == 142
663
664def test_global_const_int_size():
665    # integer constants: ignore the declared type, always just use the value
666    for value in [-2**63, -2**31, -2**15,
667                  2**15-1, 2**15, 2**31-1, 2**31, 2**32-1, 2**32,
668                  2**63-1, 2**63, 2**64-1]:
669        ffi = FFI()
670        if value == int(ffi.cast("long long", value)):
671            if value < 0:
672                vstr = '(-%dLL-1)' % (~value,)
673            else:
674                vstr = '%dLL' % value
675        elif value == int(ffi.cast("unsigned long long", value)):
676            vstr = '%dULL' % value
677        else:
678            raise AssertionError(value)
679        ffi.cdef("static const unsigned short AA;")
680        lib = ffi.verify("#define AA %s\n" % vstr)
681        assert lib.AA == value
682        assert type(lib.AA) is type(int(lib.AA))
683
684def test_global_constants_non_int():
685    ffi = FFI()
686    ffi.cdef("static char *const PP;")
687    lib = ffi.verify('static char *const PP = "testing!";\n')
688    assert ffi.typeof(lib.PP) == ffi.typeof("char *")
689    assert ffi.string(lib.PP) == b"testing!"
690
691def test_nonfull_enum():
692    ffi = FFI()
693    ffi.cdef("enum ee { EE1, EE2, EE3, ... \n \t };")
694    py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE2')
695    ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };")
696    assert ffi.string(ffi.cast('enum ee', 11)) == "EE2"
697    assert ffi.string(ffi.cast('enum ee', -10)) == "EE3"
698    #
699    assert ffi.typeof("enum ee").relements == {'EE1': 10, 'EE2': 11, 'EE3': -10}
700    assert ffi.typeof("enum ee").elements == {10: 'EE1', 11: 'EE2', -10: 'EE3'}
701
702def test_full_enum():
703    ffi = FFI()
704    ffi.cdef("enum ee { EE1, EE2, EE3 };")
705    lib = ffi.verify("enum ee { EE1, EE2, EE3 };")
706    assert [lib.EE1, lib.EE2, lib.EE3] == [0, 1, 2]
707
708def test_enum_usage():
709    ffi = FFI()
710    ffi.cdef("enum ee { EE1,EE2 }; typedef struct { enum ee x; } *sp;")
711    lib = ffi.verify("enum ee { EE1,EE2 }; typedef struct { enum ee x; } *sp;")
712    assert lib.EE2 == 1
713    s = ffi.new("sp", [lib.EE2])
714    assert s.x == 1
715    s.x = 17
716    assert s.x == 17
717
718def test_anonymous_enum():
719    ffi = FFI()
720    ffi.cdef("enum { EE1 }; enum { EE2, EE3 };")
721    lib = ffi.verify("enum { EE1 }; enum { EE2, EE3 };")
722    assert lib.EE1 == 0
723    assert lib.EE2 == 0
724    assert lib.EE3 == 1
725
726def test_nonfull_anonymous_enum():
727    ffi = FFI()
728    ffi.cdef("enum { EE1, ... }; enum { EE3, ... };")
729    lib = ffi.verify("enum { EE2, EE1 }; enum { EE3 };")
730    assert lib.EE1 == 1
731    assert lib.EE3 == 0
732
733def test_nonfull_enum_syntax2():
734    ffi = FFI()
735    ffi.cdef("enum ee { EE1, EE2=\t..., EE3 };")
736    py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE1')
737    ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };")
738    assert ffi.string(ffi.cast('enum ee', 11)) == 'EE2'
739    assert ffi.string(ffi.cast('enum ee', -10)) == 'EE3'
740    #
741    ffi = FFI()
742    ffi.cdef("enum ee { EE1, EE2=\t... };")
743    py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE1')
744    ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };")
745    assert ffi.string(ffi.cast('enum ee', 11)) == 'EE2'
746    #
747    ffi = FFI()
748    ffi.cdef("enum ee2 { EE4=..., EE5=..., ... };")
749    ffi.verify("enum ee2 { EE4=-1234-5, EE5 }; ")
750    assert ffi.string(ffi.cast('enum ee2', -1239)) == 'EE4'
751    assert ffi.string(ffi.cast('enum ee2', -1238)) == 'EE5'
752
753def test_get_set_errno():
754    ffi = FFI()
755    ffi.cdef("int foo(int);")
756    lib = ffi.verify("""
757        static int foo(int x)
758        {
759            errno += 1;
760            return x * 7;
761        }
762    """)
763    ffi.errno = 15
764    assert lib.foo(6) == 42
765    assert ffi.errno == 16
766
767def test_define_int():
768    ffi = FFI()
769    ffi.cdef("#define FOO ...\n"
770             "\t#\tdefine\tBAR\t...\t\n"
771             "#define BAZ ...\n")
772    lib = ffi.verify("#define FOO 42\n"
773                     "#define BAR (-44)\n"
774                     "#define BAZ 0xffffffffffffffffULL\n")
775    assert lib.FOO == 42
776    assert lib.BAR == -44
777    assert lib.BAZ == 0xffffffffffffffff
778
779def test_access_variable():
780    ffi = FFI()
781    ffi.cdef("static int foo(void);\n"
782             "static int somenumber;")
783    lib = ffi.verify("""
784        static int somenumber = 2;
785        static int foo(void) {
786            return somenumber * 7;
787        }
788    """)
789    assert lib.somenumber == 2
790    assert lib.foo() == 14
791    lib.somenumber = -6
792    assert lib.foo() == -42
793    assert lib.somenumber == -6
794    lib.somenumber = 2   # reset for the next run, if any
795
796def test_access_address_of_variable():
797    # access the address of 'somenumber': need a trick
798    ffi = FFI()
799    ffi.cdef("static int somenumber; static int *const somenumberptr;")
800    lib = ffi.verify("""
801        static int somenumber = 2;
802        #define somenumberptr (&somenumber)
803    """)
804    assert lib.somenumber == 2
805    lib.somenumberptr[0] = 42
806    assert lib.somenumber == 42
807    lib.somenumber = 2    # reset for the next run, if any
808
809def test_access_array_variable(length=5):
810    ffi = FFI()
811    ffi.cdef("static int foo(int);\n"
812             "static int somenumber[%s];" % (length,))
813    lib = ffi.verify("""
814        static int somenumber[] = {2, 2, 3, 4, 5};
815        static int foo(int i) {
816            return somenumber[i] * 7;
817        }
818    """)
819    if length == '':
820        # a global variable of an unknown array length is implicitly
821        # transformed into a global pointer variable, because we can only
822        # work with array instances whose length we know.  using a pointer
823        # instead of an array gives the correct effects.
824        assert repr(lib.somenumber).startswith("<cdata 'int *' 0x")
825        py.test.raises(TypeError, len, lib.somenumber)
826    else:
827        assert repr(lib.somenumber).startswith("<cdata 'int[%s]' 0x" % length)
828        assert len(lib.somenumber) == 5
829    assert lib.somenumber[3] == 4
830    assert lib.foo(3) == 28
831    lib.somenumber[3] = -6
832    assert lib.foo(3) == -42
833    assert lib.somenumber[3] == -6
834    assert lib.somenumber[4] == 5
835    lib.somenumber[3] = 4    # reset for the next run, if any
836
837def test_access_array_variable_length_hidden():
838    test_access_array_variable(length='')
839
840def test_access_struct_variable():
841    ffi = FFI()
842    ffi.cdef("struct foo { int x; ...; };\n"
843             "static int foo(int);\n"
844             "static struct foo stuff;")
845    lib = ffi.verify("""
846        struct foo { int x, y, z; };
847        static struct foo stuff = {2, 5, 8};
848        static int foo(int i) {
849            switch (i) {
850            case 0: return stuff.x * 7;
851            case 1: return stuff.y * 7;
852            case 2: return stuff.z * 7;
853            }
854            return -1;
855        }
856    """)
857    assert lib.stuff.x == 2
858    assert lib.foo(0) == 14
859    assert lib.foo(1) == 35
860    assert lib.foo(2) == 56
861    lib.stuff.x = -6
862    assert lib.foo(0) == -42
863    assert lib.foo(1) == 35
864    lib.stuff.x = 2      # reset for the next run, if any
865
866def test_access_callback():
867    ffi = FFI()
868    ffi.cdef("static int (*cb)(int);\n"
869             "static int foo(int);\n"
870             "static void reset_cb(void);")
871    lib = ffi.verify("""
872        static int g(int x) { return x * 7; }
873        static int (*cb)(int);
874        static int foo(int i) { return cb(i) - 1; }
875        static void reset_cb(void) { cb = g; }
876    """)
877    lib.reset_cb()
878    assert lib.foo(6) == 41
879    my_callback = ffi.callback("int(*)(int)", lambda n: n * 222)
880    lib.cb = my_callback
881    assert lib.foo(4) == 887
882
883def test_access_callback_function_typedef():
884    ffi = FFI()
885    ffi.cdef("typedef int mycallback_t(int);\n"
886             "static mycallback_t *cb;\n"
887             "static int foo(int);\n"
888             "static void reset_cb(void);")
889    lib = ffi.verify("""
890        static int g(int x) { return x * 7; }
891        static int (*cb)(int);
892        static int foo(int i) { return cb(i) - 1; }
893        static void reset_cb(void) { cb = g; }
894    """)
895    lib.reset_cb()
896    assert lib.foo(6) == 41
897    my_callback = ffi.callback("int(*)(int)", lambda n: n * 222)
898    lib.cb = my_callback
899    assert lib.foo(4) == 887
900
901def test_call_with_struct_ptr():
902    ffi = FFI()
903    ffi.cdef("typedef struct { int x; ...; } foo_t; int foo(foo_t *);")
904    lib = ffi.verify("""
905        typedef struct { int y, x; } foo_t;
906        static int foo(foo_t *f) { return f->x * 7; }
907    """)
908    f = ffi.new("foo_t *")
909    f.x = 6
910    assert lib.foo(f) == 42
911
912def test_unknown_type():
913    ffi = FFI()
914    ffi.cdef("""
915        typedef ... token_t;
916        int foo(token_t *);
917        #define TOKEN_SIZE ...
918    """)
919    lib = ffi.verify("""
920        typedef float token_t;
921        static int foo(token_t *tk) {
922            if (!tk)
923                return -42;
924            *tk += 1.601f;
925            return (int)*tk;
926        }
927        #define TOKEN_SIZE sizeof(token_t)
928    """)
929    # we cannot let ffi.new("token_t *") work, because we don't know ahead of
930    # time if it's ok to ask 'sizeof(token_t)' in the C code or not.
931    # See test_unknown_type_2.  Workaround.
932    tkmem = ffi.new("char[]", lib.TOKEN_SIZE)    # zero-initialized
933    tk = ffi.cast("token_t *", tkmem)
934    results = [lib.foo(tk) for i in range(6)]
935    assert results == [1, 3, 4, 6, 8, 9]
936    assert lib.foo(ffi.NULL) == -42
937
938def test_unknown_type_2():
939    ffi = FFI()
940    ffi.cdef("typedef ... token_t;")
941    lib = ffi.verify("typedef struct token_s token_t;")
942    # assert did not crash, even though 'sizeof(token_t)' is not valid in C.
943
944def test_unknown_type_3():
945    ffi = FFI()
946    ffi.cdef("""
947        typedef ... *token_p;
948        token_p foo(token_p);
949    """)
950    lib = ffi.verify("""
951        typedef struct _token_s *token_p;
952        token_p foo(token_p arg) {
953            if (arg)
954                return (token_p)0x12347;
955            else
956                return (token_p)0x12345;
957        }
958    """)
959    p = lib.foo(ffi.NULL)
960    assert int(ffi.cast("intptr_t", p)) == 0x12345
961    q = lib.foo(p)
962    assert int(ffi.cast("intptr_t", q)) == 0x12347
963
964def test_varargs():
965    ffi = FFI()
966    ffi.cdef("int foo(int x, ...);")
967    lib = ffi.verify("""
968        int foo(int x, ...) {
969            va_list vargs;
970            va_start(vargs, x);
971            x -= va_arg(vargs, int);
972            x -= va_arg(vargs, int);
973            va_end(vargs);
974            return x;
975        }
976    """)
977    assert lib.foo(50, ffi.cast("int", 5), ffi.cast("int", 3)) == 42
978
979def test_varargs_exact():
980    if sys.platform == 'win32':
981        py.test.skip("XXX fixme: only gives warnings")
982    ffi = FFI()
983    ffi.cdef("int foo(int x, ...);")
984    py.test.raises(VerificationError, ffi.verify, """
985        int foo(long long x, ...) {
986            return x;
987        }
988    """)
989
990def test_varargs_struct():
991    ffi = FFI()
992    ffi.cdef("struct foo_s { char a; int b; }; int foo(int x, ...);")
993    lib = ffi.verify("""
994        struct foo_s {
995            char a; int b;
996        };
997        int foo(int x, ...) {
998            va_list vargs;
999            struct foo_s s;
1000            va_start(vargs, x);
1001            s = va_arg(vargs, struct foo_s);
1002            va_end(vargs);
1003            return s.a - s.b;
1004        }
1005    """)
1006    s = ffi.new("struct foo_s *", [b'B', 1])
1007    assert lib.foo(50, s[0]) == ord('A')
1008
1009def test_autofilled_struct_as_argument():
1010    ffi = FFI()
1011    ffi.cdef("struct foo_s { long a; double b; ...; };\n"
1012             "int foo(struct foo_s);")
1013    lib = ffi.verify("""
1014        struct foo_s {
1015            double b;
1016            long a;
1017        };
1018        int foo(struct foo_s s) {
1019            return (int)s.a - (int)s.b;
1020        }
1021    """)
1022    s = ffi.new("struct foo_s *", [100, 1])
1023    assert lib.foo(s[0]) == 99
1024    assert lib.foo([100, 1]) == 99
1025
1026def test_autofilled_struct_as_argument_dynamic():
1027    ffi = FFI()
1028    ffi.cdef("struct foo_s { long a; ...; };\n"
1029             "static int (*foo)(struct foo_s);")
1030    lib = ffi.verify("""
1031        struct foo_s {
1032            double b;
1033            long a;
1034        };
1035        int foo1(struct foo_s s) {
1036            return (int)s.a - (int)s.b;
1037        }
1038        static int (*foo)(struct foo_s s) = &foo1;
1039    """)
1040    e = py.test.raises(NotImplementedError, lib.foo, "?")
1041    msg = ("ctype 'struct foo_s' not supported as argument.  It is a struct "
1042           'declared with "...;", but the C calling convention may depend on '
1043           "the missing fields; or, it contains anonymous struct/unions.  "
1044           "Such structs are only supported as argument "
1045           "if the function is 'API mode' and non-variadic (i.e. declared "
1046           "inside ffibuilder.cdef()+ffibuilder.set_source() and not taking "
1047           "a final '...' argument)")
1048    assert str(e.value) == msg
1049
1050def test_func_returns_struct():
1051    ffi = FFI()
1052    ffi.cdef("""
1053        struct foo_s { int aa, bb; };
1054        struct foo_s foo(int a, int b);
1055    """)
1056    lib = ffi.verify("""
1057        struct foo_s { int aa, bb; };
1058        struct foo_s foo(int a, int b) {
1059            struct foo_s r;
1060            r.aa = a*a;
1061            r.bb = b*b;
1062            return r;
1063        }
1064    """)
1065    s = lib.foo(6, 7)
1066    assert repr(s) == "<cdata 'struct foo_s' owning 8 bytes>"
1067    assert s.aa == 36
1068    assert s.bb == 49
1069
1070def test_func_as_funcptr():
1071    ffi = FFI()
1072    ffi.cdef("int *(*const fooptr)(void);")
1073    lib = ffi.verify("""
1074        int *foo(void) {
1075            return (int*)"foobar";
1076        }
1077        int *(*fooptr)(void) = foo;
1078    """)
1079    foochar = ffi.cast("char *(*)(void)", lib.fooptr)
1080    s = foochar()
1081    assert ffi.string(s) == b"foobar"
1082
1083def test_funcptr_as_argument():
1084    ffi = FFI()
1085    ffi.cdef("""
1086        void qsort(void *base, size_t nel, size_t width,
1087            int (*compar)(const void *, const void *));
1088    """)
1089    ffi.verify("#include <stdlib.h>")
1090
1091def test_func_as_argument():
1092    ffi = FFI()
1093    ffi.cdef("""
1094        void qsort(void *base, size_t nel, size_t width,
1095            int compar(const void *, const void *));
1096    """)
1097    ffi.verify("#include <stdlib.h>")
1098
1099def test_array_as_argument():
1100    ffi = FFI()
1101    ffi.cdef("""
1102        size_t strlen(char string[]);
1103    """)
1104    ffi.verify("#include <string.h>")
1105
1106def test_enum_as_argument():
1107    ffi = FFI()
1108    ffi.cdef("""
1109        enum foo_e { AA, BB, ... };
1110        int foo_func(enum foo_e);
1111    """)
1112    lib = ffi.verify("""
1113        enum foo_e { AA, CC, BB };
1114        int foo_func(enum foo_e e) { return (int)e; }
1115    """)
1116    assert lib.foo_func(lib.BB) == 2
1117    py.test.raises(TypeError, lib.foo_func, "BB")
1118
1119def test_enum_as_function_result():
1120    ffi = FFI()
1121    ffi.cdef("""
1122        enum foo_e { AA, BB, ... };
1123        enum foo_e foo_func(int x);
1124    """)
1125    lib = ffi.verify("""
1126        enum foo_e { AA, CC, BB };
1127        enum foo_e foo_func(int x) { return (enum foo_e)x; }
1128    """)
1129    assert lib.foo_func(lib.BB) == lib.BB == 2
1130
1131def test_enum_values():
1132    ffi = FFI()
1133    ffi.cdef("enum enum1_e { AA, BB };")
1134    lib = ffi.verify("enum enum1_e { AA, BB };")
1135    assert lib.AA == 0
1136    assert lib.BB == 1
1137    assert ffi.string(ffi.cast("enum enum1_e", 1)) == 'BB'
1138
1139def test_typedef_complete_enum():
1140    ffi = FFI()
1141    ffi.cdef("typedef enum { AA, BB } enum1_t;")
1142    lib = ffi.verify("typedef enum { AA, BB } enum1_t;")
1143    assert ffi.string(ffi.cast("enum1_t", 1)) == 'BB'
1144    assert lib.AA == 0
1145    assert lib.BB == 1
1146
1147def test_typedef_broken_complete_enum():
1148    # xxx this is broken in old cffis, but works with recompiler.py
1149    ffi = FFI()
1150    ffi.cdef("typedef enum { AA, BB } enum1_t;")
1151    lib = ffi.verify("typedef enum { AA, CC, BB } enum1_t;")
1152    assert lib.AA == 0
1153    assert lib.BB == 2
1154
1155def test_typedef_incomplete_enum():
1156    ffi = FFI()
1157    ffi.cdef("typedef enum { AA, BB, ... } enum1_t;")
1158    lib = ffi.verify("typedef enum { AA, CC, BB } enum1_t;")
1159    assert ffi.string(ffi.cast("enum1_t", 1)) == '1'
1160    assert ffi.string(ffi.cast("enum1_t", 2)) == 'BB'
1161    assert lib.AA == 0
1162    assert lib.BB == 2
1163
1164def test_typedef_enum_as_argument():
1165    ffi = FFI()
1166    ffi.cdef("""
1167        typedef enum { AA, BB, ... } foo_t;
1168        int foo_func(foo_t);
1169    """)
1170    lib = ffi.verify("""
1171        typedef enum { AA, CC, BB } foo_t;
1172        int foo_func(foo_t e) { return (int)e; }
1173    """)
1174    assert lib.foo_func(lib.BB) == lib.BB == 2
1175    py.test.raises(TypeError, lib.foo_func, "BB")
1176
1177def test_typedef_enum_as_function_result():
1178    ffi = FFI()
1179    ffi.cdef("""
1180        typedef enum { AA, BB, ... } foo_t;
1181        foo_t foo_func(int x);
1182    """)
1183    lib = ffi.verify("""
1184        typedef enum { AA, CC, BB } foo_t;
1185        foo_t foo_func(int x) { return (foo_t)x; }
1186    """)
1187    assert lib.foo_func(lib.BB) == lib.BB == 2
1188
1189def test_function_typedef():
1190    ffi = FFI()
1191    ffi.cdef("""
1192        typedef double func_t(double);
1193        func_t sin;
1194    """)
1195    lib = ffi.verify('#include <math.h>', libraries=lib_m)
1196    assert lib.sin(1.23) == math.sin(1.23)
1197
1198def test_opaque_integer_as_function_result():
1199    #import platform
1200    #if platform.machine().startswith('sparc'):
1201    #    py.test.skip('Breaks horribly on sparc (SIGILL + corrupted stack)')
1202    #elif platform.machine() == 'mips64' and sys.maxsize > 2**32:
1203    #    py.test.skip('Segfaults on mips64el')
1204    # XXX bad abuse of "struct { ...; }".  It only works a bit by chance
1205    # anyway.  XXX think about something better :-(
1206    ffi = FFI()
1207    ffi.cdef("""
1208        typedef struct { ...; } myhandle_t;
1209        myhandle_t foo(void);
1210    """)
1211    lib = ffi.verify("""
1212        typedef short myhandle_t;
1213        myhandle_t foo(void) { return 42; }
1214    """)
1215    h = lib.foo()
1216    assert ffi.sizeof(h) == ffi.sizeof("short")
1217
1218def test_return_partial_struct():
1219    ffi = FFI()
1220    ffi.cdef("""
1221        typedef struct { int x; ...; } foo_t;
1222        foo_t foo(void);
1223    """)
1224    lib = ffi.verify("""
1225        typedef struct { int y, x; } foo_t;
1226        foo_t foo(void) { foo_t r = { 45, 81 }; return r; }
1227    """)
1228    h = lib.foo()
1229    assert ffi.sizeof(h) == 2 * ffi.sizeof("int")
1230    assert h.x == 81
1231
1232def test_take_and_return_partial_structs():
1233    ffi = FFI()
1234    ffi.cdef("""
1235        typedef struct { int x; ...; } foo_t;
1236        foo_t foo(foo_t, foo_t);
1237    """)
1238    lib = ffi.verify("""
1239        typedef struct { int y, x; } foo_t;
1240        foo_t foo(foo_t a, foo_t b) {
1241            foo_t r = { 100, a.x * 5 + b.x * 7 };
1242            return r;
1243        }
1244    """)
1245    args = ffi.new("foo_t[3]")
1246    args[0].x = 1000
1247    args[2].x = -498
1248    h = lib.foo(args[0], args[2])
1249    assert ffi.sizeof(h) == 2 * ffi.sizeof("int")
1250    assert h.x == 1000 * 5 - 498 * 7
1251
1252def test_cannot_name_struct_type():
1253    ffi = FFI()
1254    ffi.cdef("typedef struct { int x; } **sp; void foo(sp);")
1255    e = py.test.raises(VerificationError, ffi.verify,
1256                       "typedef struct { int x; } **sp; void foo(sp x) { }")
1257    assert 'in argument of foo: unknown type name' in str(e.value)
1258
1259def test_dont_check_unnamable_fields():
1260    ffi = FFI()
1261    ffi.cdef("struct foo_s { struct { int x; } someone; };")
1262    ffi.verify("struct foo_s { struct { int x; } someone; };")
1263    # assert did not crash
1264
1265def test_nested_anonymous_struct_exact():
1266    if sys.platform == 'win32':
1267        py.test.skip("nested anonymous struct/union")
1268    ffi = FFI()
1269    ffi.cdef("""
1270        struct foo_s { struct { int a; char b; }; union { char c, d; }; };
1271    """)
1272    assert ffi.offsetof("struct foo_s", "c") == 2 * ffi.sizeof("int")
1273    assert ffi.sizeof("struct foo_s") == 3 * ffi.sizeof("int")
1274    ffi.verify("""
1275        struct foo_s { struct { int a; char b; }; union { char c, d; }; };
1276    """)
1277    p = ffi.new("struct foo_s *")
1278    assert ffi.sizeof(p[0]) == 3 * ffi.sizeof("int")    # with alignment
1279    p.a = 1234567
1280    p.b = b'X'
1281    p.c = b'Y'
1282    assert p.a == 1234567
1283    assert p.b == b'X'
1284    assert p.c == b'Y'
1285    assert p.d == b'Y'
1286
1287def test_nested_anonymous_struct_exact_error():
1288    if sys.platform == 'win32':
1289        py.test.skip("nested anonymous struct/union")
1290    ffi = FFI()
1291    ffi.cdef("""
1292        struct foo_s { struct { int a; char b; }; union { char c, d; }; };
1293    """)
1294    py.test.raises(VerificationError, ffi.verify, """
1295        struct foo_s { struct { int a; short b; }; union { char c, d; }; };
1296    """)
1297    # works fine now
1298    #py.test.raises(VerificationError, ffi.verify, """
1299    #    struct foo_s { struct { int a; char e, b; }; union { char c, d; }; };
1300    #""")
1301
1302def test_nested_anonymous_struct_inexact_1():
1303    ffi = FFI()
1304    ffi.cdef("""
1305        struct foo_s { struct { char b; ...; }; union { char c, d; }; };
1306    """)
1307    ffi.verify("""
1308        struct foo_s { int a, padding; char c, d, b; };
1309    """)
1310    assert ffi.sizeof("struct foo_s") == 3 * ffi.sizeof("int")
1311
1312def test_nested_anonymous_struct_inexact_2():
1313    ffi = FFI()
1314    ffi.cdef("""
1315        struct foo_s { union { char c, d; }; struct { int a; char b; }; ...; };
1316    """)
1317    ffi.verify("""
1318        struct foo_s { int a, padding; char c, d, b; };
1319    """)
1320    assert ffi.sizeof("struct foo_s") == 3 * ffi.sizeof("int")
1321
1322def test_ffi_union():
1323    ffi = FFI()
1324    ffi.cdef("union foo_u { char x; long *z; };")
1325    ffi.verify("union foo_u { char x; int y; long *z; };")
1326
1327def test_ffi_union_partial():
1328    ffi = FFI()
1329    ffi.cdef("union foo_u { char x; ...; };")
1330    ffi.verify("union foo_u { char x; int y; };")
1331    assert ffi.sizeof("union foo_u") == 4
1332
1333def test_ffi_union_with_partial_struct():
1334    ffi = FFI()
1335    ffi.cdef("struct foo_s { int x; ...; }; union foo_u { struct foo_s s; };")
1336    ffi.verify("struct foo_s { int a; int x; }; "
1337               "union foo_u { char b[32]; struct foo_s s; };")
1338    assert ffi.sizeof("struct foo_s") == 8
1339    assert ffi.sizeof("union foo_u") == 32
1340
1341def test_ffi_union_partial_2():
1342    ffi = FFI()
1343    ffi.cdef("typedef union { char x; ...; } u1;")
1344    ffi.verify("typedef union { char x; int y; } u1;")
1345    assert ffi.sizeof("u1") == 4
1346
1347def test_ffi_union_with_partial_struct_2():
1348    ffi = FFI()
1349    ffi.cdef("typedef struct { int x; ...; } s1;"
1350             "typedef union { s1 s; } u1;")
1351    ffi.verify("typedef struct { int a; int x; } s1; "
1352               "typedef union { char b[32]; s1 s; } u1;")
1353    assert ffi.sizeof("s1") == 8
1354    assert ffi.sizeof("u1") == 32
1355    assert ffi.offsetof("u1", "s") == 0
1356
1357def test_ffi_struct_packed():
1358    if sys.platform == 'win32':
1359        py.test.skip("needs a GCC extension")
1360    ffi = FFI()
1361    ffi.cdef("struct foo_s { int b; ...; };")
1362    ffi.verify("""
1363        struct foo_s {
1364            char a;
1365            int b;
1366        } __attribute__((packed));
1367    """)
1368
1369def test_tmpdir():
1370    import tempfile, os
1371    from testing.udir import udir
1372    tmpdir = tempfile.mkdtemp(dir=str(udir))
1373    ffi = FFI()
1374    ffi.cdef("int foo(int);")
1375    lib = ffi.verify("int foo(int a) { return a + 42; }", tmpdir=tmpdir)
1376    assert os.listdir(tmpdir)
1377    assert lib.foo(100) == 142
1378
1379def test_relative_to():
1380    py.test.skip("not available")
1381    import tempfile, os
1382    from testing.udir import udir
1383    tmpdir = tempfile.mkdtemp(dir=str(udir))
1384    ffi = FFI()
1385    ffi.cdef("int foo(int);")
1386    f = open(os.path.join(tmpdir, 'foo.h'), 'w')
1387    f.write("int foo(int a) { return a + 42; }\n")
1388    f.close()
1389    lib = ffi.verify('#include "foo.h"',
1390                     include_dirs=['.'],
1391                     relative_to=os.path.join(tmpdir, 'x'))
1392    assert lib.foo(100) == 142
1393
1394def test_bug1():
1395    ffi = FFI()
1396    ffi.cdef("""
1397        typedef struct tdlhandle_s { ...; } *tdl_handle_t;
1398        typedef struct my_error_code_ {
1399            tdl_handle_t *rh;
1400        } my_error_code_t;
1401    """)
1402    ffi.verify("""
1403        typedef struct tdlhandle_s { int foo; } *tdl_handle_t;
1404        typedef struct my_error_code_ {
1405            tdl_handle_t *rh;
1406        } my_error_code_t;
1407    """)
1408
1409def test_bool():
1410    if sys.platform == 'win32':
1411        py.test.skip("_Bool not in MSVC")
1412    ffi = FFI()
1413    ffi.cdef("struct foo_s { _Bool x; };"
1414             "_Bool foo(_Bool); static _Bool (*foop)(_Bool);")
1415    lib = ffi.verify("""
1416        struct foo_s { _Bool x; };
1417        int foo(int arg) {
1418            return !arg;
1419        }
1420        _Bool _foofunc(_Bool x) {
1421            return !x;
1422        }
1423        static _Bool (*foop)(_Bool) = _foofunc;
1424    """)
1425    p = ffi.new("struct foo_s *")
1426    p.x = 1
1427    assert p.x is True
1428    with pytest.raises(OverflowError):
1429        p.x = -1
1430    with pytest.raises(TypeError):
1431        p.x = 0.0
1432    assert lib.foop(1) is False
1433    assert lib.foop(True) is False
1434    assert lib.foop(0) is True
1435    py.test.raises(OverflowError, lib.foop, 42)
1436    py.test.raises(TypeError, lib.foop, 0.0)
1437    assert lib.foo(1) is False
1438    assert lib.foo(True) is False
1439    assert lib.foo(0) is True
1440    py.test.raises(OverflowError, lib.foo, 42)
1441    py.test.raises(TypeError, lib.foo, 0.0)
1442    assert int(ffi.cast("_Bool", long(1))) == 1
1443    assert int(ffi.cast("_Bool", long(0))) == 0
1444    assert int(ffi.cast("_Bool", long(-1))) == 1
1445    assert int(ffi.cast("_Bool", 10**200)) == 1
1446    assert int(ffi.cast("_Bool", 10**40000)) == 1
1447    #
1448    class Foo(object):
1449        def __int__(self):
1450            self.seen = 1
1451            return result
1452    f = Foo()
1453    f.seen = 0
1454    result = 42
1455    assert int(ffi.cast("_Bool", f)) == 1
1456    assert f.seen
1457    f.seen = 0
1458    result = 0
1459    assert int(ffi.cast("_Bool", f)) == 0
1460    assert f.seen
1461    #
1462    py.test.raises(TypeError, ffi.cast, "_Bool", [])
1463
1464def test_bool_on_long_double():
1465    if sys.platform == 'win32':
1466        py.test.skip("_Bool not in MSVC")
1467    f = 1E-250
1468    if f == 0.0 or f*f != 0.0:
1469        py.test.skip("unexpected precision")
1470    ffi = FFI()
1471    ffi.cdef("long double square(long double f); _Bool opposite(_Bool);")
1472    lib = ffi.verify("long double square(long double f) { return f*f; }\n"
1473                     "_Bool opposite(_Bool x) { return !x; }")
1474    f0 = lib.square(0.0)
1475    f2 = lib.square(f)
1476    f3 = lib.square(f * 2.0)
1477    if repr(f2) == repr(f3):
1478        py.test.skip("long double doesn't have enough precision")
1479    assert float(f0) == float(f2) == float(f3) == 0.0  # too tiny for 'double'
1480    assert int(ffi.cast("_Bool", f2)) == 1
1481    assert int(ffi.cast("_Bool", f3)) == 1
1482    assert int(ffi.cast("_Bool", f0)) == 0
1483    py.test.raises(TypeError, lib.opposite, f2)
1484
1485def test_cannot_pass_float():
1486    for basetype in ['char', 'short', 'int', 'long', 'long long']:
1487        for sign in ['signed', 'unsigned']:
1488            type = '%s %s' % (sign, basetype)
1489            ffi = FFI()
1490            ffi.cdef("struct foo_s { %s x; };\n"
1491                     "int foo(%s);" % (type, type))
1492            lib = ffi.verify("""
1493                struct foo_s { %s x; };
1494                int foo(%s arg) {
1495                    return !arg;
1496                }
1497            """ % (type, type))
1498            p = ffi.new("struct foo_s *")
1499            with pytest.raises(TypeError):
1500                p.x = 0.0
1501            assert lib.foo(42) == 0
1502            assert lib.foo(0) == 1
1503            py.test.raises(TypeError, lib.foo, 0.0)
1504
1505def test_addressof():
1506    ffi = FFI()
1507    ffi.cdef("""
1508        struct point_s { int x, y; };
1509        struct foo_s { int z; struct point_s point; };
1510        struct point_s sum_coord(struct point_s *);
1511    """)
1512    lib = ffi.verify("""
1513        struct point_s { int x, y; };
1514        struct foo_s { int z; struct point_s point; };
1515        struct point_s sum_coord(struct point_s *point) {
1516            struct point_s r;
1517            r.x = point->x + point->y;
1518            r.y = point->x - point->y;
1519            return r;
1520        }
1521    """)
1522    p = ffi.new("struct foo_s *")
1523    p.point.x = 16
1524    p.point.y = 9
1525    py.test.raises(TypeError, lib.sum_coord, p.point)
1526    res = lib.sum_coord(ffi.addressof(p.point))
1527    assert res.x == 25
1528    assert res.y == 7
1529    res2 = lib.sum_coord(ffi.addressof(res))
1530    assert res2.x == 32
1531    assert res2.y == 18
1532    py.test.raises(TypeError, lib.sum_coord, res2)
1533
1534def test_callback_in_thread():
1535    py.test.xfail("adapt or remove")
1536    if sys.platform == 'win32':
1537        py.test.skip("pthread only")
1538    import os, subprocess, imp
1539    arg = os.path.join(os.path.dirname(__file__), 'callback_in_thread.py')
1540    g = subprocess.Popen([sys.executable, arg,
1541                          os.path.dirname(imp.find_module('cffi')[1])])
1542    result = g.wait()
1543    assert result == 0
1544
1545def test_keepalive_lib():
1546    py.test.xfail("adapt or remove")
1547    ffi = FFI()
1548    ffi.cdef("int foobar(void);")
1549    lib = ffi.verify("int foobar(void) { return 42; }")
1550    func = lib.foobar
1551    ffi_r = weakref.ref(ffi)
1552    lib_r = weakref.ref(lib)
1553    del ffi
1554    import gc; gc.collect()       # lib stays alive
1555    assert lib_r() is not None
1556    assert ffi_r() is not None
1557    assert func() == 42
1558
1559def test_keepalive_ffi():
1560    py.test.xfail("adapt or remove")
1561    ffi = FFI()
1562    ffi.cdef("int foobar(void);")
1563    lib = ffi.verify("int foobar(void) { return 42; }")
1564    func = lib.foobar
1565    ffi_r = weakref.ref(ffi)
1566    lib_r = weakref.ref(lib)
1567    del lib
1568    import gc; gc.collect()       # ffi stays alive
1569    assert ffi_r() is not None
1570    assert lib_r() is not None
1571    assert func() == 42
1572
1573def test_FILE_stored_in_stdout():
1574    if not sys.platform.startswith('linux'):
1575        py.test.skip("likely, we cannot assign to stdout")
1576    ffi = FFI()
1577    ffi.cdef("int printf(const char *, ...); FILE *setstdout(FILE *);")
1578    lib = ffi.verify("""
1579        #include <stdio.h>
1580        FILE *setstdout(FILE *f) {
1581            FILE *result = stdout;
1582            stdout = f;
1583            return result;
1584        }
1585    """)
1586    import os
1587    fdr, fdw = os.pipe()
1588    fw1 = os.fdopen(fdw, 'wb', 256)
1589    old_stdout = lib.setstdout(fw1)
1590    try:
1591        #
1592        fw1.write(b"X")
1593        r = lib.printf(b"hello, %d!\n", ffi.cast("int", 42))
1594        fw1.close()
1595        assert r == len("hello, 42!\n")
1596        #
1597    finally:
1598        lib.setstdout(old_stdout)
1599    #
1600    result = os.read(fdr, 256)
1601    os.close(fdr)
1602    # the 'X' might remain in the user-level buffer of 'fw1' and
1603    # end up showing up after the 'hello, 42!\n'
1604    assert result == b"Xhello, 42!\n" or result == b"hello, 42!\nX"
1605
1606def test_FILE_stored_explicitly():
1607    ffi = FFI()
1608    ffi.cdef("int myprintf11(const char *, int); extern FILE *myfile;")
1609    lib = ffi.verify("""
1610        #include <stdio.h>
1611        FILE *myfile;
1612        int myprintf11(const char *out, int value) {
1613            return fprintf(myfile, out, value);
1614        }
1615    """)
1616    import os
1617    fdr, fdw = os.pipe()
1618    fw1 = os.fdopen(fdw, 'wb', 256)
1619    lib.myfile = ffi.cast("FILE *", fw1)
1620    #
1621    fw1.write(b"X")
1622    r = lib.myprintf11(b"hello, %d!\n", ffi.cast("int", 42))
1623    fw1.close()
1624    assert r == len("hello, 42!\n")
1625    #
1626    result = os.read(fdr, 256)
1627    os.close(fdr)
1628    # the 'X' might remain in the user-level buffer of 'fw1' and
1629    # end up showing up after the 'hello, 42!\n'
1630    assert result == b"Xhello, 42!\n" or result == b"hello, 42!\nX"
1631
1632def test_global_array_with_missing_length():
1633    ffi = FFI()
1634    ffi.cdef("extern int fooarray[];")
1635    lib = ffi.verify("int fooarray[50];")
1636    assert repr(lib.fooarray).startswith("<cdata 'int *'")
1637
1638def test_global_array_with_dotdotdot_length():
1639    ffi = FFI()
1640    ffi.cdef("extern int fooarray[...];")
1641    lib = ffi.verify("int fooarray[50];")
1642    assert repr(lib.fooarray).startswith("<cdata 'int[50]'")
1643
1644def test_bad_global_array_with_dotdotdot_length():
1645    py.test.xfail("was detected only because 23 bytes cannot be divided by 4; "
1646                  "redo more generally")
1647    ffi = FFI()
1648    ffi.cdef("extern int fooarray[...];")
1649    py.test.raises(VerificationError, ffi.verify, "char fooarray[23];")
1650
1651def test_struct_containing_struct():
1652    ffi = FFI()
1653    ffi.cdef("struct foo_s { ...; }; struct bar_s { struct foo_s f; ...; };")
1654    ffi.verify("struct foo_s { int x; }; struct bar_s { struct foo_s f; };")
1655    #
1656    ffi = FFI()
1657    ffi.cdef("struct foo_s { struct bar_s f; ...; }; struct bar_s { ...; };")
1658    ffi.verify("struct bar_s { int x; }; struct foo_s { struct bar_s f; };")
1659
1660def test_struct_returned_by_func():
1661    ffi = FFI()
1662    ffi.cdef("typedef ... foo_t; foo_t myfunc(void);")
1663    e = py.test.raises(TypeError, ffi.verify,
1664                       "typedef struct { int x; } foo_t; "
1665                       "foo_t myfunc(void) { foo_t x = { 42 }; return x; }")
1666    assert str(e.value) == (
1667        "function myfunc: 'foo_t' is used as result type, but is opaque")
1668
1669def test_include():
1670    ffi1 = FFI()
1671    ffi1.cdef("typedef struct { int x; ...; } foo_t;")
1672    ffi1.verify("typedef struct { int y, x; } foo_t;")
1673    ffi2 = FFI()
1674    ffi2.include(ffi1)
1675    ffi2.cdef("int myfunc(foo_t *);")
1676    lib = ffi2.verify("typedef struct { int y, x; } foo_t;"
1677                      "int myfunc(foo_t *p) { return 42 * p->x; }")
1678    res = lib.myfunc(ffi2.new("foo_t *", {'x': 10}))
1679    assert res == 420
1680    res = lib.myfunc(ffi1.new("foo_t *", {'x': -10}))
1681    assert res == -420
1682
1683def test_include_enum():
1684    ffi1 = FFI()
1685    ffi1.cdef("enum foo_e { AA, ... };")
1686    lib1 = ffi1.verify("enum foo_e { CC, BB, AA };")
1687    ffi2 = FFI()
1688    ffi2.include(ffi1)
1689    ffi2.cdef("int myfunc(enum foo_e);")
1690    lib2 = ffi2.verify("enum foo_e { CC, BB, AA };"
1691                       "int myfunc(enum foo_e x) { return (int)x; }")
1692    res = lib2.myfunc(lib2.AA)
1693    assert res == 2
1694
1695def test_named_pointer_as_argument():
1696    ffi = FFI()
1697    ffi.cdef("typedef struct { int x; } *mystruct_p;\n"
1698             "mystruct_p ff5a(mystruct_p);")
1699    lib = ffi.verify("typedef struct { int x; } *mystruct_p;\n"
1700                     "mystruct_p ff5a(mystruct_p p) { p->x += 40; return p; }")
1701    p = ffi.new("mystruct_p", [-2])
1702    q = lib.ff5a(p)
1703    assert q == p
1704    assert p.x == 38
1705
1706def test_enum_size():
1707    cases = [('123',           4, 4294967295),
1708             ('4294967295U',   4, 4294967295),
1709             ('-123',          4, -1),
1710             ('-2147483647-1', 4, -1),
1711             ]
1712    if FFI().sizeof("long") == 8:
1713        cases += [('4294967296L',        8, 2**64-1),
1714                  ('%dUL' % (2**64-1),   8, 2**64-1),
1715                  ('-2147483649L',       8, -1),
1716                  ('%dL-1L' % (1-2**63), 8, -1)]
1717    for hidden_value, expected_size, expected_minus1 in cases:
1718        if sys.platform == 'win32' and 'U' in hidden_value:
1719            continue   # skipped on Windows
1720        ffi = FFI()
1721        ffi.cdef("enum foo_e { AA, BB, ... };")
1722        lib = ffi.verify("enum foo_e { AA, BB=%s };" % hidden_value)
1723        assert lib.AA == 0
1724        assert lib.BB == eval(hidden_value.replace('U', '').replace('L', ''))
1725        assert ffi.sizeof("enum foo_e") == expected_size
1726        if sys.platform != 'win32':
1727            assert int(ffi.cast("enum foo_e", -1)) == expected_minus1
1728    # test with the large value hidden:
1729    # disabled so far, doesn't work
1730##    for hidden_value, expected_size, expected_minus1 in cases:
1731##        ffi = FFI()
1732##        ffi.cdef("enum foo_e { AA, BB, ... };")
1733##        lib = ffi.verify("enum foo_e { AA, BB=%s };" % hidden_value)
1734##        assert lib.AA == 0
1735##        assert ffi.sizeof("enum foo_e") == expected_size
1736##        assert int(ffi.cast("enum foo_e", -1)) == expected_minus1
1737
1738def test_enum_bug118():
1739    maxulong = 256 ** FFI().sizeof("unsigned long") - 1
1740    for c2, c2c in [(-1, ''),
1741                    (-1, ''),
1742                    (0xffffffff, 'U'),
1743                    (maxulong, 'UL'),
1744                    (-int(maxulong / 3), 'L')]:
1745        if c2c and sys.platform == 'win32':
1746            continue     # enums may always be signed with MSVC
1747        ffi = FFI()
1748        ffi.cdef("enum foo_e { AA };")
1749        lib = ffi.verify("enum foo_e { AA=%s%s };" % (c2, c2c))
1750        assert lib.AA == c2
1751
1752def test_string_to_voidp_arg():
1753    ffi = FFI()
1754    ffi.cdef("int myfunc(void *);")
1755    lib = ffi.verify("int myfunc(void *p) { return ((signed char *)p)[0]; }")
1756    res = lib.myfunc(b"hi!")
1757    assert res == ord(b"h")
1758    p = ffi.new("char[]", b"gah")
1759    res = lib.myfunc(p)
1760    assert res == ord(b"g")
1761    res = lib.myfunc(ffi.cast("void *", p))
1762    assert res == ord(b"g")
1763    res = lib.myfunc(ffi.cast("int *", p))
1764    assert res == ord(b"g")
1765
1766def test_callback_indirection():
1767    ffi = FFI()
1768    ffi.cdef("""
1769        static int (*python_callback)(int how_many, int *values);
1770        int (*const c_callback)(int,...);   /* pass this ptr to C routines */
1771        int some_c_function(int(*cb)(int,...));
1772    """)
1773    lib = ffi.verify("""
1774        #include <stdarg.h>
1775        #ifdef _WIN32
1776        #include <malloc.h>
1777        #define alloca _alloca
1778        #else
1779        # ifdef __FreeBSD__
1780        #  include <stdlib.h>
1781        # else
1782        #  include <alloca.h>
1783        # endif
1784        #endif
1785        static int (*python_callback)(int how_many, int *values);
1786        static int c_callback(int how_many, ...) {
1787            va_list ap;
1788            /* collect the "..." arguments into the values[] array */
1789            int i, *values = alloca((size_t)how_many * sizeof(int));
1790            va_start(ap, how_many);
1791            for (i=0; i<how_many; i++)
1792                values[i] = va_arg(ap, int);
1793            va_end(ap);
1794            return python_callback(how_many, values);
1795        }
1796        int some_c_function(int(*cb)(int,...)) {
1797            int result = cb(2, 10, 20);
1798            result += cb(3, 30, 40, 50);
1799            return result;
1800        }
1801    """)
1802    seen = []
1803    @ffi.callback("int(int, int*)")
1804    def python_callback(how_many, values):
1805        seen.append([values[i] for i in range(how_many)])
1806        return 42
1807    lib.python_callback = python_callback
1808
1809    res = lib.some_c_function(lib.c_callback)
1810    assert res == 84
1811    assert seen == [[10, 20], [30, 40, 50]]
1812
1813def test_floatstar_argument():
1814    ffi = FFI()
1815    ffi.cdef("float sum3floats(float *);")
1816    lib = ffi.verify("""
1817        float sum3floats(float *f) {
1818            return f[0] + f[1] + f[2];
1819        }
1820    """)
1821    assert lib.sum3floats((1.5, 2.5, 3.5)) == 7.5
1822    p = ffi.new("float[]", (1.5, 2.5, 3.5))
1823    assert lib.sum3floats(p) == 7.5
1824
1825def test_charstar_argument():
1826    ffi = FFI()
1827    ffi.cdef("char sum3chars(char *);")
1828    lib = ffi.verify("""
1829        char sum3chars(char *f) {
1830            return (char)(f[0] + f[1] + f[2]);
1831        }
1832    """)
1833    assert lib.sum3chars((b'\x10', b'\x20', b'\x30')) == b'\x60'
1834    p = ffi.new("char[]", b'\x10\x20\x30')
1835    assert lib.sum3chars(p) == b'\x60'
1836
1837def test_passing_string_or_NULL():
1838    ffi = FFI()
1839    ffi.cdef("int seeme1(char *); int seeme2(int *);")
1840    lib = ffi.verify("""
1841        int seeme1(char *x) {
1842            return (x == NULL);
1843        }
1844        int seeme2(int *x) {
1845            return (x == NULL);
1846        }
1847    """)
1848    assert lib.seeme1(b"foo") == 0
1849    assert lib.seeme1(ffi.NULL) == 1
1850    assert lib.seeme2([42, 43]) == 0
1851    assert lib.seeme2(ffi.NULL) == 1
1852    py.test.raises(TypeError, lib.seeme1, None)
1853    py.test.raises(TypeError, lib.seeme2, None)
1854    py.test.raises(TypeError, lib.seeme1, 0.0)
1855    py.test.raises(TypeError, lib.seeme2, 0.0)
1856    py.test.raises(TypeError, lib.seeme1, 0)
1857    py.test.raises(TypeError, lib.seeme2, 0)
1858    zeroL  = 99999999999999999999
1859    zeroL -= 99999999999999999999
1860    py.test.raises(TypeError, lib.seeme2, zeroL)
1861
1862def test_typeof_function():
1863    ffi = FFI()
1864    ffi.cdef("int foo(int, char);")
1865    lib = ffi.verify("int foo(int x, char y) { (void)x; (void)y; return 42; }")
1866    ctype = ffi.typeof(lib.foo)
1867    assert len(ctype.args) == 2
1868    assert ctype.result == ffi.typeof("int")
1869
1870def test_call_with_voidstar_arg():
1871    ffi = FFI()
1872    ffi.cdef("int f(void *);")
1873    lib = ffi.verify("int f(void *x) { return ((char*)x)[0]; }")
1874    assert lib.f(b"foobar") == ord(b"f")
1875
1876def test_dir():
1877    ffi = FFI()
1878    ffi.cdef("""void somefunc(void);
1879                extern int somevar, somearray[2];
1880                static char *const sv2;
1881                enum my_e { AA, BB, ... };
1882                #define FOO ...""")
1883    lib = ffi.verify("""void somefunc(void) { }
1884                        int somevar, somearray[2];
1885                        #define sv2 "text"
1886                        enum my_e { AA, BB };
1887                        #define FOO 42""")
1888    assert dir(lib) == ['AA', 'BB', 'FOO', 'somearray',
1889                        'somefunc', 'somevar', 'sv2']
1890
1891def test_typeof_func_with_struct_argument():
1892    ffi = FFI()
1893    ffi.cdef("""struct s { int a; }; int foo(struct s);""")
1894    lib = ffi.verify("""struct s { int a; };
1895                        int foo(struct s x) { return x.a; }""")
1896    s = ffi.new("struct s *", [-1234])
1897    m = lib.foo(s[0])
1898    assert m == -1234
1899    assert repr(ffi.typeof(lib.foo)) == "<ctype 'int(*)(struct s)'>"
1900
1901def test_bug_const_char_ptr_array_1():
1902    ffi = FFI()
1903    ffi.cdef("""extern const char *a[...];""")
1904    lib = ffi.verify("""const char *a[5];""")
1905    assert repr(ffi.typeof(lib.a)) == "<ctype 'char *[5]'>"
1906
1907def test_bug_const_char_ptr_array_2():
1908    ffi = FFI()
1909    ffi.cdef("""extern const int a[];""")
1910    lib = ffi.verify("""const int a[5];""")
1911    assert repr(ffi.typeof(lib.a)) == "<ctype 'int *'>"
1912
1913def _test_various_calls(force_libffi):
1914    cdef_source = """
1915    extern int xvalue;
1916    extern long long ivalue, rvalue;
1917    extern float fvalue;
1918    extern double dvalue;
1919    extern long double Dvalue;
1920    signed char tf_bb(signed char x, signed char c);
1921    unsigned char tf_bB(signed char x, unsigned char c);
1922    short tf_bh(signed char x, short c);
1923    unsigned short tf_bH(signed char x, unsigned short c);
1924    int tf_bi(signed char x, int c);
1925    unsigned int tf_bI(signed char x, unsigned int c);
1926    long tf_bl(signed char x, long c);
1927    unsigned long tf_bL(signed char x, unsigned long c);
1928    long long tf_bq(signed char x, long long c);
1929    unsigned long long tf_bQ(signed char x, unsigned long long c);
1930    float tf_bf(signed char x, float c);
1931    double tf_bd(signed char x, double c);
1932    long double tf_bD(signed char x, long double c);
1933    """
1934    if force_libffi:
1935        cdef_source = (cdef_source
1936            .replace('tf_', '(*const tf_')
1937            .replace('(signed char x', ')(signed char x'))
1938    ffi = FFI()
1939    ffi.cdef(cdef_source)
1940    lib = ffi.verify("""
1941    int xvalue;
1942    long long ivalue, rvalue;
1943    float fvalue;
1944    double dvalue;
1945    long double Dvalue;
1946
1947    typedef signed char b_t;
1948    typedef unsigned char B_t;
1949    typedef short h_t;
1950    typedef unsigned short H_t;
1951    typedef int i_t;
1952    typedef unsigned int I_t;
1953    typedef long l_t;
1954    typedef unsigned long L_t;
1955    typedef long long q_t;
1956    typedef unsigned long long Q_t;
1957    typedef float f_t;
1958    typedef double d_t;
1959    typedef long double D_t;
1960    #define S(letter)  xvalue = (int)x; letter##value = (letter##_t)c;
1961    #define R(letter)  return (letter##_t)rvalue;
1962
1963    signed char tf_bb(signed char x, signed char c) { S(i) R(b) }
1964    unsigned char tf_bB(signed char x, unsigned char c) { S(i) R(B) }
1965    short tf_bh(signed char x, short c) { S(i) R(h) }
1966    unsigned short tf_bH(signed char x, unsigned short c) { S(i) R(H) }
1967    int tf_bi(signed char x, int c) { S(i) R(i) }
1968    unsigned int tf_bI(signed char x, unsigned int c) { S(i) R(I) }
1969    long tf_bl(signed char x, long c) { S(i) R(l) }
1970    unsigned long tf_bL(signed char x, unsigned long c) { S(i) R(L) }
1971    long long tf_bq(signed char x, long long c) { S(i) R(q) }
1972    unsigned long long tf_bQ(signed char x, unsigned long long c) { S(i) R(Q) }
1973    float tf_bf(signed char x, float c) { S(f) R(f) }
1974    double tf_bd(signed char x, double c) { S(d) R(d) }
1975    long double tf_bD(signed char x, long double c) { S(D) R(D) }
1976    """)
1977    lib.rvalue = 0x7182838485868788
1978    for kind, cname in [('b', 'signed char'),
1979                        ('B', 'unsigned char'),
1980                        ('h', 'short'),
1981                        ('H', 'unsigned short'),
1982                        ('i', 'int'),
1983                        ('I', 'unsigned int'),
1984                        ('l', 'long'),
1985                        ('L', 'unsigned long'),
1986                        ('q', 'long long'),
1987                        ('Q', 'unsigned long long'),
1988                        ('f', 'float'),
1989                        ('d', 'double'),
1990                        ('D', 'long double')]:
1991        sign = +1 if 'unsigned' in cname else -1
1992        lib.xvalue = 0
1993        lib.ivalue = 0
1994        lib.fvalue = 0
1995        lib.dvalue = 0
1996        lib.Dvalue = 0
1997        fun = getattr(lib, 'tf_b' + kind)
1998        res = fun(-42, sign * 99)
1999        if kind == 'D':
2000            res = float(res)
2001        assert res == int(ffi.cast(cname, 0x7182838485868788))
2002        assert lib.xvalue == -42
2003        if kind in 'fdD':
2004            assert float(getattr(lib, kind + 'value')) == -99.0
2005        else:
2006            assert lib.ivalue == sign * 99
2007
2008def test_various_calls_direct():
2009    _test_various_calls(force_libffi=False)
2010
2011def test_various_calls_libffi():
2012    _test_various_calls(force_libffi=True)
2013
2014def test_ptr_to_opaque():
2015    ffi = FFI()
2016    ffi.cdef("typedef ... foo_t; int f1(foo_t*); foo_t *f2(int);")
2017    lib = ffi.verify("""
2018        #include <stdlib.h>
2019        typedef struct { int x; } foo_t;
2020        int f1(foo_t* p) {
2021            int x = p->x;
2022            free(p);
2023            return x;
2024        }
2025        foo_t *f2(int x) {
2026            foo_t *p = malloc(sizeof(foo_t));
2027            p->x = x;
2028            return p;
2029        }
2030    """)
2031    p = lib.f2(42)
2032    x = lib.f1(p)
2033    assert x == 42
2034
2035def _run_in_multiple_threads(test1):
2036    test1()
2037    import sys
2038    try:
2039        import thread
2040    except ImportError:
2041        import _thread as thread
2042    errors = []
2043    def wrapper(lock):
2044        try:
2045            test1()
2046        except:
2047            errors.append(sys.exc_info())
2048        lock.release()
2049    locks = []
2050    for i in range(10):
2051        _lock = thread.allocate_lock()
2052        _lock.acquire()
2053        thread.start_new_thread(wrapper, (_lock,))
2054        locks.append(_lock)
2055    for _lock in locks:
2056        _lock.acquire()
2057        if errors:
2058            raise errors[0][1]
2059
2060def test_errno_working_even_with_pypys_jit():
2061    ffi = FFI()
2062    ffi.cdef("int f(int);")
2063    lib = ffi.verify("""
2064        #include <errno.h>
2065        int f(int x) { return (errno = errno + x); }
2066    """)
2067    @_run_in_multiple_threads
2068    def test1():
2069        ffi.errno = 0
2070        for i in range(10000):
2071            e = lib.f(1)
2072            assert e == i + 1
2073            assert ffi.errno == e
2074        for i in range(10000):
2075            ffi.errno = i
2076            e = lib.f(42)
2077            assert e == i + 42
2078
2079def test_getlasterror_working_even_with_pypys_jit():
2080    if sys.platform != 'win32':
2081        py.test.skip("win32-only test")
2082    ffi = FFI()
2083    ffi.cdef("void SetLastError(DWORD);")
2084    lib = ffi.dlopen("Kernel32.dll")
2085    @_run_in_multiple_threads
2086    def test1():
2087        for i in range(10000):
2088            n = (1 << 29) + i
2089            lib.SetLastError(n)
2090            assert ffi.getwinerror()[0] == n
2091
2092def test_verify_dlopen_flags():
2093    if not hasattr(sys, 'setdlopenflags'):
2094        py.test.skip("requires sys.setdlopenflags()")
2095    # Careful with RTLD_GLOBAL.  If by chance the FFI is not deleted
2096    # promptly, like on PyPy, then other tests may see the same
2097    # exported symbols as well.  So we must not export a simple name
2098    # like 'foo'!
2099    old = sys.getdlopenflags()
2100    try:
2101        ffi1 = FFI()
2102        ffi1.cdef("extern int foo_verify_dlopen_flags_1;")
2103        sys.setdlopenflags(ffi1.RTLD_GLOBAL | ffi1.RTLD_NOW)
2104        lib1 = ffi1.verify("int foo_verify_dlopen_flags_1;")
2105    finally:
2106        sys.setdlopenflags(old)
2107
2108    ffi2 = FFI()
2109    ffi2.cdef("int *getptr(void);")
2110    lib2 = ffi2.verify("""
2111        extern int foo_verify_dlopen_flags_1;
2112        static int *getptr(void) { return &foo_verify_dlopen_flags_1; }
2113    """)
2114    p = lib2.getptr()
2115    assert ffi1.addressof(lib1, 'foo_verify_dlopen_flags_1') == p
2116
2117def test_consider_not_implemented_function_type():
2118    ffi = FFI()
2119    ffi.cdef("typedef union { int a; float b; } Data;"
2120             "typedef struct { int a:2; } MyStr;"
2121             "typedef void (*foofunc_t)(Data);"
2122             "typedef Data (*bazfunc_t)(void);"
2123             "typedef MyStr (*barfunc_t)(void);")
2124    fooptr = ffi.cast("foofunc_t", 123)
2125    bazptr = ffi.cast("bazfunc_t", 123)
2126    barptr = ffi.cast("barfunc_t", 123)
2127    # assert did not crash so far
2128    e = py.test.raises(NotImplementedError, fooptr, ffi.new("Data *"))
2129    assert str(e.value) == (
2130        "ctype 'Data' not supported as argument by libffi.  Unions are only "
2131        "supported as argument if the function is 'API mode' and "
2132        "non-variadic (i.e. declared inside ffibuilder.cdef()+"
2133        "ffibuilder.set_source() and not taking a final '...' argument)")
2134    e = py.test.raises(NotImplementedError, bazptr)
2135    assert str(e.value) == (
2136        "ctype 'Data' not supported as return value by libffi.  Unions are "
2137        "only supported as return value if the function is 'API mode' and "
2138        "non-variadic (i.e. declared inside ffibuilder.cdef()+"
2139        "ffibuilder.set_source() and not taking a final '...' argument)")
2140    e = py.test.raises(NotImplementedError, barptr)
2141    assert str(e.value) == (
2142        "ctype 'MyStr' not supported as return value.  It is a struct with "
2143        "bit fields, which libffi does not support.  Such structs are only "
2144        "supported as return value if the function is 'API mode' and non-"
2145        "variadic (i.e. declared inside ffibuilder.cdef()+ffibuilder."
2146        "set_source() and not taking a final '...' argument)")
2147
2148def test_verify_extra_arguments():
2149    ffi = FFI()
2150    ffi.cdef("#define ABA ...")
2151    lib = ffi.verify("", define_macros=[('ABA', '42')])
2152    assert lib.ABA == 42
2153
2154def test_implicit_unicode_on_windows():
2155    from cffi import FFIError
2156    if sys.platform != 'win32':
2157        py.test.skip("win32-only test")
2158    ffi = FFI()
2159    e = py.test.raises(FFIError, ffi.cdef, "int foo(LPTSTR);")
2160    assert str(e.value) == ("The Windows type 'LPTSTR' is only available after"
2161                            " you call ffi.set_unicode()")
2162    for with_unicode in [True, False]:
2163        ffi = FFI()
2164        ffi.set_unicode(with_unicode)
2165        ffi.cdef("""
2166            DWORD GetModuleFileName(HMODULE hModule, LPTSTR lpFilename,
2167                                    DWORD nSize);
2168        """)
2169        lib = ffi.verify("""
2170            #include <windows.h>
2171        """, libraries=['Kernel32'])
2172        outbuf = ffi.new("TCHAR[]", 200)
2173        n = lib.GetModuleFileName(ffi.NULL, outbuf, 500)
2174        assert 0 < n < 500
2175        for i in range(n):
2176            #print repr(outbuf[i])
2177            assert ord(outbuf[i]) != 0
2178        assert ord(outbuf[n]) == 0
2179        assert ord(outbuf[0]) < 128     # should be a letter, or '\'
2180
2181def test_define_known_value():
2182    ffi = FFI()
2183    ffi.cdef("#define FOO 0x123")
2184    lib = ffi.verify("#define FOO 0x123")
2185    assert lib.FOO == 0x123
2186
2187def test_define_wrong_value():
2188    ffi = FFI()
2189    ffi.cdef("#define FOO 123")
2190    lib = ffi.verify("#define FOO 124")     # used to complain
2191    with pytest.raises(ffi.error) as e:
2192        lib.FOO
2193    assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c),"
2194                            " but the cdef disagrees")
2195
2196def test_some_integer_type_for_issue73():
2197    ffi = FFI()
2198    ffi.cdef("""
2199        typedef int... AnIntegerWith32Bits;
2200        typedef AnIntegerWith32Bits (*AFunctionReturningInteger) (void);
2201        AnIntegerWith32Bits InvokeFunction(AFunctionReturningInteger);
2202    """)
2203    lib = ffi.verify("""
2204        #ifdef __LP64__
2205        typedef int AnIntegerWith32Bits;
2206        #else
2207        typedef long AnIntegerWith32Bits;
2208        #endif
2209        typedef AnIntegerWith32Bits (*AFunctionReturningInteger) (void);
2210        AnIntegerWith32Bits InvokeFunction(AFunctionReturningInteger f) {
2211            return f();
2212        }
2213    """)
2214    @ffi.callback("AFunctionReturningInteger")
2215    def add():
2216        return 3 + 4
2217    x = lib.InvokeFunction(add)
2218    assert x == 7
2219
2220def test_unsupported_some_primitive_types():
2221    ffi = FFI()
2222    py.test.raises((FFIError,      # with pycparser <= 2.17
2223                    CDefError),    # with pycparser >= 2.18
2224                   ffi.cdef, """typedef void... foo_t;""")
2225    #
2226    ffi.cdef("typedef int... foo_t;")
2227    py.test.raises(VerificationError, ffi.verify, "typedef float foo_t;")
2228
2229def test_windows_dllimport_data():
2230    if sys.platform != 'win32':
2231        py.test.skip("Windows only")
2232    from testing.udir import udir
2233    tmpfile = udir.join('dllimport_data.c')
2234    tmpfile.write('int my_value = 42;\n')
2235    ffi = FFI()
2236    ffi.cdef("int my_value;")
2237    lib = ffi.verify("extern __declspec(dllimport) int my_value;",
2238                     sources = [str(tmpfile)])
2239    assert lib.my_value == 42
2240
2241def test_macro_var():
2242    ffi = FFI()
2243    ffi.cdef("extern int myarray[50], my_value;")
2244    lib = ffi.verify("""
2245        int myarray[50];
2246        int *get_my_value(void) {
2247            static int index = 0;
2248            return &myarray[index++];
2249        }
2250        #define my_value (*get_my_value())
2251    """)
2252    assert lib.my_value == 0             # [0]
2253    lib.my_value = 42                    # [1]
2254    assert lib.myarray[1] == 42
2255    assert lib.my_value == 0             # [2]
2256    lib.myarray[3] = 63
2257    assert lib.my_value == 63            # [3]
2258    p = ffi.addressof(lib, 'my_value')   # [4]
2259    assert p[-1] == 63
2260    assert p[0] == 0
2261    assert p == lib.myarray + 4
2262    p[1] = 82
2263    assert lib.my_value == 82            # [5]
2264
2265def test_const_pointer_to_pointer():
2266    ffi = FFI()
2267    ffi.cdef("struct s { char *const *a; };")
2268    ffi.verify("struct s { char *const *a; };")
2269
2270def test_share_FILE():
2271    ffi1 = FFI()
2272    ffi1.cdef("void do_stuff(FILE *);")
2273    lib1 = ffi1.verify("void do_stuff(FILE *f) { (void)f; }")
2274    ffi2 = FFI()
2275    ffi2.cdef("FILE *barize(void);")
2276    lib2 = ffi2.verify("FILE *barize(void) { return NULL; }")
2277    lib1.do_stuff(lib2.barize())
2278
2279def test_win_common_types():
2280    if sys.platform != 'win32':
2281        py.test.skip("Windows only")
2282    ffi = FFI()
2283    ffi.set_unicode(True)
2284    ffi.verify("")
2285    assert ffi.typeof("PBYTE") is ffi.typeof("unsigned char *")
2286    if sys.maxsize > 2**32:
2287        expected = "unsigned long long"
2288    else:
2289        expected = "unsigned int"
2290    assert ffi.typeof("UINT_PTR") is ffi.typeof(expected)
2291    assert ffi.typeof("PTSTR") is ffi.typeof("wchar_t *")
2292
2293def _only_test_on_linux_intel():
2294    if not sys.platform.startswith('linux'):
2295        py.test.skip('only running the memory-intensive test on Linux')
2296    import platform
2297    machine = platform.machine()
2298    if 'x86' not in machine and 'x64' not in machine:
2299        py.test.skip('only running the memory-intensive test on x86/x64')
2300
2301def test_ffi_gc_size_arg():
2302    _only_test_on_linux_intel()
2303    ffi = FFI()
2304    ffi.cdef("void *malloc(size_t); void free(void *);")
2305    lib = ffi.verify(r"""
2306        #include <stdlib.h>
2307    """)
2308    for i in range(2000):
2309        p = lib.malloc(20*1024*1024)    # 20 MB
2310        p1 = ffi.cast("char *", p)
2311        for j in range(0, 20*1024*1024, 4096):
2312            p1[j] = b'!'
2313        p = ffi.gc(p, lib.free, 20*1024*1024)
2314        del p
2315        # with PyPy's GC, the above would rapidly consume 40 GB of RAM
2316        # without the third argument to ffi.gc()
2317
2318def test_ffi_gc_size_arg_2():
2319    # a variant of the above: this "attack" works on cpython's cyclic gc too
2320    # and I found no obvious way to prevent that.  So for now, this test
2321    # is skipped on CPython, where it eats all the memory.
2322    if '__pypy__' not in sys.builtin_module_names:
2323        py.test.skip("find a way to tweak the cyclic GC of CPython")
2324    _only_test_on_linux_intel()
2325    ffi = FFI()
2326    ffi.cdef("void *malloc(size_t); void free(void *);")
2327    lib = ffi.verify(r"""
2328        #include <stdlib.h>
2329    """)
2330    class X(object):
2331        pass
2332    for i in range(2000):
2333        p = lib.malloc(50*1024*1024)    # 50 MB
2334        p1 = ffi.cast("char *", p)
2335        for j in range(0, 50*1024*1024, 4096):
2336            p1[j] = b'!'
2337        p = ffi.gc(p, lib.free, 50*1024*1024)
2338        x = X()
2339        x.p = p
2340        x.cyclic = x
2341        del p, x
2342
2343def test_ffi_new_with_cycles():
2344    # still another variant, with ffi.new()
2345    if '__pypy__' not in sys.builtin_module_names:
2346        py.test.skip("find a way to tweak the cyclic GC of CPython")
2347    ffi = FFI()
2348    ffi.cdef("")
2349    lib = ffi.verify("")
2350    class X(object):
2351        pass
2352    for i in range(2000):
2353        p = ffi.new("char[]", 50*1024*1024)    # 50 MB
2354        for j in range(0, 50*1024*1024, 4096):
2355            p[j] = b'!'
2356        x = X()
2357        x.p = p
2358        x.cyclic = x
2359        del p, x
2360