Author: Armin Rigo <[email protected]>
Branch:
Changeset: r871:78e101dc0f74
Date: 2012-08-22 19:20 +0200
http://bitbucket.org/cffi/cffi/changeset/78e101dc0f74/
Log: Give a better error message than pycparser's default one on
ParseErrors
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -1,6 +1,6 @@
from . import api, model
-import pycparser, weakref, re
+import pycparser.c_parser, weakref, re
_r_comment = re.compile(r"/\*.*?\*/|//.*?$", re.DOTALL | re.MULTILINE)
_r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)\s+(.*?)$",
@@ -61,9 +61,30 @@
csource, macros = _preprocess(csource)
csourcelines.append(csource)
csource = '\n'.join(csourcelines)
- ast = _get_parser().parse(csource)
+ try:
+ ast = _get_parser().parse(csource)
+ except pycparser.c_parser.ParseError, e:
+ self.convert_pycparser_error(e, csource)
return ast, macros
+ def convert_pycparser_error(self, e, csource):
+ # xxx look for ":NUM:" at the start of str(e) and try to interpret
+ # it as a line number
+ line = None
+ msg = str(e)
+ if msg.startswith(':') and ':' in msg[1:]:
+ linenum = msg[1:msg.find(':',1)]
+ if linenum.isdigit():
+ linenum = int(linenum, 10)
+ csourcelines = csource.splitlines()
+ if 1 <= linenum <= len(csourcelines):
+ line = csourcelines[linenum-1]
+ if line:
+ msg = 'cannot parse "%s"\n%s' % (line, msg)
+ else:
+ msg = 'parse error\n%s' % (msg,)
+ raise api.CDefError(msg)
+
def parse(self, csource, override=False):
prev_override = self._override
try:
diff --git a/testing/test_parsing.py b/testing/test_parsing.py
--- a/testing/test_parsing.py
+++ b/testing/test_parsing.py
@@ -1,4 +1,4 @@
-import py, sys
+import py, sys, re
from cffi import FFI, FFIError, CDefError, VerificationError
class FakeBackend(object):
@@ -184,3 +184,8 @@
e = py.test.raises(CDefError, ffi.cdef, "int foo(...);")
assert str(e.value) == \
"foo: a function with only '(...)' as argument is not correct C"
+
+def test_parse_error():
+ ffi = FFI()
+ e = py.test.raises(CDefError, ffi.cdef, " x y z ")
+ assert re.match(r'cannot parse " x y z "\n:\d+:', str(e.value))
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit