#!/usr/bin/env python | |
import sys | |
import unittest | |
sys.path.insert(0, '..') # for c-to-c.py | |
sys.path.insert(0, '../..') # for pycparser libs | |
from pycparser import c_parser | |
c2cmodule = __import__('c-to-c') | |
_c_parser = c_parser.CParser( | |
lex_optimize=False, | |
yacc_debug=True, | |
yacc_optimize=False, | |
yacctab='yacctab') | |
def compare_asts(ast1, ast2): | |
if type(ast1) != type(ast2): | |
return False | |
for attr in ast1.attr_names: | |
if getattr(ast1, attr) != getattr(ast2, attr): | |
return False | |
for i, c1 in enumerate(ast1.children()): | |
if compare_asts(c1, ast2.children()[i]) == False: | |
return False | |
return True | |
def parse_to_ast(src): | |
return _c_parser.parse(src) | |
class TestCtoC(unittest.TestCase): | |
def _run_c_to_c(self, src): | |
ast = parse_to_ast(src) | |
generator = c2cmodule.CGenerator() | |
return generator.visit(ast) | |
def _assert_ctoc_correct(self, src): | |
""" Checks that the c2c translation was correct by parsing the code | |
generated by c2c for src and comparing the AST with the original | |
AST. | |
""" | |
src2 = self._run_c_to_c(src) | |
self.assertTrue(compare_asts(parse_to_ast(src), parse_to_ast(src2)), src2) | |
def test_trivial_decls(self): | |
self._assert_ctoc_correct('int a;') | |
self._assert_ctoc_correct('int b, a;') | |
self._assert_ctoc_correct('int c, b, a;') | |
def test_complex_decls(self): | |
self._assert_ctoc_correct('int** (*a)(void);') | |
self._assert_ctoc_correct('int** (*a)(void*, int);') | |
def test_casts(self): | |
self._assert_ctoc_correct(r''' | |
int main() { | |
int b = (int) f; | |
int c = (int*) f; | |
}''') | |
def test_initlist(self): | |
self._assert_ctoc_correct('int arr[] = {1, 2, 3};') | |
def test_statements(self): | |
self._assert_ctoc_correct(r''' | |
int main() { | |
int a; | |
a = 5; | |
return a; | |
}''') | |
def test_issue36(self): | |
self._assert_ctoc_correct(r''' | |
int main() { | |
}''') | |
if __name__ == "__main__": | |
unittest.main() |