eli.bendersky | 8e6c586 | 2011-05-20 12:35:08 +0300 | [diff] [blame] | 1 | #!/usr/bin/env python
|
| 2 |
|
| 3 | import sys
|
| 4 | import unittest
|
| 5 |
|
| 6 | sys.path.insert(0, '..') # for c-to-c.py
|
| 7 | sys.path.insert(0, '../..') # for pycparser libs
|
| 8 |
|
| 9 | from pycparser import c_parser
|
| 10 | c2cmodule = __import__('c-to-c')
|
| 11 |
|
| 12 | _c_parser = c_parser.CParser(
|
| 13 | lex_optimize=False,
|
| 14 | yacc_debug=True,
|
| 15 | yacc_optimize=False,
|
| 16 | yacctab='yacctab')
|
| 17 |
|
| 18 |
|
| 19 | def compare_asts(ast1, ast2): |
| 20 | if type(ast1) != type(ast2):
|
| 21 | return False
|
| 22 | for attr in ast1.attr_names:
|
| 23 | if getattr(ast1, attr) != getattr(ast2, attr):
|
| 24 | return False
|
| 25 | for i, c1 in enumerate(ast1.children()):
|
| 26 | if compare_asts(c1, ast2.children()[i]) == False:
|
| 27 | return False
|
| 28 | return True
|
| 29 |
|
| 30 |
|
| 31 | def parse_to_ast(src): |
| 32 | return _c_parser.parse(src)
|
| 33 |
|
| 34 |
|
| 35 | class TestCtoC(unittest.TestCase):
|
| 36 | def _run_c_to_c(self, src): |
| 37 | ast = parse_to_ast(src)
|
| 38 | generator = c2cmodule.CGenerator()
|
| 39 | return generator.visit(ast)
|
| 40 |
|
| 41 | def _assert_ctoc_correct(self, src): |
| 42 | """ Checks that the c2c translation was correct by parsing the code
|
| 43 | generated by c2c for src and comparing the AST with the original
|
| 44 | AST. |
| 45 | """
|
| 46 | src2 = self._run_c_to_c(src)
|
| 47 | self.assertTrue(compare_asts(parse_to_ast(src), parse_to_ast(src2)), src2)
|
| 48 |
|
| 49 | def test_trivial_decls(self): |
| 50 | self._assert_ctoc_correct('int a;')
|
| 51 | self._assert_ctoc_correct('int b, a;')
|
| 52 | self._assert_ctoc_correct('int c, b, a;')
|
| 53 |
|
| 54 | def test_complex_decls(self): |
| 55 | self._assert_ctoc_correct('int** (*a)(void);')
|
| 56 | self._assert_ctoc_correct('int** (*a)(void*, int);')
|
| 57 |
|
| 58 | def test_casts(self): |
| 59 | self._assert_ctoc_correct(r'''
|
| 60 | int main() {
|
| 61 | int b = (int) f;
|
| 62 | int c = (int*) f;
|
| 63 | }''')
|
| 64 |
|
| 65 | def test_initlist(self):
|
| 66 | self._assert_ctoc_correct('int arr[] = {1, 2, 3};')
|
| 67 |
|
eli.bendersky | d4a9975 | 2011-05-26 07:04:19 +0300 | [diff] [blame] | 68 | def test_exprs(self): |
| 69 | self._assert_ctoc_correct('''
|
| 70 | int main(void)
|
| 71 | {
|
| 72 | int a;
|
| 73 | int b = a++;
|
| 74 | int c = ++a;
|
| 75 | int d = a--;
|
| 76 | int e = --a;
|
| 77 | }''')
|
| 78 |
|
eli.bendersky | 8e6c586 | 2011-05-20 12:35:08 +0300 | [diff] [blame] | 79 | def test_statements(self): |
| 80 | self._assert_ctoc_correct(r'''
|
| 81 | int main() {
|
| 82 | int a;
|
| 83 | a = 5;
|
eli.bendersky | 91c0aa3 | 2011-10-16 05:50:43 +0200 | [diff] [blame] | 84 | ;
|
eli.bendersky | 8e6c586 | 2011-05-20 12:35:08 +0300 | [diff] [blame] | 85 | return a;
|
| 86 | }''')
|
eli.bendersky | cad1cfd | 2011-05-26 06:56:27 +0300 | [diff] [blame] | 87 |
|
eli.bendersky | 1bd6c17 | 2011-07-16 06:43:20 +0300 | [diff] [blame] | 88 | def test_struct_decl(self): |
| 89 | self._assert_ctoc_correct(r'''
|
| 90 | typedef struct node_t {
|
| 91 | struct node_t* next;
|
| 92 | int data;
|
| 93 | } node;
|
| 94 | ''')
|
| 95 |
|
eli.bendersky | cad1cfd | 2011-05-26 06:56:27 +0300 | [diff] [blame] | 96 | def test_issue36(self): |
| 97 | self._assert_ctoc_correct(r'''
|
| 98 | int main() {
|
| 99 | }''')
|
eli.bendersky | 8e6c586 | 2011-05-20 12:35:08 +0300 | [diff] [blame] | 100 |
|
eli.bendersky | 8348a9d | 2011-05-26 07:01:43 +0300 | [diff] [blame] | 101 | def test_issue37(self):
|
| 102 | self._assert_ctoc_correct(r'''
|
| 103 | int main(void)
|
| 104 | {
|
| 105 | unsigned size;
|
| 106 | size = sizeof(size);
|
| 107 | return 0;
|
| 108 | }''')
|
| 109 |
|
eli.bendersky | 8e6c586 | 2011-05-20 12:35:08 +0300 | [diff] [blame] | 110 |
|
| 111 |
|
| 112 | if __name__ == "__main__":
|
| 113 | unittest.main()
|