diff options
author | eli.bendersky <devnull@localhost> | 2011-05-20 12:35:08 +0300 |
---|---|---|
committer | eli.bendersky <devnull@localhost> | 2011-05-20 12:35:08 +0300 |
commit | 8e6c58672000a3675814071b2ccfa299bc70bbab (patch) | |
tree | 6b5191cd76a5979fe3f131ea400e8d59336ce339 /examples | |
parent | 7f3b7bd3167d903536fa12206048de3fc1a2cf4d (diff) | |
download | pycparser-8e6c58672000a3675814071b2ccfa299bc70bbab.tar.gz |
* A couple of bug fixes in c-to-c.py (Issue 35, and comlex types in function argument declarations)
* added unit tests for c-to-c.py
Diffstat (limited to 'examples')
-rw-r--r-- | examples/c-to-c.py | 41 | ||||
-rw-r--r-- | examples/tests/test_c-to-c.py | 80 |
2 files changed, 109 insertions, 12 deletions
diff --git a/examples/c-to-c.py b/examples/c-to-c.py index fed92aa..5cbcb98 100644 --- a/examples/c-to-c.py +++ b/examples/c-to-c.py @@ -120,7 +120,13 @@ class CGenerator(object): return s + ' ' + self.visit(n.expr) def visit_ExprList(self, n): - return ', '.join(self.visit(expr) for expr in n.exprs) + visited_subexprs = [] + for expr in n.exprs: + if isinstance(expr, c_ast.ExprList): + visited_subexprs.append('{' + self.visit(expr) + '}') + else: + visited_subexprs.append(self.visit(expr)) + return ', '.join(visited_subexprs) def visit_Enum(self, n): s = 'enum' @@ -251,6 +257,9 @@ class CGenerator(object): def visit_Struct(self, n): return self._generate_struct_union(n, 'struct') + def visit_Typename(self, n): + return self._generate_type(n.type) + def visit_Union(self, n): return self._generate_struct_union(n, 'union') @@ -390,17 +399,25 @@ def translate_to_c(filename): def zz_test_translate(): # internal use - src = r''' - int main(int** k, float ar[5][2]) { - int a, *b; - b = (int *) a; - } - ''' - parser = c_parser.CParser() - ast = parser.parse(src) - ast.show() - generator = CGenerator() - print(generator.visit(ast)) + src = r''' + typedef struct +{ + int a; +} s; +s arr[] = {{1}, {2}}; + ''' + parser = c_parser.CParser() + ast = parser.parse(src) + ast.show() + generator = CGenerator() + + print(generator.visit(ast)) + + # tracing the generator for debugging + #~ import trace + #~ tr = trace.Trace(countcallers=1) + #~ tr.runfunc(generator.visit, ast) + #~ tr.results().write_results() #------------------------------------------------------------------------------ diff --git a/examples/tests/test_c-to-c.py b/examples/tests/test_c-to-c.py new file mode 100644 index 0000000..4cd13ba --- /dev/null +++ b/examples/tests/test_c-to-c.py @@ -0,0 +1,80 @@ +#!/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')
+
+
+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
+
+
+def parse_to_ast(src): + 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)
+
+ 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
+ AST. + """
+ 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;')
+
+ def test_complex_decls(self): + 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};')
+
+ def test_statements(self): + self._assert_ctoc_correct(r'''
+ int main() {
+ int a;
+ a = 5;
+ return a;
+ }''')
+ +
+
+
+if __name__ == "__main__":
+ unittest.main()
|