Issue 49: Allow dots ('.') in string escapes for the sake of #line directives with Windows paths like "..\..\test"
+ added tests
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 @@
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 @@
dsf
# 9
armo
+ #line 10 "..\..\test.h"
+ tok1
+ #line 99999 "include/me.h"
+ tok2
"""
#~ self.clex.filename
@@ -243,6 +247,18 @@
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 @@
#~ 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)