[pygccxml-commit] SF.net SVN: pygccxml:[1552] pygccxml_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2009-01-08 21:16:21
|
Revision: 1552 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1552&view=rev Author: roman_yakovenko Date: 2009-01-08 21:16:13 +0000 (Thu, 08 Jan 2009) Log Message: ----------- binary parser, nm based, was fixed Modified Paths: -------------- pygccxml_dev/pygccxml/binary_parsers/parsers.py pygccxml_dev/pygccxml/binary_parsers/undname.py pygccxml_dev/unittests/undname_creator_tester.py Modified: pygccxml_dev/pygccxml/binary_parsers/parsers.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/parsers.py 2009-01-08 12:31:59 UTC (rev 1551) +++ pygccxml_dev/pygccxml/binary_parsers/parsers.py 2009-01-08 21:16:13 UTC (rev 1552) @@ -109,7 +109,7 @@ self.__formated_decls = {} self.undname_creator = undname.undname_creator_t() - formatter = lambda decl: self.undname_creator.format_decl( f, hint ) + formatter = lambda decl: self.undname_creator.format_decl( decl, hint ) for f in self.global_ns.calldefs( allow_empty=True, recursive=True ): self.__formated_decls[ formatter( f ) ] = f @@ -208,7 +208,7 @@ return blob, decl -class so_file_parser_t( libparser_t ): +class so_file_parser_t( formated_mapping_parser_t ): nm_executable = 'nm' #numeric-sort used for mapping between mangled and unmangled name cmd_mangled = '%(nm)s --extern-only --dynamic --defined-only --numeric-sort %(lib)s' @@ -216,15 +216,8 @@ entry = re.compile( r'^(?P<address>(?:\w|\d)+)\s\w\s(?P<symbol>.+)$' ) def __init__( self, global_ns, binary_file ): - libparser_t.__init__( self, global_ns, binary_file ) - self.__mangled2decls = {} + formated_mapping_parser_t.__init__( self, global_ns, binary_file, 'nm' ) - for f in self.global_ns.calldefs( allow_empty=True, recursive=True ): - self.__mangled2decls[ f.mangled ] = f - - for v in self.global_ns.variables( allow_empty=True, recursive=True ): - self.__mangled2decls[ v.mangled ] = v - def __execute_nm( self, cmd ): process = subprocess.Popen( args=cmd , shell=True @@ -261,15 +254,32 @@ result = [] for address, blob in mangled_smbls.iteritems(): if address in demangled_smbls: - result.append( blob, demangled_smbls[address] ) + result.append( ( blob, demangled_smbls[address] ) ) return result def merge( self, smbl ): decorated, undecorated = smbl - if undecorated not in self.formated_decls: - return None, None - decl = self.formated_decls[ undecorated ] - return decorated, decl + if decorated == undecorated: + #we deal with C function ( or may be we deal with variable?, I have to check the latest + try: + f = self.global_ns.free_fun( decorated ) + #TODO create usecase, where C function uses different calling convention + f.calling_convention = CCTS.CDECL + return decorated, f + except self.global_ns.declaration_not_found_t: + v = self.global_ns.vars( decorated, allow_empty=True, recursive=False ) + if v: + return decorated, v[0] + else: + return None, None + else: + undecorated_normalized = self.undname_creator.normalize_undecorated( undecorated ) + if undecorated_normalized not in self.formated_decls: + return None, None + decl = self.formated_decls[ undecorated_normalized ] + if isinstance( decl, declarations.calldef_t ): + decl.calling_convention = CCTS.extract( undecorated, CCTS.CDECL ) + return decorated, decl def merge_information( global_ns, fname, runs_under_unittest=False ): """high level function - select the appropriate binary file parser and integrates Modified: pygccxml_dev/pygccxml/binary_parsers/undname.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/undname.py 2009-01-08 12:31:59 UTC (rev 1551) +++ pygccxml_dev/pygccxml/binary_parsers/undname.py 2009-01-08 21:16:13 UTC (rev 1552) @@ -82,9 +82,11 @@ class undname_creator_t: def __init__( self ): - import ctypes.wintypes - self.__undname = ctypes.windll.dbghelp.UnDecorateSymbolName - self.__undname.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint] + if 'win32' in sys.platform: + import ctypes.wintypes + self.__undname = ctypes.windll.dbghelp.UnDecorateSymbolName + self.__undname.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint] + self.__clean_ecsu = ( re.compile( r'(?P<startswith>^|\W)(?:(class|enum|struct|union)\s)' ) , '%(startswith)s' ) self.__fundamental_types = ( @@ -160,11 +162,13 @@ return '' else: formater = lambda type_: self.__format_type_as_undecorated( type_, True, hint ) - return ','.join( map( formater, argtypes ) ) + argsep =',' + if hint == 'nm': + argsep = ', ' #ugly hack, later, I will replace ', ' with ',', so single space will still exist + return argsep.join( map( formater, argtypes ) ) def format_calldef( self, calldef, hint ): calldef_type = calldef.function_type() - result = [] is_mem_fun = isinstance( calldef, declarations.member_calldef_t ) if is_mem_fun and hint == 'msvc' and calldef.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: @@ -186,16 +190,15 @@ result.append( '(%s)' % self.format_argtypes( calldef_type.arguments_types, hint ) ) if is_mem_fun and calldef.has_const: - if hint == 'msvc': - result.append( 'const' ) - else: - result.append( ' const' ) + if hint == 'nm': + result.append( ' ' ) + result.append( 'const' ) return ''.join( result ) def format_var( self, decl, hint ): result = [] is_mem_var = isinstance( decl.parent, declarations.class_t ) - if is_mem_var and decl.type_qualifiers.has_static: + if is_mem_var and decl.type_qualifiers.has_static and hint == 'msvc': result.append( 'static ' ) if hint == 'msvc': result.append( self.__format_type_as_undecorated( decl.type, False, hint ) ) Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2009-01-08 12:31:59 UTC (rev 1551) +++ pygccxml_dev/unittests/undname_creator_tester.py 2009-01-08 21:16:13 UTC (rev 1552) @@ -19,18 +19,38 @@ global_ns = None - known_issues = set([ - # array as function argument: 'int FA10_i_i(int * const)' - '?FA10_i_i@@YAHQAH@Z' - #pointer to function: 'void myclass_t::set_do_smth(void (**)(std::auto_ptr<number_t> &))' - , '?set_do_smth@myclass_t@@QAEXPAP6AXAAV?$auto_ptr@Vnumber_t@@@std@@@Z@Z' - #pointer to functions: 'void (** myclass_t::get_do_smth(void))(std::auto_ptr<number_t> &)' - , '?get_do_smth@myclass_t@@QAEPAP6AXAAV?$auto_ptr@Vnumber_t@@@std@@@ZXZ' - ]) - if 'msvc71' == utils.native_compiler.get_gccxml_compiler(): - #missing reference in argument - compiler issue 'std::auto_ptr<number_t> & std::auto_ptr<number_t>::operator=(std::auto_ptr_ref<number_t>)' - known_issues.add( '??4?$auto_ptr@Vnumber_t@@@std@@QAEAAV01@U?$auto_ptr_ref@Vnumber_t@@@1@@Z' ) + @property + def known_issues( self ): + if 'win32' in sys.platform: + issues = set([ + # array as function argument: 'int FA10_i_i(int * const)' + '?FA10_i_i@@YAHQAH@Z' + #pointer to function: 'void myclass_t::set_do_smth(void (**)(std::auto_ptr<number_t> &))' + , '?set_do_smth@myclass_t@@QAEXPAP6AXAAV?$auto_ptr@Vnumber_t@@@std@@@Z@Z' + #pointer to functions: 'void (** myclass_t::get_do_smth(void))(std::auto_ptr<number_t> &)' + , '?get_do_smth@myclass_t@@QAEPAP6AXAAV?$auto_ptr@Vnumber_t@@@std@@@ZXZ' + ]) + if 'msvc71' == utils.native_compiler.get_gccxml_compiler(): + #missing reference in argument - compiler issue 'std::auto_ptr<number_t> & std::auto_ptr<number_t>::operator=(std::auto_ptr_ref<number_t>)' + issues.add( '??4?$auto_ptr@Vnumber_t@@@std@@QAEAAV01@U?$auto_ptr_ref@Vnumber_t@@@1@@Z' ) + return issues + else: + return set([ + #even c++filt fails + '_ZNSt8auto_ptrI8number_tEcvSt12auto_ptr_refIT_EIS0_EEv' + #typeinfo name for number_t + , '_ZTI8number_t' + , '_ZTV8number_t' + , '_ZTS8number_t' + #it seems that gccxml doesn't report this one + , '_ZNSt12auto_ptr_refI8number_tEC1EPS0_' + #the following are some global symbols + , '_init' + , '_edata' + , '_fini' + , '_end' ]) + def __init__(self, *args ): parser_test_case.parser_test_case_t.__init__( self, *args ) self.binary_parsers_dir = os.path.join( autoconfig.data_directory, 'binary_parsers' ) @@ -70,8 +90,11 @@ else: return False - def __tester_impl( self, fname ): + def __tester_impl( self, fname, expected_symbols ): symbols, parser = binary_parsers.merge_information( self.global_ns, fname, runs_under_unittest=True ) + self.failUnless( len(symbols) == expected_symbols + , "The expected symbols number(%d), is different frm the actual one(%d)" + % ( expected_symbols, len(symbols) ) ) self.failUnless( 'identity' in symbols ) blob_names = set() @@ -134,14 +157,18 @@ def test_so_file( self ): if 'linux2' in sys.platform: - self.__tester_impl( self.so_file ) + self.__tester_impl( self.so_file, 64 ) - def test_print( self ): - symbols, parser = binary_parsers.merge_information( self.global_ns, self.map_file, runs_under_unittest=True ) - for d in symbols.itervalues(): - print binary_parsers.format_decl( d, 'nm' ) + def dont_test_print( self ): + """primary used for debugging""" + symbols, parser = binary_parsers.merge_information( self.global_ns, self.so_file, runs_under_unittest=True ) + for f in self.global_ns.calldefs( allow_empty=True, recursive=True ): + print binary_parsers.format_decl( f, 'nm' ) + for v in self.global_ns.variables( allow_empty=True, recursive=True ): + print binary_parsers.format_decl( v, 'nm' ) + def create_suite(): suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |