1
2import sys, os, py
3from cffi import FFI, VerificationError, FFIError, CDefError
4from cffi import recompiler
5from testing.udir import udir
6from testing.support import u, long
7from testing.support import FdWriteCapture, StdErrCapture, _verify
8
9try:
10    import importlib
11except ImportError:
12    importlib = None
13
14
15def check_type_table(input, expected_output, included=None):
16    ffi = FFI()
17    if included:
18        ffi1 = FFI()
19        ffi1.cdef(included)
20        ffi.include(ffi1)
21    ffi.cdef(input)
22    recomp = recompiler.Recompiler(ffi, 'testmod')
23    recomp.collect_type_table()
24    assert ''.join(map(str, recomp.cffi_types)) == expected_output
25
26def verify(ffi, module_name, source, *args, **kwds):
27    no_cpp = kwds.pop('no_cpp', False)
28    kwds.setdefault('undef_macros', ['NDEBUG'])
29    module_name = '_CFFI_' + module_name
30    ffi.set_source(module_name, source)
31    if not os.environ.get('NO_CPP') and not no_cpp:   # test the .cpp mode too
32        kwds.setdefault('source_extension', '.cpp')
33        source = 'extern "C" {\n%s\n}' % (source,)
34    elif sys.platform != 'win32':
35        # add '-Werror' to the existing 'extra_compile_args' flags
36        kwds['extra_compile_args'] = (kwds.get('extra_compile_args', []) +
37                                      ['-Werror'])
38    return _verify(ffi, module_name, source, *args, **kwds)
39
40def test_set_source_no_slashes():
41    ffi = FFI()
42    py.test.raises(ValueError, ffi.set_source, "abc/def", None)
43    py.test.raises(ValueError, ffi.set_source, "abc/def", "C code")
44
45
46def test_type_table_func():
47    check_type_table("double sin(double);",
48                     "(FUNCTION 1)(PRIMITIVE 14)(FUNCTION_END 0)")
49    check_type_table("float sin(double);",
50                     "(FUNCTION 3)(PRIMITIVE 14)(FUNCTION_END 0)(PRIMITIVE 13)")
51    check_type_table("float sin(void);",
52                     "(FUNCTION 2)(FUNCTION_END 0)(PRIMITIVE 13)")
53    check_type_table("double sin(float); double cos(float);",
54                     "(FUNCTION 3)(PRIMITIVE 13)(FUNCTION_END 0)(PRIMITIVE 14)")
55    check_type_table("double sin(float); double cos(double);",
56                     "(FUNCTION 1)(PRIMITIVE 14)(FUNCTION_END 0)"   # cos
57                     "(FUNCTION 1)(PRIMITIVE 13)(FUNCTION_END 0)")  # sin
58    check_type_table("float sin(double); float cos(float);",
59                     "(FUNCTION 4)(PRIMITIVE 14)(FUNCTION_END 0)"   # sin
60                     "(FUNCTION 4)(PRIMITIVE 13)(FUNCTION_END 0)")  # cos
61
62def test_type_table_use_noop_for_repeated_args():
63    check_type_table("double sin(double *, double *);",
64                     "(FUNCTION 4)(POINTER 4)(NOOP 1)(FUNCTION_END 0)"
65                     "(PRIMITIVE 14)")
66    check_type_table("double sin(double *, double *, double);",
67                     "(FUNCTION 3)(POINTER 3)(NOOP 1)(PRIMITIVE 14)"
68                     "(FUNCTION_END 0)")
69
70def test_type_table_dont_use_noop_for_primitives():
71    check_type_table("double sin(double, double);",
72                     "(FUNCTION 1)(PRIMITIVE 14)(PRIMITIVE 14)(FUNCTION_END 0)")
73
74def test_type_table_funcptr_as_argument():
75    check_type_table("int sin(double(float));",
76                     "(FUNCTION 6)(PRIMITIVE 13)(FUNCTION_END 0)"
77                     "(FUNCTION 7)(POINTER 0)(FUNCTION_END 0)"
78                     "(PRIMITIVE 14)(PRIMITIVE 7)")
79
80def test_type_table_variadic_function():
81    check_type_table("int sin(int, ...);",
82                     "(FUNCTION 1)(PRIMITIVE 7)(FUNCTION_END 1)(POINTER 0)")
83
84def test_type_table_array():
85    check_type_table("int a[100];",
86                     "(PRIMITIVE 7)(ARRAY 0)(None 100)")
87
88def test_type_table_typedef():
89    check_type_table("typedef int foo_t;",
90                     "(PRIMITIVE 7)")
91
92def test_type_table_prebuilt_type():
93    check_type_table("int32_t f(void);",
94                     "(FUNCTION 2)(FUNCTION_END 0)(PRIMITIVE 21)")
95
96def test_type_table_struct_opaque():
97    check_type_table("struct foo_s;",
98                     "(STRUCT_UNION 0)")
99
100def test_type_table_struct():
101    check_type_table("struct foo_s { int a; long b; };",
102                     "(PRIMITIVE 7)(PRIMITIVE 9)(STRUCT_UNION 0)")
103
104def test_type_table_union():
105    check_type_table("union foo_u { int a; long b; };",
106                     "(PRIMITIVE 7)(PRIMITIVE 9)(STRUCT_UNION 0)")
107
108def test_type_table_struct_used():
109    check_type_table("struct foo_s { int a; long b; }; int f(struct foo_s*);",
110                     "(FUNCTION 3)(POINTER 5)(FUNCTION_END 0)"
111                     "(PRIMITIVE 7)(PRIMITIVE 9)"
112                     "(STRUCT_UNION 0)")
113
114def test_type_table_anonymous_struct_with_typedef():
115    check_type_table("typedef struct { int a; long b; } foo_t;",
116                     "(STRUCT_UNION 0)(PRIMITIVE 7)(PRIMITIVE 9)")
117
118def test_type_table_enum():
119    check_type_table("enum foo_e { AA, BB, ... };",
120                     "(ENUM 0)")
121
122def test_type_table_include_1():
123    check_type_table("foo_t sin(foo_t);",
124                     "(FUNCTION 1)(PRIMITIVE 14)(FUNCTION_END 0)",
125                     included="typedef double foo_t;")
126
127def test_type_table_include_2():
128    check_type_table("struct foo_s *sin(struct foo_s *);",
129                     "(FUNCTION 1)(POINTER 3)(FUNCTION_END 0)(STRUCT_UNION 0)",
130                     included="struct foo_s { int x, y; };")
131
132
133def test_math_sin():
134    import math
135    ffi = FFI()
136    ffi.cdef("float sin(double); double cos(double);")
137    lib = verify(ffi, 'test_math_sin', '#include <math.h>')
138    assert lib.cos(1.43) == math.cos(1.43)
139
140def test_repr_lib():
141    ffi = FFI()
142    lib = verify(ffi, 'test_repr_lib', '')
143    assert repr(lib) == "<Lib object for '_CFFI_test_repr_lib'>"
144
145def test_funcarg_ptr():
146    ffi = FFI()
147    ffi.cdef("int foo(int *);")
148    lib = verify(ffi, 'test_funcarg_ptr', 'int foo(int *p) { return *p; }')
149    assert lib.foo([-12345]) == -12345
150
151def test_funcres_ptr():
152    ffi = FFI()
153    ffi.cdef("int *foo(void);")
154    lib = verify(ffi, 'test_funcres_ptr',
155                 'int *foo(void) { static int x=-12345; return &x; }')
156    assert lib.foo()[0] == -12345
157
158def test_global_var_array():
159    ffi = FFI()
160    ffi.cdef("int a[100];")
161    lib = verify(ffi, 'test_global_var_array', 'int a[100] = { 9999 };')
162    lib.a[42] = 123456
163    assert lib.a[42] == 123456
164    assert lib.a[0] == 9999
165
166def test_verify_typedef():
167    ffi = FFI()
168    ffi.cdef("typedef int **foo_t;")
169    lib = verify(ffi, 'test_verify_typedef', 'typedef int **foo_t;')
170    assert ffi.sizeof("foo_t") == ffi.sizeof("void *")
171
172def test_verify_typedef_dotdotdot():
173    ffi = FFI()
174    ffi.cdef("typedef ... foo_t;")
175    verify(ffi, 'test_verify_typedef_dotdotdot', 'typedef int **foo_t;')
176
177def test_verify_typedef_star_dotdotdot():
178    ffi = FFI()
179    ffi.cdef("typedef ... *foo_t;")
180    verify(ffi, 'test_verify_typedef_star_dotdotdot', 'typedef int **foo_t;')
181
182def test_global_var_int():
183    ffi = FFI()
184    ffi.cdef("int a, b, c;")
185    lib = verify(ffi, 'test_global_var_int', 'int a = 999, b, c;')
186    assert lib.a == 999
187    lib.a -= 1001
188    assert lib.a == -2
189    lib.a = -2147483648
190    assert lib.a == -2147483648
191    py.test.raises(OverflowError, "lib.a = 2147483648")
192    py.test.raises(OverflowError, "lib.a = -2147483649")
193    lib.b = 525      # try with the first access being in setattr, too
194    assert lib.b == 525
195    py.test.raises(AttributeError, "del lib.a")
196    py.test.raises(AttributeError, "del lib.c")
197    py.test.raises(AttributeError, "del lib.foobarbaz")
198
199def test_macro():
200    ffi = FFI()
201    ffi.cdef("#define FOOBAR ...")
202    lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)")
203    assert lib.FOOBAR == -6912
204    py.test.raises(AttributeError, "lib.FOOBAR = 2")
205
206def test_macro_check_value():
207    # the value '-0x80000000' in C sources does not have a clear meaning
208    # to me; it appears to have a different effect than '-2147483648'...
209    # Moreover, on 32-bits, -2147483648 is actually equal to
210    # -2147483648U, which in turn is equal to 2147483648U and so positive.
211    vals = ['42', '-42', '0x80000000', '-2147483648',
212            '0', '9223372036854775809ULL',
213            '-9223372036854775807LL']
214    if sys.maxsize <= 2**32 or sys.platform == 'win32':
215        vals.remove('-2147483648')
216    ffi = FFI()
217    cdef_lines = ['#define FOO_%d_%d %s' % (i, j, vals[i])
218                  for i in range(len(vals))
219                  for j in range(len(vals))]
220    ffi.cdef('\n'.join(cdef_lines))
221
222    verify_lines = ['#define FOO_%d_%d %s' % (i, j, vals[j])  # [j], not [i]
223                    for i in range(len(vals))
224                    for j in range(len(vals))]
225    lib = verify(ffi, 'test_macro_check_value_ok',
226                 '\n'.join(verify_lines))
227    #
228    for j in range(len(vals)):
229        c_got = int(vals[j].replace('U', '').replace('L', ''), 0)
230        c_compiler_msg = str(c_got)
231        if c_got > 0:
232            c_compiler_msg += ' (0x%x)' % (c_got,)
233        #
234        for i in range(len(vals)):
235            attrname = 'FOO_%d_%d' % (i, j)
236            if i == j:
237                x = getattr(lib, attrname)
238                assert x == c_got
239            else:
240                e = py.test.raises(ffi.error, getattr, lib, attrname)
241                assert str(e.value) == (
242                    "the C compiler says '%s' is equal to "
243                    "%s, but the cdef disagrees" % (attrname, c_compiler_msg))
244
245def test_constant():
246    ffi = FFI()
247    ffi.cdef("static const int FOOBAR;")
248    lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)")
249    assert lib.FOOBAR == -6912
250    py.test.raises(AttributeError, "lib.FOOBAR = 2")
251
252def test_check_value_of_static_const():
253    ffi = FFI()
254    ffi.cdef("static const int FOOBAR = 042;")
255    lib = verify(ffi, 'test_check_value_of_static_const',
256                 "#define FOOBAR (-6912)")
257    e = py.test.raises(ffi.error, getattr, lib, 'FOOBAR')
258    assert str(e.value) == (
259       "the C compiler says 'FOOBAR' is equal to -6912, but the cdef disagrees")
260
261def test_constant_nonint():
262    ffi = FFI()
263    ffi.cdef("static const double FOOBAR;")
264    lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)")
265    assert lib.FOOBAR == -6912.5
266    py.test.raises(AttributeError, "lib.FOOBAR = 2")
267
268def test_constant_ptr():
269    ffi = FFI()
270    ffi.cdef("static double *const FOOBAR;")
271    lib = verify(ffi, 'test_constant_ptr', "#define FOOBAR NULL")
272    assert lib.FOOBAR == ffi.NULL
273    assert ffi.typeof(lib.FOOBAR) == ffi.typeof("double *")
274
275def test_dir():
276    ffi = FFI()
277    ffi.cdef("int ff(int); int aa; static const int my_constant;")
278    lib = verify(ffi, 'test_dir', """
279        #define my_constant  (-45)
280        int aa;
281        int ff(int x) { return x+aa; }
282    """)
283    lib.aa = 5
284    assert dir(lib) == ['aa', 'ff', 'my_constant']
285    #
286    aaobj = lib.__dict__['aa']
287    assert not isinstance(aaobj, int)    # some internal object instead
288    assert lib.__dict__ == {
289        'ff': lib.ff,
290        'aa': aaobj,
291        'my_constant': -45}
292    lib.__dict__['ff'] = "??"
293    assert lib.ff(10) == 15
294
295def test_verify_opaque_struct():
296    ffi = FFI()
297    ffi.cdef("struct foo_s;")
298    lib = verify(ffi, 'test_verify_opaque_struct', "struct foo_s;")
299    assert ffi.typeof("struct foo_s").cname == "struct foo_s"
300
301def test_verify_opaque_union():
302    ffi = FFI()
303    ffi.cdef("union foo_s;")
304    lib = verify(ffi, 'test_verify_opaque_union', "union foo_s;")
305    assert ffi.typeof("union foo_s").cname == "union foo_s"
306
307def test_verify_struct():
308    ffi = FFI()
309    ffi.cdef("""struct foo_s { int b; short a; ...; };
310                struct bar_s { struct foo_s *f; };""")
311    lib = verify(ffi, 'test_verify_struct',
312                 """struct foo_s { short a; int b; };
313                    struct bar_s { struct foo_s *f; };""")
314    ffi.typeof("struct bar_s *")
315    p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648})
316    assert p.a == -32768
317    assert p.b == -2147483648
318    py.test.raises(OverflowError, "p.a -= 1")
319    py.test.raises(OverflowError, "p.b -= 1")
320    q = ffi.new("struct bar_s *", {'f': p})
321    assert q.f == p
322    #
323    assert ffi.offsetof("struct foo_s", "a") == 0
324    assert ffi.offsetof("struct foo_s", "b") == 4
325    assert ffi.offsetof(u+"struct foo_s", u+"b") == 4
326    #
327    py.test.raises(TypeError, ffi.addressof, p)
328    assert ffi.addressof(p[0]) == p
329    assert ffi.typeof(ffi.addressof(p[0])) is ffi.typeof("struct foo_s *")
330    assert ffi.typeof(ffi.addressof(p, "b")) is ffi.typeof("int *")
331    assert ffi.addressof(p, "b")[0] == p.b
332
333def test_verify_exact_field_offset():
334    ffi = FFI()
335    ffi.cdef("""struct foo_s { int b; short a; };""")
336    lib = verify(ffi, 'test_verify_exact_field_offset',
337                 """struct foo_s { short a; int b; };""")
338    e = py.test.raises(ffi.error, ffi.new, "struct foo_s *", [])    # lazily
339    assert str(e.value) == ("struct foo_s: wrong offset for field 'b' (cdef "
340                       'says 0, but C compiler says 4). fix it or use "...;" '
341                       "in the cdef for struct foo_s to make it flexible")
342
343def test_type_caching():
344    ffi1 = FFI(); ffi1.cdef("struct foo_s;")
345    ffi2 = FFI(); ffi2.cdef("struct foo_s;")    # different one!
346    lib1 = verify(ffi1, 'test_type_caching_1', 'struct foo_s;')
347    lib2 = verify(ffi2, 'test_type_caching_2', 'struct foo_s;')
348    # shared types
349    assert ffi1.typeof("long") is ffi2.typeof("long")
350    assert ffi1.typeof("long**") is ffi2.typeof("long * *")
351    assert ffi1.typeof("long(*)(int, ...)") is ffi2.typeof("long(*)(int, ...)")
352    # non-shared types
353    assert ffi1.typeof("struct foo_s") is not ffi2.typeof("struct foo_s")
354    assert ffi1.typeof("struct foo_s *") is not ffi2.typeof("struct foo_s *")
355    assert ffi1.typeof("struct foo_s*(*)()") is not (
356        ffi2.typeof("struct foo_s*(*)()"))
357    assert ffi1.typeof("void(*)(struct foo_s*)") is not (
358        ffi2.typeof("void(*)(struct foo_s*)"))
359
360def test_verify_enum():
361    ffi = FFI()
362    ffi.cdef("""enum e1 { B1, A1, ... }; enum e2 { B2, A2, ... };""")
363    lib = verify(ffi, 'test_verify_enum',
364                 "enum e1 { A1, B1, C1=%d };" % sys.maxsize +
365                 "enum e2 { A2, B2, C2 };")
366    ffi.typeof("enum e1")
367    ffi.typeof("enum e2")
368    assert lib.A1 == 0
369    assert lib.B1 == 1
370    assert lib.A2 == 0
371    assert lib.B2 == 1
372    assert ffi.sizeof("enum e1") == ffi.sizeof("long")
373    assert ffi.sizeof("enum e2") == ffi.sizeof("int")
374    assert repr(ffi.cast("enum e1", 0)) == "<cdata 'enum e1' 0: A1>"
375
376def test_duplicate_enum():
377    ffi = FFI()
378    ffi.cdef("enum e1 { A1, ... }; enum e2 { A1, ... };")
379    py.test.raises(VerificationError, verify, ffi, 'test_duplicate_enum',
380                    "enum e1 { A1 }; enum e2 { B1 };")
381
382def test_dotdotdot_length_of_array_field():
383    ffi = FFI()
384    ffi.cdef("struct foo_s { int a[...]; int b[...]; };")
385    verify(ffi, 'test_dotdotdot_length_of_array_field',
386           "struct foo_s { int a[42]; int b[11]; };")
387    assert ffi.sizeof("struct foo_s") == (42 + 11) * 4
388    p = ffi.new("struct foo_s *")
389    assert p.a[41] == p.b[10] == 0
390    py.test.raises(IndexError, "p.a[42]")
391    py.test.raises(IndexError, "p.b[11]")
392
393def test_dotdotdot_global_array():
394    ffi = FFI()
395    ffi.cdef("int aa[...]; int bb[...];")
396    lib = verify(ffi, 'test_dotdotdot_global_array',
397                 "int aa[41]; int bb[12];")
398    assert ffi.sizeof(lib.aa) == 41 * 4
399    assert ffi.sizeof(lib.bb) == 12 * 4
400    assert lib.aa[40] == lib.bb[11] == 0
401    py.test.raises(IndexError, "lib.aa[41]")
402    py.test.raises(IndexError, "lib.bb[12]")
403
404def test_misdeclared_field_1():
405    ffi = FFI()
406    ffi.cdef("struct foo_s { int a[5]; };")
407    try:
408        verify(ffi, 'test_misdeclared_field_1',
409               "struct foo_s { int a[6]; };")
410    except VerificationError:
411        pass    # ok, fail during compilation already (e.g. C++)
412    else:
413        assert ffi.sizeof("struct foo_s") == 24  # found by the actual C code
414        try:
415            # lazily build the fields and boom:
416            p = ffi.new("struct foo_s *")
417            p.a
418            assert False, "should have raised"
419        except ffi.error as e:
420            assert str(e).startswith("struct foo_s: wrong size for field 'a' "
421                                     "(cdef says 20, but C compiler says 24)")
422
423def test_open_array_in_struct():
424    ffi = FFI()
425    ffi.cdef("struct foo_s { int b; int a[]; };")
426    verify(ffi, 'test_open_array_in_struct',
427           "struct foo_s { int b; int a[]; };")
428    assert ffi.sizeof("struct foo_s") == 4
429    p = ffi.new("struct foo_s *", [5, [10, 20, 30, 40]])
430    assert p.a[2] == 30
431    assert ffi.sizeof(p) == ffi.sizeof("void *")
432    assert ffi.sizeof(p[0]) == 5 * ffi.sizeof("int")
433
434def test_math_sin_type():
435    ffi = FFI()
436    ffi.cdef("double sin(double); void *xxtestfunc();")
437    lib = verify(ffi, 'test_math_sin_type', """
438        #include <math.h>
439        void *xxtestfunc(void) { return 0; }
440    """)
441    # 'lib.sin' is typed as a <built-in method> object on lib
442    assert ffi.typeof(lib.sin).cname == "double(*)(double)"
443    # 'x' is another <built-in method> object on lib, made very indirectly
444    x = type(lib).__dir__.__get__(lib)
445    py.test.raises(TypeError, ffi.typeof, x)
446    #
447    # present on built-in functions on CPython; must be emulated on PyPy:
448    assert lib.sin.__name__ == 'sin'
449    assert lib.sin.__module__ == '_CFFI_test_math_sin_type'
450    assert lib.sin.__doc__ == (
451        "double sin(double);\n"
452        "\n"
453        "CFFI C function from _CFFI_test_math_sin_type.lib")
454
455    assert ffi.typeof(lib.xxtestfunc).cname == "void *(*)()"
456    assert lib.xxtestfunc.__doc__ == (
457        "void *xxtestfunc();\n"
458        "\n"
459        "CFFI C function from _CFFI_test_math_sin_type.lib")
460
461def test_verify_anonymous_struct_with_typedef():
462    ffi = FFI()
463    ffi.cdef("typedef struct { int a; long b; ...; } foo_t;")
464    verify(ffi, 'test_verify_anonymous_struct_with_typedef',
465           "typedef struct { long b; int hidden, a; } foo_t;")
466    p = ffi.new("foo_t *", {'b': 42})
467    assert p.b == 42
468    assert repr(p).startswith("<cdata 'foo_t *' ")
469
470def test_verify_anonymous_struct_with_star_typedef():
471    ffi = FFI()
472    ffi.cdef("typedef struct { int a; long b; } *foo_t;")
473    verify(ffi, 'test_verify_anonymous_struct_with_star_typedef',
474           "typedef struct { int a; long b; } *foo_t;")
475    p = ffi.new("foo_t", {'b': 42})
476    assert p.b == 42
477
478def test_verify_anonymous_enum_with_typedef():
479    ffi = FFI()
480    ffi.cdef("typedef enum { AA, ... } e1;")
481    lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef1',
482                 "typedef enum { BB, CC, AA } e1;")
483    assert lib.AA == 2
484    assert ffi.sizeof("e1") == ffi.sizeof("int")
485    assert repr(ffi.cast("e1", 2)) == "<cdata 'e1' 2: AA>"
486    #
487    ffi = FFI()
488    ffi.cdef("typedef enum { AA=%d } e1;" % sys.maxsize)
489    lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef2',
490                 "typedef enum { AA=%d } e1;" % sys.maxsize)
491    assert lib.AA == int(ffi.cast("long", sys.maxsize))
492    assert ffi.sizeof("e1") == ffi.sizeof("long")
493
494def test_unique_types():
495    CDEF = "struct foo_s; union foo_u; enum foo_e { AA };"
496    ffi1 = FFI(); ffi1.cdef(CDEF); verify(ffi1, "test_unique_types_1", CDEF)
497    ffi2 = FFI(); ffi2.cdef(CDEF); verify(ffi2, "test_unique_types_2", CDEF)
498    #
499    assert ffi1.typeof("char") is ffi2.typeof("char ")
500    assert ffi1.typeof("long") is ffi2.typeof("signed long int")
501    assert ffi1.typeof("double *") is ffi2.typeof("double*")
502    assert ffi1.typeof("int ***") is ffi2.typeof(" int * * *")
503    assert ffi1.typeof("int[]") is ffi2.typeof("signed int[]")
504    assert ffi1.typeof("signed int*[17]") is ffi2.typeof("int *[17]")
505    assert ffi1.typeof("void") is ffi2.typeof("void")
506    assert ffi1.typeof("int(*)(int,int)") is ffi2.typeof("int(*)(int,int)")
507    #
508    # these depend on user-defined data, so should not be shared
509    for name in ["struct foo_s",
510                 "union foo_u *",
511                 "enum foo_e",
512                 "struct foo_s *(*)()",
513                 "void(*)(struct foo_s *)",
514                 "struct foo_s *(*[5])[8]",
515                 ]:
516        assert ffi1.typeof(name) is not ffi2.typeof(name)
517    # sanity check: twice 'ffi1'
518    assert ffi1.typeof("struct foo_s*") is ffi1.typeof("struct foo_s *")
519
520def test_module_name_in_package():
521    ffi = FFI()
522    ffi.cdef("int foo(int);")
523    recompiler.recompile(ffi, "test_module_name_in_package.mymod",
524                         "int foo(int x) { return x + 32; }",
525                         tmpdir=str(udir))
526    old_sys_path = sys.path[:]
527    try:
528        package_dir = udir.join('test_module_name_in_package')
529        for name in os.listdir(str(udir)):
530            assert not name.startswith('test_module_name_in_package.')
531        assert os.path.isdir(str(package_dir))
532        assert len(os.listdir(str(package_dir))) > 0
533        assert os.path.exists(str(package_dir.join('mymod.c')))
534        package_dir.join('__init__.py').write('')
535        #
536        getattr(importlib, 'invalidate_caches', object)()
537        #
538        sys.path.insert(0, str(udir))
539        import test_module_name_in_package.mymod
540        assert test_module_name_in_package.mymod.lib.foo(10) == 42
541        assert test_module_name_in_package.mymod.__name__ == (
542            'test_module_name_in_package.mymod')
543    finally:
544        sys.path[:] = old_sys_path
545
546def test_bad_size_of_global_1():
547    ffi = FFI()
548    ffi.cdef("short glob;")
549    py.test.raises(VerificationError, verify, ffi,
550                   "test_bad_size_of_global_1", "long glob;")
551
552def test_bad_size_of_global_2():
553    ffi = FFI()
554    ffi.cdef("int glob[10];")
555    py.test.raises(VerificationError, verify, ffi,
556                   "test_bad_size_of_global_2", "int glob[9];")
557
558def test_unspecified_size_of_global_1():
559    ffi = FFI()
560    ffi.cdef("int glob[];")
561    lib = verify(ffi, "test_unspecified_size_of_global_1", "int glob[10];")
562    assert ffi.typeof(lib.glob) == ffi.typeof("int *")
563
564def test_unspecified_size_of_global_2():
565    ffi = FFI()
566    ffi.cdef("int glob[][5];")
567    lib = verify(ffi, "test_unspecified_size_of_global_2", "int glob[10][5];")
568    assert ffi.typeof(lib.glob) == ffi.typeof("int(*)[5]")
569
570def test_unspecified_size_of_global_3():
571    ffi = FFI()
572    ffi.cdef("int glob[][...];")
573    lib = verify(ffi, "test_unspecified_size_of_global_3", "int glob[10][5];")
574    assert ffi.typeof(lib.glob) == ffi.typeof("int(*)[5]")
575
576def test_unspecified_size_of_global_4():
577    ffi = FFI()
578    ffi.cdef("int glob[...][...];")
579    lib = verify(ffi, "test_unspecified_size_of_global_4", "int glob[10][5];")
580    assert ffi.typeof(lib.glob) == ffi.typeof("int[10][5]")
581
582def test_include_1():
583    ffi1 = FFI()
584    ffi1.cdef("typedef double foo_t;")
585    verify(ffi1, "test_include_1_parent", "typedef double foo_t;")
586    ffi = FFI()
587    ffi.include(ffi1)
588    ffi.cdef("foo_t ff1(foo_t);")
589    lib = verify(ffi, "test_include_1", "double ff1(double x) { return 42.5; }")
590    assert lib.ff1(0) == 42.5
591    assert ffi1.typeof("foo_t") is ffi.typeof("foo_t") is ffi.typeof("double")
592
593def test_include_1b():
594    ffi1 = FFI()
595    ffi1.cdef("int foo1(int);")
596    lib1 = verify(ffi1, "test_include_1b_parent",
597                  "int foo1(int x) { return x + 10; }")
598    ffi = FFI()
599    ffi.include(ffi1)
600    ffi.cdef("int foo2(int);")
601    lib = verify(ffi, "test_include_1b", "int foo2(int x) { return x - 5; }")
602    assert lib.foo2(42) == 37
603    assert lib.foo1(42) == 52
604    assert lib.foo1 is lib1.foo1
605
606def test_include_2():
607    ffi1 = FFI()
608    ffi1.cdef("struct foo_s { int x, y; };")
609    verify(ffi1, "test_include_2_parent", "struct foo_s { int x, y; };")
610    ffi = FFI()
611    ffi.include(ffi1)
612    ffi.cdef("struct foo_s *ff2(struct foo_s *);")
613    lib = verify(ffi, "test_include_2",
614                 "struct foo_s { int x, y; }; //usually from a #include\n"
615                 "struct foo_s *ff2(struct foo_s *p) { p->y++; return p; }")
616    p = ffi.new("struct foo_s *")
617    p.y = 41
618    q = lib.ff2(p)
619    assert q == p
620    assert p.y == 42
621    assert ffi1.typeof("struct foo_s") is ffi.typeof("struct foo_s")
622
623def test_include_3():
624    ffi1 = FFI()
625    ffi1.cdef("typedef short sshort_t;")
626    verify(ffi1, "test_include_3_parent", "typedef short sshort_t;")
627    ffi = FFI()
628    ffi.include(ffi1)
629    ffi.cdef("sshort_t ff3(sshort_t);")
630    lib = verify(ffi, "test_include_3",
631                 "typedef short sshort_t; //usually from a #include\n"
632                 "sshort_t ff3(sshort_t x) { return x + 42; }")
633    assert lib.ff3(10) == 52
634    assert ffi.typeof(ffi.cast("sshort_t", 42)) is ffi.typeof("short")
635    assert ffi1.typeof("sshort_t") is ffi.typeof("sshort_t")
636
637def test_include_4():
638    ffi1 = FFI()
639    ffi1.cdef("typedef struct { int x; } mystruct_t;")
640    verify(ffi1, "test_include_4_parent",
641           "typedef struct { int x; } mystruct_t;")
642    ffi = FFI()
643    ffi.include(ffi1)
644    ffi.cdef("mystruct_t *ff4(mystruct_t *);")
645    lib = verify(ffi, "test_include_4",
646           "typedef struct {int x; } mystruct_t; //usually from a #include\n"
647           "mystruct_t *ff4(mystruct_t *p) { p->x += 42; return p; }")
648    p = ffi.new("mystruct_t *", [10])
649    q = lib.ff4(p)
650    assert q == p
651    assert p.x == 52
652    assert ffi1.typeof("mystruct_t") is ffi.typeof("mystruct_t")
653
654def test_include_5():
655    ffi1 = FFI()
656    ffi1.cdef("typedef struct { int x[2]; int y; } *mystruct_p;")
657    verify(ffi1, "test_include_5_parent",
658           "typedef struct { int x[2]; int y; } *mystruct_p;")
659    ffi = FFI()
660    ffi.include(ffi1)
661    ffi.cdef("mystruct_p ff5(mystruct_p);")
662    lib = verify(ffi, "test_include_5",
663        "typedef struct {int x[2]; int y; } *mystruct_p; //usually #include\n"
664        "mystruct_p ff5(mystruct_p p) { p->x[1] += 42; return p; }")
665    assert ffi.alignof(ffi.typeof("mystruct_p").item) == 4
666    assert ffi1.typeof("mystruct_p") is ffi.typeof("mystruct_p")
667    p = ffi.new("mystruct_p", [[5, 10], -17])
668    q = lib.ff5(p)
669    assert q == p
670    assert p.x[0] == 5
671    assert p.x[1] == 52
672    assert p.y == -17
673    assert ffi.alignof(ffi.typeof(p[0])) == 4
674
675def test_include_6():
676    ffi1 = FFI()
677    ffi1.cdef("typedef ... mystruct_t;")
678    verify(ffi1, "test_include_6_parent",
679           "typedef struct _mystruct_s mystruct_t;")
680    ffi = FFI()
681    ffi.include(ffi1)
682    ffi.cdef("mystruct_t *ff6(void); int ff6b(mystruct_t *);")
683    lib = verify(ffi, "test_include_6",
684           "typedef struct _mystruct_s mystruct_t; //usually from a #include\n"
685           "struct _mystruct_s { int x; };\n"
686           "static mystruct_t result_struct = { 42 };\n"
687           "mystruct_t *ff6(void) { return &result_struct; }\n"
688           "int ff6b(mystruct_t *p) { return p->x; }")
689    p = lib.ff6()
690    assert ffi.cast("int *", p)[0] == 42
691    assert lib.ff6b(p) == 42
692
693def test_include_7():
694    ffi1 = FFI()
695    ffi1.cdef("typedef ... mystruct_t;\n"
696              "int ff7b(mystruct_t *);")
697    verify(ffi1, "test_include_7_parent",
698           "typedef struct { int x; } mystruct_t;\n"
699           "int ff7b(mystruct_t *p) { return p->x; }")
700    ffi = FFI()
701    ffi.include(ffi1)
702    ffi.cdef("mystruct_t *ff7(void);")
703    lib = verify(ffi, "test_include_7",
704           "typedef struct { int x; } mystruct_t; //usually from a #include\n"
705           "static mystruct_t result_struct = { 42 };"
706           "mystruct_t *ff7(void) { return &result_struct; }")
707    p = lib.ff7()
708    assert ffi.cast("int *", p)[0] == 42
709    assert lib.ff7b(p) == 42
710
711def test_include_8():
712    ffi1 = FFI()
713    ffi1.cdef("struct foo_s;")
714    verify(ffi1, "test_include_8_parent", "struct foo_s;")
715    ffi = FFI()
716    ffi.include(ffi1)
717    ffi.cdef("struct foo_s { int x, y; };")
718    verify(ffi, "test_include_8", "struct foo_s { int x, y; };")
719    e = py.test.raises(NotImplementedError, ffi.new, "struct foo_s *")
720    assert str(e.value) == (
721        "'struct foo_s' is opaque in the ffi.include(), but no longer in "
722        "the ffi doing the include (workaround: don't use ffi.include() but"
723        " duplicate the declarations of everything using struct foo_s)")
724
725def test_unicode_libraries():
726    try:
727        unicode
728    except NameError:
729        py.test.skip("for python 2.x")
730    #
731    import math
732    lib_m = "m"
733    if sys.platform == 'win32':
734        #there is a small chance this fails on Mingw via environ $CC
735        import distutils.ccompiler
736        if distutils.ccompiler.get_default_compiler() == 'msvc':
737            lib_m = 'msvcrt'
738    ffi = FFI()
739    ffi.cdef(unicode("float sin(double); double cos(double);"))
740    lib = verify(ffi, 'test_math_sin_unicode', unicode('#include <math.h>'),
741                 libraries=[unicode(lib_m)])
742    assert lib.cos(1.43) == math.cos(1.43)
743
744def test_incomplete_struct_as_arg():
745    ffi = FFI()
746    ffi.cdef("struct foo_s { int x; ...; }; int f(int, struct foo_s);")
747    lib = verify(ffi, "test_incomplete_struct_as_arg",
748                 "struct foo_s { int a, x, z; };\n"
749                 "int f(int b, struct foo_s s) { return s.x * b; }")
750    s = ffi.new("struct foo_s *", [21])
751    assert s.x == 21
752    assert ffi.sizeof(s[0]) == 12
753    assert ffi.offsetof(ffi.typeof(s), 'x') == 4
754    assert lib.f(2, s[0]) == 42
755    assert ffi.typeof(lib.f) == ffi.typeof("int(*)(int, struct foo_s)")
756
757def test_incomplete_struct_as_result():
758    ffi = FFI()
759    ffi.cdef("struct foo_s { int x; ...; }; struct foo_s f(int);")
760    lib = verify(ffi, "test_incomplete_struct_as_result",
761            "struct foo_s { int a, x, z; };\n"
762            "struct foo_s f(int x) { struct foo_s r; r.x = x * 2; return r; }")
763    s = lib.f(21)
764    assert s.x == 42
765    assert ffi.typeof(lib.f) == ffi.typeof("struct foo_s(*)(int)")
766
767def test_incomplete_struct_as_both():
768    ffi = FFI()
769    ffi.cdef("struct foo_s { int x; ...; }; struct bar_s { int y; ...; };\n"
770             "struct foo_s f(int, struct bar_s);")
771    lib = verify(ffi, "test_incomplete_struct_as_both",
772            "struct foo_s { int a, x, z; };\n"
773            "struct bar_s { int b, c, y, d; };\n"
774            "struct foo_s f(int x, struct bar_s b) {\n"
775            "  struct foo_s r; r.x = x * b.y; return r;\n"
776            "}")
777    b = ffi.new("struct bar_s *", [7])
778    s = lib.f(6, b[0])
779    assert s.x == 42
780    assert ffi.typeof(lib.f) == ffi.typeof(
781        "struct foo_s(*)(int, struct bar_s)")
782    s = lib.f(14, {'y': -3})
783    assert s.x == -42
784
785def test_name_of_unnamed_struct():
786    ffi = FFI()
787    ffi.cdef("typedef struct { int x; } foo_t;\n"
788             "typedef struct { int y; } *bar_p;\n"
789             "typedef struct { int y; } **baz_pp;\n")
790    verify(ffi, "test_name_of_unnamed_struct",
791             "typedef struct { int x; } foo_t;\n"
792             "typedef struct { int y; } *bar_p;\n"
793             "typedef struct { int y; } **baz_pp;\n")
794    assert repr(ffi.typeof("foo_t")) == "<ctype 'foo_t'>"
795    assert repr(ffi.typeof("bar_p")) == "<ctype 'struct $1 *'>"
796    assert repr(ffi.typeof("baz_pp")) == "<ctype 'struct $2 * *'>"
797
798def test_address_of_global_var():
799    ffi = FFI()
800    ffi.cdef("""
801        long bottom, bottoms[2];
802        long FetchRectBottom(void);
803        long FetchRectBottoms1(void);
804        #define FOOBAR 42
805    """)
806    lib = verify(ffi, "test_address_of_global_var", """
807        long bottom, bottoms[2];
808        long FetchRectBottom(void) { return bottom; }
809        long FetchRectBottoms1(void) { return bottoms[1]; }
810        #define FOOBAR 42
811    """)
812    lib.bottom = 300
813    assert lib.FetchRectBottom() == 300
814    lib.bottom += 1
815    assert lib.FetchRectBottom() == 301
816    lib.bottoms[1] = 500
817    assert lib.FetchRectBottoms1() == 500
818    lib.bottoms[1] += 2
819    assert lib.FetchRectBottoms1() == 502
820    #
821    p = ffi.addressof(lib, 'bottom')
822    assert ffi.typeof(p) == ffi.typeof("long *")
823    assert p[0] == 301
824    p[0] += 1
825    assert lib.FetchRectBottom() == 302
826    p = ffi.addressof(lib, 'bottoms')
827    assert ffi.typeof(p) == ffi.typeof("long(*)[2]")
828    assert p[0] == lib.bottoms
829    #
830    py.test.raises(AttributeError, ffi.addressof, lib, 'unknown_var')
831    py.test.raises(AttributeError, ffi.addressof, lib, "FOOBAR")
832
833def test_defines__CFFI_():
834    # Check that we define the macro _CFFI_ automatically.
835    # It should be done before including Python.h, so that PyPy's Python.h
836    # can check for it.
837    ffi = FFI()
838    ffi.cdef("""
839        #define CORRECT 1
840    """)
841    lib = verify(ffi, "test_defines__CFFI_", """
842    #ifdef _CFFI_
843    #    define CORRECT 1
844    #endif
845    """)
846    assert lib.CORRECT == 1
847
848def test_unpack_args():
849    ffi = FFI()
850    ffi.cdef("void foo0(void); void foo1(int); void foo2(int, int);")
851    lib = verify(ffi, "test_unpack_args", """
852    void foo0(void) { }
853    void foo1(int x) { }
854    void foo2(int x, int y) { }
855    """)
856    assert 'foo0' in repr(lib.foo0)
857    assert 'foo1' in repr(lib.foo1)
858    assert 'foo2' in repr(lib.foo2)
859    lib.foo0()
860    lib.foo1(42)
861    lib.foo2(43, 44)
862    e1 = py.test.raises(TypeError, lib.foo0, 42)
863    e2 = py.test.raises(TypeError, lib.foo0, 43, 44)
864    e3 = py.test.raises(TypeError, lib.foo1)
865    e4 = py.test.raises(TypeError, lib.foo1, 43, 44)
866    e5 = py.test.raises(TypeError, lib.foo2)
867    e6 = py.test.raises(TypeError, lib.foo2, 42)
868    e7 = py.test.raises(TypeError, lib.foo2, 45, 46, 47)
869    assert str(e1.value) == "foo0() takes no arguments (1 given)"
870    assert str(e2.value) == "foo0() takes no arguments (2 given)"
871    assert str(e3.value) == "foo1() takes exactly one argument (0 given)"
872    assert str(e4.value) == "foo1() takes exactly one argument (2 given)"
873    assert str(e5.value) in ["foo2 expected 2 arguments, got 0",
874                             "foo2() takes exactly 2 arguments (0 given)"]
875    assert str(e6.value) in ["foo2 expected 2 arguments, got 1",
876                             "foo2() takes exactly 2 arguments (1 given)"]
877    assert str(e7.value) in ["foo2 expected 2 arguments, got 3",
878                             "foo2() takes exactly 2 arguments (3 given)"]
879
880def test_address_of_function():
881    ffi = FFI()
882    ffi.cdef("long myfunc(long x);")
883    lib = verify(ffi, "test_addressof_function", """
884        char myfunc(char x) { return (char)(x + 42); }
885    """)
886    assert lib.myfunc(5) == 47
887    assert lib.myfunc(0xABC05) == 47
888    assert not isinstance(lib.myfunc, ffi.CData)
889    assert ffi.typeof(lib.myfunc) == ffi.typeof("long(*)(long)")
890    addr = ffi.addressof(lib, 'myfunc')
891    assert addr(5) == 47
892    assert addr(0xABC05) == 47
893    assert isinstance(addr, ffi.CData)
894    assert ffi.typeof(addr) == ffi.typeof("long(*)(long)")
895
896def test_address_of_function_with_struct():
897    ffi = FFI()
898    ffi.cdef("struct foo_s { int x; }; long myfunc(struct foo_s);")
899    lib = verify(ffi, "test_addressof_function_with_struct", """
900        struct foo_s { int x; };
901        char myfunc(struct foo_s input) { return (char)(input.x + 42); }
902    """)
903    s = ffi.new("struct foo_s *", [5])[0]
904    assert lib.myfunc(s) == 47
905    assert not isinstance(lib.myfunc, ffi.CData)
906    assert ffi.typeof(lib.myfunc) == ffi.typeof("long(*)(struct foo_s)")
907    addr = ffi.addressof(lib, 'myfunc')
908    assert addr(s) == 47
909    assert isinstance(addr, ffi.CData)
910    assert ffi.typeof(addr) == ffi.typeof("long(*)(struct foo_s)")
911
912def test_issue198():
913    ffi = FFI()
914    ffi.cdef("""
915        typedef struct{...;} opaque_t;
916        const opaque_t CONSTANT;
917        int toint(opaque_t);
918    """)
919    lib = verify(ffi, 'test_issue198', """
920        typedef int opaque_t;
921        #define CONSTANT ((opaque_t)42)
922        static int toint(opaque_t o) { return o; }
923    """)
924    def random_stuff():
925        pass
926    assert lib.toint(lib.CONSTANT) == 42
927    random_stuff()
928    assert lib.toint(lib.CONSTANT) == 42
929
930def test_constant_is_not_a_compiler_constant():
931    ffi = FFI()
932    ffi.cdef("static const float almost_forty_two;")
933    lib = verify(ffi, 'test_constant_is_not_a_compiler_constant', """
934        static float f(void) { return 42.25; }
935        #define almost_forty_two (f())
936    """)
937    assert lib.almost_forty_two == 42.25
938
939def test_constant_of_unknown_size():
940    ffi = FFI()
941    ffi.cdef("""
942        typedef ... opaque_t;
943        const opaque_t CONSTANT;
944    """)
945    lib = verify(ffi, 'test_constant_of_unknown_size',
946                 "typedef int opaque_t;"
947                 "const int CONSTANT = 42;")
948    e = py.test.raises(ffi.error, getattr, lib, 'CONSTANT')
949    assert str(e.value) == ("constant 'CONSTANT' is of "
950                            "type 'opaque_t', whose size is not known")
951
952def test_variable_of_unknown_size():
953    ffi = FFI()
954    ffi.cdef("""
955        typedef ... opaque_t;
956        opaque_t globvar;
957    """)
958    lib = verify(ffi, 'test_variable_of_unknown_size', """
959        typedef char opaque_t[6];
960        opaque_t globvar = "hello";
961    """)
962    # can't read or write it at all
963    e = py.test.raises(TypeError, getattr, lib, 'globvar')
964    assert str(e.value) in ["cdata 'opaque_t' is opaque",
965                            "'opaque_t' is opaque or not completed yet"] #pypy
966    e = py.test.raises(TypeError, setattr, lib, 'globvar', [])
967    assert str(e.value) in ["'opaque_t' is opaque",
968                            "'opaque_t' is opaque or not completed yet"] #pypy
969    # but we can get its address
970    p = ffi.addressof(lib, 'globvar')
971    assert ffi.typeof(p) == ffi.typeof('opaque_t *')
972    assert ffi.string(ffi.cast("char *", p), 8) == b"hello"
973
974def test_constant_of_value_unknown_to_the_compiler():
975    extra_c_source = udir.join(
976        'extra_test_constant_of_value_unknown_to_the_compiler.c')
977    extra_c_source.write('const int external_foo = 42;\n')
978    ffi = FFI()
979    ffi.cdef("const int external_foo;")
980    lib = verify(ffi, 'test_constant_of_value_unknown_to_the_compiler', """
981        extern const int external_foo;
982    """, sources=[str(extra_c_source)])
983    assert lib.external_foo == 42
984
985def test_dotdot_in_source_file_names():
986    extra_c_source = udir.join(
987        'extra_test_dotdot_in_source_file_names.c')
988    extra_c_source.write('const int external_foo = 42;\n')
989    ffi = FFI()
990    ffi.cdef("const int external_foo;")
991    lib = verify(ffi, 'test_dotdot_in_source_file_names', """
992        extern const int external_foo;
993    """, sources=[os.path.join(os.path.dirname(str(extra_c_source)),
994                               'foobar', '..',
995                               os.path.basename(str(extra_c_source)))])
996    assert lib.external_foo == 42
997
998def test_call_with_incomplete_structs():
999    ffi = FFI()
1000    ffi.cdef("typedef struct {...;} foo_t; "
1001             "foo_t myglob; "
1002             "foo_t increment(foo_t s); "
1003             "double getx(foo_t s);")
1004    lib = verify(ffi, 'test_call_with_incomplete_structs', """
1005        typedef double foo_t;
1006        double myglob = 42.5;
1007        double getx(double x) { return x; }
1008        double increment(double x) { return x + 1; }
1009    """)
1010    assert lib.getx(lib.myglob) == 42.5
1011    assert lib.getx(lib.increment(lib.myglob)) == 43.5
1012
1013def test_struct_array_guess_length_2():
1014    ffi = FFI()
1015    ffi.cdef("struct foo_s { int a[...][...]; };")
1016    lib = verify(ffi, 'test_struct_array_guess_length_2',
1017                 "struct foo_s { int x; int a[5][8]; int y; };")
1018    assert ffi.sizeof('struct foo_s') == 42 * ffi.sizeof('int')
1019    s = ffi.new("struct foo_s *")
1020    assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
1021    assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int')
1022    assert s.a[4][7] == 0
1023    py.test.raises(IndexError, 's.a[4][8]')
1024    py.test.raises(IndexError, 's.a[5][0]')
1025    assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
1026    assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]")
1027
1028def test_struct_array_guess_length_3():
1029    ffi = FFI()
1030    ffi.cdef("struct foo_s { int a[][...]; };")
1031    lib = verify(ffi, 'test_struct_array_guess_length_3',
1032                 "struct foo_s { int x; int a[5][7]; int y; };")
1033    assert ffi.sizeof('struct foo_s') == 37 * ffi.sizeof('int')
1034    s = ffi.new("struct foo_s *")
1035    assert ffi.typeof(s.a) == ffi.typeof("int[][7]")
1036    assert s.a[4][6] == 0
1037    py.test.raises(IndexError, 's.a[4][7]')
1038    assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]")
1039
1040def test_global_var_array_2():
1041    ffi = FFI()
1042    ffi.cdef("int a[...][...];")
1043    lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];')
1044    lib.a[9][7] = 123456
1045    assert lib.a[9][7] == 123456
1046    py.test.raises(IndexError, 'lib.a[0][8]')
1047    py.test.raises(IndexError, 'lib.a[10][0]')
1048    assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]")
1049    assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
1050
1051def test_global_var_array_3():
1052    ffi = FFI()
1053    ffi.cdef("int a[][...];")
1054    lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];')
1055    lib.a[9][7] = 123456
1056    assert lib.a[9][7] == 123456
1057    py.test.raises(IndexError, 'lib.a[0][8]')
1058    assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]")
1059    assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
1060
1061def test_global_var_array_4():
1062    ffi = FFI()
1063    ffi.cdef("int a[10][...];")
1064    lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];')
1065    lib.a[9][7] = 123456
1066    assert lib.a[9][7] == 123456
1067    py.test.raises(IndexError, 'lib.a[0][8]')
1068    py.test.raises(IndexError, 'lib.a[10][8]')
1069    assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]")
1070    assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
1071
1072def test_some_integer_type():
1073    ffi = FFI()
1074    ffi.cdef("""
1075        typedef int... foo_t;
1076        typedef unsigned long... bar_t;
1077        typedef struct { foo_t a, b; } mystruct_t;
1078        foo_t foobar(bar_t, mystruct_t);
1079        static const bar_t mu = -20;
1080        static const foo_t nu = 20;
1081    """)
1082    lib = verify(ffi, 'test_some_integer_type', """
1083        typedef unsigned long long foo_t;
1084        typedef short bar_t;
1085        typedef struct { foo_t a, b; } mystruct_t;
1086        static foo_t foobar(bar_t x, mystruct_t s) {
1087            return (foo_t)x + s.a + s.b;
1088        }
1089        static const bar_t mu = -20;
1090        static const foo_t nu = 20;
1091    """)
1092    assert ffi.sizeof("foo_t") == ffi.sizeof("unsigned long long")
1093    assert ffi.sizeof("bar_t") == ffi.sizeof("short")
1094    maxulonglong = 2 ** 64 - 1
1095    assert int(ffi.cast("foo_t", -1)) == maxulonglong
1096    assert int(ffi.cast("bar_t", -1)) == -1
1097    assert lib.foobar(-1, [0, 0]) == maxulonglong
1098    assert lib.foobar(2 ** 15 - 1, [0, 0]) == 2 ** 15 - 1
1099    assert lib.foobar(10, [20, 31]) == 61
1100    assert lib.foobar(0, [0, maxulonglong]) == maxulonglong
1101    py.test.raises(OverflowError, lib.foobar, 2 ** 15, [0, 0])
1102    py.test.raises(OverflowError, lib.foobar, -(2 ** 15) - 1, [0, 0])
1103    py.test.raises(OverflowError, ffi.new, "mystruct_t *", [0, -1])
1104    assert lib.mu == -20
1105    assert lib.nu == 20
1106
1107def test_some_float_type():
1108    ffi = FFI()
1109    ffi.cdef("""
1110        typedef double... foo_t;
1111        typedef float... bar_t;
1112        foo_t sum(foo_t[]);
1113        bar_t neg(bar_t);
1114        """)
1115    lib = verify(ffi, 'test_some_float_type', """
1116        typedef float foo_t;
1117        static foo_t sum(foo_t x[]) { return x[0] + x[1]; }
1118        typedef double bar_t;
1119        static double neg(double x) { return -x; }
1120    """)
1121    assert lib.sum([40.0, 2.25]) == 42.25
1122    assert lib.sum([12.3, 45.6]) != 12.3 + 45.6     # precision loss
1123    assert lib.neg(12.3) == -12.3                   # no precision loss
1124    assert ffi.sizeof("foo_t") == ffi.sizeof("float")
1125    assert ffi.sizeof("bar_t") == ffi.sizeof("double")
1126
1127def test_some_float_invalid_1():
1128    ffi = FFI()
1129    py.test.raises((FFIError,      # with pycparser <= 2.17
1130                    CDefError),    # with pycparser >= 2.18
1131                   ffi.cdef, "typedef long double... foo_t;")
1132
1133def test_some_float_invalid_2():
1134    ffi = FFI()
1135    ffi.cdef("typedef double... foo_t; foo_t neg(foo_t);")
1136    lib = verify(ffi, 'test_some_float_invalid_2', """
1137        typedef unsigned long foo_t;
1138        foo_t neg(foo_t x) { return -x; }
1139    """)
1140    e = py.test.raises(ffi.error, getattr, lib, 'neg')
1141    assert str(e.value) == ("primitive floating-point type with an unexpected "
1142                            "size (or not a float type at all)")
1143
1144def test_some_float_invalid_3():
1145    ffi = FFI()
1146    ffi.cdef("typedef double... foo_t; foo_t neg(foo_t);")
1147    lib = verify(ffi, 'test_some_float_invalid_3', """
1148        typedef long double foo_t;
1149        foo_t neg(foo_t x) { return -x; }
1150    """)
1151    if ffi.sizeof("long double") == ffi.sizeof("double"):
1152        assert lib.neg(12.3) == -12.3
1153    else:
1154        e = py.test.raises(ffi.error, getattr, lib, 'neg')
1155        assert str(e.value) == ("primitive floating-point type is "
1156                                "'long double', not supported for now with "
1157                                "the syntax 'typedef double... xxx;'")
1158
1159def test_issue200():
1160    ffi = FFI()
1161    ffi.cdef("""
1162        typedef void (function_t)(void*);
1163        void function(void *);
1164    """)
1165    lib = verify(ffi, 'test_issue200', """
1166        static void function(void *p) { (void)p; }
1167    """)
1168    ffi.typeof('function_t*')
1169    lib.function(ffi.NULL)
1170    # assert did not crash
1171
1172def test_alignment_of_longlong():
1173    ffi = FFI()
1174    x1 = ffi.alignof('unsigned long long')
1175    assert x1 in [4, 8]
1176    ffi.cdef("struct foo_s { unsigned long long x; };")
1177    lib = verify(ffi, 'test_alignment_of_longlong',
1178                 "struct foo_s { unsigned long long x; };")
1179    assert ffi.alignof('unsigned long long') == x1
1180    assert ffi.alignof('struct foo_s') == x1
1181
1182def test_import_from_lib():
1183    ffi = FFI()
1184    ffi.cdef("int mybar(int); int myvar;\n#define MYFOO ...")
1185    lib = verify(ffi, 'test_import_from_lib',
1186                 "#define MYFOO 42\n"
1187                 "static int mybar(int x) { return x + 1; }\n"
1188                 "static int myvar = -5;")
1189    assert sys.modules['_CFFI_test_import_from_lib'].lib is lib
1190    assert sys.modules['_CFFI_test_import_from_lib.lib'] is lib
1191    from _CFFI_test_import_from_lib.lib import MYFOO
1192    assert MYFOO == 42
1193    assert hasattr(lib, '__dict__')
1194    assert lib.__all__ == ['MYFOO', 'mybar']   # but not 'myvar'
1195    assert lib.__name__ == '_CFFI_test_import_from_lib.lib'
1196    assert lib.__class__ is type(sys)   # !! hack for help()
1197
1198def test_macro_var_callback():
1199    ffi = FFI()
1200    ffi.cdef("int my_value; int *(*get_my_value)(void);")
1201    lib = verify(ffi, 'test_macro_var_callback',
1202                 "int *(*get_my_value)(void);\n"
1203                 "#define my_value (*get_my_value())")
1204    #
1205    values = ffi.new("int[50]")
1206    def it():
1207        for i in range(50):
1208            yield i
1209    it = it()
1210    #
1211    @ffi.callback("int *(*)(void)")
1212    def get_my_value():
1213        for nextvalue in it:
1214            return values + nextvalue
1215    lib.get_my_value = get_my_value
1216    #
1217    values[0] = 41
1218    assert lib.my_value == 41            # [0]
1219    p = ffi.addressof(lib, 'my_value')   # [1]
1220    assert p == values + 1
1221    assert p[-1] == 41
1222    assert p[+1] == 0
1223    lib.my_value = 42                    # [2]
1224    assert values[2] == 42
1225    assert p[-1] == 41
1226    assert p[+1] == 42
1227    #
1228    # if get_my_value raises or returns nonsense, the exception is printed
1229    # to stderr like with any callback, but then the C expression 'my_value'
1230    # expand to '*NULL'.  We assume here that '&my_value' will return NULL
1231    # without segfaulting, and check for NULL when accessing the variable.
1232    @ffi.callback("int *(*)(void)")
1233    def get_my_value():
1234        raise LookupError
1235    lib.get_my_value = get_my_value
1236    py.test.raises(ffi.error, getattr, lib, 'my_value')
1237    py.test.raises(ffi.error, setattr, lib, 'my_value', 50)
1238    py.test.raises(ffi.error, ffi.addressof, lib, 'my_value')
1239    @ffi.callback("int *(*)(void)")
1240    def get_my_value():
1241        return "hello"
1242    lib.get_my_value = get_my_value
1243    py.test.raises(ffi.error, getattr, lib, 'my_value')
1244    e = py.test.raises(ffi.error, setattr, lib, 'my_value', 50)
1245    assert str(e.value) == "global variable 'my_value' is at address NULL"
1246
1247def test_const_fields():
1248    ffi = FFI()
1249    ffi.cdef("""struct foo_s { const int a; void *const b; };""")
1250    lib = verify(ffi, 'test_const_fields', """
1251        struct foo_s { const int a; void *const b; };""")
1252    foo_s = ffi.typeof("struct foo_s")
1253    assert foo_s.fields[0][0] == 'a'
1254    assert foo_s.fields[0][1].type is ffi.typeof("int")
1255    assert foo_s.fields[1][0] == 'b'
1256    assert foo_s.fields[1][1].type is ffi.typeof("void *")
1257
1258def test_restrict_fields():
1259    ffi = FFI()
1260    ffi.cdef("""struct foo_s { void * restrict b; };""")
1261    lib = verify(ffi, 'test_restrict_fields', """
1262        struct foo_s { void * __restrict b; };""")
1263    foo_s = ffi.typeof("struct foo_s")
1264    assert foo_s.fields[0][0] == 'b'
1265    assert foo_s.fields[0][1].type is ffi.typeof("void *")
1266
1267def test_volatile_fields():
1268    ffi = FFI()
1269    ffi.cdef("""struct foo_s { void * volatile b; };""")
1270    lib = verify(ffi, 'test_volatile_fields', """
1271        struct foo_s { void * volatile b; };""")
1272    foo_s = ffi.typeof("struct foo_s")
1273    assert foo_s.fields[0][0] == 'b'
1274    assert foo_s.fields[0][1].type is ffi.typeof("void *")
1275
1276def test_const_array_fields():
1277    ffi = FFI()
1278    ffi.cdef("""struct foo_s { const int a[4]; };""")
1279    lib = verify(ffi, 'test_const_array_fields', """
1280        struct foo_s { const int a[4]; };""")
1281    foo_s = ffi.typeof("struct foo_s")
1282    assert foo_s.fields[0][0] == 'a'
1283    assert foo_s.fields[0][1].type is ffi.typeof("int[4]")
1284
1285def test_const_array_fields_varlength():
1286    ffi = FFI()
1287    ffi.cdef("""struct foo_s { const int a[]; ...; };""")
1288    lib = verify(ffi, 'test_const_array_fields_varlength', """
1289        struct foo_s { const int a[4]; };""")
1290    foo_s = ffi.typeof("struct foo_s")
1291    assert foo_s.fields[0][0] == 'a'
1292    assert foo_s.fields[0][1].type is ffi.typeof("int[]")
1293
1294def test_const_array_fields_unknownlength():
1295    ffi = FFI()
1296    ffi.cdef("""struct foo_s { const int a[...]; ...; };""")
1297    lib = verify(ffi, 'test_const_array_fields_unknownlength', """
1298        struct foo_s { const int a[4]; };""")
1299    foo_s = ffi.typeof("struct foo_s")
1300    assert foo_s.fields[0][0] == 'a'
1301    assert foo_s.fields[0][1].type is ffi.typeof("int[4]")
1302
1303def test_const_function_args():
1304    ffi = FFI()
1305    ffi.cdef("""int foobar(const int a, const int *b, const int c[]);""")
1306    lib = verify(ffi, 'test_const_function_args', """
1307        int foobar(const int a, const int *b, const int c[]) {
1308            return a + *b + *c;
1309        }
1310    """)
1311    assert lib.foobar(100, ffi.new("int *", 40), ffi.new("int *", 2)) == 142
1312
1313def test_const_function_type_args():
1314    ffi = FFI()
1315    ffi.cdef("""int (*foobar)(const int a, const int *b, const int c[]);""")
1316    lib = verify(ffi, 'test_const_function_type_args', """
1317        int (*foobar)(const int a, const int *b, const int c[]);
1318    """)
1319    t = ffi.typeof(lib.foobar)
1320    assert t.args[0] is ffi.typeof("int")
1321    assert t.args[1] is ffi.typeof("int *")
1322    assert t.args[2] is ffi.typeof("int *")
1323
1324def test_const_constant():
1325    ffi = FFI()
1326    ffi.cdef("""struct foo_s { int x,y; }; const struct foo_s myfoo;""")
1327    lib = verify(ffi, 'test_const_constant', """
1328        struct foo_s { int x,y; }; const struct foo_s myfoo = { 40, 2 };
1329    """)
1330    assert lib.myfoo.x == 40
1331    assert lib.myfoo.y == 2
1332
1333def test_const_via_typedef():
1334    ffi = FFI()
1335    ffi.cdef("""typedef const int const_t; const_t aaa;""")
1336    lib = verify(ffi, 'test_const_via_typedef', """
1337        typedef const int const_t;
1338        #define aaa 42
1339    """)
1340    assert lib.aaa == 42
1341    py.test.raises(AttributeError, "lib.aaa = 43")
1342
1343def test_win32_calling_convention_0():
1344    ffi = FFI()
1345    ffi.cdef("""
1346        int call1(int(__cdecl   *cb)(int));
1347        int (*const call2)(int(__stdcall *cb)(int));
1348    """)
1349    lib = verify(ffi, 'test_win32_calling_convention_0', r"""
1350        #ifndef _MSC_VER
1351        #  define __stdcall  /* nothing */
1352        #endif
1353        int call1(int(*cb)(int)) {
1354            int i, result = 0;
1355            //printf("call1: cb = %p\n", cb);
1356            for (i = 0; i < 1000; i++)
1357                result += cb(i);
1358            //printf("result = %d\n", result);
1359            return result;
1360        }
1361        int call2(int(__stdcall *cb)(int)) {
1362            int i, result = 0;
1363            //printf("call2: cb = %p\n", cb);
1364            for (i = 0; i < 1000; i++)
1365                result += cb(-i);
1366            //printf("result = %d\n", result);
1367            return result;
1368        }
1369    """)
1370    @ffi.callback("int(int)")
1371    def cb1(x):
1372        return x * 2
1373    @ffi.callback("int __stdcall(int)")
1374    def cb2(x):
1375        return x * 3
1376    res = lib.call1(cb1)
1377    assert res == 500*999*2
1378    assert res == ffi.addressof(lib, 'call1')(cb1)
1379    res = lib.call2(cb2)
1380    assert res == -500*999*3
1381    assert res == ffi.addressof(lib, 'call2')(cb2)
1382    if sys.platform == 'win32' and not sys.maxsize > 2**32:
1383        assert '__stdcall' in str(ffi.typeof(cb2))
1384        assert '__stdcall' not in str(ffi.typeof(cb1))
1385        py.test.raises(TypeError, lib.call1, cb2)
1386        py.test.raises(TypeError, lib.call2, cb1)
1387    else:
1388        assert '__stdcall' not in str(ffi.typeof(cb2))
1389        assert ffi.typeof(cb2) is ffi.typeof(cb1)
1390
1391def test_win32_calling_convention_1():
1392    ffi = FFI()
1393    ffi.cdef("""
1394        int __cdecl   call1(int(__cdecl   *cb)(int));
1395        int __stdcall call2(int(__stdcall *cb)(int));
1396        int (__cdecl   *const cb1)(int);
1397        int (__stdcall *const cb2)(int);
1398    """)
1399    lib = verify(ffi, 'test_win32_calling_convention_1', r"""
1400        #ifndef _MSC_VER
1401        #  define __cdecl
1402        #  define __stdcall
1403        #endif
1404        int __cdecl   cb1(int x) { return x * 2; }
1405        int __stdcall cb2(int x) { return x * 3; }
1406
1407        int __cdecl call1(int(__cdecl *cb)(int)) {
1408            int i, result = 0;
1409            //printf("here1\n");
1410            //printf("cb = %p, cb1 = %p\n", cb, (void *)cb1);
1411            for (i = 0; i < 1000; i++)
1412                result += cb(i);
1413            //printf("result = %d\n", result);
1414            return result;
1415        }
1416        int __stdcall call2(int(__stdcall *cb)(int)) {
1417            int i, result = 0;
1418            //printf("here1\n");
1419            //printf("cb = %p, cb2 = %p\n", cb, (void *)cb2);
1420            for (i = 0; i < 1000; i++)
1421                result += cb(-i);
1422            //printf("result = %d\n", result);
1423            return result;
1424        }
1425    """)
1426    #print '<<< cb1 =', ffi.addressof(lib, 'cb1')
1427    ptr_call1 = ffi.addressof(lib, 'call1')
1428    assert lib.call1(ffi.addressof(lib, 'cb1')) == 500*999*2
1429    assert ptr_call1(ffi.addressof(lib, 'cb1')) == 500*999*2
1430    #print '<<< cb2 =', ffi.addressof(lib, 'cb2')
1431    ptr_call2 = ffi.addressof(lib, 'call2')
1432    assert lib.call2(ffi.addressof(lib, 'cb2')) == -500*999*3
1433    assert ptr_call2(ffi.addressof(lib, 'cb2')) == -500*999*3
1434    #print '<<< done'
1435
1436def test_win32_calling_convention_2():
1437    # any mistake in the declaration of plain function (including the
1438    # precise argument types and, here, the calling convention) are
1439    # automatically corrected.  But this does not apply to the 'cb'
1440    # function pointer argument.
1441    ffi = FFI()
1442    ffi.cdef("""
1443        int __stdcall call1(int(__cdecl   *cb)(int));
1444        int __cdecl   call2(int(__stdcall *cb)(int));
1445        int (__cdecl   *const cb1)(int);
1446        int (__stdcall *const cb2)(int);
1447    """)
1448    lib = verify(ffi, 'test_win32_calling_convention_2', """
1449        #ifndef _MSC_VER
1450        #  define __cdecl
1451        #  define __stdcall
1452        #endif
1453        int __cdecl call1(int(__cdecl *cb)(int)) {
1454            int i, result = 0;
1455            for (i = 0; i < 1000; i++)
1456                result += cb(i);
1457            return result;
1458        }
1459        int __stdcall call2(int(__stdcall *cb)(int)) {
1460            int i, result = 0;
1461            for (i = 0; i < 1000; i++)
1462                result += cb(-i);
1463            return result;
1464        }
1465        int __cdecl   cb1(int x) { return x * 2; }
1466        int __stdcall cb2(int x) { return x * 3; }
1467    """)
1468    ptr_call1 = ffi.addressof(lib, 'call1')
1469    ptr_call2 = ffi.addressof(lib, 'call2')
1470    if sys.platform == 'win32' and not sys.maxsize > 2**32:
1471        py.test.raises(TypeError, lib.call1, ffi.addressof(lib, 'cb2'))
1472        py.test.raises(TypeError, ptr_call1, ffi.addressof(lib, 'cb2'))
1473        py.test.raises(TypeError, lib.call2, ffi.addressof(lib, 'cb1'))
1474        py.test.raises(TypeError, ptr_call2, ffi.addressof(lib, 'cb1'))
1475    assert lib.call1(ffi.addressof(lib, 'cb1')) == 500*999*2
1476    assert ptr_call1(ffi.addressof(lib, 'cb1')) == 500*999*2
1477    assert lib.call2(ffi.addressof(lib, 'cb2')) == -500*999*3
1478    assert ptr_call2(ffi.addressof(lib, 'cb2')) == -500*999*3
1479
1480def test_win32_calling_convention_3():
1481    ffi = FFI()
1482    ffi.cdef("""
1483        struct point { int x, y; };
1484
1485        int (*const cb1)(struct point);
1486        int (__stdcall *const cb2)(struct point);
1487
1488        struct point __stdcall call1(int(*cb)(struct point));
1489        struct point call2(int(__stdcall *cb)(struct point));
1490    """)
1491    lib = verify(ffi, 'test_win32_calling_convention_3', r"""
1492        #ifndef _MSC_VER
1493        #  define __cdecl
1494        #  define __stdcall
1495        #endif
1496        struct point { int x, y; };
1497        int           cb1(struct point pt) { return pt.x + 10 * pt.y; }
1498        int __stdcall cb2(struct point pt) { return pt.x + 100 * pt.y; }
1499        struct point __stdcall call1(int(__cdecl *cb)(struct point)) {
1500            int i;
1501            struct point result = { 0, 0 };
1502            //printf("here1\n");
1503            //printf("cb = %p, cb1 = %p\n", cb, (void *)cb1);
1504            for (i = 0; i < 1000; i++) {
1505                struct point p = { i, -i };
1506                int r = cb(p);
1507                result.x += r;
1508                result.y -= r;
1509            }
1510            return result;
1511        }
1512        struct point __cdecl call2(int(__stdcall *cb)(struct point)) {
1513            int i;
1514            struct point result = { 0, 0 };
1515            for (i = 0; i < 1000; i++) {
1516                struct point p = { -i, i };
1517                int r = cb(p);
1518                result.x += r;
1519                result.y -= r;
1520            }
1521            return result;
1522        }
1523    """)
1524    ptr_call1 = ffi.addressof(lib, 'call1')
1525    ptr_call2 = ffi.addressof(lib, 'call2')
1526    if sys.platform == 'win32' and not sys.maxsize > 2**32:
1527        py.test.raises(TypeError, lib.call1, ffi.addressof(lib, 'cb2'))
1528        py.test.raises(TypeError, ptr_call1, ffi.addressof(lib, 'cb2'))
1529        py.test.raises(TypeError, lib.call2, ffi.addressof(lib, 'cb1'))
1530        py.test.raises(TypeError, ptr_call2, ffi.addressof(lib, 'cb1'))
1531    pt = lib.call1(ffi.addressof(lib, 'cb1'))
1532    assert (pt.x, pt.y) == (-9*500*999, 9*500*999)
1533    pt = ptr_call1(ffi.addressof(lib, 'cb1'))
1534    assert (pt.x, pt.y) == (-9*500*999, 9*500*999)
1535    pt = lib.call2(ffi.addressof(lib, 'cb2'))
1536    assert (pt.x, pt.y) == (99*500*999, -99*500*999)
1537    pt = ptr_call2(ffi.addressof(lib, 'cb2'))
1538    assert (pt.x, pt.y) == (99*500*999, -99*500*999)
1539
1540def test_extern_python_1():
1541    import warnings
1542    ffi = FFI()
1543    with warnings.catch_warnings(record=True) as log:
1544        ffi.cdef("""
1545        extern "Python" {
1546            int bar(int, int);
1547            void baz(int, int);
1548            int bok(void);
1549            void boz(void);
1550        }
1551        """)
1552    assert len(log) == 0, "got a warning: %r" % (log,)
1553    lib = verify(ffi, 'test_extern_python_1', """
1554        static void baz(int, int);   /* forward */
1555    """)
1556    assert ffi.typeof(lib.bar) == ffi.typeof("int(*)(int, int)")
1557    with FdWriteCapture() as f:
1558        res = lib.bar(4, 5)
1559    assert res == 0
1560    assert f.getvalue() == (
1561        b"extern \"Python\": function _CFFI_test_extern_python_1.bar() called, "
1562        b"but no code was attached "
1563        b"to it yet with @ffi.def_extern().  Returning 0.\n")
1564
1565    @ffi.def_extern("bar")
1566    def my_bar(x, y):
1567        seen.append(("Bar", x, y))
1568        return x * y
1569    assert my_bar != lib.bar
1570    seen = []
1571    res = lib.bar(6, 7)
1572    assert seen == [("Bar", 6, 7)]
1573    assert res == 42
1574
1575    def baz(x, y):
1576        seen.append(("Baz", x, y))
1577    baz1 = ffi.def_extern()(baz)
1578    assert baz1 is baz
1579    seen = []
1580    baz(long(40), long(4))
1581    res = lib.baz(long(50), long(8))
1582    assert res is None
1583    assert seen == [("Baz", 40, 4), ("Baz", 50, 8)]
1584    assert type(seen[0][1]) is type(seen[0][2]) is long
1585    assert type(seen[1][1]) is type(seen[1][2]) is int
1586
1587    @ffi.def_extern(name="bok")
1588    def bokk():
1589        seen.append("Bok")
1590        return 42
1591    seen = []
1592    assert lib.bok() == 42
1593    assert seen == ["Bok"]
1594
1595    @ffi.def_extern()
1596    def boz():
1597        seen.append("Boz")
1598    seen = []
1599    assert lib.boz() is None
1600    assert seen == ["Boz"]
1601
1602def test_extern_python_bogus_name():
1603    ffi = FFI()
1604    ffi.cdef("int abc;")
1605    lib = verify(ffi, 'test_extern_python_bogus_name', "int abc;")
1606    def fn():
1607        pass
1608    py.test.raises(ffi.error, ffi.def_extern("unknown_name"), fn)
1609    py.test.raises(ffi.error, ffi.def_extern("abc"), fn)
1610    assert lib.abc == 0
1611    e = py.test.raises(ffi.error, ffi.def_extern("abc"), fn)
1612    assert str(e.value) == ("ffi.def_extern('abc'): no 'extern \"Python\"' "
1613                            "function with this name")
1614    e = py.test.raises(ffi.error, ffi.def_extern(), fn)
1615    assert str(e.value) == ("ffi.def_extern('fn'): no 'extern \"Python\"' "
1616                            "function with this name")
1617    #
1618    py.test.raises(TypeError, ffi.def_extern(42), fn)
1619    py.test.raises((TypeError, AttributeError), ffi.def_extern(), "foo")
1620    class X:
1621        pass
1622    x = X()
1623    x.__name__ = x
1624    py.test.raises(TypeError, ffi.def_extern(), x)
1625
1626def test_extern_python_bogus_result_type():
1627    ffi = FFI()
1628    ffi.cdef("""extern "Python" void bar(int);""")
1629    lib = verify(ffi, 'test_extern_python_bogus_result_type', "")
1630    #
1631    @ffi.def_extern()
1632    def bar(n):
1633        return n * 10
1634    with StdErrCapture() as f:
1635        res = lib.bar(321)
1636    assert res is None
1637    assert f.getvalue() == (
1638        "From cffi callback %r:\n" % (bar,) +
1639        "Trying to convert the result back to C:\n"
1640        "TypeError: callback with the return type 'void' must return None\n")
1641
1642def test_extern_python_redefine():
1643    ffi = FFI()
1644    ffi.cdef("""extern "Python" int bar(int);""")
1645    lib = verify(ffi, 'test_extern_python_redefine', "")
1646    #
1647    @ffi.def_extern()
1648    def bar(n):
1649        return n * 10
1650    assert lib.bar(42) == 420
1651    #
1652    @ffi.def_extern()
1653    def bar(n):
1654        return -n
1655    assert lib.bar(42) == -42
1656
1657def test_extern_python_struct():
1658    ffi = FFI()
1659    ffi.cdef("""
1660        struct foo_s { int a, b, c; };
1661        extern "Python" int bar(int, struct foo_s, int);
1662        extern "Python" { struct foo_s baz(int, int);
1663                          struct foo_s bok(void); }
1664    """)
1665    lib = verify(ffi, 'test_extern_python_struct',
1666                 "struct foo_s { int a, b, c; };")
1667    #
1668    @ffi.def_extern()
1669    def bar(x, s, z):
1670        return x + s.a + s.b + s.c + z
1671    res = lib.bar(1000, [1001, 1002, 1004], 1008)
1672    assert res == 5015
1673    #
1674    @ffi.def_extern()
1675    def baz(x, y):
1676        return [x + y, x - y, x * y]
1677    res = lib.baz(1000, 42)
1678    assert res.a == 1042
1679    assert res.b == 958
1680    assert res.c == 42000
1681    #
1682    @ffi.def_extern()
1683    def bok():
1684        return [10, 20, 30]
1685    res = lib.bok()
1686    assert [res.a, res.b, res.c] == [10, 20, 30]
1687
1688def test_extern_python_long_double():
1689    ffi = FFI()
1690    ffi.cdef("""
1691        extern "Python" int bar(int, long double, int);
1692        extern "Python" long double baz(int, int);
1693        extern "Python" long double bok(void);
1694    """)
1695    lib = verify(ffi, 'test_extern_python_long_double', "")
1696    #
1697    @ffi.def_extern()
1698    def bar(x, l, z):
1699        seen.append((x, l, z))
1700        return 6
1701    seen = []
1702    lib.bar(10, 3.5, 20)
1703    expected = ffi.cast("long double", 3.5)
1704    assert repr(seen) == repr([(10, expected, 20)])
1705    #
1706    @ffi.def_extern()
1707    def baz(x, z):
1708        assert x == 10 and z == 20
1709        return expected
1710    res = lib.baz(10, 20)
1711    assert repr(res) == repr(expected)
1712    #
1713    @ffi.def_extern()
1714    def bok():
1715        return expected
1716    res = lib.bok()
1717    assert repr(res) == repr(expected)
1718
1719def test_extern_python_signature():
1720    ffi = FFI()
1721    lib = verify(ffi, 'test_extern_python_signature', "")
1722    py.test.raises(TypeError, ffi.def_extern(425), None)
1723    py.test.raises(TypeError, ffi.def_extern, 'a', 'b', 'c', 'd')
1724
1725def test_extern_python_errors():
1726    ffi = FFI()
1727    ffi.cdef("""
1728        extern "Python" int bar(int);
1729    """)
1730    lib = verify(ffi, 'test_extern_python_errors', "")
1731
1732    seen = []
1733    def oops(*args):
1734        seen.append(args)
1735
1736    @ffi.def_extern(onerror=oops)
1737    def bar(x):
1738        return x + ""
1739    assert lib.bar(10) == 0
1740
1741    @ffi.def_extern(name="bar", onerror=oops, error=-66)
1742    def bar2(x):
1743        return x + ""
1744    assert lib.bar(10) == -66
1745
1746    assert len(seen) == 2
1747    exc, val, tb = seen[0]
1748    assert exc is TypeError
1749    assert isinstance(val, TypeError)
1750    assert tb.tb_frame.f_code.co_name == "bar"
1751    exc, val, tb = seen[1]
1752    assert exc is TypeError
1753    assert isinstance(val, TypeError)
1754    assert tb.tb_frame.f_code.co_name == "bar2"
1755    #
1756    # a case where 'onerror' is not callable
1757    py.test.raises(TypeError, ffi.def_extern(name='bar', onerror=42),
1758                   lambda x: x)
1759
1760def test_extern_python_stdcall():
1761    ffi = FFI()
1762    ffi.cdef("""
1763        extern "Python" int __stdcall foo(int);
1764        extern "Python" int WINAPI bar(int);
1765        int (__stdcall * mycb1)(int);
1766        int indirect_call(int);
1767    """)
1768    lib = verify(ffi, 'test_extern_python_stdcall', """
1769        #ifndef _MSC_VER
1770        #  define __stdcall
1771        #endif
1772        static int (__stdcall * mycb1)(int);
1773        static int indirect_call(int x) {
1774            return mycb1(x);
1775        }
1776    """)
1777    #
1778    @ffi.def_extern()
1779    def foo(x):
1780        return x + 42
1781    @ffi.def_extern()
1782    def bar(x):
1783        return x + 43
1784    assert lib.foo(100) == 142
1785    assert lib.bar(100) == 143
1786    lib.mycb1 = lib.foo
1787    assert lib.mycb1(200) == 242
1788    assert lib.indirect_call(300) == 342
1789
1790def test_extern_python_plus_c():
1791    ffi = FFI()
1792    ffi.cdef("""
1793        extern "Python+C" int foo(int);
1794        extern "C +\tPython" int bar(int);
1795        int call_me(int);
1796    """)
1797    lib = verify(ffi, 'test_extern_python_plus_c', """
1798        int foo(int);
1799        #ifdef __GNUC__
1800        __attribute__((visibility("hidden")))
1801        #endif
1802        int bar(int);
1803
1804        static int call_me(int x) {
1805            return foo(x) - bar(x);
1806        }
1807    """)
1808    #
1809    @ffi.def_extern()
1810    def foo(x):
1811        return x * 42
1812    @ffi.def_extern()
1813    def bar(x):
1814        return x * 63
1815    assert lib.foo(100) == 4200
1816    assert lib.bar(100) == 6300
1817    assert lib.call_me(100) == -2100
1818
1819def test_introspect_function():
1820    ffi = FFI()
1821    ffi.cdef("float f1(double);")
1822    lib = verify(ffi, 'test_introspect_function', """
1823        float f1(double x) { return x; }
1824    """)
1825    assert dir(lib) == ['f1']
1826    FUNC = ffi.typeof(lib.f1)
1827    assert FUNC.kind == 'function'
1828    assert FUNC.args[0].cname == 'double'
1829    assert FUNC.result.cname == 'float'
1830    assert ffi.typeof(ffi.addressof(lib, 'f1')) is FUNC
1831
1832def test_introspect_global_var():
1833    ffi = FFI()
1834    ffi.cdef("float g1;")
1835    lib = verify(ffi, 'test_introspect_global_var', """
1836        float g1;
1837    """)
1838    assert dir(lib) == ['g1']
1839    FLOATPTR = ffi.typeof(ffi.addressof(lib, 'g1'))
1840    assert FLOATPTR.kind == 'pointer'
1841    assert FLOATPTR.item.cname == 'float'
1842
1843def test_introspect_global_var_array():
1844    ffi = FFI()
1845    ffi.cdef("float g1[100];")
1846    lib = verify(ffi, 'test_introspect_global_var_array', """
1847        float g1[100];
1848    """)
1849    assert dir(lib) == ['g1']
1850    FLOATARRAYPTR = ffi.typeof(ffi.addressof(lib, 'g1'))
1851    assert FLOATARRAYPTR.kind == 'pointer'
1852    assert FLOATARRAYPTR.item.kind == 'array'
1853    assert FLOATARRAYPTR.item.length == 100
1854    assert ffi.typeof(lib.g1) is FLOATARRAYPTR.item
1855
1856def test_introspect_integer_const():
1857    ffi = FFI()
1858    ffi.cdef("#define FOO 42")
1859    lib = verify(ffi, 'test_introspect_integer_const', """
1860        #define FOO 42
1861    """)
1862    assert dir(lib) == ['FOO']
1863    assert lib.FOO == ffi.integer_const('FOO') == 42
1864
1865def test_introspect_typedef():
1866    ffi = FFI()
1867    ffi.cdef("typedef int foo_t;")
1868    lib = verify(ffi, 'test_introspect_typedef', """
1869        typedef int foo_t;
1870    """)
1871    assert ffi.list_types() == (['foo_t'], [], [])
1872    assert ffi.typeof('foo_t').kind == 'primitive'
1873    assert ffi.typeof('foo_t').cname == 'int'
1874
1875def test_introspect_typedef_multiple():
1876    ffi = FFI()
1877    ffi.cdef("typedef signed char a_t, c_t, g_t, b_t;")
1878    lib = verify(ffi, 'test_introspect_typedef_multiple', """
1879        typedef signed char a_t, c_t, g_t, b_t;
1880    """)
1881    assert ffi.list_types() == (['a_t', 'b_t', 'c_t', 'g_t'], [], [])
1882
1883def test_introspect_struct():
1884    ffi = FFI()
1885    ffi.cdef("struct foo_s { int a; };")
1886    lib = verify(ffi, 'test_introspect_struct', """
1887        struct foo_s { int a; };
1888    """)
1889    assert ffi.list_types() == ([], ['foo_s'], [])
1890    assert ffi.typeof('struct foo_s').kind == 'struct'
1891    assert ffi.typeof('struct foo_s').cname == 'struct foo_s'
1892
1893def test_introspect_union():
1894    ffi = FFI()
1895    ffi.cdef("union foo_s { int a; };")
1896    lib = verify(ffi, 'test_introspect_union', """
1897        union foo_s { int a; };
1898    """)
1899    assert ffi.list_types() == ([], [], ['foo_s'])
1900    assert ffi.typeof('union foo_s').kind == 'union'
1901    assert ffi.typeof('union foo_s').cname == 'union foo_s'
1902
1903def test_introspect_struct_and_typedef():
1904    ffi = FFI()
1905    ffi.cdef("typedef struct { int a; } foo_t;")
1906    lib = verify(ffi, 'test_introspect_struct_and_typedef', """
1907        typedef struct { int a; } foo_t;
1908    """)
1909    assert ffi.list_types() == (['foo_t'], [], [])
1910    assert ffi.typeof('foo_t').kind == 'struct'
1911    assert ffi.typeof('foo_t').cname == 'foo_t'
1912
1913def test_introspect_included_type():
1914    SOURCE = """
1915        typedef signed char schar_t;
1916        struct sint_t { int x; };
1917    """
1918    ffi1 = FFI()
1919    ffi1.cdef(SOURCE)
1920    ffi2 = FFI()
1921    ffi2.include(ffi1)
1922    verify(ffi1, "test_introspect_included_type_parent", SOURCE)
1923    verify(ffi2, "test_introspect_included_type", SOURCE)
1924    assert ffi1.list_types() == ffi2.list_types() == (
1925            ['schar_t'], ['sint_t'], [])
1926
1927def test_introspect_order():
1928    ffi = FFI()
1929    ffi.cdef("union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb;")
1930    ffi.cdef("union CFFIg   { int a; }; typedef struct CFFIcc  { int a; } CFFIbbb;")
1931    ffi.cdef("union CFFIaa  { int a; }; typedef struct CFFIa   { int a; } CFFIbb;")
1932    verify(ffi, "test_introspect_order", """
1933        union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb;
1934        union CFFIg   { int a; }; typedef struct CFFIcc  { int a; } CFFIbbb;
1935        union CFFIaa  { int a; }; typedef struct CFFIa   { int a; } CFFIbb;
1936    """)
1937    assert ffi.list_types() == (['CFFIb', 'CFFIbb', 'CFFIbbb'],
1938                                ['CFFIa', 'CFFIcc', 'CFFIccc'],
1939                                ['CFFIaa', 'CFFIaaa', 'CFFIg'])
1940
1941def test_bool_in_cpp():
1942    # this works when compiled as C, but in cffi < 1.7 it fails as C++
1943    ffi = FFI()
1944    ffi.cdef("bool f(void);")
1945    lib = verify(ffi, "test_bool_in_cpp", "char f(void) { return 2; }")
1946    assert lib.f() is True
1947
1948def test_bool_in_cpp_2():
1949    ffi = FFI()
1950    ffi.cdef('int add(int a, int b);')
1951    lib = verify(ffi, "test_bool_bug_cpp", '''
1952        typedef bool _Bool;  /* there is a Windows header with this line */
1953        int add(int a, int b)
1954        {
1955            return a + b;
1956        }''', source_extension='.cpp')
1957    c = lib.add(2, 3)
1958    assert c == 5
1959
1960def test_struct_field_opaque():
1961    ffi = FFI()
1962    ffi.cdef("struct a { struct b b; };")
1963    e = py.test.raises(TypeError, verify,
1964                       ffi, "test_struct_field_opaque", "?")
1965    assert str(e.value) == ("struct a: field 'a.b' is of an opaque"
1966                            " type (not declared in cdef())")
1967    ffi = FFI()
1968    ffi.cdef("struct a { struct b b[2]; };")
1969    e = py.test.raises(TypeError, verify,
1970                       ffi, "test_struct_field_opaque", "?")
1971    assert str(e.value) == ("struct a: field 'a.b' is of an opaque"
1972                            " type (not declared in cdef())")
1973    ffi = FFI()
1974    ffi.cdef("struct a { struct b b[]; };")
1975    e = py.test.raises(TypeError, verify,
1976                       ffi, "test_struct_field_opaque", "?")
1977    assert str(e.value) == ("struct a: field 'a.b' is of an opaque"
1978                            " type (not declared in cdef())")
1979
1980def test_function_arg_opaque():
1981    py.test.skip("can currently declare a function with an opaque struct "
1982                 "as argument, but AFAICT it's impossible to call it later")
1983
1984def test_function_returns_opaque():
1985    ffi = FFI()
1986    ffi.cdef("struct a foo(int);")
1987    e = py.test.raises(TypeError, verify,
1988                       ffi, "test_function_returns_opaque", "?")
1989    assert str(e.value) == ("function foo: 'struct a' is used as result type,"
1990                            " but is opaque")
1991
1992def test_function_returns_union():
1993    ffi = FFI()
1994    ffi.cdef("union u1 { int a, b; }; union u1 f1(int);")
1995    lib = verify(ffi, "test_function_returns_union", """
1996        union u1 { int a, b; };
1997        static union u1 f1(int x) { union u1 u; u.b = x; return u; }
1998    """)
1999    assert lib.f1(51).a == 51
2000
2001def test_function_returns_partial_struct():
2002    ffi = FFI()
2003    ffi.cdef("struct aaa { int a; ...; }; struct aaa f1(int);")
2004    lib = verify(ffi, "test_function_returns_partial_struct", """
2005        struct aaa { int b, a, c; };
2006        static struct aaa f1(int x) { struct aaa s = {0}; s.a = x; return s; }
2007    """)
2008    assert lib.f1(52).a == 52
2009
2010def test_function_returns_float_complex():
2011    if sys.platform == 'win32':
2012        py.test.skip("MSVC may not support _Complex")
2013    ffi = FFI()
2014    ffi.cdef("float _Complex f1(float a, float b);");
2015    lib = verify(ffi, "test_function_returns_float_complex", """
2016        #include <complex.h>
2017        static float _Complex f1(float a, float b) { return a + I*2.0*b; }
2018    """, no_cpp=True)    # <complex.h> fails on some systems with C++
2019    result = lib.f1(1.25, 5.1)
2020    assert type(result) == complex
2021    assert result.real == 1.25   # exact
2022    assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-5) # inexact
2023
2024def test_function_returns_double_complex():
2025    if sys.platform == 'win32':
2026        py.test.skip("MSVC may not support _Complex")
2027    ffi = FFI()
2028    ffi.cdef("double _Complex f1(double a, double b);");
2029    lib = verify(ffi, "test_function_returns_double_complex", """
2030        #include <complex.h>
2031        static double _Complex f1(double a, double b) { return a + I*2.0*b; }
2032    """, no_cpp=True)    # <complex.h> fails on some systems with C++
2033    result = lib.f1(1.25, 5.1)
2034    assert type(result) == complex
2035    assert result.real == 1.25   # exact
2036    assert result.imag == 2*5.1  # exact
2037
2038def test_function_argument_float_complex():
2039    if sys.platform == 'win32':
2040        py.test.skip("MSVC may not support _Complex")
2041    ffi = FFI()
2042    ffi.cdef("float f1(float _Complex x);");
2043    lib = verify(ffi, "test_function_argument_float_complex", """
2044        #include <complex.h>
2045        static float f1(float _Complex x) { return cabsf(x); }
2046    """, no_cpp=True)    # <complex.h> fails on some systems with C++
2047    x = complex(12.34, 56.78)
2048    result = lib.f1(x)
2049    assert abs(result - abs(x)) < 1e-5
2050
2051def test_function_argument_double_complex():
2052    if sys.platform == 'win32':
2053        py.test.skip("MSVC may not support _Complex")
2054    ffi = FFI()
2055    ffi.cdef("double f1(double _Complex);");
2056    lib = verify(ffi, "test_function_argument_double_complex", """
2057        #include <complex.h>
2058        static double f1(double _Complex x) { return cabs(x); }
2059    """, no_cpp=True)    # <complex.h> fails on some systems with C++
2060    x = complex(12.34, 56.78)
2061    result = lib.f1(x)
2062    assert abs(result - abs(x)) < 1e-11
2063
2064def test_typedef_array_dotdotdot():
2065    ffi = FFI()
2066    ffi.cdef("""
2067        typedef int foo_t[...], bar_t[...];
2068        int gv[...];
2069        typedef int mat_t[...][...];
2070        typedef int vmat_t[][...];
2071        """)
2072    lib = verify(ffi, "test_typedef_array_dotdotdot", """
2073        typedef int foo_t[50], bar_t[50];
2074        int gv[23];
2075        typedef int mat_t[6][7];
2076        typedef int vmat_t[][8];
2077    """)
2078    assert ffi.sizeof("foo_t") == 50 * ffi.sizeof("int")
2079    assert ffi.sizeof("bar_t") == 50 * ffi.sizeof("int")
2080    assert len(ffi.new("foo_t")) == 50
2081    assert len(ffi.new("bar_t")) == 50
2082    assert ffi.sizeof(lib.gv) == 23 * ffi.sizeof("int")
2083    assert ffi.sizeof("mat_t") == 6 * 7 * ffi.sizeof("int")
2084    assert len(ffi.new("mat_t")) == 6
2085    assert len(ffi.new("mat_t")[3]) == 7
2086    py.test.raises(ffi.error, ffi.sizeof, "vmat_t")
2087    p = ffi.new("vmat_t", 4)
2088    assert ffi.sizeof(p[3]) == 8 * ffi.sizeof("int")
2089
2090def test_call_with_custom_field_pos():
2091    ffi = FFI()
2092    ffi.cdef("""
2093        struct foo { int x; ...; };
2094        struct foo f(void);
2095        struct foo g(int, ...);
2096    """)
2097    lib = verify(ffi, "test_call_with_custom_field_pos", """
2098        struct foo { int y, x; };
2099        struct foo f(void) {
2100            struct foo s = { 40, 200 };
2101            return s;
2102        }
2103        struct foo g(int a, ...) { return f(); }
2104    """)
2105    assert lib.f().x == 200
2106    e = py.test.raises(NotImplementedError, lib.g, 0)
2107    assert str(e.value) == (
2108        'ctype \'struct foo\' not supported as return value.  It is a '
2109        'struct declared with "...;", but the C calling convention may '
2110        'depend on the missing fields; or, it contains anonymous '
2111        'struct/unions.  Such structs are only supported '
2112        'as return value if the function is \'API mode\' and non-variadic '
2113        '(i.e. declared inside ffibuilder.cdef()+ffibuilder.set_source() '
2114        'and not taking a final \'...\' argument)')
2115
2116def test_call_with_nested_anonymous_struct():
2117    if sys.platform == 'win32':
2118        py.test.skip("needs a GCC extension")
2119    ffi = FFI()
2120    ffi.cdef("""
2121        struct foo { int a; union { int b, c; }; };
2122        struct foo f(void);
2123        struct foo g(int, ...);
2124    """)
2125    lib = verify(ffi, "test_call_with_nested_anonymous_struct", """
2126        struct foo { int a; union { int b, c; }; };
2127        struct foo f(void) {
2128            struct foo s = { 40 };
2129            s.b = 200;
2130            return s;
2131        }
2132        struct foo g(int a, ...) { return f(); }
2133    """)
2134    assert lib.f().b == 200
2135    e = py.test.raises(NotImplementedError, lib.g, 0)
2136    assert str(e.value) == (
2137        'ctype \'struct foo\' not supported as return value.  It is a '
2138        'struct declared with "...;", but the C calling convention may '
2139        'depend on the missing fields; or, it contains anonymous '
2140        'struct/unions.  Such structs are only supported '
2141        'as return value if the function is \'API mode\' and non-variadic '
2142        '(i.e. declared inside ffibuilder.cdef()+ffibuilder.set_source() '
2143        'and not taking a final \'...\' argument)')
2144
2145def test_call_with_bitfield():
2146    ffi = FFI()
2147    ffi.cdef("""
2148        struct foo { int x:5; };
2149        struct foo f(void);
2150        struct foo g(int, ...);
2151    """)
2152    lib = verify(ffi, "test_call_with_bitfield", """
2153        struct foo { int x:5; };
2154        struct foo f(void) {
2155            struct foo s = { 11 };
2156            return s;
2157        }
2158        struct foo g(int a, ...) { return f(); }
2159    """)
2160    assert lib.f().x == 11
2161    e = py.test.raises(NotImplementedError, lib.g, 0)
2162    assert str(e.value) == (
2163        "ctype 'struct foo' not supported as return value.  It is a struct "
2164        "with bit fields, which libffi does not support.  Such structs are "
2165        "only supported as return value if the function is 'API mode' and "
2166        "non-variadic (i.e. declared inside ffibuilder.cdef()+ffibuilder."
2167        "set_source() and not taking a final '...' argument)")
2168
2169def test_call_with_zero_length_field():
2170    if sys.platform == 'win32':
2171        py.test.skip("zero-length field not supported by MSVC")
2172    ffi = FFI()
2173    ffi.cdef("""
2174        struct foo { int a; int x[0]; };
2175        struct foo f(void);
2176        struct foo g(int, ...);
2177    """)
2178    lib = verify(ffi, "test_call_with_zero_length_field", """
2179        struct foo { int a; int x[0]; };
2180        struct foo f(void) {
2181            struct foo s = { 42 };
2182            return s;
2183        }
2184        struct foo g(int a, ...) { return f(); }
2185    """)
2186    assert lib.f().a == 42
2187    e = py.test.raises(NotImplementedError, lib.g, 0)
2188    assert str(e.value) == (
2189        "ctype 'struct foo' not supported as return value.  It is a "
2190        "struct with a zero-length array, which libffi does not support."
2191        "  Such structs are only supported as return value if the function is "
2192        "'API mode' and non-variadic (i.e. declared inside ffibuilder.cdef()"
2193        "+ffibuilder.set_source() and not taking a final '...' argument)")
2194
2195def test_call_with_union():
2196    ffi = FFI()
2197    ffi.cdef("""
2198        union foo { int a; char b; };
2199        union foo f(void);
2200        union foo g(int, ...);
2201    """)
2202    lib = verify(ffi, "test_call_with_union", """
2203        union foo { int a; char b; };
2204        union foo f(void) {
2205            union foo s = { 42 };
2206            return s;
2207        }
2208        union foo g(int a, ...) { return f(); }
2209    """)
2210    assert lib.f().a == 42
2211    e = py.test.raises(NotImplementedError, lib.g, 0)
2212    assert str(e.value) == (
2213        "ctype 'union foo' not supported as return value by libffi.  "
2214        "Unions are only supported as return value if the function is "
2215        "'API mode' and non-variadic (i.e. declared inside ffibuilder.cdef()"
2216        "+ffibuilder.set_source() and not taking a final '...' argument)")
2217
2218def test_call_with_packed_struct():
2219    if sys.platform == 'win32':
2220        py.test.skip("needs a GCC extension")
2221    ffi = FFI()
2222    ffi.cdef("""
2223        struct foo { char y; int x; };
2224        struct foo f(void);
2225        struct foo g(int, ...);
2226    """, packed=True)
2227    lib = verify(ffi, "test_call_with_packed_struct", """
2228        struct foo { char y; int x; } __attribute__((packed));
2229        struct foo f(void) {
2230            struct foo s = { 40, 200 };
2231            return s;
2232        }
2233        struct foo g(int a, ...) {
2234            struct foo s = { 41, 201 };
2235            return s;
2236        }
2237    """)
2238    assert ord(lib.f().y) == 40
2239    assert lib.f().x == 200
2240    e = py.test.raises(NotImplementedError, lib.g, 0)
2241    assert str(e.value) == (
2242        "ctype 'struct foo' not supported as return value.  It is a "
2243        "'packed' structure, with a different layout than expected by libffi."
2244        "  Such structs are only supported as return value if the function is "
2245        "'API mode' and non-variadic (i.e. declared inside ffibuilder.cdef()"
2246        "+ffibuilder.set_source() and not taking a final '...' argument)")
2247
2248def test_pack_not_supported():
2249    ffi = FFI()
2250    ffi.cdef("""struct foo { char y; int x; };""", pack=2)
2251    py.test.raises(NotImplementedError, verify,
2252                   ffi, "test_pack_not_supported", "")
2253
2254def test_gcc_visibility_hidden():
2255    if sys.platform == 'win32':
2256        py.test.skip("test for gcc/clang")
2257    ffi = FFI()
2258    ffi.cdef("""
2259    int f(int);
2260    """)
2261    lib = verify(ffi, "test_gcc_visibility_hidden", """
2262    int f(int a) { return a + 40; }
2263    """, extra_compile_args=['-fvisibility=hidden'])
2264    assert lib.f(2) == 42
2265
2266def test_override_default_definition():
2267    ffi = FFI()
2268    ffi.cdef("typedef long int16_t, char16_t;")
2269    lib = verify(ffi, "test_override_default_definition", "")
2270    assert ffi.typeof("int16_t") is ffi.typeof("char16_t") is ffi.typeof("long")
2271
2272def test_char16_char32_type(no_cpp=False):
2273    if no_cpp is False and sys.platform == "win32":
2274        py.test.skip("aaaaaaa why do modern MSVC compilers still define "
2275                     "a very old __cplusplus value")
2276    ffi = FFI()
2277    ffi.cdef("""
2278        char16_t foo_2bytes(char16_t);
2279        char32_t foo_4bytes(char32_t);
2280    """)
2281    lib = verify(ffi, "test_char16_char32_type" + no_cpp * "_nocpp", """
2282    #if !defined(__cplusplus) || (!defined(_LIBCPP_VERSION) && __cplusplus < 201103L)
2283    typedef uint_least16_t char16_t;
2284    typedef uint_least32_t char32_t;
2285    #endif
2286
2287    char16_t foo_2bytes(char16_t a) { return (char16_t)(a + 42); }
2288    char32_t foo_4bytes(char32_t a) { return (char32_t)(a + 42); }
2289    """, no_cpp=no_cpp)
2290    assert lib.foo_2bytes(u+'\u1234') == u+'\u125e'
2291    assert lib.foo_4bytes(u+'\u1234') == u+'\u125e'
2292    assert lib.foo_4bytes(u+'\U00012345') == u+'\U0001236f'
2293    py.test.raises(TypeError, lib.foo_2bytes, u+'\U00012345')
2294    py.test.raises(TypeError, lib.foo_2bytes, 1234)
2295    py.test.raises(TypeError, lib.foo_4bytes, 1234)
2296
2297def test_char16_char32_plain_c():
2298    test_char16_char32_type(no_cpp=True)
2299
2300def test_loader_spec():
2301    ffi = FFI()
2302    lib = verify(ffi, "test_loader_spec", "")
2303    if sys.version_info < (3,):
2304        assert not hasattr(lib, '__loader__')
2305        assert not hasattr(lib, '__spec__')
2306    else:
2307        assert lib.__loader__ is None
2308        assert lib.__spec__ is None
2309
2310def test_realize_struct_error():
2311    ffi = FFI()
2312    ffi.cdef("""typedef ... foo_t; struct foo_s { void (*x)(foo_t); };""")
2313    lib = verify(ffi, "test_realize_struct_error", """
2314        typedef int foo_t; struct foo_s { void (*x)(foo_t); };
2315    """)
2316    py.test.raises(TypeError, ffi.new, "struct foo_s *")
2317