1import pprint
2import re
3import sys
4import unittest
5import weakref
6
7sys.path.insert(0, '..')
8import pycparser.c_ast as c_ast
9import pycparser.plyparser as plyparser
10
11
12class Test_c_ast(unittest.TestCase):
13    def test_BinaryOp(self):
14        b1 = c_ast.BinaryOp(
15            op='+',
16            left=c_ast.Constant(type='int', value='6'),
17            right=c_ast.ID(name='joe'))
18
19        self.assertIsInstance(b1.left, c_ast.Constant)
20        self.assertEqual(b1.left.type, 'int')
21        self.assertEqual(b1.left.value, '6')
22
23        self.assertIsInstance(b1.right, c_ast.ID)
24        self.assertEqual(b1.right.name, 'joe')
25
26    def test_weakref_works_on_nodes(self):
27        c1 = c_ast.Constant(type='float', value='3.14')
28        wr = weakref.ref(c1)
29        cref = wr()
30        self.assertEqual(cref.type, 'float')
31        self.assertEqual(weakref.getweakrefcount(c1), 1)
32
33    def test_weakref_works_on_coord(self):
34        coord = plyparser.Coord(file='a', line=2)
35        wr = weakref.ref(coord)
36        cref = wr()
37        self.assertEqual(cref.line, 2)
38        self.assertEqual(weakref.getweakrefcount(coord), 1)
39
40
41class TestNodeVisitor(unittest.TestCase):
42    class ConstantVisitor(c_ast.NodeVisitor):
43        def __init__(self):
44            self.values = []
45
46        def visit_Constant(self, node):
47            self.values.append(node.value)
48
49    def test_scalar_children(self):
50        b1 = c_ast.BinaryOp(
51            op='+',
52            left=c_ast.Constant(type='int', value='6'),
53            right=c_ast.ID(name='joe'))
54
55        cv = self.ConstantVisitor()
56        cv.visit(b1)
57
58        self.assertEqual(cv.values, ['6'])
59
60        b2 = c_ast.BinaryOp(
61            op='*',
62            left=c_ast.Constant(type='int', value='111'),
63            right=b1)
64
65        b3 = c_ast.BinaryOp(
66            op='^',
67            left=b2,
68            right=b1)
69
70        cv = self.ConstantVisitor()
71        cv.visit(b3)
72
73        self.assertEqual(cv.values, ['111', '6', '6'])
74
75    def tests_list_children(self):
76        c1 = c_ast.Constant(type='float', value='5.6')
77        c2 = c_ast.Constant(type='char', value='t')
78
79        b1 = c_ast.BinaryOp(
80            op='+',
81            left=c1,
82            right=c2)
83
84        b2 = c_ast.BinaryOp(
85            op='-',
86            left=b1,
87            right=c2)
88
89        comp = c_ast.Compound(
90            block_items=[b1, b2, c1, c2])
91
92        cv = self.ConstantVisitor()
93        cv.visit(comp)
94
95        self.assertEqual(cv.values,
96                         ['5.6', 't', '5.6', 't', 't', '5.6', 't'])
97
98    def test_repr(self):
99        c1 = c_ast.Constant(type='float', value='5.6')
100        c2 = c_ast.Constant(type='char', value='t')
101
102        b1 = c_ast.BinaryOp(
103            op='+',
104            left=c1,
105            right=c2)
106
107        b2 = c_ast.BinaryOp(
108            op='-',
109            left=b1,
110            right=c2)
111
112        comp = c_ast.Compound(
113            block_items=[b1, b2, c1, c2])
114
115        expected = ("Compound(block_items=[BinaryOp(op='+',\n"
116                    "                               left=Constant(type='float',\n"
117                    "                                             value='5.6'\n"
118                    "                                             ),\n"
119                    "                               right=Constant(type='char',\n"
120                    "                                              value='t'\n"
121                    "                                              )\n"
122                    "                               ),\n"
123                    "                      BinaryOp(op='-',\n"
124                    "                               left=BinaryOp(op='+',\n"
125                    "                                             left=Constant(type='float',\n"
126                    "                                                           value='5.6'\n"
127                    "                                                           ),\n"
128                    "                                             right=Constant(type='char',\n"
129                    "                                                            value='t'\n"
130                    "                                                            )\n"
131                    "                                             ),\n"
132                    "                               right=Constant(type='char',\n"
133                    "                                              value='t'\n"
134                    "                                              )\n"
135                    "                               ),\n"
136                    "                      Constant(type='float',\n"
137                    "                               value='5.6'\n"
138                    "                               ),\n"
139                    "                      Constant(type='char',\n"
140                    "                               value='t'\n"
141                    "                               )\n"
142                    "                     ]\n"
143                    "         )")
144
145        self.assertEqual(repr(comp),
146                         expected)
147
148
149if __name__ == '__main__':
150    unittest.main()
151