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