summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreli.bendersky <devnull@localhost>2011-05-20 12:35:08 +0300
committereli.bendersky <devnull@localhost>2011-05-20 12:35:08 +0300
commit8e6c58672000a3675814071b2ccfa299bc70bbab (patch)
tree6b5191cd76a5979fe3f131ea400e8d59336ce339
parent7f3b7bd3167d903536fa12206048de3fc1a2cf4d (diff)
downloadpycparser-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
-rw-r--r--.hgignore3
-rw-r--r--TODO.txt1
-rw-r--r--examples/c-to-c.py41
-rw-r--r--examples/tests/test_c-to-c.py80
-rw-r--r--z_test.py10
5 files changed, 114 insertions, 21 deletions
diff --git a/.hgignore b/.hgignore
index a666b98..3fd332a 100644
--- a/.hgignore
+++ b/.hgignore
@@ -4,7 +4,8 @@ syntax: glob
tests/parser.out
tests/*tab.py
build
-
+yacctab.py
+lextab.py
glob:utils/z.c
diff --git a/TODO.txt b/TODO.txt
index eb7ae31..ff64e3f 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -2,6 +2,7 @@ Todo
----
- change license to BSD
+- c-to-c fixes (were there??)
Changes since last
------------------
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()
diff --git a/z_test.py b/z_test.py
index de5252b..44a3eb9 100644
--- a/z_test.py
+++ b/z_test.py
@@ -76,15 +76,9 @@ class NodeVisitor(object):
if __name__ == "__main__":
source_code = """
-typedef char FlagType;
-
int main()
{
-}
-
-int myproc( int FlagType)
-{
-
+ x = 5 + 10;
}
@@ -107,7 +101,7 @@ int myproc( int FlagType)
#--------------- Parsing
parser = CParser()
ast = parser.parse(source_code, filename='zz')
- ast.show(showcoord=True)
+ ast.show(showcoord=False)
nv=NodeVisitor()
nv.visit(ast)