[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.
|