From 49f3b63db7e63f38c702676bcd10046b363f1f7f Mon Sep 17 00:00:00 2001 From: "eli.bendersky" Date: Mon, 31 Oct 2011 06:38:41 +0200 Subject: Issue 49: Allow dots ('.') in string escapes for the sake of #line directives with Windows paths like "..\..\test" + added tests --- _clean_tables.py | 24 ++++++++++++++++++++++++ pycparser/c_lexer.py | 8 ++++---- tests/test_c_lexer.py | 16 ++++++++++++++++ z_test.py | 3 +++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 _clean_tables.py 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) -- cgit v1.2.1