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
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)
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 _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)
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)
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()
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)
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)
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)
def run_token_translate(self, kind, spelling, answer): output = StringIO() Token(kind, spelling).translate(output) self.assertEqual(output.getvalue(), answer)
def __init__(self): self.bufs = [StringIO()] self.substitutions = {} self.seq_id = 0
def begin_substitution(self): '''Begin substitution session.''' self.bufs.append(StringIO())
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