[pygccxml-commit] SF.net SVN: pygccxml: [1253] pygccxml_dev/pygccxml
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-02-23 08:54:01
|
Revision: 1253 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1253&view=rev Author: roman_yakovenko Date: 2008-02-23 00:54:06 -0800 (Sat, 23 Feb 2008) Log Message: ----------- pdb reader - adding treatment of inner classes Modified Paths: -------------- pygccxml_dev/pygccxml/pdb_parser/details.py pygccxml_dev/pygccxml/pdb_parser/msdia_details.py pygccxml_dev/pygccxml/pdb_parser/reader.py pygccxml_dev/pygccxml/utils/__init__.py Modified: pygccxml_dev/pygccxml/pdb_parser/details.py =================================================================== --- pygccxml_dev/pygccxml/pdb_parser/details.py 2008-02-21 08:05:30 UTC (rev 1252) +++ pygccxml_dev/pygccxml/pdb_parser/details.py 2008-02-23 08:54:06 UTC (rev 1253) @@ -1,3 +1,6 @@ +from msdia_details import msdia +from pygccxml import declarations + def guess_class_type( udt_kind ): if msdia.UdtKind.UdtStruct == udt_kind: return declarations.CLASS_TYPES.STRUCT @@ -6,7 +9,14 @@ else: return declarations.CLASS_TYPES.UNION - +def guess_access_type( access_type ): + if msdia.CV_access_e.CV_private == access_type: + return declarations.ACCESS_TYPES.PRIVATE + elif msdia.CV_access_e.CV_protected == access_type: + return declarations.ACCESS_TYPES.PROTECTED + else: + return declarations.ACCESS_TYPES.PUBLIC + class full_name_splitter_t( object ): def __init__( self, full_name ): self.__full_name = full_name @@ -20,7 +30,7 @@ @property def scope_names( self ): if None is self.__scope_identifiers: - self.__scope_identifiers = ['::'] + self.__scope_identifiers = []# ['::'] for i in range( len(self.__identifiers) - 1): self.__scope_identifiers.append( '::'.join( self.__identifiers[0:i+1] ) ) return self.__scope_identifiers @@ -46,7 +56,16 @@ result.append( token ) return result +__name_splitters = {} +def get_name_splitter( full_name ): + try: + return __name_splitters[full_name] + except KeyError: + splitter = full_name_splitter_t( full_name ) + __name_splitters[full_name] = splitter + return splitter + if '__main__' == __name__: name = "boost::detail::is_base_and_derived_impl2<engine_objects::universal_base_t,engine_objects::erroneous_transactions_file_configuration_t>::Host" fnsp = full_name_splitter_t( name ) Modified: pygccxml_dev/pygccxml/pdb_parser/msdia_details.py =================================================================== --- pygccxml_dev/pygccxml/pdb_parser/msdia_details.py 2008-02-21 08:05:30 UTC (rev 1252) +++ pygccxml_dev/pygccxml/pdb_parser/msdia_details.py 2008-02-23 08:54:06 UTC (rev 1253) @@ -23,8 +23,7 @@ def __get_msdia_dll_paths( self, vss_installed ): msdia_dlls = [] for vs in vss_installed: - vs = os.path.split( vs )[0] - debug_dir = os.path.join( vs, 'Packages', 'Debugger' ) + debug_dir = os.path.join( vs, 'Common7', 'Packages', 'Debugger' ) files = filter( lambda f: f.startswith( 'msdia' ) and f.endswith( '.dll' ) , os.listdir( debug_dir ) ) if not files: @@ -35,16 +34,18 @@ return msdia_dlls def __get_installed_vs_dirs( self ): - vs_reg_path = 'Software\Microsoft\VisualStudio' - vss = self.read_keys( self.root_reg_key, vs_reg_path ) - vs_installed_and_exist = [] + 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 + #~ 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' ) @@ -69,9 +70,13 @@ #Adding code, that was not generated for some reason. class UdtKind: - UdtStruct, UdtClass, UdtUnion = ( 0, 1, 2 ) + UdtStruct, UdtClass, UdtUnion = (0, 1, 2) +class CV_access_e: + CV_private, CV_protected, CV_public = (1, 2, 3) + msdia.UdtKind = UdtKind +msdia.CV_access_e = CV_access_e class NameSearchOptions: nsNone = 0 Modified: pygccxml_dev/pygccxml/pdb_parser/reader.py =================================================================== --- pygccxml_dev/pygccxml/pdb_parser/reader.py 2008-02-21 08:05:30 UTC (rev 1252) +++ pygccxml_dev/pygccxml/pdb_parser/reader.py 2008-02-23 08:54:06 UTC (rev 1253) @@ -1,6 +1,7 @@ import os import sys import ctypes +import logging import comtypes import comtypes.client from msdia_details import msdia @@ -47,7 +48,8 @@ class pdb_reader_t(object): def __init__(self, pdb_file_path ): - self.logger = utils.loggers.gccxml + 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 ) @@ -55,16 +57,10 @@ self.logger.debug( 'opening session' ) self.__dia_session = self.__dia_source.openSession() self.__global_ns = declarations.namespace_t( '::' ) - self.__id2decl = {} #hash table unique symbol id : pygccxml declaration def read(self): self.__populate_scopes() - - files = iter( self.__dia_session.findFile( None, '', 0 ) ) - for f in files: - f = ctypes.cast( f, ctypes.POINTER(msdia.IDiaSourceFile) ) - print 'File: ', f.fileName - + @property def dia_global_scope(self): return self.__dia_session.globalScope @@ -72,15 +68,14 @@ @property def global_ns(self): return self.__global_ns - - def __found_udt( self, name ): + 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( fount.Item[0] ) + 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 ) @@ -92,50 +87,80 @@ else: self.logger.debug( 'name( "%s" ) is **NOT** UDT symbol' % name ) return False - - def __populate_scopes(self): - classes = {} #full name to list of symbols + + def __list_main_classes( self ): + #in this context main classes, are classes that was defined within a namespace + #as opposite to 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 ) - if not classes.has_key( dia_class.name ): - classes[ dia_class.name ] = [ dia_class ] + name_splitter = details.get_name_splitter( dia_class.name ) + for scope in name_splitter.scope_names: + udt = self.__find_udt( scope ) + if udt: + classes.append( udt ) + break else: - classes[ dia_class.name ].append( dia_class ) + classes.append( dia_class ) + return classes + + def __add_inner_classes( self ): + for klass in self.global_ns.classes(recursive=True): + for dia_symbol in klass.dia_symbols: + flags = msdia.NameSearchOptions.nsCaseInRegularExpression + inner_name = dia_symbol.name + '::.*' + found = dia_symbol.findChildren( msdia.SymTagUDT, None, flags ) + for inner_dia_class in iter(found): + inner_dia_class = AsDiaSymbol( inner_dia_class ) + inner_name_splitter = details.get_name_splitter( inner_dia_class.name ) + try: + inner_klass = klass.class_( inner_name_splitter.name, recursive=False ) + inner_klass.dia_symbols.append( inner_dia_class ) + except klass.declaration_not_found_t: + klass.adopt_declaration( self.__create_class( inner_dia_class ) + , details.guess_access_type( inner_dia_class.access ) ) - for name, class_list in classes.iteritems(): - fname_splitter = details.full_name_splitter_t( name ) - klass = declarations.class_t(fname_splitter.name) - klass.class_type = details.guess_class_type( dia_class.udtKind ) - klass.dia_symbols = class_list - - for index, scope in enumerate( fname_splitter.scope_names ): - - - if not fname_splitter.scope_name: - classes.append( klass ) - else: - ns_ref = self.global_ns - for i in range( len(scope_identifiers) - 1): - full_identifier = '::'.join( scope_identifiers[0:i+1] ) - if not self.__is_udt( full_identifier ): - #we have namespace - try: - ns_ref = ns_ref.namespace( scope_identifiers[i], recursive=False) - except ns_ref.declaration_not_found_t: - new_ns = declarations.namespace_t( scope_identifiers[i] ) - ns_ref.adopt_declaration( new_ns ) - ns_ref = new_ns - else: - classes.append( klass ) - break - #~ classes.sort( lambda klass1, klass2: cmp( klass1.name, klass2.name ) ) - #~ for i in classes: - #~ print str(i) - #~ declarations.print_declarations( self.global_ns ) - + def __create_parent_ns( self, ns_full_name ): + name_splitter = details.get_name_splitter( ns_full_name ) + ns_ref = self.global_ns + for ns_name in name_splitter.identifiers: + try: + ns_ref = ns_ref.ns( ns_name, recursive=False ) + except ns_ref.declaration_not_found_t: + ns = declarations.namespace_t( ns_name ) + ns_ref.adopt_declaration( ns ) + ns_ref = ns + + 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 = [ dia_class ] + return klass + + def __populate_scopes(self): + main_classes = self.__list_main_classes() + for dia_class in main_classes: + name_splitter = details.get_name_splitter( dia_class.name ) + map( self.__create_parent_ns, name_splitter.scope_names ) + for dia_class in main_classes: + name_splitter = details.get_name_splitter( dia_class.name ) + ns_ref = self.global_ns + if 1 < len(name_splitter.identifiers): + ns_ref = self.global_ns.ns( '::' + name_splitter.scope_names[-1] ) + try: + klass = ns_ref.class_( name_splitter.name, recursive=False ) + klass.dia_symbols.append( dia_class ) + except ns_ref.declaration_not_found_t: + ns_ref.adopt_declaration( self.__create_class( dia_class ) ) + + self.__add_inner_classes() + + declarations.print_declarations( self.global_ns ) + if __name__ == '__main__': control_pdb = r'C:\dev\produce_pdb\Debug\produce_pdb.pdb' - control_pdb = r'xxx.pdb' + #control_pdb = r'xxx.pdb' reader = pdb_reader_t( control_pdb ) reader.read() Modified: pygccxml_dev/pygccxml/utils/__init__.py =================================================================== --- pygccxml_dev/pygccxml/utils/__init__.py 2008-02-21 08:05:30 UTC (rev 1252) +++ pygccxml_dev/pygccxml/utils/__init__.py 2008-02-23 08:54:06 UTC (rev 1253) @@ -19,7 +19,7 @@ handler = logging.StreamHandler() handler.setFormatter( logging.Formatter( os.linesep + '%(levelname)s %(message)s' ) ) logger.addHandler(handler) - logger.setLevel(logging.DEBUG) + logger.setLevel(logging.INFO) return logger class loggers: @@ -33,7 +33,12 @@ """ gccxml = cxx_parser #backward compatability - + + pdb_reader = _create_logger_( 'pygccxml.pdb_reader' ) + """logger for MS .pdb file reader functionality + """ + + queries_engine = _create_logger_( 'pygccxml.queries_engine' ) """logger for query engine functionality. @@ -53,7 +58,7 @@ root = logging.getLogger( 'pygccxml' ) """root logger exists for your convinience only""" - all = [ root, cxx_parser, queries_engine, declarations_cache ] + all = [ root, cxx_parser, queries_engine, declarations_cache, pdb_reader ] """contains all logger classes, defined by the class""" def remove_file_no_raise(file_name ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |