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 _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, 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)