aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaullo Carvalho Castelo Branco <saullocarvalho@gmail.com>2019-06-27 09:44:20 -0300
committerEli Bendersky <eliben@users.noreply.github.com>2019-06-27 05:44:20 -0700
commitb8086eb3711a2486e2bf0b03acab6dbbb79e4f8a (patch)
tree6e5db93565b00993e6f8f4d30e415a3d8dee0212
parentdd6b6f1d4eb149b32934e02bd1e9a4af6575ce06 (diff)
downloadpycparser-b8086eb3711a2486e2bf0b03acab6dbbb79e4f8a.tar.gz
Fix issue #99: parser for FuncDecl incorrectly sets declname attribute on return type (#329)
-rw-r--r--pycparser/c_generator.py12
-rw-r--r--tests/test_c_generator.py42
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()