diff options
Diffstat (limited to 'testing/cffi0/test_parsing.py')
-rw-r--r-- | testing/cffi0/test_parsing.py | 152 |
1 files changed, 147 insertions, 5 deletions
diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py index 2d75850..a5e4587 100644 --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -174,7 +174,7 @@ def test_remove_line_continuation_comments(): double // blah \\ more comments x(void); - double // blah\\\\ + double // blah // blah\\\\ y(void); double // blah\\ \ etc @@ -185,6 +185,93 @@ def test_remove_line_continuation_comments(): m.y m.z +def test_dont_remove_comment_in_line_directives(): + ffi = FFI(backend=FakeBackend()) + e = py.test.raises(CDefError, ffi.cdef, """ + \t # \t line \t 8 \t "baz.c" \t + + some syntax error here + """) + assert str(e.value) == "parse error\nbaz.c:9:14: before: syntax" + # + e = py.test.raises(CDefError, ffi.cdef, """ + #line 7 "foo//bar.c" + + some syntax error here + """) + # + assert str(e.value) == "parse error\nfoo//bar.c:8:14: before: syntax" + ffi = FFI(backend=FakeBackend()) + e = py.test.raises(CDefError, ffi.cdef, """ + \t # \t 8 \t "baz.c" \t + + some syntax error here + """) + assert str(e.value) == "parse error\nbaz.c:9:14: before: syntax" + # + e = py.test.raises(CDefError, ffi.cdef, """ + # 7 "foo//bar.c" + + some syntax error here + """) + assert str(e.value) == "parse error\nfoo//bar.c:8:14: before: syntax" + +def test_multiple_line_directives(): + ffi = FFI(backend=FakeBackend()) + e = py.test.raises(CDefError, ffi.cdef, + """ #line 5 "foo.c" + extern int xx; + #line 6 "bar.c" + extern int yy; + #line 7 "baz.c" + some syntax error here + #line 8 "yadda.c" + extern int zz; + """) + assert str(e.value) == "parse error\nbaz.c:7:14: before: syntax" + # + e = py.test.raises(CDefError, ffi.cdef, + """ # 5 "foo.c" + extern int xx; + # 6 "bar.c" + extern int yy; + # 7 "baz.c" + some syntax error here + # 8 "yadda.c" + extern int zz; + """) + assert str(e.value) == "parse error\nbaz.c:7:14: before: syntax" + +def test_commented_line_directive(): + ffi = FFI(backend=FakeBackend()) + e = py.test.raises(CDefError, ffi.cdef, """ + /* + #line 5 "foo.c" + */ + void xx(void); + + #line 6 "bar.c" + /* + #line 35 "foo.c" + */ + some syntax error + """) + # + assert str(e.value) == "parse error\nbar.c:9:14: before: syntax" + e = py.test.raises(CDefError, ffi.cdef, """ + /* + # 5 "foo.c" + */ + void xx(void); + + # 6 "bar.c" + /* + # 35 "foo.c" + */ + some syntax error + """) + assert str(e.value) == "parse error\nbar.c:9:14: before: syntax" + def test_line_continuation_in_defines(): ffi = FFI(backend=FakeBackend()) ffi.cdef(""" @@ -324,6 +411,7 @@ def test_WPARAM_on_windows(): assert value == sys.maxsize * 2 - 40 def test__is_constant_globalvar(): + import warnings for input, expected_output in [ ("int a;", False), ("const int a;", True), @@ -341,10 +429,13 @@ def test__is_constant_globalvar(): ("const int a[5][6];", False), ]: ffi = FFI() - ffi.cdef(input) + with warnings.catch_warnings(record=True) as log: + warnings.simplefilter("always") + ffi.cdef(input) declarations = ffi._parser._declarations assert ('constant a' in declarations) == expected_output assert ('variable a' in declarations) == (not expected_output) + assert len(log) == (1 - expected_output) def test_restrict(): from cffi import model @@ -354,7 +445,7 @@ def test_restrict(): ("int *a;", False), ]: ffi = FFI() - ffi.cdef(input) + ffi.cdef("extern " + input) tp, quals = ffi._parser._declarations['variable a'] assert bool(quals & model.Q_RESTRICT) == expected_output @@ -409,7 +500,17 @@ def test_const_pointer_to_pointer(): def test_enum(): ffi = FFI() ffi.cdef(""" - enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1, OP = (POS+TWO)-1}; + enum Enum { + POS = +1, + TWO = 2, + NIL = 0, + NEG = -1, + ADDSUB = (POS+TWO)-1, + DIVMULINT = (3 * 3) / 2, + SHIFT = (1 << 3) >> 1, + BINOPS = (0x7 & 0x1) | 0x8, + XOR = 0xf ^ 0xa + }; """) needs_dlopen_none() C = ffi.dlopen(None) @@ -417,7 +518,11 @@ def test_enum(): assert C.TWO == 2 assert C.NIL == 0 assert C.NEG == -1 - assert C.OP == 2 + assert C.ADDSUB == 2 + assert C.DIVMULINT == 4 + assert C.SHIFT == 4 + assert C.BINOPS == 0b1001 + assert C.XOR == 0b0101 def test_stdcall(): ffi = FFI() @@ -466,3 +571,40 @@ def test_error_invalid_syntax_for_cdef(): e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == ('<cdef source string>:1: unexpected <FuncDef>: ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result |