Commits

eli.bendersky  committed eb08e82

fixing issue 23: coords of casts

  • Participants
  • Parent commits 6d2b768

Comments (0)

Files changed (3)

File examples/c-to-c.py

         if n.expr: s += ' ' + self.visit(n.expr)
         return s + ';'
 
+    def visit_Break(self, n):
+        return 'break;'
+        
+    def visit_Continue(self, n):
+        return 'continue;'
+        
     def visit_For(self, n):
         s = 'for ('
         if n.init: s += self.visit(n.init)
         s += self._generate_stmt(n.stmt, add_indent=True)
         return s
 
+    def visit_While(self, n):
+        s = 'while ('
+        if n.cond: s += self.visit(n.cond)
+        s += ')\n'
+        s += self._generate_stmt(n.stmt, add_indent=True)
+        return s
+
     def _generate_stmt(self, n, add_indent=False):
         """ Generation from a statement node. This method exists as a wrapper
             for individual visit_* methods to handle different treatment of 
         """
         typ = type(n)
         if add_indent: self.indent_level += 2
-        s = self._make_indent()
+        indent = self._make_indent()
         if add_indent: self.indent_level -= 2
         
         if typ in ( c_ast.Decl, c_ast.Assignment, c_ast.Cast, c_ast.UnaryOp,
             # These can also appear in an expression context so no semicolon
             # is added to them automatically
             #
-            return s + self.visit(n) + ';\n'
+            return indent + self.visit(n) + ';\n'
         elif typ in (c_ast.Compound,):
             # No extra indentation required before the opening brace of a 
             # compound - because it consists of multiple lines it has to 
             #
             return self.visit(n)
         else:
-            return s + self.visit(n) + '\n'
+            return indent + self.visit(n) + '\n'
 
     def _generate_decl(self, n):
         """ Generation from a Decl node.
     a++;
     ++a;
 
-    for (hash_value = 0; *str != 0; ++str)
-        {hash_value = (a*hash_value + *str) % table_size;}
+    while (hash_value == 0) {
+        hash_value = (a*hash_value + *str) % table_size;
+        break;
+    }
 
     return hash_value;
 }
 # assignments... - where to parenthesize? maybe just in BinaryOp?
 # Other precedence-important operators (such as cast) need parens as well
 
+# ZZZ: turn self.indent_level += 2 ... -= 2 into a context manager!
+

File pycparser/c_parser.py

         spec = p[1]
         decl = c_ast.Typename(
             quals=spec['qual'], 
-            type=p[2] or c_ast.TypeDecl(None, None, None))
+            type=p[2] or c_ast.TypeDecl(None, None, None),
+            coord=self._coord(p.lineno(2)))
             
         typename = spec['type'] or ['int']
         p[0] = self._fix_decl_name_type(decl, typename)        
         
         typename = c_ast.Typename(
             quals=p[1]['qual'], 
-            type=p[2] or c_ast.TypeDecl(None, None, None))
+            type=p[2] or c_ast.TypeDecl(None, None, None),
+            coord=self._coord(p.lineno(2)))
         
         p[0] = self._fix_decl_name_type(typename, p[1]['type'])
 
         
     def p_cast_expression_2(self, p):
         """ cast_expression : LPAREN type_name RPAREN cast_expression """
-        p[0] = c_ast.Cast(p[2], p[4], p[2].coord)
+        p[0] = c_ast.Cast(p[2], p[4], self._coord(p.lineno(1)))
     
     def p_unary_expression_1(self, p):
         """ unary_expression    : postfix_expression """

File tests/test_c_parser.py

         f1_1 = self.parse(t1_1, filename='test.c')
         self.assert_coord(f1_1.ext[0].body.block_items[0], 3, 'test.c')
         self.assert_coord(f1_1.ext[0].body.block_items[1], 4, 'test.c')
+       
+        t1_2 = '''
+        int main () {
+            int p = (int) k;
+        }'''
+        f1_2 = self.parse(t1_2, filename='test.c')
+        # make sure that the Cast has a coord (issue 23)
+        self.assert_coord(f1_2.ext[0].body.block_items[0].init, 3, 'test.c')
         
         t2 = """
         #line 99