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