blob: 35558ccd4173b918c5f18408ec7a85886e7b9235 [file] [log] [blame]
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001#!/usr/bin/env python
2
3import pprint
4import re
Eli Benderskyd0973782012-01-19 08:09:33 +02005import os, sys
Jon Dufresne13224c12018-06-26 13:48:31 -07006import io
Eli Bendersky3921e8e2010-05-21 09:05:39 +03007import unittest
8
Eli Bendersky3877c4c2013-07-13 06:54:04 -07009sys.path[0:0] = ['.', '..']
Eli Bendersky3921e8e2010-05-21 09:05:39 +030010
11from pycparser import c_parser
12from pycparser.c_ast import *
13from pycparser.c_parser import CParser, Coord, ParseError
14
Eli Bendersky3921e8e2010-05-21 09:05:39 +030015_c_parser = c_parser.CParser(
16 lex_optimize=False,
Eli Bendersky86f2eee2013-01-18 06:04:01 -080017 yacc_debug=True,
Eli Bendersky3921e8e2010-05-21 09:05:39 +030018 yacc_optimize=False,
19 yacctab='yacctab')
20
21
22def expand_decl(decl):
23 """ Converts the declaration into a nested list.
24 """
25 typ = type(decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080026
Eli Bendersky3921e8e2010-05-21 09:05:39 +030027 if typ == TypeDecl:
28 return ['TypeDecl', expand_decl(decl.type)]
29 elif typ == IdentifierType:
30 return ['IdentifierType', decl.names]
31 elif typ == ID:
32 return ['ID', decl.name]
33 elif typ in [Struct, Union]:
34 decls = [expand_decl(d) for d in decl.decls or []]
35 return [typ.__name__, decl.name, decls]
Eli Bendersky86f2eee2013-01-18 06:04:01 -080036 else:
Eli Bendersky3921e8e2010-05-21 09:05:39 +030037 nested = expand_decl(decl.type)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080038
Eli Bendersky3921e8e2010-05-21 09:05:39 +030039 if typ == Decl:
40 if decl.quals:
41 return ['Decl', decl.quals, decl.name, nested]
42 else:
43 return ['Decl', decl.name, nested]
44 elif typ == Typename: # for function parameters
45 if decl.quals:
46 return ['Typename', decl.quals, nested]
47 else:
48 return ['Typename', nested]
49 elif typ == ArrayDecl:
50 dimval = decl.dim.value if decl.dim else ''
Eli Bendersky8aad3182014-01-25 06:30:53 -080051 return ['ArrayDecl', dimval, decl.dim_quals, nested]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030052 elif typ == PtrDecl:
Eli Benderskyb17da152015-04-21 14:35:18 -070053 if decl.quals:
54 return ['PtrDecl', decl.quals, nested]
55 else:
56 return ['PtrDecl', nested]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030057 elif typ == Typedef:
58 return ['Typedef', decl.name, nested]
59 elif typ == FuncDecl:
60 if decl.args:
61 params = [expand_decl(param) for param in decl.args.params]
62 else:
63 params = []
64 return ['FuncDecl', params, nested]
Eli Bendersky86f2eee2013-01-18 06:04:01 -080065
Eli Bendersky3921e8e2010-05-21 09:05:39 +030066
67def expand_init(init):
68 """ Converts an initialization into a nested list
69 """
70 typ = type(init)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080071
eli.benderskyf890a862010-10-30 12:13:23 +020072 if typ == NamedInitializer:
73 des = [expand_init(dp) for dp in init.name]
74 return (des, expand_init(init.expr))
Eli Bendersky293ea912012-12-25 14:52:48 -080075 elif typ in (InitList, ExprList):
eli.benderskyf890a862010-10-30 12:13:23 +020076 return [expand_init(expr) for expr in init.exprs]
77 elif typ == Constant:
Eli Bendersky3921e8e2010-05-21 09:05:39 +030078 return ['Constant', init.type, init.value]
79 elif typ == ID:
80 return ['ID', init.name]
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -050081 elif typ == UnaryOp:
82 return ['UnaryOp', init.op, expand_decl(init.expr)]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030083
84
eli.bendersky85d2e732011-05-20 19:47:26 +030085class TestCParser_base(unittest.TestCase):
Eli Bendersky3921e8e2010-05-21 09:05:39 +030086 def parse(self, txt, filename=''):
87 return self.cparser.parse(txt, filename)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080088
Eli Bendersky3921e8e2010-05-21 09:05:39 +030089 def setUp(self):
90 self.cparser = _c_parser
Eli Bendersky86f2eee2013-01-18 06:04:01 -080091
serpilliere471442f2017-03-10 15:02:00 +010092 def assert_coord(self, node, line, column=None, file=None):
Eli Benderskyb77d6c02016-10-11 20:33:53 -070093 self.assertEqual(node.coord.line, line)
serpilliere471442f2017-03-10 15:02:00 +010094 if column is not None:
95 self.assertEqual(node.coord.column, column)
Eli Benderskyb77d6c02016-10-11 20:33:53 -070096 if file:
97 self.assertEqual(node.coord.file, file)
98
eli.bendersky85d2e732011-05-20 19:47:26 +030099
serpilliere471442f2017-03-10 15:02:00 +0100100
eli.bendersky85d2e732011-05-20 19:47:26 +0300101class TestCParser_fundamentals(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300102 def get_decl(self, txt, index=0):
103 """ Given a source and an index returns the expanded
104 declaration at that index.
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800105
106 FileAST holds a list of 'external declarations'.
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300107 index is the offset of the desired declaration in that
108 list.
109 """
110 t = self.parse(txt).ext[index]
111 return expand_decl(t)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800112
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300113 def get_decl_init(self, txt, index=0):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800114 """ Returns the expanded initializer of the declaration
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300115 at index.
116 """
117 t = self.parse(txt).ext[index]
118 return expand_init(t.init)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800119
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300120 def test_FileAST(self):
121 t = self.parse('int a; char c;')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700122 self.assertIsInstance(t, FileAST)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300123 self.assertEqual(len(t.ext), 2)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800124
eli.bendersky43cf0b22011-10-19 05:56:15 +0200125 # empty file
126 t2 = self.parse('')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700127 self.assertIsInstance(t2, FileAST)
eli.bendersky43cf0b22011-10-19 05:56:15 +0200128 self.assertEqual(len(t2.ext), 0)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300129
eli.bendersky38165b72011-02-04 08:13:39 +0200130 def test_empty_toplevel_decl(self):
131 code = 'int foo;;'
132 t = self.parse(code)
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700133 self.assertIsInstance(t, FileAST)
eli.bendersky38165b72011-02-04 08:13:39 +0200134 self.assertEqual(len(t.ext), 1)
135 self.assertEqual(self.get_decl(code),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800136 ['Decl', 'foo',
eli.bendersky38165b72011-02-04 08:13:39 +0200137 ['TypeDecl', ['IdentifierType', ['int']]]])
138
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300139 def test_coords(self):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800140 """ Tests the "coordinates" of parsed elements - file
serpilliere471442f2017-03-10 15:02:00 +0100141 name, line and column numbers, with modification
142 insterted by #line directives.
eli.bendersky38165b72011-02-04 08:13:39 +0200143 """
serpilliere471442f2017-03-10 15:02:00 +0100144 self.assert_coord(self.parse('int a;').ext[0], 1, 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800145
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300146 t1 = """
147 int a;
148 int b;\n\n
149 int c;
150 """
151 f1 = self.parse(t1, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100152 self.assert_coord(f1.ext[0], 2, 13, 'test.c')
153 self.assert_coord(f1.ext[1], 3, 13, 'test.c')
154 self.assert_coord(f1.ext[2], 6, 13, 'test.c')
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300155
156 t1_1 = '''
157 int main() {
158 k = p;
159 printf("%d", b);
160 return 0;
161 }'''
162 f1_1 = self.parse(t1_1, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100163 self.assert_coord(f1_1.ext[0].body.block_items[0], 3, 13, 'test.c')
164 self.assert_coord(f1_1.ext[0].body.block_items[1], 4, 13, 'test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800165
eli.benderskyfc96e5e2011-03-04 09:51:23 +0200166 t1_2 = '''
167 int main () {
168 int p = (int) k;
169 }'''
170 f1_2 = self.parse(t1_2, filename='test.c')
171 # make sure that the Cast has a coord (issue 23)
serpilliere471442f2017-03-10 15:02:00 +0100172 self.assert_coord(f1_2.ext[0].body.block_items[0].init, 3, 21, file='test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800173
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300174 t2 = """
175 #line 99
176 int c;
177 """
serpilliere471442f2017-03-10 15:02:00 +0100178 self.assert_coord(self.parse(t2).ext[0], 99, 13)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800179
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300180 t3 = """
181 int dsf;
182 char p;
183 #line 3000 "in.h"
184 char d;
185 """
186 f3 = self.parse(t3, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100187 self.assert_coord(f3.ext[0], 2, 13, 'test.c')
188 self.assert_coord(f3.ext[1], 3, 14, 'test.c')
189 self.assert_coord(f3.ext[2], 3000, 14, 'in.h')
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300190
191 t4 = """
192 #line 20 "restore.h"
193 int maydler(char);
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800194
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300195 #line 30 "includes/daween.ph"
196 long j, k;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800197
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300198 #line 50000
199 char* ro;
200 """
201 f4 = self.parse(t4, filename='myb.c')
serpilliere471442f2017-03-10 15:02:00 +0100202 self.assert_coord(f4.ext[0], 20, 13, 'restore.h')
203 self.assert_coord(f4.ext[1], 30, 14, 'includes/daween.ph')
204 self.assert_coord(f4.ext[2], 30, 17, 'includes/daween.ph')
205 self.assert_coord(f4.ext[3], 50000, 13, 'includes/daween.ph')
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300206
207 t5 = """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800208 int
209 #line 99
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300210 c;
211 """
serpilliere471442f2017-03-10 15:02:00 +0100212 self.assert_coord(self.parse(t5).ext[0], 99, 9)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300213
Eli Bendersky203b9672012-06-15 10:11:24 +0300214 # coord for ellipsis
215 t6 = """
216 int foo(int j,
217 ...) {
218 }"""
219 f6 = self.parse(t6, filename='z.c')
serpilliere471442f2017-03-10 15:02:00 +0100220 self.assert_coord(self.parse(t6).ext[0].decl.type.args.params[1], 3, 17)
Eli Bendersky203b9672012-06-15 10:11:24 +0300221
Eli Bendersky8e5d3a92014-03-15 14:06:00 -0700222 def test_forloop_coord(self):
223 t = '''\
224 void foo() {
225 for(int z=0; z<4;
226 z++){}
227 }
228 '''
229 s = self.parse(t, filename='f.c')
230 forloop = s.ext[0].body.block_items[0]
serpilliere471442f2017-03-10 15:02:00 +0100231 self.assert_coord(forloop.init, 2, 13, 'f.c')
232 self.assert_coord(forloop.cond, 2, 26, 'f.c')
233 self.assert_coord(forloop.next, 3, 17, 'f.c')
Eli Bendersky8e5d3a92014-03-15 14:06:00 -0700234
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300235 def test_simple_decls(self):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800236 self.assertEqual(self.get_decl('int a;'),
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300237 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
238
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800239 self.assertEqual(self.get_decl('unsigned int a;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200240 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]])
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300241
eli.benderskyaffe0322011-09-24 06:16:55 +0300242 self.assertEqual(self.get_decl('_Bool a;'),
243 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['_Bool']]]])
244
Eli Benderskyf4d73462012-01-19 05:56:27 +0200245 self.assertEqual(self.get_decl('float _Complex fcc;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200246 ['Decl', 'fcc', ['TypeDecl', ['IdentifierType', ['float', '_Complex']]]])
Eli Benderskyf4d73462012-01-19 05:56:27 +0200247
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800248 self.assertEqual(self.get_decl('char* string;'),
249 ['Decl', 'string',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300250 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]])
251
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800252 self.assertEqual(self.get_decl('long ar[15];'),
253 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800254 ['ArrayDecl', '15', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300255 ['TypeDecl', ['IdentifierType', ['long']]]]])
eli.bendersky98f45372010-10-30 09:46:29 +0200256
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800257 self.assertEqual(self.get_decl('long long ar[15];'),
258 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800259 ['ArrayDecl', '15', [],
eli.benderskyf890a862010-10-30 12:13:23 +0200260 ['TypeDecl', ['IdentifierType', ['long', 'long']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800261
262 self.assertEqual(self.get_decl('unsigned ar[];'),
263 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800264 ['ArrayDecl', '', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300265 ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800266
267 self.assertEqual(self.get_decl('int strlen(char* s);'),
268 ['Decl', 'strlen',
269 ['FuncDecl',
270 [['Decl', 's',
271 ['PtrDecl',
272 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300273 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800274
275 self.assertEqual(self.get_decl('int strcmp(char* s1, char* s2);'),
276 ['Decl', 'strcmp',
277 ['FuncDecl',
278 [ ['Decl', 's1',
279 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
280 ['Decl', 's2',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300281 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800282 ],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300283 ['TypeDecl', ['IdentifierType', ['int']]]]])
284
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400285 # function return values and parameters may not have type information
Eli Bendersky09e22a62013-07-02 06:00:36 -0700286 self.assertEqual(self.get_decl('extern foobar(foo, bar);'),
287 ['Decl', 'foobar',
288 ['FuncDecl',
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400289 [ ['ID', 'foo'],
290 ['ID', 'bar']
Eli Bendersky09e22a62013-07-02 06:00:36 -0700291 ],
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400292 ['TypeDecl', ['IdentifierType', ['int']]]]])
293
Manuel Jacob0a15d7d2017-01-12 15:46:05 +0100294 def test_int128(self):
295 self.assertEqual(self.get_decl('__int128 a;'),
296 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['__int128']]]])
297
298
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300299 def test_nested_decls(self): # the fun begins
300 self.assertEqual(self.get_decl('char** ar2D;'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800301 ['Decl', 'ar2D',
302 ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300303 ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800304
305 self.assertEqual(self.get_decl('int (*a)[1][2];'),
306 ['Decl', 'a',
307 ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800308 ['ArrayDecl', '1', [],
309 ['ArrayDecl', '2', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300310 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
311
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800312 self.assertEqual(self.get_decl('int *a[1][2];'),
313 ['Decl', 'a',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800314 ['ArrayDecl', '1', [],
315 ['ArrayDecl', '2', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300316 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800317
Eli Benderskyb17da152015-04-21 14:35:18 -0700318 self.assertEqual(self.get_decl('char* const* p;'),
319 ['Decl', 'p',
320 ['PtrDecl', ['PtrDecl', ['const'],
321 ['TypeDecl', ['IdentifierType', ['char']]]]]])
322
323 self.assertEqual(self.get_decl('char* * const p;'),
324 ['Decl', 'p',
325 ['PtrDecl', ['const'], ['PtrDecl',
326 ['TypeDecl', ['IdentifierType', ['char']]]]]])
327
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300328 self.assertEqual(self.get_decl('char ***ar3D[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800329 ['Decl', 'ar3D',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800330 ['ArrayDecl', '40', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800331 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300332 ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800333
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300334 self.assertEqual(self.get_decl('char (***ar3D)[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800335 ['Decl', 'ar3D',
336 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800337 ['ArrayDecl', '40', [], ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800338
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300339 self.assertEqual(self.get_decl('int (*x[4])(char, int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800340 ['Decl', 'x',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800341 ['ArrayDecl', '4', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800342 ['PtrDecl',
343 ['FuncDecl',
344 [ ['Typename', ['TypeDecl', ['IdentifierType', ['char']]]],
345 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300346 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800347
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300348 self.assertEqual(self.get_decl('char *(*(**foo [][8])())[];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800349 ['Decl', 'foo',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800350 ['ArrayDecl', '', [],
351 ['ArrayDecl', '8', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800352 ['PtrDecl', ['PtrDecl',
353 ['FuncDecl',
354 [],
355 ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800356 ['ArrayDecl', '', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800357 ['PtrDecl',
358 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300359 ['IdentifierType', ['char']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800360
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300361 # explore named and unnamed function pointer parameters,
362 # with and without qualifiers
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800363
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300364 # unnamed w/o quals
365 self.assertEqual(self.get_decl('int (*k)(int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800366 ['Decl', 'k',
367 ['PtrDecl',
368 ['FuncDecl',
369 [['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300370 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800371
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300372 # unnamed w/ quals
373 self.assertEqual(self.get_decl('int (*k)(const int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800374 ['Decl', 'k',
375 ['PtrDecl',
376 ['FuncDecl',
377 [['Typename', ['const'], ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300378 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800379
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300380 # named w/o quals
381 self.assertEqual(self.get_decl('int (*k)(int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800382 ['Decl', 'k',
383 ['PtrDecl',
384 ['FuncDecl',
385 [['Decl', 'q', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300386 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800387
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300388 # named w/ quals
389 self.assertEqual(self.get_decl('int (*k)(const volatile int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800390 ['Decl', 'k',
391 ['PtrDecl',
392 ['FuncDecl',
393 [['Decl', ['const', 'volatile'], 'q',
394 ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300395 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800396
Eli Benderskycecb6382018-06-15 05:36:02 -0700397 self.assertEqual(self.get_decl('int (*k)(const volatile int* q);'),
398 ['Decl', 'k',
399 ['PtrDecl',
400 ['FuncDecl',
401 [['Decl', ['const', 'volatile'], 'q',
402 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]],
403 ['TypeDecl', ['IdentifierType', ['int']]]]]])
404
eli.bendersky79d5cf62010-10-29 13:33:52 +0200405 # restrict qualifier
406 self.assertEqual(self.get_decl('int (*k)(restrict int* q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800407 ['Decl', 'k',
408 ['PtrDecl',
409 ['FuncDecl',
410 [['Decl', ['restrict'], 'q',
eli.bendersky79d5cf62010-10-29 13:33:52 +0200411 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800412 ['TypeDecl', ['IdentifierType', ['int']]]]]],
eli.bendersky79d5cf62010-10-29 13:33:52 +0200413 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800414
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800415 def test_func_decls_with_array_dim_qualifiers(self):
416 self.assertEqual(self.get_decl('int zz(int p[static 10]);'),
417 ['Decl', 'zz',
418 ['FuncDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800419 [['Decl', 'p', ['ArrayDecl', '10', ['static'],
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800420 ['TypeDecl', ['IdentifierType', ['int']]]]]],
421 ['TypeDecl', ['IdentifierType', ['int']]]]])
422
423 self.assertEqual(self.get_decl('int zz(int p[const 10]);'),
424 ['Decl', 'zz',
425 ['FuncDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800426 [['Decl', 'p', ['ArrayDecl', '10', ['const'],
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800427 ['TypeDecl', ['IdentifierType', ['int']]]]]],
428 ['TypeDecl', ['IdentifierType', ['int']]]]])
429
necase4a6afa02014-12-19 16:38:37 -0600430 self.assertEqual(self.get_decl('int zz(int p[restrict][5]);'),
431 ['Decl', 'zz',
432 ['FuncDecl',
433 [['Decl', 'p', ['ArrayDecl', '', ['restrict'],
434 ['ArrayDecl', '5', [],
435 ['TypeDecl', ['IdentifierType', ['int']]]]]]],
436 ['TypeDecl', ['IdentifierType', ['int']]]]])
437
438 self.assertEqual(self.get_decl('int zz(int p[const restrict static 10][5]);'),
439 ['Decl', 'zz',
440 ['FuncDecl',
441 [['Decl', 'p', ['ArrayDecl', '10', ['const', 'restrict', 'static'],
442 ['ArrayDecl', '5', [],
443 ['TypeDecl', ['IdentifierType', ['int']]]]]]],
444 ['TypeDecl', ['IdentifierType', ['int']]]]])
445
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300446 def test_qualifiers_storage_specifiers(self):
447 def assert_qs(txt, index, quals, storage):
448 d = self.parse(txt).ext[index]
449 self.assertEqual(d.quals, quals)
450 self.assertEqual(d.storage, storage)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800451
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300452 assert_qs("extern int p;", 0, [], ['extern'])
453 assert_qs("const long p = 6;", 0, ['const'], [])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800454
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300455 d1 = "static const int p, q, r;"
456 for i in range(3):
457 assert_qs(d1, i, ['const'], ['static'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800458
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300459 d2 = "static char * const p;"
460 assert_qs(d2, 0, [], ['static'])
461 pdecl = self.parse(d2).ext[0].type
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700462 self.assertIsInstance(pdecl, PtrDecl)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300463 self.assertEqual(pdecl.quals, ['const'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800464
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300465 def test_sizeof(self):
466 e = """
467 void foo()
468 {
469 int a = sizeof k;
470 int b = sizeof(int);
eli.benderskyc51e1d32011-02-04 08:52:33 +0200471 int c = sizeof(int**);;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800472
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300473 char* p = "just to make sure this parses w/o error...";
474 int d = sizeof(int());
475 }
476 """
477 compound = self.parse(e).ext[0].body
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800478
eli.benderskyef29ff92010-10-29 16:25:43 +0200479 s1 = compound.block_items[0].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700480 self.assertIsInstance(s1, UnaryOp)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300481 self.assertEqual(s1.op, 'sizeof')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700482 self.assertIsInstance(s1.expr, ID)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300483 self.assertEqual(s1.expr.name, 'k')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800484
eli.benderskyef29ff92010-10-29 16:25:43 +0200485 s2 = compound.block_items[1].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300486 self.assertEqual(expand_decl(s2.expr),
487 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800488
eli.benderskyef29ff92010-10-29 16:25:43 +0200489 s3 = compound.block_items[2].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300490 self.assertEqual(expand_decl(s3.expr),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800491 ['Typename',
492 ['PtrDecl',
493 ['PtrDecl',
494 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300495 ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800496
Eli Benderskye59395b2015-05-09 15:20:46 -0700497 def test_offsetof(self):
498 e = """
499 void foo() {
500 int a = offsetof(struct S, p);
501 a.b = offsetof(struct sockaddr, sp) + strlen(bar);
ksero749650a2016-09-09 07:31:09 +0200502 int a = offsetof(struct S, p.q.r);
503 int a = offsetof(struct S, p[5].q[4][5]);
Eli Benderskye59395b2015-05-09 15:20:46 -0700504 }
505 """
506 compound = self.parse(e).ext[0].body
507 s1 = compound.block_items[0].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700508 self.assertIsInstance(s1, FuncCall)
509 self.assertIsInstance(s1.name, ID)
Eli Benderskye59395b2015-05-09 15:20:46 -0700510 self.assertEqual(s1.name.name, 'offsetof')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700511 self.assertIsInstance(s1.args.exprs[0], Typename)
512 self.assertIsInstance(s1.args.exprs[1], ID)
ksero749650a2016-09-09 07:31:09 +0200513 s3 = compound.block_items[2].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700514 self.assertIsInstance(s3.args.exprs[1], StructRef)
ksero749650a2016-09-09 07:31:09 +0200515 s4 = compound.block_items[3].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700516 self.assertIsInstance(s4.args.exprs[1], ArrayRef)
Eli Benderskye59395b2015-05-09 15:20:46 -0700517
Eli Benderskydbf9be22016-10-11 20:44:32 -0700518 def test_compound_statement(self):
519 e = """
520 void foo() {
521 }
522 """
523 compound = self.parse(e).ext[0].body
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700524 self.assertIsInstance(compound, Compound)
serpilliere471442f2017-03-10 15:02:00 +0100525 self.assert_coord(compound, 2)
Eli Benderskydbf9be22016-10-11 20:44:32 -0700526
eli.bendersky9f481562010-10-30 15:50:47 +0200527 # The C99 compound literal feature
528 #
eli.benderskyf890a862010-10-30 12:13:23 +0200529 def test_compound_literals(self):
eli.bendersky9f481562010-10-30 15:50:47 +0200530 ps1 = self.parse(r'''
eli.benderskyf890a862010-10-30 12:13:23 +0200531 void foo() {
eli.bendersky9f481562010-10-30 15:50:47 +0200532 p = (long long){k};
533 tc = (struct jk){.a = {1, 2}, .b[0] = t};
534 }''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800535
eli.bendersky9f481562010-10-30 15:50:47 +0200536 compound = ps1.ext[0].body.block_items[0].rvalue
537 self.assertEqual(expand_decl(compound.type),
538 ['Typename', ['TypeDecl', ['IdentifierType', ['long', 'long']]]])
539 self.assertEqual(expand_init(compound.init),
540 [['ID', 'k']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800541
542 compound = ps1.ext[0].body.block_items[1].rvalue
eli.bendersky9f481562010-10-30 15:50:47 +0200543 self.assertEqual(expand_decl(compound.type),
544 ['Typename', ['TypeDecl', ['Struct', 'jk', []]]])
545 self.assertEqual(expand_init(compound.init),
546 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800547 ([['ID', 'a']], [['Constant', 'int', '1'], ['Constant', 'int', '2']]),
eli.bendersky9f481562010-10-30 15:50:47 +0200548 ([['ID', 'b'], ['Constant', 'int', '0']], ['ID', 't'])])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800549
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300550 def test_enums(self):
551 e1 = "enum mycolor op;"
552 e1_type = self.parse(e1).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800553
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700554 self.assertIsInstance(e1_type, Enum)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300555 self.assertEqual(e1_type.name, 'mycolor')
556 self.assertEqual(e1_type.values, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800557
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300558 e2 = "enum mysize {large=20, small, medium} shoes;"
559 e2_type = self.parse(e2).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800560
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700561 self.assertIsInstance(e2_type, Enum)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300562 self.assertEqual(e2_type.name, 'mysize')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800563
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300564 e2_elist = e2_type.values
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700565 self.assertIsInstance(e2_elist, EnumeratorList)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800566
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300567 for e2_eval in e2_elist.enumerators:
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700568 self.assertIsInstance(e2_eval, Enumerator)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800569
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300570 self.assertEqual(e2_elist.enumerators[0].name, 'large')
571 self.assertEqual(e2_elist.enumerators[0].value.value, '20')
572 self.assertEqual(e2_elist.enumerators[2].name, 'medium')
573 self.assertEqual(e2_elist.enumerators[2].value, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800574
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300575 # enum with trailing comma (C99 feature)
576 e3 = """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800577 enum
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300578 {
579 red,
580 blue,
581 green,
582 } color;
583 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800584
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300585 e3_type = self.parse(e3).ext[0].type.type
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700586 self.assertIsInstance(e3_type, Enum)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300587 e3_elist = e3_type.values
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700588 self.assertIsInstance(e3_elist, EnumeratorList)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800589
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300590 for e3_eval in e3_elist.enumerators:
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700591 self.assertIsInstance(e3_eval, Enumerator)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800592
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300593 self.assertEqual(e3_elist.enumerators[0].name, 'red')
594 self.assertEqual(e3_elist.enumerators[0].value, None)
595 self.assertEqual(e3_elist.enumerators[1].name, 'blue')
596 self.assertEqual(e3_elist.enumerators[2].name, 'green')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800597
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300598 def test_typedef(self):
599 # without typedef, error
600 s1 = """
601 node k;
602 """
603 self.assertRaises(ParseError, self.parse, s1)
604
605 # now with typedef, works
606 s2 = """
607 typedef void* node;
608 node k;
609 """
610 ps2 = self.parse(s2)
611 self.assertEqual(expand_decl(ps2.ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800612 ['Typedef', 'node',
613 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300614 ['TypeDecl', ['IdentifierType', ['void']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800615
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300616 self.assertEqual(expand_decl(ps2.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800617 ['Decl', 'k',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300618 ['TypeDecl', ['IdentifierType', ['node']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800619
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300620 s3 = """
621 typedef int T;
622 typedef T *pT;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800623
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300624 pT aa, bb;
625 """
626 ps3 = self.parse(s3)
627 self.assertEqual(expand_decl(ps3.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800628 ['Decl', 'bb',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300629 ['TypeDecl', ['IdentifierType', ['pT']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800630
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300631 s4 = '''
632 typedef char* __builtin_va_list;
633 typedef __builtin_va_list __gnuc_va_list;
634 '''
635 ps4 = self.parse(s4)
636 self.assertEqual(expand_decl(ps4.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800637 ['Typedef', '__gnuc_va_list',
638 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300639 ['IdentifierType', ['__builtin_va_list']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800640
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300641 s5 = '''typedef struct tagHash Hash;'''
642 ps5 = self.parse(s5)
643 self.assertEqual(expand_decl(ps5.ext[0]),
644 ['Typedef', 'Hash', ['TypeDecl', ['Struct', 'tagHash', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800645
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300646 def test_struct_union(self):
647 s1 = """
648 struct {
649 int id;
650 char* name;
651 } joe;
652 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800653
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300654 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800655 ['Decl', 'joe',
656 ['TypeDecl', ['Struct', None,
657 [ ['Decl', 'id',
658 ['TypeDecl',
659 ['IdentifierType', ['int']]]],
660 ['Decl', 'name',
661 ['PtrDecl',
662 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300663 ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800664
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300665 s2 = """
666 struct node p;
667 """
668 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800669 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300670 ['TypeDecl', ['Struct', 'node', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800671
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300672 s21 = """
673 union pri ra;
674 """
675 self.assertEqual(expand_decl(self.parse(s21).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800676 ['Decl', 'ra',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300677 ['TypeDecl', ['Union', 'pri', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800678
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300679 s3 = """
680 struct node* p;
681 """
682 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800683 ['Decl', 'p',
684 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300685 ['TypeDecl', ['Struct', 'node', []]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800686
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300687 s4 = """
688 struct node;
689 """
690 self.assertEqual(expand_decl(self.parse(s4).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800691 ['Decl', None,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300692 ['Struct', 'node', []]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800693
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300694 s5 = """
695 union
696 {
697 struct
698 {
699 int type;
700 } n;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800701
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300702 struct
703 {
704 int type;
705 int intnode;
706 } ni;
707 } u;
708 """
709 self.assertEqual(expand_decl(self.parse(s5).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800710 ['Decl', 'u',
711 ['TypeDecl',
712 ['Union', None,
713 [['Decl', 'n',
714 ['TypeDecl',
715 ['Struct', None,
716 [['Decl', 'type',
717 ['TypeDecl', ['IdentifierType', ['int']]]]]]]],
718 ['Decl', 'ni',
719 ['TypeDecl',
720 ['Struct', None,
721 [['Decl', 'type',
722 ['TypeDecl', ['IdentifierType', ['int']]]],
723 ['Decl', 'intnode',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300724 ['TypeDecl', ['IdentifierType', ['int']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800725
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300726 s6 = """
727 typedef struct foo_tag
728 {
729 void* data;
730 } foo, *pfoo;
731 """
732 s6_ast = self.parse(s6)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800733
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300734 self.assertEqual(expand_decl(s6_ast.ext[0]),
735 ['Typedef', 'foo',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800736 ['TypeDecl',
737 ['Struct', 'foo_tag',
738 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300739 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800740
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300741 self.assertEqual(expand_decl(s6_ast.ext[1]),
742 ['Typedef', 'pfoo',
743 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800744 ['TypeDecl',
745 ['Struct', 'foo_tag',
746 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300747 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800748
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300749 s7 = r"""
750 struct _on_exit_args {
751 void * _fnargs[32];
752 void * _dso_handle[32];
753
754 long _fntypes;
755 #line 77 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
756
757 long _is_cxa;
758 };
759 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800760
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300761 s7_ast = self.parse(s7, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100762 self.assert_coord(s7_ast.ext[0].type.decls[2], 6, 22, 'test.c')
763 self.assert_coord(s7_ast.ext[0].type.decls[3], 78, 22,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300764 r'D:\eli\cpp_stuff\libc_include/sys/reent.h')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800765
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300766 s8 = """
767 typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800768
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300769 typedef struct tagEntry
770 {
771 char* key;
772 char* value;
773 } Entry;
774
775
776 typedef struct tagNode
777 {
778 Entry* entry;
779
780 struct tagNode* next;
781 } Node;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800782
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300783 typedef struct tagHash
784 {
785 unsigned int table_size;
786
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800787 Node** heads;
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300788
789 } Hash;
790 """
791 s8_ast = self.parse(s8)
792 self.assertEqual(expand_decl(s8_ast.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800793 ['Typedef', 'Hash',
794 ['TypeDecl', ['Struct', 'tagHash',
795 [['Decl', 'table_size',
796 ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]],
797 ['Decl', 'heads',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300798 ['PtrDecl', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['Node']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800799
Eli Bendersky95e3b762016-03-19 05:21:59 -0700800 def test_struct_with_extra_semis_inside(self):
801 s1 = """
802 struct {
803 int a;;
804 } foo;
805 """
806 s1_ast = self.parse(s1)
807 self.assertEqual(expand_decl(s1_ast.ext[0]),
808 ['Decl', 'foo',
809 ['TypeDecl', ['Struct', None,
810 [['Decl', 'a',
811 ['TypeDecl', ['IdentifierType', ['int']]]]]]]])
812
813 s2 = """
814 struct {
815 int a;;;;
816 float b, c;
817 ;;
818 char d;
819 } foo;
820 """
821 s2_ast = self.parse(s2)
822 self.assertEqual(expand_decl(s2_ast.ext[0]),
823 ['Decl', 'foo',
824 ['TypeDecl', ['Struct', None,
825 [['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]],
826 ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['float']]]],
827 ['Decl', 'c', ['TypeDecl', ['IdentifierType', ['float']]]],
828 ['Decl', 'd',
829 ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
830
eli.bendersky697ecc52011-02-10 07:05:13 +0200831 def test_anonymous_struct_union(self):
832 s1 = """
833 union
834 {
835 union
836 {
837 int i;
838 long l;
839 };
840
841 struct
842 {
843 int type;
844 int intnode;
845 };
846 } u;
847 """
848
849 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
850 ['Decl', 'u',
851 ['TypeDecl',
852 ['Union', None,
853 [['Decl', None,
854 ['Union', None,
855 [['Decl', 'i',
856 ['TypeDecl',
857 ['IdentifierType', ['int']]]],
858 ['Decl', 'l',
859 ['TypeDecl',
860 ['IdentifierType', ['long']]]]]]],
861 ['Decl', None,
862 ['Struct', None,
863 [['Decl', 'type',
864 ['TypeDecl',
865 ['IdentifierType', ['int']]]],
866 ['Decl', 'intnode',
867 ['TypeDecl',
868 ['IdentifierType', ['int']]]]]]]]]]])
869
870 s2 = """
871 struct
872 {
873 int i;
874 union
875 {
876 int id;
877 char* name;
878 };
879 float f;
880 } joe;
881 """
882
883 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
884 ['Decl', 'joe',
885 ['TypeDecl',
886 ['Struct', None,
887 [['Decl', 'i',
888 ['TypeDecl',
889 ['IdentifierType', ['int']]]],
890 ['Decl', None,
891 ['Union', None,
892 [['Decl', 'id',
893 ['TypeDecl',
894 ['IdentifierType', ['int']]]],
895 ['Decl', 'name',
896 ['PtrDecl',
897 ['TypeDecl',
898 ['IdentifierType', ['char']]]]]]]],
899 ['Decl', 'f',
900 ['TypeDecl',
901 ['IdentifierType', ['float']]]]]]]])
902
903 # ISO/IEC 9899:201x Commitee Draft 2010-11-16, N1539
904 # section 6.7.2.1, par. 19, example 1
905 s3 = """
906 struct v {
907 union {
908 struct { int i, j; };
909 struct { long k, l; } w;
910 };
911 int m;
912 } v1;
913 """
914
915 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
916 ['Decl', 'v1',
917 ['TypeDecl',
918 ['Struct', 'v',
919 [['Decl', None,
920 ['Union', None,
921 [['Decl', None,
922 ['Struct', None,
923 [['Decl', 'i',
924 ['TypeDecl',
925 ['IdentifierType', ['int']]]],
926 ['Decl', 'j',
927 ['TypeDecl',
928 ['IdentifierType', ['int']]]]]]],
929 ['Decl', 'w',
930 ['TypeDecl',
931 ['Struct', None,
932 [['Decl', 'k',
933 ['TypeDecl',
934 ['IdentifierType', ['long']]]],
935 ['Decl', 'l',
936 ['TypeDecl',
937 ['IdentifierType', ['long']]]]]]]]]]],
938 ['Decl', 'm',
939 ['TypeDecl',
940 ['IdentifierType', ['int']]]]]]]])
941
eli.benderskydce29a02011-02-10 07:55:00 +0200942 s4 = """
943 struct v {
944 int i;
945 float;
946 } v2;"""
eli.bendersky6b011792011-06-22 17:50:56 +0300947 # just make sure this doesn't raise ParseError
948 self.parse(s4)
eli.benderskydce29a02011-02-10 07:55:00 +0200949
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400950 def test_struct_members_namespace(self):
Eli Bendersky4d969b32013-07-13 06:07:07 -0700951 """ Tests that structure/union member names reside in a separate
952 namespace and can be named after existing types.
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400953 """
954 s1 = """
955 typedef int Name;
956 typedef Name NameArray[10];
957
958 struct {
959 Name Name;
960 Name NameArray[3];
961 } sye;
962
963 void main(void)
964 {
965 sye.Name = 1;
966 }
967 """
968
969 s1_ast = self.parse(s1)
970 self.assertEqual(expand_decl(s1_ast.ext[2]),
971 ['Decl', 'sye',
972 ['TypeDecl', ['Struct', None,
973 [ ['Decl', 'Name',
974 ['TypeDecl',
975 ['IdentifierType', ['Name']]]],
976 ['Decl', 'NameArray',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800977 ['ArrayDecl', '3', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400978 ['TypeDecl', ['IdentifierType', ['Name']]]]]]]]])
979 self.assertEqual(s1_ast.ext[3].body.block_items[0].lvalue.field.name, 'Name')
980
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200981 def test_struct_bitfields(self):
eli.bendersky38ed9a92010-10-09 09:29:59 +0200982 # a struct with two bitfields, one unnamed
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200983 s1 = """
984 struct {
985 int k:6;
986 int :2;
987 } joe;
988 """
989
990 parsed_struct = self.parse(s1).ext[0]
991
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800992 # We can see here the name of the decl for the unnamed bitfield is
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200993 # None, but expand_decl doesn't show bitfield widths
994 # ...
995 self.assertEqual(expand_decl(parsed_struct),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800996 ['Decl', 'joe',
997 ['TypeDecl', ['Struct', None,
998 [ ['Decl', 'k',
999 ['TypeDecl',
1000 ['IdentifierType', ['int']]]],
1001 ['Decl', None,
1002 ['TypeDecl',
eli.bendersky0e0a71f2010-10-09 08:32:00 +02001003 ['IdentifierType', ['int']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001004
eli.bendersky0e0a71f2010-10-09 08:32:00 +02001005 # ...
1006 # so we test them manually
1007 self.assertEqual(parsed_struct.type.type.decls[0].bitsize.value, '6')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001008 self.assertEqual(parsed_struct.type.type.decls[1].bitsize.value, '2')
1009
ldore81a12ca2018-04-28 05:09:24 +02001010 def test_struct_empty(self):
1011 """
1012 Tests that parsing an empty struct works.
1013
1014 Empty structs do NOT follow C99 (See 6.2.5-20 of the C99 standard).
1015 This is nevertheless supported by some compilers (clang, gcc),
1016 especially when using FORTIFY code.
1017 Some compilers (visual) will fail to compile with an error.
1018 """
1019 # an empty struct. This is NOT C99 compliant
1020 s1 = """
1021 struct foo { };
1022 """
1023
1024 parsed_struct = self.parse(s1).ext[0]
1025
1026 self.assertEqual(expand_decl(parsed_struct),
1027 ['Decl', None, ['Struct', 'foo', []]]
1028 )
1029
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001030 def test_tags_namespace(self):
1031 """ Tests that the tags of structs/unions/enums reside in a separate namespace and
1032 can be named after existing types.
1033 """
1034 s1 = """
1035 typedef int tagEntry;
1036
1037 struct tagEntry
1038 {
1039 char* key;
1040 char* value;
1041 } Entry;
1042 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001043
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001044 s1_ast = self.parse(s1)
1045 self.assertEqual(expand_decl(s1_ast.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001046 ['Decl', 'Entry',
1047 ['TypeDecl', ['Struct', 'tagEntry',
1048 [['Decl', 'key',
1049 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
1050 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001051 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001052
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001053 s2 = """
1054 struct tagEntry;
1055
1056 typedef struct tagEntry tagEntry;
1057
1058 struct tagEntry
1059 {
1060 char* key;
1061 char* value;
1062 } Entry;
1063 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001064
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001065 s2_ast = self.parse(s2)
1066 self.assertEqual(expand_decl(s2_ast.ext[2]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001067 ['Decl', 'Entry',
1068 ['TypeDecl', ['Struct', 'tagEntry',
1069 [['Decl', 'key',
1070 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
1071 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001072 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001073
1074 s3 = """
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001075 typedef int mytag;
1076
1077 enum mytag {ABC, CDE};
1078 enum mytag joe;
1079 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001080
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001081 s3_type = self.parse(s3).ext[1].type
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001082
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001083 self.assertIsInstance(s3_type, Enum)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001084 self.assertEqual(s3_type.name, 'mytag')
1085
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001086 def test_multi_decls(self):
1087 d1 = 'int a, b;'
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001088
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001089 self.assertEqual(self.get_decl(d1, 0),
1090 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
1091 self.assertEqual(self.get_decl(d1, 1),
1092 ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001093
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001094 d2 = 'char* p, notp, ar[4];'
1095 self.assertEqual(self.get_decl(d2, 0),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001096 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001097 ['PtrDecl',
1098 ['TypeDecl', ['IdentifierType', ['char']]]]])
1099 self.assertEqual(self.get_decl(d2, 1),
1100 ['Decl', 'notp', ['TypeDecl', ['IdentifierType', ['char']]]])
1101 self.assertEqual(self.get_decl(d2, 2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001102 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001103 ['ArrayDecl', '4', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001104 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001105
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001106 def test_invalid_multiple_types_error(self):
1107 bad = [
1108 'int enum {ab, cd} fubr;',
1109 'enum kid char brbr;']
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001110
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001111 for b in bad:
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001112 self.assertRaises(ParseError, self.parse, b)
Eli Bendersky9dadc3f2012-07-06 15:53:53 +03001113
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001114 def test_duplicate_typedef(self):
1115 """ Tests that redeclarations of existing types are parsed correctly.
1116 This is non-standard, but allowed by many compilers.
1117 """
1118 d1 = '''
Eli Bendersky9dadc3f2012-07-06 15:53:53 +03001119 typedef int numbertype;
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001120 typedef int numbertype;
Eli Bendersky9dadc3f2012-07-06 15:53:53 +03001121 '''
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001122
1123 self.assertEqual(self.get_decl(d1, 0),
1124 ['Typedef', 'numbertype',
1125 ['TypeDecl', ['IdentifierType', ['int']]]])
1126 self.assertEqual(self.get_decl(d1, 1),
1127 ['Typedef', 'numbertype',
1128 ['TypeDecl', ['IdentifierType', ['int']]]])
1129
1130 d2 = '''
1131 typedef int (*funcptr)(int x);
1132 typedef int (*funcptr)(int x);
1133 '''
1134 self.assertEqual(self.get_decl(d2, 0),
1135 ['Typedef', 'funcptr',
1136 ['PtrDecl', ['FuncDecl',
1137 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
1138 ['TypeDecl', ['IdentifierType', ['int']]]]]])
1139 self.assertEqual(self.get_decl(d2, 1),
1140 ['Typedef', 'funcptr',
1141 ['PtrDecl', ['FuncDecl',
1142 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
1143 ['TypeDecl', ['IdentifierType', ['int']]]]]])
1144
1145 d3 = '''
1146 typedef int numberarray[5];
1147 typedef int numberarray[5];
1148 '''
1149 self.assertEqual(self.get_decl(d3, 0),
1150 ['Typedef', 'numberarray',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001151 ['ArrayDecl', '5', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001152 ['TypeDecl', ['IdentifierType', ['int']]]]])
1153 self.assertEqual(self.get_decl(d3, 1),
1154 ['Typedef', 'numberarray',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001155 ['ArrayDecl', '5', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001156 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001157
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001158 def test_decl_inits(self):
1159 d1 = 'int a = 16;'
eli.benderskyf890a862010-10-30 12:13:23 +02001160 #~ self.parse(d1).show()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001161 self.assertEqual(self.get_decl(d1),
1162 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
1163 self.assertEqual(self.get_decl_init(d1),
1164 ['Constant', 'int', '16'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001165
Eli Bendersky3b1b08d2012-06-15 12:37:54 +03001166 d1_1 = 'float f = 0xEF.56p1;'
1167 self.assertEqual(self.get_decl_init(d1_1),
1168 ['Constant', 'float', '0xEF.56p1'])
1169
Konstanty Bialkowski3bdbfdc2015-04-19 20:09:21 +10001170 d1_2 = 'int bitmask = 0b1001010;'
1171 self.assertEqual(self.get_decl_init(d1_2),
1172 ['Constant', 'int', '0b1001010'])
1173
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001174 d2 = 'long ar[] = {7, 8, 9};'
1175 self.assertEqual(self.get_decl(d2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001176 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001177 ['ArrayDecl', '', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001178 ['TypeDecl', ['IdentifierType', ['long']]]]])
1179 self.assertEqual(self.get_decl_init(d2),
1180 [ ['Constant', 'int', '7'],
1181 ['Constant', 'int', '8'],
eli.benderskyf890a862010-10-30 12:13:23 +02001182 ['Constant', 'int', '9']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001183
Eli Benderskyc830da82015-05-10 07:56:41 -07001184 d21 = 'long ar[4] = {};'
1185 self.assertEqual(self.get_decl_init(d21), [])
1186
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001187 d3 = 'char p = j;'
1188 self.assertEqual(self.get_decl(d3),
1189 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['char']]]])
1190 self.assertEqual(self.get_decl_init(d3),
1191 ['ID', 'j'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001192
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001193 d4 = "char x = 'c', *p = {0, 1, 2, {4, 5}, 6};"
1194 self.assertEqual(self.get_decl(d4, 0),
1195 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['char']]]])
1196 self.assertEqual(self.get_decl_init(d4, 0),
1197 ['Constant', 'char', "'c'"])
1198 self.assertEqual(self.get_decl(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001199 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001200 ['PtrDecl',
1201 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001202
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001203 self.assertEqual(self.get_decl_init(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001204 [ ['Constant', 'int', '0'],
1205 ['Constant', 'int', '1'],
1206 ['Constant', 'int', '2'],
1207 [['Constant', 'int', '4'],
1208 ['Constant', 'int', '5']],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001209 ['Constant', 'int', '6']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001210
eli.benderskyf890a862010-10-30 12:13:23 +02001211 def test_decl_named_inits(self):
1212 d1 = 'int a = {.k = 16};'
1213 self.assertEqual(self.get_decl_init(d1),
1214 [( [['ID', 'k']],
1215 ['Constant', 'int', '16'])])
1216
1217 d2 = 'int a = { [0].a = {1}, [1].a[0] = 2 };'
1218 self.assertEqual(self.get_decl_init(d2),
1219 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001220 ([['Constant', 'int', '0'], ['ID', 'a']],
1221 [['Constant', 'int', '1']]),
1222 ([['Constant', 'int', '1'], ['ID', 'a'], ['Constant', 'int', '0']],
eli.benderskyf890a862010-10-30 12:13:23 +02001223 ['Constant', 'int', '2'])])
1224
1225 d3 = 'int a = { .a = 1, .c = 3, 4, .b = 5};'
1226 self.assertEqual(self.get_decl_init(d3),
1227 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001228 ([['ID', 'a']], ['Constant', 'int', '1']),
1229 ([['ID', 'c']], ['Constant', 'int', '3']),
1230 ['Constant', 'int', '4'],
eli.benderskyf890a862010-10-30 12:13:23 +02001231 ([['ID', 'b']], ['Constant', 'int', '5'])])
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001232
1233 def test_function_definitions(self):
1234 def parse_fdef(str):
1235 return self.parse(str).ext[0]
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001236
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001237 def fdef_decl(fdef):
1238 return expand_decl(fdef.decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001239
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001240 f1 = parse_fdef('''
1241 int factorial(int p)
1242 {
1243 return 3;
1244 }
1245 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001246
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001247 self.assertEqual(fdef_decl(f1),
1248 ['Decl', 'factorial',
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001249 ['FuncDecl',
1250 [['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001251 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001252
eli.benderskyef29ff92010-10-29 16:25:43 +02001253 self.assertEqual(type(f1.body.block_items[0]), Return)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001254
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001255 f2 = parse_fdef('''
1256 char* zzz(int p, char* c)
1257 {
1258 int a;
1259 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001260
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001261 a = b + 2;
1262 return 3;
1263 }
1264 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001265
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001266 self.assertEqual(fdef_decl(f2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001267 ['Decl', 'zzz',
1268 ['FuncDecl',
1269 [ ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]],
1270 ['Decl', 'c', ['PtrDecl',
1271 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001272 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001273
1274 self.assertEqual(list(map(type, f2.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001275 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001276
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001277 f3 = parse_fdef('''
1278 char* zzz(p, c)
1279 long p, *c;
1280 {
1281 int a;
1282 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001283
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001284 a = b + 2;
1285 return 3;
1286 }
1287 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001288
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001289 self.assertEqual(fdef_decl(f3),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001290 ['Decl', 'zzz',
1291 ['FuncDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001292 [ ['ID', 'p'],
1293 ['ID', 'c']],
1294 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001295
1296 self.assertEqual(list(map(type, f3.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001297 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001298
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001299 self.assertEqual(expand_decl(f3.param_decls[0]),
1300 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['long']]]])
1301 self.assertEqual(expand_decl(f3.param_decls[1]),
1302 ['Decl', 'c', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['long']]]]])
1303
Sye van der Veen51a46ec2013-06-10 12:56:15 -04001304 # function return values and parameters may not have type information
1305 f4 = parse_fdef('''
1306 que(p)
1307 {
1308 return 3;
1309 }
1310 ''')
1311
1312 self.assertEqual(fdef_decl(f4),
1313 ['Decl', 'que',
1314 ['FuncDecl',
1315 [['ID', 'p']],
1316 ['TypeDecl', ['IdentifierType', ['int']]]]])
1317
eli.bendersky71540662010-07-03 12:58:52 +02001318 def test_unified_string_literals(self):
1319 # simple string, for reference
1320 d1 = self.get_decl_init('char* s = "hello";')
1321 self.assertEqual(d1, ['Constant', 'string', '"hello"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001322
eli.bendersky71540662010-07-03 12:58:52 +02001323 d2 = self.get_decl_init('char* s = "hello" " world";')
1324 self.assertEqual(d2, ['Constant', 'string', '"hello world"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001325
eli.bendersky71540662010-07-03 12:58:52 +02001326 # the test case from issue 6
1327 d3 = self.parse(r'''
1328 int main() {
1329 fprintf(stderr,
1330 "Wrong Params?\n"
1331 "Usage:\n"
1332 "%s <binary_file_path>\n",
1333 argv[0]
1334 );
1335 }
1336 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001337
eli.bendersky71540662010-07-03 12:58:52 +02001338 self.assertEqual(
eli.benderskyef29ff92010-10-29 16:25:43 +02001339 d3.ext[0].body.block_items[0].args.exprs[1].value,
eli.bendersky71540662010-07-03 12:58:52 +02001340 r'"Wrong Params?\nUsage:\n%s <binary_file_path>\n"')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001341
eli.bendersky4a89f112010-07-05 06:02:03 +02001342 d4 = self.get_decl_init('char* s = "" "foobar";')
1343 self.assertEqual(d4, ['Constant', 'string', '"foobar"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001344
eli.bendersky4a89f112010-07-05 06:02:03 +02001345 d5 = self.get_decl_init(r'char* s = "foo\"" "bar";')
1346 self.assertEqual(d5, ['Constant', 'string', r'"foo\"bar"'])
eli.bendersky71540662010-07-03 12:58:52 +02001347
Eli Benderskyc9f1a382014-03-15 14:12:00 -07001348 def test_unified_wstring_literals(self):
1349 d1 = self.get_decl_init('char* s = L"hello" L"world";')
1350 self.assertEqual(d1, ['Constant', 'string', 'L"helloworld"'])
1351
1352 d2 = self.get_decl_init('char* s = L"hello " L"world" L" and I";')
1353 self.assertEqual(d2, ['Constant', 'string', 'L"hello world and I"'])
1354
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001355 def test_inline_specifier(self):
eli.bendersky79d5cf62010-10-29 13:33:52 +02001356 ps2 = self.parse('static inline void inlinefoo(void);')
1357 self.assertEqual(ps2.ext[0].funcspec, ['inline'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001358
eli.bendersky2e907fa2010-10-29 15:51:07 +02001359 # variable length array
1360 def test_vla(self):
1361 ps2 = self.parse(r'''
1362 int main() {
1363 int size;
1364 int var[size = 5];
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001365
eli.bendersky2e907fa2010-10-29 15:51:07 +02001366 int var2[*];
1367 }
1368 ''')
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001369 self.assertIsInstance(ps2.ext[0].body.block_items[1].type.dim, Assignment)
1370 self.assertIsInstance(ps2.ext[0].body.block_items[2].type.dim, ID)
eli.bendersky79d5cf62010-10-29 13:33:52 +02001371
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001372 def test_pragma(self):
1373 s1 = r'''
1374 #pragma bar
1375 void main() {
1376 #pragma foo
1377 for(;;) {}
Julian Hammer8a174062015-12-14 14:48:16 +01001378 #pragma
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001379 }
ldoreec233182017-11-22 14:52:53 +01001380 struct s {
1381 #pragma baz
1382 } s;
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001383 '''
1384 s1_ast = self.parse(s1)
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001385 self.assertIsInstance(s1_ast.ext[0], Pragma)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001386 self.assertEqual(s1_ast.ext[0].string, 'bar')
Julian Hammer8a174062015-12-14 14:48:16 +01001387 self.assertEqual(s1_ast.ext[0].coord.line, 2)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001388
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001389 self.assertIsInstance(s1_ast.ext[1].body.block_items[0], Pragma)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001390 self.assertEqual(s1_ast.ext[1].body.block_items[0].string, 'foo')
Julian Hammer8a174062015-12-14 14:48:16 +01001391 self.assertEqual(s1_ast.ext[1].body.block_items[0].coord.line, 4)
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001392
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001393 self.assertIsInstance(s1_ast.ext[1].body.block_items[2], Pragma)
Julian Hammer8a174062015-12-14 14:48:16 +01001394 self.assertEqual(s1_ast.ext[1].body.block_items[2].string, '')
1395 self.assertEqual(s1_ast.ext[1].body.block_items[2].coord.line, 6)
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001396
1397 self.assertIsInstance(s1_ast.ext[2].type.type.decls[0], Pragma)
ldoreec233182017-11-22 14:52:53 +01001398 self.assertEqual(s1_ast.ext[2].type.type.decls[0].string, 'baz')
1399 self.assertEqual(s1_ast.ext[2].type.type.decls[0].coord.line, 9)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001400
dbluhm7af2fb92018-03-03 06:18:26 -07001401 def test_pragmacomp_or_statement(self):
1402 s1 = r'''
1403 void main() {
1404 int sum = 0;
1405 for (int i; i < 3; i++)
1406 #pragma omp critical
1407 sum += 1;
1408
1409 while(sum < 10)
1410 #pragma omp critical
1411 sum += 1;
1412
1413 mylabel:
1414 #pragma foo
1415 sum += 10;
1416
1417 if (sum > 10)
1418 #pragma bar
1419 sum = 10;
1420
1421 switch (sum)
1422 case 10:
1423 #pragma foo
1424 sum = 20;
1425 }
1426 '''
1427 s1_ast = self.parse(s1)
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001428 self.assertIsInstance(s1_ast.ext[0].body.block_items[1], For)
1429 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt, Compound)
1430 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[0], Pragma)
1431 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[1], Assignment)
1432 self.assertIsInstance(s1_ast.ext[0].body.block_items[2], While)
1433 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt, Compound)
1434 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[0], Pragma)
1435 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[1], Assignment)
1436 self.assertIsInstance(s1_ast.ext[0].body.block_items[3], Label)
1437 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt, Compound)
1438 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[0], Pragma)
1439 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[1], Assignment)
1440 self.assertIsInstance(s1_ast.ext[0].body.block_items[4], If)
1441 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue, Compound)
1442 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[0], Pragma)
1443 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[1], Assignment)
1444 self.assertIsInstance(s1_ast.ext[0].body.block_items[5], Switch)
1445 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0], Compound)
1446 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[0], Pragma)
1447 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[1], Assignment)
dbluhm7af2fb92018-03-03 06:18:26 -07001448
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001449
eli.bendersky85d2e732011-05-20 19:47:26 +03001450class TestCParser_whole_code(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001451 """ Testing of parsing whole chunks of code.
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001452
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001453 Since I don't want to rely on the structure of ASTs too
1454 much, most of these tests are implemented with visitors.
1455 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001456 # A simple helper visitor that lists the values of all the
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001457 # Constant nodes it sees.
1458 #
1459 class ConstantVisitor(NodeVisitor):
1460 def __init__(self):
1461 self.values = []
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001462
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001463 def visit_Constant(self, node):
1464 self.values.append(node.value)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001465
1466 # This visitor counts the amount of references to the ID
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001467 # with the name provided to it in the constructor.
1468 #
1469 class IDNameCounter(NodeVisitor):
1470 def __init__(self, name):
1471 self.name = name
1472 self.nrefs = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001473
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001474 def visit_ID(self, node):
1475 if node.name == self.name:
1476 self.nrefs += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001477
1478 # Counts the amount of nodes of a given class
1479 #
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001480 class NodeKlassCounter(NodeVisitor):
1481 def __init__(self, node_klass):
1482 self.klass = node_klass
1483 self.n = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001484
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001485 def generic_visit(self, node):
1486 if node.__class__ == self.klass:
1487 self.n += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001488
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001489 NodeVisitor.generic_visit(self, node)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001490
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001491 def assert_all_Constants(self, code, constants):
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001492 """ Asserts that the list of all Constant values (by
1493 'preorder' appearance) in the chunk of code is as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001494 given.
1495 """
eli.benderskyed890492010-06-25 08:25:55 +03001496 if isinstance(code, str):
1497 parsed = self.parse(code)
1498 else:
1499 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001500
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001501 cv = self.ConstantVisitor()
1502 cv.visit(parsed)
1503 self.assertEqual(cv.values, constants)
1504
1505 def assert_num_ID_refs(self, code, name, num):
1506 """ Asserts the number of references to the ID with
1507 the given name.
1508 """
1509 if isinstance(code, str):
1510 parsed = self.parse(code)
1511 else:
1512 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001513
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001514 iv = self.IDNameCounter(name)
1515 iv.visit(parsed)
1516 self.assertEqual(iv.nrefs, num)
1517
1518 def assert_num_klass_nodes(self, code, klass, num):
1519 """ Asserts the amount of klass nodes in the code.
1520 """
1521 if isinstance(code, str):
1522 parsed = self.parse(code)
1523 else:
1524 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001525
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001526 cv = self.NodeKlassCounter(klass)
1527 cv.visit(parsed)
1528 self.assertEqual(cv.n, num)
1529
1530 def test_expressions(self):
1531 e1 = '''int k = (r + 10.0) >> 6 + 8 << (3 & 0x14);'''
1532 self.assert_all_Constants(e1, ['10.0', '6', '8', '3', '0x14'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001533
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001534 e2 = r'''char n = '\n', *prefix = "st_";'''
1535 self.assert_all_Constants(e2, [r"'\n'", '"st_"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001536
Eli Bendersky09e22a62013-07-02 06:00:36 -07001537 s1 = r'''int main() {
1538 int i = 5, j = 6, k = 1;
1539 if ((i=j && k == 1) || k > j)
1540 printf("Hello, world\n");
1541 return 0;
1542 }'''
1543 ps1 = self.parse(s1)
1544 self.assert_all_Constants(ps1,
1545 ['5', '6', '1', '1', '"Hello, world\\n"', '0'])
1546 self.assert_num_ID_refs(ps1, 'i', 1)
1547 self.assert_num_ID_refs(ps1, 'j', 2)
1548
1549
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001550 def test_statements(self):
1551 s1 = r'''
1552 void foo(){
1553 if (sp == 1)
1554 if (optind >= argc ||
1555 argv[optind][0] != '-' || argv[optind][1] == '\0')
1556 return -1;
1557 else if (strcmp(argv[optind], "--") == 0) {
1558 optind++;
1559 return -1;
1560 }
1561 }
1562 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001563
1564 self.assert_all_Constants(s1,
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001565 ['1', '0', r"'-'", '1', r"'\0'", '1', r'"--"', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001566
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001567 ps1 = self.parse(s1)
1568 self.assert_num_ID_refs(ps1, 'argv', 3)
1569 self.assert_num_ID_refs(ps1, 'optind', 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001570
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001571 self.assert_num_klass_nodes(ps1, If, 3)
1572 self.assert_num_klass_nodes(ps1, Return, 2)
1573 self.assert_num_klass_nodes(ps1, FuncCall, 1) # strcmp
1574 self.assert_num_klass_nodes(ps1, BinaryOp, 7)
1575
1576 # In the following code, Hash and Node were defined as
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001577 # int to pacify the parser that sees they're used as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001578 # types
1579 #
1580 s2 = r'''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001581 typedef int Hash, Node;
1582
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001583 void HashDestroy(Hash* hash)
1584 {
1585 unsigned int i;
1586
1587 if (hash == NULL)
1588 return;
1589
1590 for (i = 0; i < hash->table_size; ++i)
1591 {
1592 Node* temp = hash->heads[i];
1593
1594 while (temp != NULL)
1595 {
1596 Node* temp2 = temp;
1597
1598 free(temp->entry->key);
1599 free(temp->entry->value);
1600 free(temp->entry);
1601
1602 temp = temp->next;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001603
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001604 free(temp2);
1605 }
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001606 }
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001607
1608 free(hash->heads);
1609 hash->heads = NULL;
1610
1611 free(hash);
1612 }
1613 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001614
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001615 ps2 = self.parse(s2)
1616 self.assert_num_klass_nodes(ps2, FuncCall, 6)
1617 self.assert_num_klass_nodes(ps2, FuncDef, 1)
1618 self.assert_num_klass_nodes(ps2, For, 1)
1619 self.assert_num_klass_nodes(ps2, While, 1)
1620 self.assert_num_klass_nodes(ps2, StructRef, 10)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001621
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001622 # declarations don't count
1623 self.assert_num_ID_refs(ps2, 'hash', 6)
1624 self.assert_num_ID_refs(ps2, 'i', 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001625
eli.benderskyed890492010-06-25 08:25:55 +03001626 s3 = r'''
1627 void x(void) {
1628 int a, b;
1629 if (a < b)
1630 do {
1631 a = 0;
1632 } while (0);
1633 else if (a == b) {
1634 a = 1;
1635 }
1636 }
1637 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001638
eli.benderskyed890492010-06-25 08:25:55 +03001639 ps3 = self.parse(s3)
1640 self.assert_num_klass_nodes(ps3, DoWhile, 1)
1641 self.assert_num_ID_refs(ps3, 'a', 4)
1642 self.assert_all_Constants(ps3, ['0', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001643
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001644 def test_empty_statements(self):
eli.bendersky91c0aa32011-10-16 05:50:43 +02001645 s1 = r'''
1646 void foo(void){
1647 ;
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001648 return;;
1649
1650 ;
eli.bendersky91c0aa32011-10-16 05:50:43 +02001651 }
1652 '''
1653 ps1 = self.parse(s1)
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001654 self.assert_num_klass_nodes(ps1, EmptyStatement, 3)
eli.bendersky91c0aa32011-10-16 05:50:43 +02001655 self.assert_num_klass_nodes(ps1, Return, 1)
serpilliere471442f2017-03-10 15:02:00 +01001656 self.assert_coord(ps1.ext[0].body.block_items[0], 3)
1657 self.assert_coord(ps1.ext[0].body.block_items[1], 4)
1658 self.assert_coord(ps1.ext[0].body.block_items[2], 4)
1659 self.assert_coord(ps1.ext[0].body.block_items[3], 6)
eli.bendersky145890d2010-10-29 12:02:32 +02001660
Ben5cd3fd62012-02-03 06:02:40 +02001661 def test_switch_statement(self):
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001662 def assert_case_node(node, const_value):
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001663 self.assertIsInstance(node, Case)
1664 self.assertIsInstance(node.expr, Constant)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001665 self.assertEqual(node.expr.value, const_value)
1666
1667 def assert_default_node(node):
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001668 self.assertIsInstance(node, Default)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001669
Ben5cd3fd62012-02-03 06:02:40 +02001670 s1 = r'''
1671 int foo(void) {
1672 switch (myvar) {
1673 case 10:
1674 k = 10;
1675 p = k + 1;
1676 return 10;
1677 case 20:
1678 case 30:
1679 return 20;
1680 default:
1681 break;
1682 }
1683 return 0;
1684 }
1685 '''
1686 ps1 = self.parse(s1)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001687 switch = ps1.ext[0].body.block_items[0]
1688
1689 block = switch.stmt.block_items
1690 assert_case_node(block[0], '10')
1691 self.assertEqual(len(block[0].stmts), 3)
1692 assert_case_node(block[1], '20')
1693 self.assertEqual(len(block[1].stmts), 0)
1694 assert_case_node(block[2], '30')
1695 self.assertEqual(len(block[2].stmts), 1)
1696 assert_default_node(block[3])
1697
1698 s2 = r'''
1699 int foo(void) {
1700 switch (myvar) {
1701 default:
1702 joe = moe;
1703 return 10;
1704 case 10:
1705 case 20:
1706 case 30:
1707 case 40:
1708 break;
1709 }
1710 return 0;
1711 }
1712 '''
1713 ps2 = self.parse(s2)
1714 switch = ps2.ext[0].body.block_items[0]
1715
1716 block = switch.stmt.block_items
1717 assert_default_node(block[0])
1718 self.assertEqual(len(block[0].stmts), 2)
1719 assert_case_node(block[1], '10')
1720 self.assertEqual(len(block[1].stmts), 0)
1721 assert_case_node(block[2], '20')
1722 self.assertEqual(len(block[1].stmts), 0)
1723 assert_case_node(block[3], '30')
1724 self.assertEqual(len(block[1].stmts), 0)
1725 assert_case_node(block[4], '40')
1726 self.assertEqual(len(block[4].stmts), 1)
Ben5cd3fd62012-02-03 06:02:40 +02001727
eli.bendersky145890d2010-10-29 12:02:32 +02001728 def test_for_statement(self):
1729 s2 = r'''
1730 void x(void)
1731 {
1732 int i;
1733 for (i = 0; i < 5; ++i) {
1734 x = 50;
1735 }
1736 }
1737 '''
1738 ps2 = self.parse(s2)
1739 self.assert_num_klass_nodes(ps2, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001740 # here there are 3 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001741 # a ref in the visitor
1742 #
1743 self.assert_num_ID_refs(ps2, 'i', 3)
Eli Bendersky4476d092012-12-25 14:07:57 -08001744
eli.bendersky145890d2010-10-29 12:02:32 +02001745 s3 = r'''
1746 void x(void)
1747 {
1748 for (int i = 0; i < 5; ++i) {
1749 x = 50;
1750 }
1751 }
1752 '''
1753 ps3 = self.parse(s3)
eli.bendersky145890d2010-10-29 12:02:32 +02001754 self.assert_num_klass_nodes(ps3, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001755 # here there are 2 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001756 # a ref in the visitor
1757 #
1758 self.assert_num_ID_refs(ps3, 'i', 2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001759
Eli Bendersky4476d092012-12-25 14:07:57 -08001760 s4 = r'''
1761 void x(void) {
1762 for (int i = 0;;)
1763 i;
1764 }
1765 '''
1766 ps4 = self.parse(s4)
1767 self.assert_num_ID_refs(ps4, 'i', 1)
1768
Eli Benderskyd0973782012-01-19 08:09:33 +02001769 def _open_c_file(self, name):
1770 """ Find a c file by name, taking into account the current dir can be
1771 in a couple of typical places
1772 """
Stefano Riveraebaf5922013-08-08 09:45:26 +02001773 testdir = os.path.dirname(__file__)
1774 name = os.path.join(testdir, 'c_files', name)
1775 assert os.path.exists(name)
Jon Dufresne13224c12018-06-26 13:48:31 -07001776 return io.open(name)
Eli Benderskyd0973782012-01-19 08:09:33 +02001777
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001778 def test_whole_file(self):
1779 # See how pycparser handles a whole, real C file.
1780 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001781 with self._open_c_file('memmgr_with_h.c') as f:
1782 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001783 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001784
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001785 self.assert_num_klass_nodes(p, FuncDef, 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001786
1787 # each FuncDef also has a FuncDecl. 4 declarations
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001788 # + 5 definitions, overall 9
1789 self.assert_num_klass_nodes(p, FuncDecl, 9)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001790
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001791 self.assert_num_klass_nodes(p, Typedef, 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001792
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001793 self.assertEqual(p.ext[4].coord.line, 88)
1794 self.assertEqual(p.ext[4].coord.file, "./memmgr.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001795
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001796 self.assertEqual(p.ext[6].coord.line, 10)
1797 self.assertEqual(p.ext[6].coord.file, "memmgr.c")
1798
1799 def test_whole_file_with_stdio(self):
1800 # Parse a whole file with stdio.h included by cpp
1801 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001802 with self._open_c_file('cppd_with_stdio_h.c') as f:
1803 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001804 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001805
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001806 self.assertIsInstance(p.ext[0], Typedef)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001807 self.assertEqual(p.ext[0].coord.line, 213)
Ville Skyttä2129f5f2017-03-05 04:52:22 +02001808 self.assertEqual(p.ext[0].coord.file, r"D:\eli\cpp_stuff\libc_include/stddef.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001809
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001810 self.assertIsInstance(p.ext[-1], FuncDef)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001811 self.assertEqual(p.ext[-1].coord.line, 15)
1812 self.assertEqual(p.ext[-1].coord.file, "example_c_file.c")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001813
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001814 self.assertIsInstance(p.ext[-8], Typedef)
1815 self.assertIsInstance(p.ext[-8].type, TypeDecl)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001816 self.assertEqual(p.ext[-8].name, 'cookie_io_functions_t')
eli.bendersky85d2e732011-05-20 19:47:26 +03001817
1818
1819class TestCParser_typenames(TestCParser_base):
1820 """ Test issues related to the typedef-name problem.
1821 """
1822 def test_innerscope_typedef(self):
1823 # should fail since TT is not a type in bar
1824 s1 = r'''
1825 void foo() {
1826 typedef char TT;
1827 TT x;
1828 }
1829 void bar() {
1830 TT y;
1831 }
1832 '''
1833 self.assertRaises(ParseError, self.parse, s1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001834
eli.bendersky85d2e732011-05-20 19:47:26 +03001835 # should succeed since TT is not a type in bar
1836 s2 = r'''
1837 void foo() {
1838 typedef char TT;
1839 TT x;
1840 }
1841 void bar() {
1842 unsigned TT;
1843 }
1844 '''
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001845 self.assertIsInstance(self.parse(s2), FileAST)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001846
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -05001847 def test_ambiguous_parameters(self):
1848 # From ISO/IEC 9899:TC2, 6.7.5.3.11:
1849 # "If, in a parameter declaration, an identifier can be treated either
1850 # as a typedef name or as a parameter name, it shall be taken as a
1851 # typedef name."
1852
1853 # foo takes an int named aa
1854 # bar takes a function taking a TT
1855 s1 = r'''
1856 typedef char TT;
1857 int foo(int (aa));
1858 int bar(int (TT));
1859 '''
1860 s1_ast = self.parse(s1)
1861 self.assertEqual(expand_decl(s1_ast.ext[1].type.args.params[0]),
1862 ['Decl', 'aa', ['TypeDecl', ['IdentifierType', ['int']]]])
1863 self.assertEqual(expand_decl(s1_ast.ext[2].type.args.params[0]),
1864 ['Typename', ['FuncDecl',
1865 [['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]],
1866 ['TypeDecl', ['IdentifierType', ['int']]]]])
1867
1868 # foo takes a function taking a char
1869 # bar takes a function taking a function taking a char
1870 s2 = r'''
1871 typedef char TT;
1872 int foo(int (aa (char)));
1873 int bar(int (TT (char)));
1874 '''
1875 s2_ast = self.parse(s2)
1876 self.assertEqual(expand_decl(s2_ast.ext[1].type.args.params[0]),
1877 ['Decl', 'aa', ['FuncDecl',
1878 [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
1879 ['TypeDecl', ['IdentifierType', ['int']]]]])
1880 self.assertEqual(expand_decl(s2_ast.ext[2].type.args.params[0]),
1881 ['Typename', ['FuncDecl',
1882 [['Typename', ['FuncDecl',
1883 [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
1884 ['TypeDecl', ['IdentifierType', ['TT']]]]]],
1885 ['TypeDecl', ['IdentifierType', ['int']]]]])
1886
1887
1888 # foo takes an int array named aa
1889 # bar takes a function taking a TT array
1890 s3 = r'''
1891 typedef char TT;
1892 int foo(int (aa[]));
1893 int bar(int (TT[]));
1894 '''
1895 s3_ast = self.parse(s3)
1896 self.assertEqual(expand_decl(s3_ast.ext[1].type.args.params[0]),
1897 ['Decl', 'aa', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['int']]]]])
1898 self.assertEqual(expand_decl(s3_ast.ext[2].type.args.params[0]),
1899 ['Typename', ['FuncDecl',
1900 [['Typename', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['TT']]]]]],
1901 ['TypeDecl', ['IdentifierType', ['int']]]]])
1902
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001903 def test_innerscope_reuse_typedef_name(self):
1904 # identifiers can be reused in inner scopes; the original should be
1905 # restored at the end of the block
1906 s1 = r'''
1907 typedef char TT;
1908 void foo(void) {
1909 unsigned TT;
1910 TT = 10;
1911 }
1912 TT x = 5;
1913 '''
1914 s1_ast = self.parse(s1)
1915 self.assertEqual(expand_decl(s1_ast.ext[1].body.block_items[0]),
1916 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
Eli Bendersky3877c4c2013-07-13 06:54:04 -07001917 self.assertEqual(expand_decl(s1_ast.ext[2]),
1918 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['TT']]]])
eli.bendersky85d2e732011-05-20 19:47:26 +03001919
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001920 # this should be recognized even with an initializer
1921 s2 = r'''
1922 typedef char TT;
1923 void foo(void) {
1924 unsigned TT = 10;
1925 }
1926 '''
1927 s2_ast = self.parse(s2)
1928 self.assertEqual(expand_decl(s2_ast.ext[1].body.block_items[0]),
1929 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1930
1931 # before the second local variable, TT is a type; after, it's a
1932 # variable
1933 s3 = r'''
1934 typedef char TT;
1935 void foo(void) {
1936 TT tt = sizeof(TT);
1937 unsigned TT = 10;
1938 }
1939 '''
1940 s3_ast = self.parse(s3)
1941 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[0]),
1942 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['TT']]]])
1943 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[1]),
1944 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1945
1946 # a variable and its type can even share the same name
1947 s4 = r'''
1948 typedef char TT;
1949 void foo(void) {
1950 TT TT = sizeof(TT);
1951 unsigned uu = TT * 2;
1952 }
1953 '''
1954 s4_ast = self.parse(s4)
1955 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[0]),
1956 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['TT']]]])
1957 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[1]),
1958 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1959
1960 # ensure an error is raised if a type, redeclared as a variable, is
1961 # used as a type
1962 s5 = r'''
1963 typedef char TT;
1964 void foo(void) {
1965 unsigned TT = 10;
1966 TT erroneous = 20;
1967 }
1968 '''
1969 self.assertRaises(ParseError, self.parse, s5)
1970
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -05001971 # reusing a type name should work with multiple declarators
1972 s6 = r'''
1973 typedef char TT;
1974 void foo(void) {
1975 unsigned TT, uu;
1976 }
1977 '''
1978 s6_ast = self.parse(s6)
1979 items = s6_ast.ext[1].body.block_items
1980 self.assertEqual(expand_decl(items[0]),
1981 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1982 self.assertEqual(expand_decl(items[1]),
1983 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1984
1985 # reusing a type name should work after a pointer
1986 s7 = r'''
1987 typedef char TT;
1988 void foo(void) {
1989 unsigned * TT;
1990 }
1991 '''
1992 s7_ast = self.parse(s7)
1993 items = s7_ast.ext[1].body.block_items
1994 self.assertEqual(expand_decl(items[0]),
1995 ['Decl', 'TT', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
1996
1997 # redefine a name in the middle of a multi-declarator declaration
1998 s8 = r'''
1999 typedef char TT;
2000 void foo(void) {
2001 int tt = sizeof(TT), TT, uu = sizeof(TT);
2002 int uu = sizeof(tt);
2003 }
2004 '''
2005 s8_ast = self.parse(s8)
2006 items = s8_ast.ext[1].body.block_items
2007 self.assertEqual(expand_decl(items[0]),
2008 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['int']]]])
2009 self.assertEqual(expand_decl(items[1]),
2010 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['int']]]])
2011 self.assertEqual(expand_decl(items[2]),
2012 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['int']]]])
2013
2014 # Don't test this until we have support for it
2015 # self.assertEqual(expand_init(items[0].init),
2016 # ['UnaryOp', 'sizeof', ['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]])
2017 # self.assertEqual(expand_init(items[2].init),
2018 # ['UnaryOp', 'sizeof', ['ID', 'TT']])
2019
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002020 def test_parameter_reuse_typedef_name(self):
2021 # identifiers can be reused as parameter names; parameter name scope
2022 # begins and ends with the function body; it's important that TT is
Eli Bendersky4d969b32013-07-13 06:07:07 -07002023 # used immediately before the LBRACE or after the RBRACE, to test
2024 # a corner case
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002025 s1 = r'''
2026 typedef char TT;
2027 void foo(unsigned TT, TT bar) {
2028 TT = 10;
2029 }
2030 TT x = 5;
2031 '''
2032 s1_ast = self.parse(s1)
2033 self.assertEqual(expand_decl(s1_ast.ext[1].decl),
2034 ['Decl', 'foo',
2035 ['FuncDecl',
2036 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
2037 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
2038 ['TypeDecl', ['IdentifierType', ['void']]]]])
2039
2040 # the scope of a parameter name in a function declaration ends at the
2041 # end of the declaration...so it is effectively never used; it's
2042 # important that TT is used immediately after the declaration, to
2043 # test a corner case
2044 s2 = r'''
2045 typedef char TT;
2046 void foo(unsigned TT, TT bar);
2047 TT x = 5;
2048 '''
2049 s2_ast = self.parse(s2)
2050 self.assertEqual(expand_decl(s2_ast.ext[1]),
2051 ['Decl', 'foo',
2052 ['FuncDecl',
2053 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
2054 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
2055 ['TypeDecl', ['IdentifierType', ['void']]]]])
2056
2057 # ensure an error is raised if a type, redeclared as a parameter, is
2058 # used as a type
2059 s3 = r'''
2060 typedef char TT;
2061 void foo(unsigned TT, TT bar) {
2062 TT erroneous = 20;
2063 }
2064 '''
2065 self.assertRaises(ParseError, self.parse, s3)
2066
2067 def test_nested_function_decls(self):
2068 # parameter names of nested function declarations must not escape into
2069 # the top-level function _definition's_ scope; the following must
2070 # succeed because TT is still a typedef inside foo's body
2071 s1 = r'''
2072 typedef char TT;
2073 void foo(unsigned bar(int TT)) {
2074 TT x = 10;
2075 }
2076 '''
Jon Dufresnee8afcc92018-06-26 13:49:06 -07002077 self.assertIsInstance(self.parse(s1), FileAST)
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002078
2079 def test_samescope_reuse_name(self):
2080 # a typedef name cannot be reused as an object name in the same scope
2081 s1 = r'''
2082 typedef char TT;
2083 char TT = 5;
2084 '''
2085 self.assertRaises(ParseError, self.parse, s1)
2086
2087 # ...and vice-versa
2088 s2 = r'''
2089 char TT = 5;
2090 typedef char TT;
2091 '''
2092 self.assertRaises(ParseError, self.parse, s2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002093
Julian Hammerdb9f2da2015-10-12 15:52:12 +02002094
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002095if __name__ == '__main__':
2096 #~ suite = unittest.TestLoader().loadTestsFromNames(
2097 #~ ['test_c_parser.TestCParser_fundamentals.test_typedef'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08002098
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002099 #~ unittest.TextTestRunner(verbosity=2).run(suite)
2100 unittest.main()