Пример #1
0
def format_two_column(code1, code2, output):
    '''Format codes in two column.'''
    input1 = StringIO(code1)
    input2 = StringIO(code2)
    column1 = []
    column2 = []
    longest = 0
    while True:
        line1 = input1.readline()
        line2 = input2.readline()
        if not line1 and not line2:
            break
        line1 = line1.rstrip()
        line2 = line2.rstrip()
        longest = max(longest, len(line1))
        if line1:
            column1.append(line1)
        if line2:
            column2.append(line2)
    fmt = '{0:<%d} | {1}\n' % longest
    i = 0
    while i < len(column1) or i < len(column2):
        if i < len(column1):
            line1 = column1[i]
        else:
            line1 = ''
        if i < len(column2):
            line2 = column2[i]
        else:
            line2 = ''
        output.write(fmt.format(line1, line2))
        i += 1
Пример #2
0
 def run_test(self, c_expr, answer, py_expr=None):
     parser = Parser()
     expr = parser.parse(c_expr)
     self.compare_expr(expr, answer)
     output = StringIO()
     expr.translate(output)
     self.assertEqual(output.getvalue(), py_expr or c_expr)
Пример #3
0
    def run_test(self, c_code, python_code,
                 filename='input.c', args=None, config=None,
                 enable_cpp=False,
                 assert_layout=False):
        '''Generate Python code from C code and compare it to the answer.'''
        CodeGen.ENABLE_CPP = enable_cpp
        CodeGen.ASSERT_LAYOUT = assert_layout
        cbgen = CtypesBindingGenerator()
        if config is not None:
            import yaml
            config = yaml.load(config)
            cbgen.config(config)
        if isinstance(c_code, str):
            c_src = StringIO(c_code)
            cbgen.parse(filename, contents=c_src, args=args)
        else:
            for filename, code in c_code:
                c_src = StringIO(code)
                cbgen.parse(filename, contents=c_src, args=args)
        output = StringIO()
        if config and 'preamble' in config:
            cbgen.generate_preamble('cbind', None, output)
        cbgen.generate(output)
        gen_code = output.getvalue()

        error_message = prepare_error_message(
            python_code, gen_code, tunits=cbgen.get_translation_units())
        self.assertTrue(compare_codes(gen_code, python_code), error_message)
        code = compile(gen_code, 'output.py', 'exec')
        if assert_layout:
            # Test if layout assertions are true
            exec(code, self.get_env())  # pylint: disable=W0122
 def run_test(self, c_expr, answer, py_expr=None):
     parser = Parser()
     expr = parser.parse(c_expr)
     self.compare_expr(expr, answer)
     output = StringIO()
     expr.translate(output)
     self.assertEqual(output.getvalue(), py_expr or c_expr)
Пример #5
0
 def _clang_const_int(cls, c_path, args, symbols):
     '''Run clang on constant integers.'''
     c_abs_path = os.path.abspath(c_path)
     src = StringIO()
     src.write('#include "%s"\n' % c_abs_path)
     src.write('enum {\n')
     for symbol in symbols:
         src.write('%s_%s = %s,\n' % (_MAGIC, symbol.name, symbol.body))
     src.write('};\n')
     syntax_tree = SyntaxTree.parse('input.c', contents=src.getvalue(),
                                    args=args)
     return cls._find_enums(syntax_tree)
Пример #6
0
    def run_test(self, c_code, python_code, macro_int=None, stderr=None):
        '''Generate Python code from C code and compare it to the answer.'''
        with os.fdopen(self.header_fd, 'w') as header_file:
            header_file.write(c_code)

        mcgen = MacroGenerator(macro_int=macro_int)
        mcgen.parse(self.header_path, None, stderr=stderr)
        output = StringIO()
        mcgen.generate(output)
        gen_code = output.getvalue()

        error_message = prepare_error_message(python_code, gen_code)
        self.assertTrue(compare_codes(gen_code, python_code), error_message)
Пример #7
0
    def run_test(self, c_code, python_code, macro_int=None, stderr=None):
        '''Generate Python code from C code and compare it to the answer.'''
        with os.fdopen(self.header_fd, 'w') as header_file:
            header_file.write(c_code)

        mcgen = MacroGenerator(macro_int=macro_int)
        mcgen.parse(self.header_path, None, stderr=stderr)
        output = StringIO()
        mcgen.generate(output)
        gen_code = output.getvalue()

        error_message = prepare_error_message(python_code, gen_code)
        self.assertTrue(compare_codes(gen_code, python_code), error_message)
Пример #8
0
def prepare_error_message(python_code, gen_code, tunits=None):
    '''Generate standard error message.'''
    output = StringIO()
    output.write('Codes are not equivalent:\n')
    format_two_column(python_code, gen_code, output)
    if tunits:
        output.write('\n')
        format_ast(tunits, output)
    return output.getvalue()
Пример #9
0
def format_two_column(code1, code2, output):
    '''Format codes in two column.'''
    input1 = StringIO(code1)
    input2 = StringIO(code2)
    column1 = []
    column2 = []
    longest = 0
    while True:
        line1 = input1.readline()
        line2 = input2.readline()
        if not line1 and not line2:
            break
        line1 = line1.rstrip()
        line2 = line2.rstrip()
        longest = max(longest, len(line1))
        if line1:
            column1.append(line1)
        if line2:
            column2.append(line2)
    fmt = '{0:<%d} | {1}\n' % longest
    i = 0
    while i < len(column1) or i < len(column2):
        if i < len(column1):
            line1 = column1[i]
        else:
            line1 = ''
        if i < len(column2):
            line2 = column2[i]
        else:
            line2 = ''
        output.write(fmt.format(line1, line2))
        i += 1
Пример #10
0
def prepare_error_message(python_code, gen_code, tunits=None):
    '''Generate standard error message.'''
    output = StringIO()
    output.write('Codes are not equivalent:\n')
    format_two_column(python_code, gen_code, output)
    if tunits:
        output.write('\n')
        format_ast(tunits, output)
    return output.getvalue()
Пример #11
0
    def run_test(self,
                 c_code,
                 python_code,
                 filename='input.c',
                 args=None,
                 config=None,
                 enable_cpp=False,
                 assert_layout=False):
        '''Generate Python code from C code and compare it to the answer.'''
        CodeGen.ENABLE_CPP = enable_cpp
        CodeGen.ASSERT_LAYOUT = assert_layout
        cbgen = CtypesBindingGenerator()
        if config is not None:
            import yaml
            config = yaml.load(config)
            cbgen.config(config)
        if isinstance(c_code, str):
            c_src = StringIO(c_code)
            cbgen.parse(filename, contents=c_src, args=args)
        else:
            for filename, code in c_code:
                c_src = StringIO(code)
                cbgen.parse(filename, contents=c_src, args=args)
        output = StringIO()
        if config and 'preamble' in config:
            cbgen.generate_preamble('cbind', None, output)
        cbgen.generate(output)
        gen_code = output.getvalue()

        error_message = prepare_error_message(
            python_code, gen_code, tunits=cbgen.get_translation_units())
        self.assertTrue(compare_codes(gen_code, python_code), error_message)
        code = compile(gen_code, 'output.py', 'exec')
        if assert_layout:
            # Test if layout assertions are true
            exec(code, self.get_env())  # pylint: disable=W0122
Пример #12
0
 def run_test(self, cpp_code, symbols, args=None):
     '''Test mangler.'''
     cbgen = CtypesBindingGenerator()
     cpp_src = StringIO(cpp_code)
     cbgen.parse('input.cpp', contents=cpp_src, args=args)
     root = cbgen.syntax_tree_forest[0]
     symbol_table = self._make_symbol_table(symbols, root)
     errmsg = StringIO()
     errmsg.write('In comparing mangled names:\n')
     for blob in symbol_table:
         symbol = blob['symbol']
         mangled_name = blob['mangled_name']
         output_name = blob['output_name']
         if mangled_name != output_name:
             errmsg.write(
                 'Mangling symbol %s: %s != %s\n' %
                 (repr(symbol), repr(mangled_name), repr(output_name)))
     format_ast([root.translation_unit], errmsg)
     errmsg = errmsg.getvalue()
     for blob in symbol_table:
         mangled_name = blob['mangled_name']
         output_name = blob['output_name']
         self.assertEqual(mangled_name, output_name, errmsg)
Пример #13
0
 def process(cls, c_path, clang_args, stderr):
     '''Run clang preprocessor and return an iterator of MacroSymbol.'''
     candidates = cls._list_candidates(c_path)
     # Generate C source and feed it to preprocessor
     source = StringIO()
     source.write('#include "%s"\n' % c_path)
     for symbol in candidates.values():
         if symbol.args is not None:
             args_list = '(%s)' % ', '.join(symbol.args)
         else:
             args_list = ''
         source.write('%s_%s %s%s\n' %
                      (_MAGIC, symbol.name, symbol.name, args_list))
     clang = ['clang', '-E', '-x', 'c', '-']
     clang.extend(clang_args or ())
     proc = subprocess.Popen(clang,
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stderr=stderr)
     macros = decode_str(proc.communicate(source.getvalue().encode())[0])
     if proc.returncode != 0:
         raise MacroException('clang preprocessor returns %d' %
                              proc.returncode)
     macros = StringIO(macros)
     # Parse preprocessor output
     for define_line in macros:
         define_line = define_line.lstrip()  # remove leading spaces
         if not define_line.startswith(_MAGIC):
             continue
         sep = define_line.find(' ')
         name = define_line[len(_MAGIC) + 1:sep]  # sep == -1 is okay here!
         symbol = candidates[name]
         if sep != -1:
             body = define_line[sep:].strip()
         else:
             body = None
         yield cls(name=symbol.name, args=symbol.args, body=body, expr=None)
Пример #14
0
 def process(cls, c_path, clang_args, stderr):
     '''Run clang preprocessor and return an iterator of MacroSymbol.'''
     candidates = cls._list_candidates(c_path)
     # Generate C source and feed it to preprocessor
     source = StringIO()
     source.write('#include "%s"\n' % c_path)
     for symbol in candidates.values():
         if symbol.args is not None:
             args_list = '(%s)' % ', '.join(symbol.args)
         else:
             args_list = ''
         source.write('%s_%s %s%s\n' %
                      (_MAGIC, symbol.name, symbol.name, args_list))
     clang = ['clang', '-E', '-x', 'c', '-']
     clang.extend(clang_args or ())
     proc = subprocess.Popen(clang,
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stderr=stderr)
     macros = decode_str(proc.communicate(source.getvalue().encode())[0])
     if proc.returncode != 0:
         raise MacroException('clang preprocessor returns %d' %
                              proc.returncode)
     macros = StringIO(macros)
     # Parse preprocessor output
     for define_line in macros:
         define_line = define_line.lstrip()  # remove leading spaces
         if not define_line.startswith(_MAGIC):
             continue
         sep = define_line.find(' ')
         name = define_line[len(_MAGIC) + 1:sep]  # sep == -1 is okay here!
         symbol = candidates[name]
         if sep != -1:
             body = define_line[sep:].strip()
         else:
             body = None
         yield cls(name=symbol.name, args=symbol.args, body=body, expr=None)
Пример #15
0
 def run_test(self, cpp_code, symbols, args=None):
     '''Test mangler.'''
     cbgen = CtypesBindingGenerator()
     cpp_src = StringIO(cpp_code)
     cbgen.parse('input.cpp', contents=cpp_src, args=args)
     root = cbgen.syntax_tree_forest[0]
     symbol_table = self._make_symbol_table(symbols, root)
     errmsg = StringIO()
     errmsg.write('In comparing mangled names:\n')
     for blob in symbol_table:
         symbol = blob['symbol']
         mangled_name = blob['mangled_name']
         output_name = blob['output_name']
         if mangled_name != output_name:
             errmsg.write('Mangling symbol %s: %s != %s\n' %
                          (repr(symbol),
                           repr(mangled_name),
                           repr(output_name)))
     format_ast([root.translation_unit], errmsg)
     errmsg = errmsg.getvalue()
     for blob in symbol_table:
         mangled_name = blob['mangled_name']
         output_name = blob['output_name']
         self.assertEqual(mangled_name, output_name, errmsg)
Пример #16
0
 def run_token_translate(self, kind, spelling, answer):
     output = StringIO()
     Token(kind, spelling).translate(output)
     self.assertEqual(output.getvalue(), answer)
 def run_token_translate(self, kind, spelling, answer):
     output = StringIO()
     Token(kind, spelling).translate(output)
     self.assertEqual(output.getvalue(), answer)
Пример #18
0
 def __init__(self):
     self.bufs = [StringIO()]
     self.substitutions = {}
     self.seq_id = 0
Пример #19
0
 def begin_substitution(self):
     '''Begin substitution session.'''
     self.bufs.append(StringIO())
Пример #20
0
 def _clang_const_int(cls, c_path, args, symbols):
     '''Run clang on constant integers.'''
     c_abs_path = os.path.abspath(c_path)
     src = StringIO()
     src.write('#include "%s"\n' % c_abs_path)
     src.write('enum {\n')
     for symbol in symbols:
         src.write('%s_%s = %s,\n' % (_MAGIC, symbol.name, symbol.body))
     src.write('};\n')
     syntax_tree = SyntaxTree.parse('input.c',
                                    contents=src.getvalue(),
                                    args=args)
     return cls._find_enums(syntax_tree)
Пример #21
0
 def get_tokens(code):
     '''Return tokens important to comparison.'''
     tokens = tokenize.generate_tokens(StringIO(code).readline)
     for token_type, token_str, _, _, _ in tokens:
         if token_type not in unimportant_token_types:
             yield token_str