From: <rom...@us...> - 2008-02-24 08:11:55
|
Revision: 1257 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1257&view=rev Author: roman_yakovenko Date: 2008-02-24 00:12:00 -0800 (Sun, 24 Feb 2008) Log Message: ----------- Modified Paths: -------------- pygccxml_dev/pygccxml/pdb_reader/msdia_details.py Added Paths: ----------- pygccxml_dev/pygccxml/pdb_reader/scanner.py Removed Paths: ------------- pygccxml_dev/pygccxml/pdb_reader/reader.py Modified: pygccxml_dev/pygccxml/pdb_reader/msdia_details.py =================================================================== --- pygccxml_dev/pygccxml/pdb_reader/msdia_details.py 2008-02-24 06:31:16 UTC (rev 1256) +++ pygccxml_dev/pygccxml/pdb_reader/msdia_details.py 2008-02-24 08:12:00 UTC (rev 1257) @@ -11,9 +11,6 @@ def find_path( self ): vss_installed = self.__get_installed_vs_dirs() msdia_dlls = self.__get_msdia_dll_paths( vss_installed ) - #D:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\ - #D:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger\msdia71.dll - #C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\msdia90.dll if 1 == len(msdia_dlls): return msdia_dlls[0] else: @@ -37,20 +34,6 @@ vs_reg_path = 'Software\Microsoft\VisualStudio\SxS\VS7' values = self.read_values( self.root_reg_key, vs_reg_path ) return [ values.values()[0] ] - #~ vss = self.read_keys( self.root_reg_key, vs_reg_path ) - #~ vs_installed_and_exist = [] - - #~ for vs_installed in vss: - #~ values = self.read_values( self.root_reg_key, vs_reg_path + '\\' + vs_installed ) - #~ try: - #~ vs_installed_and_exist.append( os.path.realpath( values['installdir'] ) ) - #~ except KeyError: - #~ pass - - if not vs_installed_and_exist: - raise RuntimeError( 'pygccxml unable to find out a Visual Studio installation directory' ) - return vs_installed_and_exist - def read_keys(self, base, key): return msvccompiler.read_keys(base, key) @@ -59,6 +42,7 @@ return msvccompiler.read_values(base, key) msdia_path = msdia_searcher_t().find_path() +print msdia_path comtypes_client_gen_dir = comtypes.client.gen_dir try: Deleted: pygccxml_dev/pygccxml/pdb_reader/reader.py =================================================================== --- pygccxml_dev/pygccxml/pdb_reader/reader.py 2008-02-24 06:31:16 UTC (rev 1256) +++ pygccxml_dev/pygccxml/pdb_reader/reader.py 2008-02-24 08:12:00 UTC (rev 1257) @@ -1,223 +0,0 @@ -import os -import sys -import ctypes -import pprint -import logging -import comtypes -import comtypes.client -from msdia_details import msdia - -sys.path.append( r'../..' ) -#sys.path.append( r'C:\dev\language-binding\pygccxml_dev' ) - -from pygccxml import utils -from pygccxml import declarations - -import details - - -SymTagEnum = 12 - -def AsDiaSymbol( x ): - return ctypes.cast( x, ctypes.POINTER( msdia.IDiaSymbol ) ) - - -def print_files( session ): - files = iter( session.findFile( None, '', 0 ) ) - for f in files: - f = ctypes.cast( f, ctypes.POINTER(msdia.IDiaSourceFile) ) - print 'File: ', f.fileName - - -class pdb_reader_t(object): - def __init__(self, pdb_file_path ): - self.logger = utils.loggers.pdb_reader - self.logger.setLevel(logging.DEBUG) - self.logger.debug( 'creating DiaSource object' ) - self.__dia_source = comtypes.client.CreateObject( msdia.DiaSource ) - self.logger.debug( 'loading pdb file: %s' % pdb_file_path ) - self.__dia_source.loadDataFromPdb(pdb_file_path) - self.logger.debug( 'opening session' ) - self.__dia_session = self.__dia_source.openSession() - self.logger.debug( 'opening session - done' ) - self.__global_ns = declarations.namespace_t( '::' ) - self.__classes = {} - self.__namespaces = {'': self.__global_ns} - - - def read(self): - self.__populate_scopes() - - @property - def dia_global_scope(self): - return self.__dia_session.globalScope - - @property - def global_ns(self): - return self.__global_ns - - def __find_udt( self, name ): - self.logger.debug( 'testing whether name( "%s" ) is UDT symbol' % name ) - flags = msdia.NameSearchOptions.nsfCaseSensitive - found = self.dia_global_scope.findChildren( msdia.SymTagUDT, name, flags ) - if found.Count == 1: - self.logger.debug( 'name( "%s" ) is UDT symbol' % name ) - return AsDiaSymbol( found.Item(0) ) - elif 1 < found.Count: - raise RuntimeError( "duplicated UDTs with name '%s', were found" % name ) - #~ self.logger.debug( 'name( "%s" ) is UDT symbol' % name ) - #~ return [AsDiaSymbol( s ) for s in iter(found)] - #~ for s in iter(found): - #~ s = - #~ print s.name - #~ print details.guess_class_type(s.udtKind) - else: - self.logger.debug( 'name( "%s" ) is **NOT** UDT symbol' % name ) - return None - - def __list_main_classes( self ): - #in this context main classes, are classes that were defined within a namespace - #as opposite to the classes defined in other classes - classes = [] - dia_classes = self.dia_global_scope.findChildren( msdia.SymTagUDT, None, 0 ) - for dia_class in iter( dia_classes ): - dia_class = AsDiaSymbol( dia_class ) - name_splitter = details.get_name_splitter( dia_class.name ) - for index, scope in enumerate( name_splitter.scope_names ): - if scope in self.__namespaces: - continue - else: - udt = self.__find_udt( scope ) - if udt: - classes.append( udt ) - if index: - self.__namespaces[ name_splitter.scope_names[index-1] ] = None - break - else: - self.__namespaces[ scope ] = None - else: - classes.append( dia_class ) - if name_splitter.scope_names: - self.__namespaces[ name_splitter.scope_names[-1] ] = None - return classes - - def __add_inner_classes( self, parent_class ): - self.logger.debug( 'adding inner classes to "%s"' % parent_class.decl_string ) - for symbol_id in parent_class.dia_symbols: - self.logger.debug( '\tdia symbol id: %d' % symbol_id ) - dia_symbol = self.__dia_session.symbolById( symbol_id ) - found = dia_symbol.findChildren( msdia.SymTagUDT, None, 0 ) - for inner_dia_class in iter(found): - inner_dia_class = AsDiaSymbol( inner_dia_class ) - self.logger.debug( '\t\tinner UDT found - %s' % inner_dia_class.name ) - inner_name_splitter = details.get_name_splitter( inner_dia_class.name ) - try: - inner_klass = parent_class.class_( inner_name_splitter.name, recursive=False ) - inner_klass.dia_symbols.add( inner_dia_class.symIndexId ) - except parent_class.declaration_not_found_t: - inner_klass = self.__create_class( inner_dia_class ) - parent_class.adopt_declaration( inner_klass - , details.guess_access_type( inner_dia_class.access ) ) - self.__classes[ inner_dia_class.name ] = inner_klass - self.logger.debug( 'adding inner classes to "%s" - done' % parent_class.decl_string ) - - def __create_enum( self, enum_smbl ): - name_splitter = details.get_name_splitter( enum_smbl.name ) - enum_decl = declarations.enumeration_t( name_splitter.name ) - values = enum_smbl.findChildren( msdia.SymTagData, None, 0 ) - for v in iter(values): - v = AsDiaSymbol(v) - if v.classParent.symIndexId != enum_smbl.symIndexId: - continue - enum_decl.append_value( v.name, v.value ) - if enum_decl.values: - return enum_decl - else: - #for some reason same enum could appear under global namespace and - #under the class, it was defined in. This is a criteria I use to distinguish - #between those cases - return None - - def __add_enums( self, parent_symbol_id ): - parent_symbol = self.__dia_session.symbolById( parent_symbol_id ) - self.logger.debug( 'adding enums to "%s" ' % parent_symbol.name ) - for enum_smbl in iter( parent_symbol.findChildren( SymTagEnum, None, 0 ) ): - enum_smbl = AsDiaSymbol( enum_smbl ) - enum_decl = self.__create_enum( enum_smbl ) - if not enum_decl: - continue - self.logger.debug( '\tfound %s' % str(enum_decl) ) - name_splitter = details.get_name_splitter( enum_smbl.name ) - if not name_splitter.scope_names: - self.global_ns.adopt_declaration( enum_decl ) - self.logger.debug( '\tenum "%s" was added to global namespace' % enum_decl.name ) - else: - try: - self.logger.debug( '\tadding enum "%s" to a namespace' % enum_decl.name ) - ns = self.__namespaces[ name_splitter.scope_names[-1] ] - ns.adopt_declaration( enum_decl ) - self.logger.debug( '\tadding enum "%s" to a namespace - done' % enum_decl.name ) - except KeyError: - self.logger.debug( '\tadding enum "%s" to a class' % enum_decl.name ) - klass = self.__classes[ name_splitter.scope_names[-1] ] - klass.adopt_declaration( enum_decl, details.guess_access_type( enum_smbl.access ) ) - self.logger.debug( '\tadding enum "%s" to a class - done' % enum_decl.name ) - self.logger.debug( 'adding enums to "%s" - done' % parent_symbol.name ) - - def __create_nss( self ): - nss = self.__namespaces.keys() - nss.sort() - - for ns_name in nss: - name_splitter = details.get_name_splitter( ns_name ) - if not name_splitter.scope_names: - parent_ns = self.global_ns - else: - parent_ns = self.__namespaces[ name_splitter.scope_names[-1] ] - ns_decl = declarations.namespace_t( name_splitter.name ) - parent_ns.adopt_declaration( ns_decl ) - self.__namespaces[ ns_name ] = ns_decl - - def __create_class( self, dia_class ): - name_splitter = details.get_name_splitter( dia_class.name ) - klass = declarations.class_t( name_splitter.name ) - klass.class_type = details.guess_class_type(dia_class.udtKind) - klass.dia_symbols = set([dia_class.symIndexId]) - return klass - - def __populate_scopes(self): - main_classes = self.__list_main_classes() - self.__create_nss() - - for dia_class in main_classes: - name_splitter = details.get_name_splitter( dia_class.name ) - if not name_splitter.scope_names: - parent_ns = self.global_ns - else: - parent_ns = self.__namespaces[ name_splitter.scope_names[-1] ] - - try: - klass = parent_ns.class_( name_splitter.name, recursive=False ) - klass.dia_symbols.add( dia_class.symIndexId ) - except parent_ns.declaration_not_found_t: - klass = self.__create_class( dia_class ) - parent_ns.adopt_declaration( klass ) - self.__classes[ dia_class.name ] = klass - - map( self.__add_inner_classes, self.__classes.values() ) - - self.__add_enums( self.dia_global_scope.symIndexId ) - for klass in self.__classes.itervalues(): - map( self.__add_enums, klass.dia_symbols ) - - #declarations.print_declarations( self.global_ns )#.namespace( 'ns1' ) ) - #declarations.print_declarations( self.global_ns.namespace( 'std' ) ) - -if __name__ == '__main__': - control_pdb = r'C:\dev\produce_pdb\Debug\produce_pdb.pdb' - #control_pdb = r'xxx.pdb' - reader = pdb_reader_t( control_pdb ) - reader.read() - f = file( 'decls.cpp', 'w+' ) - declarations.print_declarations( reader.global_ns, writer=f.write ) - f.close() \ No newline at end of file Copied: pygccxml_dev/pygccxml/pdb_reader/scanner.py (from rev 1256, pygccxml_dev/pygccxml/pdb_reader/reader.py) =================================================================== --- pygccxml_dev/pygccxml/pdb_reader/scanner.py (rev 0) +++ pygccxml_dev/pygccxml/pdb_reader/scanner.py 2008-02-24 08:12:00 UTC (rev 1257) @@ -0,0 +1,254 @@ +import os +import sys +import ctypes +import pprint +import logging +import comtypes +import comtypes.client +from msdia_details import msdia + +sys.path.append( r'../..' ) +#sys.path.append( r'C:\dev\language-binding\pygccxml_dev' ) + +from pygccxml import utils +from pygccxml import declarations + +import details + + +SymTagEnum = 12 + +def AsDiaSymbol( x ): + return ctypes.cast( x, ctypes.POINTER( msdia.IDiaSymbol ) ) + + +def print_files( session ): + files = iter( session.findFile( None, '', 0 ) ) + for f in files: + f = ctypes.cast( f, ctypes.POINTER(msdia.IDiaSourceFile) ) + print 'File: ', f.fileName + + +class scanner_t(object): + def __init__(self, pdb_file_path ): + self.logger = utils.loggers.pdb_reader + self.logger.setLevel(logging.DEBUG) + self.logger.debug( 'creating DiaSource object' ) + self.__dia_source = comtypes.client.CreateObject( msdia.DiaSource ) + self.logger.debug( 'loading pdb file: %s' % pdb_file_path ) + self.__dia_source.loadDataFromPdb(pdb_file_path) + self.logger.debug( 'opening session' ) + self.__dia_session = self.__dia_source.openSession() + self.logger.debug( 'opening session - done' ) + self.__global_ns = declarations.namespace_t( '::' ) + + self.__enums = {} + self.__classes = {} + self.__namespaces = {'': self.__global_ns} + + + def read(self): + self.__populate_scopes() + + @property + def dia_global_scope(self): + return self.__dia_session.globalScope + + @property + def global_ns(self): + return self.__global_ns + + def __are_symbols_equivalent( self, smbl1_id, smbl2_id ): + smbl1 = self.__dia_session.symbolById(smbl1_id) + smbl2 = self.__dia_session.symbolById(smbl2_id) + result = self.__dia_session.symsAreEquiv( smbl1, smbl2 ) + if result: + msg = 'Symbols "%s(%d)" and "%s(%d)" are equivalent.' + else: + msg = 'Symbols "%s(%d)" and "%s(%d)" are NOT equivalent.' + self.logger.debug( msg, smbl1.name, smbl1_id, smbl2.name, smbl2_id ) + return result + + def __find_udt( self, name ): + self.logger.debug( 'testing whether name( "%s" ) is UDT symbol' % name ) + flags = msdia.NameSearchOptions.nsfCaseSensitive + found = self.dia_global_scope.findChildren( msdia.SymTagUDT, name, flags ) + if found.Count == 1: + self.logger.debug( 'name( "%s" ) is UDT symbol' % name ) + return AsDiaSymbol( found.Item(0) ) + elif 1 < found.Count: + raise RuntimeError( "duplicated UDTs with name '%s', were found" % name ) + #~ self.logger.debug( 'name( "%s" ) is UDT symbol' % name ) + #~ return [AsDiaSymbol( s ) for s in iter(found)] + #~ for s in iter(found): + #~ s = + #~ print s.name + #~ print details.guess_class_type(s.udtKind) + else: + self.logger.debug( 'name( "%s" ) is **NOT** UDT symbol' % name ) + return None + + def __list_main_classes( self ): + #in this context main classes, are classes that were defined within a namespace + #as opposite to the classes defined in other classes + classes = [] + dia_classes = self.dia_global_scope.findChildren( msdia.SymTagUDT, None, 0 ) + for dia_class in iter( dia_classes ): + dia_class = AsDiaSymbol( dia_class ) + name_splitter = details.get_name_splitter( dia_class.name ) + for index, scope in enumerate( name_splitter.scope_names ): + if scope in self.__namespaces: + continue + else: + udt = self.__find_udt( scope ) + if udt: + classes.append( udt ) + if index: + self.__namespaces[ name_splitter.scope_names[index-1] ] = None + break + else: + self.__namespaces[ scope ] = None + else: + classes.append( dia_class ) + if name_splitter.scope_names: + self.__namespaces[ name_splitter.scope_names[-1] ] = None + return classes + + def __add_inner_classes( self, parent_class ): + self.logger.debug( 'adding inner classes to "%s"' % parent_class.decl_string ) + for symbol_id in parent_class.dia_symbols: + self.logger.debug( '\tdia symbol id: %d' % symbol_id ) + dia_symbol = self.__dia_session.symbolById( symbol_id ) + found = dia_symbol.findChildren( msdia.SymTagUDT, None, 0 ) + for inner_dia_class in iter(found): + inner_dia_class = AsDiaSymbol( inner_dia_class ) + self.logger.debug( '\t\tinner UDT found - %s' % inner_dia_class.name ) + inner_name_splitter = details.get_name_splitter( inner_dia_class.name ) + try: + inner_klass = parent_class.class_( inner_name_splitter.name, recursive=False ) + inner_klass.dia_symbols.add( inner_dia_class.symIndexId ) + except parent_class.declaration_not_found_t: + inner_klass = self.__create_class( inner_dia_class ) + parent_class.adopt_declaration( inner_klass + , details.guess_access_type( inner_dia_class.access ) ) + self.__classes[ inner_dia_class.name ] = inner_klass + self.logger.debug( 'adding inner classes to "%s" - done' % parent_class.decl_string ) + + def __create_enum( self, enum_smbl ): + name_splitter = details.get_name_splitter( enum_smbl.name ) + enum_decl = declarations.enumeration_t( name_splitter.name ) + enum_decl.dia_symbols = [ enum_smbl.symIndexId ] + values = enum_smbl.findChildren( msdia.SymTagData, None, 0 ) + for v in iter(values): + v = AsDiaSymbol(v) + if v.classParent.symIndexId != enum_smbl.symIndexId: + continue + enum_decl.append_value( v.name, v.value ) + if enum_decl.values: + return enum_decl + else: + #for some reason same enum could appear under global namespace and + #under the class, it was defined in. This is a criteria I use to distinguish + #between those cases + return None + + def __load_enums( self, parent_symbol_id ): + parent_symbol = self.__dia_session.symbolById( parent_symbol_id ) + self.logger.debug( 'loading enums to "%s" ' % parent_symbol.name ) + for enum_smbl in iter( parent_symbol.findChildren( SymTagEnum, None, 0 ) ): + enum_smbl = AsDiaSymbol( enum_smbl ) + enum_decl = self.__create_enum( enum_smbl ) + if enum_decl: + try: + for enum_discovered in self.__enums[ enum_smbl.name ]: + if self.__are_symbols_equivalent( enum_smbl.symIndexId, enum_discovered.dia_symbols[0] ): + continue + else: + self.__enums[ enum_smbl.name ].append( enum_decl ) + except KeyError: + self.__enums[ enum_smbl.name ] = [ enum_decl ] + self.logger.debug( '\tfound %s %s' % ( enum_smbl.name, str(enum_decl) ) ) + self.logger.debug( 'loading enums to "%s" - done' % parent_symbol.name ) + + + def __load_classes( self, parent_symbol_id ): + parent_symbol = self.__dia_session.symbolById( parent_symbol_id ) + self.logger.debug( 'loading classes to "%s" ' % parent_symbol.name ) + for class_smbl in iter( parent_symbol.findChildren( msdia.SymTagUDT, None, 0 ) ): + class_smbl = AsDiaSymbol( class_smbl ) + class_decl = self.__create_class( class_smbl ) + try: + equivalent_found = False + for class_discovered in self.__classes[ class_smbl.name ]: + for smbl_discovered in class_discovered.dia_symbols: + equivalent_found = self.__are_symbols_equivalent( smbl_discovered, class_smbl.symIndexId ) + if equivalent_found: + class_discovered.dia_symbols.add( class_smbl.symIndexId ) + break + if equivalent_found: + break + if not equivalent_found: + self.__classes[ class_smbl.name ].append( class_decl ) + except KeyError: + self.__classes[ class_smbl.name ] = [ class_decl ] + self.logger.debug( '\tfound %s' % str(class_decl) ) + self.logger.debug( 'loading classes to "%s" - done' % parent_symbol.name ) + + def __create_nss( self ): + nss = self.__namespaces.keys() + nss.sort() + for ns_name in nss: + name_splitter = details.get_name_splitter( ns_name ) + if not name_splitter.scope_names: + parent_ns = self.global_ns + else: + parent_ns = self.__namespaces[ name_splitter.scope_names[-1] ] + ns_decl = declarations.namespace_t( name_splitter.name ) + parent_ns.adopt_declaration( ns_decl ) + self.__namespaces[ ns_name ] = ns_decl + + def __create_class( self, dia_class ): + name_splitter = details.get_name_splitter( dia_class.name ) + klass = declarations.class_t( name_splitter.name ) + klass.class_type = details.guess_class_type(dia_class.udtKind) + klass.dia_symbols = set([dia_class.symIndexId]) + return klass + + def __populate_scopes(self): + self.__load_enums( self.dia_global_scope.symIndexId ) + self.__load_classes( self.dia_global_scope.symIndexId ) + #~ main_classes = self.__list_main_classes() + #~ self.__create_nss() + + #~ for dia_class in main_classes: + #~ name_splitter = details.get_name_splitter( dia_class.name ) + #~ if not name_splitter.scope_names: + #~ parent_ns = self.global_ns + #~ else: + #~ parent_ns = self.__namespaces[ name_splitter.scope_names[-1] ] + + #~ try: + #~ klass = parent_ns.class_( name_splitter.name, recursive=False ) + #~ klass.dia_symbols.add( dia_class.symIndexId ) + #~ except parent_ns.declaration_not_found_t: + #~ klass = self.__create_class( dia_class ) + #~ parent_ns.adopt_declaration( klass ) + #~ self.__classes[ dia_class.name ] = klass + + #~ map( self.__add_inner_classes, self.__classes.values() ) + + #~ self.__add_enums( self.dia_global_scope.symIndexId ) + #~ for klass in self.__classes.itervalues(): + #~ map( self.__add_enums, klass.dia_symbols ) + + #declarations.print_declarations( self.global_ns )#.namespace( 'ns1' ) ) + #declarations.print_declarations( self.global_ns.namespace( 'std' ) ) + +if __name__ == '__main__': + control_pdb = r'C:\dev\produce_pdb\Debug\produce_pdb.pdb' + control_pdb = r'xxx.pdb' + reader = scanner_t( control_pdb ) + reader.read() + f = file( 'decls.cpp', 'w+' ) + declarations.print_declarations( reader.global_ns, writer=f.write ) + f.close() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |