diff options
author | Saullo Carvalho Castelo Branco <saullocarvalho@gmail.com> | 2019-06-27 09:44:20 -0300 |
---|---|---|
committer | Eli Bendersky <eliben@users.noreply.github.com> | 2019-06-27 05:44:20 -0700 |
commit | b8086eb3711a2486e2bf0b03acab6dbbb79e4f8a (patch) | |
tree | 6e5db93565b00993e6f8f4d30e415a3d8dee0212 | |
parent | dd6b6f1d4eb149b32934e02bd1e9a4af6575ce06 (diff) | |
download | pycparser-b8086eb3711a2486e2bf0b03acab6dbbb79e4f8a.tar.gz |
Fix issue #99: parser for FuncDecl incorrectly sets declname attribute on return type (#329)
-rw-r--r-- | pycparser/c_generator.py | 12 | ||||
-rw-r--r-- | tests/test_c_generator.py | 42 |
2 files changed, 46 insertions, 8 deletions
diff --git a/pycparser/c_generator.py b/pycparser/c_generator.py index 2cd83fa..973d24a 100644 --- a/pycparser/c_generator.py +++ b/pycparser/c_generator.py @@ -119,7 +119,7 @@ class CGenerator(object): return s def visit_Cast(self, n): - s = '(' + self._generate_type(n.to_type) + ')' + s = '(' + self._generate_type(n.to_type, emit_declname=False) + ')' return s + ' ' + self._parenthesize_unless_simple(n.expr) def visit_ExprList(self, n): @@ -293,10 +293,10 @@ class CGenerator(object): def visit_ArrayDecl(self, n): return self._generate_type(n, emit_declname=False) - + def visit_TypeDecl(self, n): return self._generate_type(n, emit_declname=False) - + def visit_PtrDecl(self, n): return self._generate_type(n, emit_declname=False) @@ -389,7 +389,7 @@ class CGenerator(object): # for i, modifier in enumerate(modifiers): if isinstance(modifier, c_ast.ArrayDecl): - if (i != 0 and + if (i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl)): nstr = '(' + nstr + ')' nstr += '[' @@ -397,13 +397,13 @@ class CGenerator(object): nstr += ' '.join(modifier.dim_quals) + ' ' nstr += self.visit(modifier.dim) + ']' elif isinstance(modifier, c_ast.FuncDecl): - if (i != 0 and + if (i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl)): nstr = '(' + nstr + ')' nstr += '(' + self.visit(modifier.args) + ')' elif isinstance(modifier, c_ast.PtrDecl): if modifier.quals: - nstr = '* %s%s' % (' '.join(modifier.quals), + nstr = '* %s%s' % (' '.join(modifier.quals), ' ' + nstr if nstr else '') else: nstr = '*' + nstr diff --git a/tests/test_c_generator.py b/tests/test_c_generator.py index b48094e..edff90b 100644 --- a/tests/test_c_generator.py +++ b/tests/test_c_generator.py @@ -1,11 +1,12 @@ +import os +import platform import sys -import textwrap import unittest # Run from the root dir sys.path.insert(0, '.') -from pycparser import c_parser, c_generator, c_ast +from pycparser import c_parser, c_generator, c_ast, parse_file _c_parser = c_parser.CParser( lex_optimize=False, @@ -353,5 +354,42 @@ class TestCtoC(unittest.TestCase): self.assertEqual(generator.visit(ast.ext[0].type.type.type), 'const int') + +class TestCasttoC(unittest.TestCase): + def _find_file(self, name): + test_dir = os.path.dirname(__file__) + name = os.path.join(test_dir, 'c_files', name) + assert os.path.exists(name) + return name + + + def test_to_type(self): + src = 'int *x;' + generator = c_generator.CGenerator() + test_fun = c_ast.FuncCall(c_ast.ID('test_fun'), c_ast.ExprList([])) + + ast1 = parse_to_ast(src) + int_ptr_type = ast1.ext[0].type + int_type = int_ptr_type.type + self.assertEqual(generator.visit(c_ast.Cast(int_ptr_type, test_fun)), + '(int *) test_fun()') + self.assertEqual(generator.visit(c_ast.Cast(int_type, test_fun)), + '(int) test_fun()') + + @unittest.skipUnless(platform.system() == 'Linux', + 'cpp only works on Linux') + def test_to_type_with_cpp(self): + generator = c_generator.CGenerator() + test_fun = c_ast.FuncCall(c_ast.ID('test_fun'), c_ast.ExprList([])) + memmgr_path = self._find_file('memmgr.h') + + ast2 = parse_file(memmgr_path, use_cpp=True) + void_ptr_type = ast2.ext[-3].type.type + void_type = void_ptr_type.type + self.assertEqual(generator.visit(c_ast.Cast(void_ptr_type, test_fun)), + '(void *) test_fun()') + self.assertEqual(generator.visit(c_ast.Cast(void_type, test_fun)), + '(void) test_fun()') + if __name__ == "__main__": unittest.main() |