summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreli.bendersky <devnull@localhost>2011-10-31 06:38:41 +0200
committereli.bendersky <devnull@localhost>2011-10-31 06:38:41 +0200
commit49f3b63db7e63f38c702676bcd10046b363f1f7f (patch)
treee19019c3238542bf722fb9d0c1d606f2eec55c50
parent171c99fd4dff5deef0ffa868122b66014529f426 (diff)
downloadpycparser-49f3b63db7e63f38c702676bcd10046b363f1f7f.tar.gz
Issue 49: Allow dots ('.') in string escapes for the sake of #line directives with Windows paths like "..\..\test"
+ added tests
-rw-r--r--_clean_tables.py24
-rw-r--r--pycparser/c_lexer.py8
-rw-r--r--tests/test_c_lexer.py16
-rw-r--r--z_test.py3
4 files changed, 47 insertions, 4 deletions
diff --git a/_clean_tables.py b/_clean_tables.py
new file mode 100644
index 0000000..48417b0
--- /dev/null
+++ b/_clean_tables.py
@@ -0,0 +1,24 @@
+# Cleanup all table and PYC files to ensure no PLY stuff is cached
+#
+import fnmatch
+import os, shutil
+
+file_patterns = ('yacctab.*', 'lextab.*', '*.pyc')
+
+def do_cleanup(root):
+ for path, dirs, files in os.walk(root):
+ for file in files:
+ try:
+ for pattern in file_patterns:
+ if fnmatch.fnmatch(file, pattern):
+ fullpath = os.path.join(path, file)
+ os.remove(fullpath)
+ print 'Deleted', fullpath
+ except OSError:
+ pass
+
+if __name__ == "__main__":
+ do_cleanup('.')
+
+
+ \ No newline at end of file
diff --git a/pycparser/c_lexer.py b/pycparser/c_lexer.py
index 0fda764..235f8f0 100644
--- a/pycparser/c_lexer.py
+++ b/pycparser/c_lexer.py
@@ -179,13 +179,13 @@ class CLexer(object):
bad_octal_constant = '0[0-7]*[89]'
# character constants (K&R2: A.2.5.2)
- # Note: a-zA-Z are allowed as escape chars to support #line
- # directives with Windows paths as filenames (\dir\file...)
+ # Note: a-zA-Z and '.' are allowed as escape chars to support #line
+ # directives with Windows paths as filenames (..\..\dir\file)
#
- simple_escape = r"""([a-zA-Z\\?'"])"""
+ simple_escape = r"""([a-zA-Z.\\?'"])"""
octal_escape = r"""([0-7]{1,3})"""
hex_escape = r"""(x[0-9a-fA-F]+)"""
- bad_escape = r"""([\\][^a-zA-Z\\?'"x0-7])"""
+ bad_escape = r"""([\\][^a-zA-Z.\\?'"x0-7])"""
escape_sequence = r"""(\\("""+simple_escape+'|'+octal_escape+'|'+hex_escape+'))'
cconst_char = r"""([^'\\\n]|"""+escape_sequence+')'
diff --git a/tests/test_c_lexer.py b/tests/test_c_lexer.py
index 5f3f83e..3851569 100644
--- a/tests/test_c_lexer.py
+++ b/tests/test_c_lexer.py
@@ -219,6 +219,10 @@ class TestCLexerNoErrors(unittest.TestCase):
dsf
# 9
armo
+ #line 10 "..\..\test.h"
+ tok1
+ #line 99999 "include/me.h"
+ tok2
"""
#~ self.clex.filename
@@ -243,6 +247,18 @@ class TestCLexerNoErrors(unittest.TestCase):
self.assertEqual(t.lineno, 9)
self.assertEqual(self.clex.filename, r'kwas\df.h')
+ t4 = self.clex.token()
+ self.assertEqual(t4.type, 'ID')
+ self.assertEqual(t4.value, 'tok1')
+ self.assertEqual(t4.lineno, 10)
+ self.assertEqual(self.clex.filename, r'..\..\test.h')
+
+ t5 = self.clex.token()
+ self.assertEqual(t5.type, 'ID')
+ self.assertEqual(t5.value, 'tok2')
+ self.assertEqual(t5.lineno, 99999)
+ self.assertEqual(self.clex.filename, r'include/me.h')
+
# Keeps all the errors the lexer spits in one place, to allow
diff --git a/z_test.py b/z_test.py
index 6f22260..7cad4ac 100644
--- a/z_test.py
+++ b/z_test.py
@@ -95,6 +95,9 @@ if __name__ == "__main__":
#~ printme([tok.value, tok.type, tok.lineno, clex.filename, tok.lexpos])
#--------------- Parsing
+ source_code = r'''#line 1 "..\..\test.h"
+ int a;
+ '''
parser = CParser(lex_optimize=False, yacc_optimize=False, yacc_debug=True)
ast = parser.parse(source_code, filename='zz')
ast.show(showcoord=False)