diff --git a/cffi/cparser.py b/cffi/cparser.py index 54810acbf34db2d9944970aa42c15182ab0d51f5_Y2ZmaS9jcGFyc2VyLnB5..b6c5e557534e338f0990811ea7a785c577113c83_Y2ZmaS9jcGFyc2VyLnB5 100644 --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -29,7 +29,7 @@ _r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)" r"\b((?:[^\n\\]|\\.)*?)$", re.DOTALL | re.MULTILINE) -_r_line_directive = re.compile(r"^[ \t]*#[ \t]*line\b.*$", re.MULTILINE) +_r_line_directive = re.compile(r"^[ \t]*#[ \t]*(?:line|\d+)\b.*$", re.MULTILINE) _r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") _r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") _r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") @@ -166,9 +166,9 @@ def _remove_line_directives(csource): # _r_line_directive matches whole lines, without the final \n, if they - # start with '#line' with some spacing allowed. This function stores - # them away and replaces them with exactly the string '#line@N', where - # N is the index in the list 'line_directives'. + # start with '#line' with some spacing allowed, or '#NUMBER'. This + # function stores them away and replaces them with exactly the string + # '#line@N', where N is the index in the list 'line_directives'. line_directives = [] def replace(m): i = len(line_directives) diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py index 54810acbf34db2d9944970aa42c15182ab0d51f5_dGVzdGluZy9jZmZpMC90ZXN0X3BhcnNpbmcucHk=..b6c5e557534e338f0990811ea7a785c577113c83_dGVzdGluZy9jZmZpMC90ZXN0X3BhcnNpbmcucHk= 100644 --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -199,6 +199,21 @@ 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(): @@ -214,6 +229,18 @@ 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()) @@ -229,6 +256,20 @@ */ 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():