summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/c-to-c.py41
-rw-r--r--examples/tests/test_c-to-c.py80
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()