diff options
author | Eli Bendersky <eliben@gmail.com> | 2012-01-19 06:20:24 +0200 |
---|---|---|
committer | Eli Bendersky <eliben@gmail.com> | 2012-01-19 06:20:24 +0200 |
commit | dfd0df314362fa7fc2b6a76363c40852112f718b (patch) | |
tree | 2736498a6a761d19d92bdd2e99ef32ab70cbaff4 | |
parent | 68497c24db5bb73aa5d75db43f5f837d7ca7c4b0 (diff) | |
download | pycparser-dfd0df314362fa7fc2b6a76363c40852112f718b.tar.gz |
fix problem in c-to-c generation of casts. Patch by Andreas Kloeckner
-rw-r--r-- | examples/c-to-c.py | 2 | ||||
-rw-r--r-- | examples/tests/test_c-to-c.py | 216 | ||||
-rw-r--r-- | pycparser/_ast_gen.py | 3 |
3 files changed, 118 insertions, 103 deletions
diff --git a/examples/c-to-c.py b/examples/c-to-c.py index 99d734e..e1277ab 100644 --- a/examples/c-to-c.py +++ b/examples/c-to-c.py @@ -123,7 +123,7 @@ class CGenerator(object): def visit_Cast(self, n): s = '(' + self._generate_type(n.to_type) + ')' - return s + ' ' + self.visit(n.expr) + return s + ' ' + self._parenthesize_unless_simple(n.expr) def visit_ExprList(self, n): visited_subexprs = [] diff --git a/examples/tests/test_c-to-c.py b/examples/tests/test_c-to-c.py index 8015891..2c3ddcc 100644 --- a/examples/tests/test_c-to-c.py +++ b/examples/tests/test_c-to-c.py @@ -1,113 +1,127 @@ -#!/usr/bin/env python
-
-import sys
-import unittest
-
-sys.path.insert(0, '..') # for c-to-c.py
-sys.path.insert(0, '../..') # for pycparser libs
-
-from pycparser import c_parser
-c2cmodule = __import__('c-to-c')
-
-_c_parser = c_parser.CParser(
- lex_optimize=False,
- yacc_debug=True,
- yacc_optimize=False,
- yacctab='yacctab')
-
-
+#!/usr/bin/env python + +import sys +import unittest + +sys.path.insert(0, '..') # for c-to-c.py +sys.path.insert(0, '../..') # for pycparser libs +sys.path.insert(0, 'examples') # for running from root dir + +from pycparser import c_parser +c2cmodule = __import__('c-to-c') + +_c_parser = c_parser.CParser( + lex_optimize=False, + yacc_debug=True, + yacc_optimize=False, + yacctab='yacctab') + + def compare_asts(ast1, ast2): - if type(ast1) != type(ast2):
- return False
- for attr in ast1.attr_names:
- if getattr(ast1, attr) != getattr(ast2, attr):
- return False
- for i, c1 in enumerate(ast1.children()):
- if compare_asts(c1, ast2.children()[i]) == False:
- return False
- return True
-
-
+ if type(ast1) != type(ast2): + return False + if isinstance(ast1, tuple) and isinstance(ast2, tuple): + if ast1[0] != ast2[0]: + return False + ast1 = ast1[1] + ast2 = ast2[1] + for attr in ast1.attr_names: + if getattr(ast1, attr) != getattr(ast2, attr): + return False + for i, c1 in enumerate(ast1.children()): + if compare_asts(c1, ast2.children()[i]) == False: + return False + return True + + def parse_to_ast(src): - return _c_parser.parse(src)
-
-
-class TestCtoC(unittest.TestCase):
+ return _c_parser.parse(src) + + +class TestCtoC(unittest.TestCase): def _run_c_to_c(self, src): - ast = parse_to_ast(src)
- generator = c2cmodule.CGenerator()
- return generator.visit(ast)
-
+ ast = parse_to_ast(src) + generator = c2cmodule.CGenerator() + return generator.visit(ast) + def _assert_ctoc_correct(self, src): - """ Checks that the c2c translation was correct by parsing the code
- generated by c2c for src and comparing the AST with the original
+ """ Checks that the c2c translation was correct by parsing the code + generated by c2c for src and comparing the AST with the original AST. - """
- src2 = self._run_c_to_c(src)
- self.assertTrue(compare_asts(parse_to_ast(src), parse_to_ast(src2)), src2)
-
+ """ + src2 = self._run_c_to_c(src) + self.assertTrue(compare_asts(parse_to_ast(src), parse_to_ast(src2)), src2) + def test_trivial_decls(self): - self._assert_ctoc_correct('int a;')
- self._assert_ctoc_correct('int b, a;')
- self._assert_ctoc_correct('int c, b, a;')
-
+ self._assert_ctoc_correct('int a;') + self._assert_ctoc_correct('int b, a;') + self._assert_ctoc_correct('int c, b, a;') + def test_complex_decls(self): - self._assert_ctoc_correct('int** (*a)(void);')
- self._assert_ctoc_correct('int** (*a)(void*, int);')
-
+ self._assert_ctoc_correct('int** (*a)(void);') + self._assert_ctoc_correct('int** (*a)(void*, int);') + def test_casts(self): - self._assert_ctoc_correct(r'''
- int main() {
- int b = (int) f;
- int c = (int*) f;
- }''')
-
- def test_initlist(self):
- self._assert_ctoc_correct('int arr[] = {1, 2, 3};')
-
+ self._assert_ctoc_correct(r''' + int main() { + int b = (int) f; + int c = (int*) f; + }''') + + def test_initlist(self): + self._assert_ctoc_correct('int arr[] = {1, 2, 3};') + def test_exprs(self): - self._assert_ctoc_correct('''
- int main(void)
- {
- int a;
- int b = a++;
- int c = ++a;
- int d = a--;
- int e = --a;
- }''')
-
+ self._assert_ctoc_correct(''' + int main(void) + { + int a; + int b = a++; + int c = ++a; + int d = a--; + int e = --a; + }''') + def test_statements(self): - self._assert_ctoc_correct(r'''
- int main() {
- int a;
- a = 5;
- ;
- return a;
- }''')
-
+ self._assert_ctoc_correct(r''' + int main() { + int a; + a = 5; + ; + return a; + }''') + + def test_casts(self): + self._assert_ctoc_correct(r''' + int main() { + int a = (int) b + 8; + int t = (int) c; + } + ''') + def test_struct_decl(self): - self._assert_ctoc_correct(r'''
- typedef struct node_t {
- struct node_t* next;
- int data;
- } node;
- ''')
-
+ self._assert_ctoc_correct(r''' + typedef struct node_t { + struct node_t* next; + int data; + } node; + ''') + def test_issue36(self): - self._assert_ctoc_correct(r'''
- int main() {
- }''')
-
- def test_issue37(self):
- self._assert_ctoc_correct(r'''
- int main(void)
- {
- unsigned size;
- size = sizeof(size);
- return 0;
- }''')
-
-
-
-if __name__ == "__main__":
- unittest.main()
+ self._assert_ctoc_correct(r''' + int main() { + }''') + + def test_issue37(self): + self._assert_ctoc_correct(r''' + int main(void) + { + unsigned size; + size = sizeof(size); + return 0; + }''') + + + +if __name__ == "__main__": + unittest.main() diff --git a/pycparser/_ast_gen.py b/pycparser/_ast_gen.py index b3f3135..9560a25 100644 --- a/pycparser/_ast_gen.py +++ b/pycparser/_ast_gen.py @@ -20,7 +20,8 @@ class ASTCodeGenerator(object): file. """ self.cfg_filename = cfg_filename - self.node_cfg = [NodeCfg(name, contents) for (name, contents) in self.parse_cfgfile(cfg_filename)] + self.node_cfg = [NodeCfg(name, contents) + for (name, contents) in self.parse_cfgfile(cfg_filename)] def generate(self, file=None): """ Generates the code into file, an open file buffer. |