[pygccxml-commit] SF.net SVN: pygccxml: [1246] pygccxml_dev/pygccxml/parser
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-02-19 22:48:40
|
Revision: 1246 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1246&view=rev Author: roman_yakovenko Date: 2008-02-19 14:48:47 -0800 (Tue, 19 Feb 2008) Log Message: ----------- updating pdb parser Modified Paths: -------------- pygccxml_dev/pygccxml/parser/pdb_reader.py Added Paths: ----------- pygccxml_dev/pygccxml/parser/msdia_details.py Added: pygccxml_dev/pygccxml/parser/msdia_details.py =================================================================== --- pygccxml_dev/pygccxml/parser/msdia_details.py (rev 0) +++ pygccxml_dev/pygccxml/parser/msdia_details.py 2008-02-19 22:48:47 UTC (rev 1246) @@ -0,0 +1,49 @@ +import getpass +import comtypes +import comtypes.client + +msdia_path = None +if 'root' == getpass.getuser(): + msdia_path = r'C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\msdia90.dll' + +msdia = comtypes.client.GetModule( msdia_path ) + +class UdtKind: + UdtStruct, UdtClass, UdtUnion = ( 0, 1, 2 ) + +msdia.UdtKind = UdtKind + +class NameSearchOptions: + nsNone = 0 + nsfCaseSensitive = 0x1 + nsfCaseInsensitive = 0x2 + nsfFNameExt = 0x4 + nsfRegularExpression = 0x8 + nsfUndecoratedName = 0x10 + + # For backward compabibility: + nsCaseSensitive = nsfCaseSensitive + nsCaseInsensitive = nsfCaseInsensitive + nsFNameExt = nsfFNameExt + nsRegularExpression = nsfRegularExpression | nsfCaseSensitive + nsCaseInRegularExpression = nsfRegularExpression | nsfCaseInsensitive + +msdia.NameSearchOptions = NameSearchOptions + + +# +#from distutils import ccompiler +#from distutils import msvccompiler +# +#if 'msvc' == ccompiler.get_default_compiler(): +# cc = msvccompiler.MSVCCompiler() +# cc.initialize() +# generator = 'NMake Makefiles' +# native_build = '"%s" /A all' % cc.find_exe( 'nmake.exe' ) +# configure_environment_script = cc.find_exe( 'vsvars32.bat' ) +# if not configure_environment_script: +# configure_environment_script = cc.find_exe( 'vcvars32.bat' ) +# cl_mapping = { 6.0 : "msvc6", 7.0 : "msvc7", 7.1 : "msvc71", 8.0 : "msvc8" } +# compiler = cl_mapping[ msvccompiler.get_build_version() ] +#else: +# raise RuntimeError( "Unable to find out MSDIA dll location") Modified: pygccxml_dev/pygccxml/parser/pdb_reader.py =================================================================== --- pygccxml_dev/pygccxml/parser/pdb_reader.py 2008-02-19 22:48:10 UTC (rev 1245) +++ pygccxml_dev/pygccxml/parser/pdb_reader.py 2008-02-19 22:48:47 UTC (rev 1246) @@ -3,26 +3,15 @@ import ctypes import comtypes import comtypes.client -from sets import Set as set +from msdia_details import msdia -msdia_dll = r'C:\Program Files\Microsoft Visual Studio .NET 2003\Visual Studio SDKs\DIA SDK\bin\msdia71.dll' -msdia_dll = r'D:\Program Files\Microsoft Visual Studio .NET 2003\Visual Studio SDKs\DIA SDK\bin\msdia71.dll' +sys.path.append( r'C:\dev\language-binding\pygccxml_dev' ) -msdia_dll = 'msdia80.dll' +from pygccxml import utils +from pygccxml import declarations -msdia = comtypes.client.GetModule( msdia_dll ) -control_pdb = r'C:\dev\produce_pdb\Debug\produce_pdb.pdb' -control_pdb = r'xxx.pdb' -ds = comtypes.client.CreateObject( msdia.DiaSource ) -ds.loadDataFromPdb(control_pdb) -session = ds.openSession() - -root_symbol = session.globalScope - -print root_symbol - SymTagEnum = 12 def AsDiaSymbol( x ): @@ -31,23 +20,17 @@ def print_enums( smb ): enums = smb.findChildren( SymTagEnum, None, 0 ) for enum in iter( enums ): - enum = AsDiaSymbol( enum ) - if 'shared_consts' not in enum.name: - continue + enum = AsDiaSymbol( enum ) print 'name: ', enum.name if enum.container: print 'container: ', enum.container.name - if enum.classParent: + if enum.classParent: print 'parent: ', enum.classParent.name if enum.lexicalParent: print 'lexical parent: ', enum.lexicalParent.Name - #~ print 'enum: ', enum.symIndexId - #~ f = session.findFile( internal_smb, internal_smb.name, 0 ) - #~ print 'name: ', internal_smb.name - #~ print f - - values = enum.findChildren( msdia.SymTagData, None, 0 ) - for v in iter(values): + + values = enum.findChildren( msdia.SymTagData, None, 0 ) + for v in iter(values): v = AsDiaSymbol(v) if v.classParent.symIndexId != enum.symIndexId: continue @@ -68,4 +51,95 @@ print 'File: ', f.fileName #~ print_files( session ) -print_enums( root_symbol ) +#print_enums( root_symbol ) + +class pdb_reader_t(object): + def __init__(self, pdb_file_path ): + self.logger = utils.loggers.gccxml + 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.__global_ns = declarations.namespace_t( '::' ) + + 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 __split_scope_identifiers( self, name ): + result = [] + tmp = name.split( '::' ) + tmp.reverse() + while tmp: + token = tmp.pop() + less_count = token.count( '<' ) + greater_count = token.count( '>' ) + if less_count != greater_count: + while less_count != greater_count: + next_token = tmp.pop() + token = token + '::' + next_token + less_count += next_token.count( '<' ) + greater_count += next_token.count( '>' ) + result.append( token ) + return result + + def __is_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: + self.logger.debug( 'name( "%s" ) is UDT symbol' % name ) + else: + self.logger.debug( 'name( "%s" ) is **NOT** UDT symbol' % name ) + return found.Count + + def __populate_scopes(self): + 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 '$' in dia_class.name: + continue + klass = declarations.class_t(dia_class.name) + if msdia.UdtKind.UdtStruct == dia_class.udtKind: + klass.class_type = declarations.CLASS_TYPES.STRUCT + elif msdia.UdtKind.UdtClass == dia_class.udtKind: + klass.class_type = declarations.CLASS_TYPES.CLASS + else: + klass.class_type = declarations.CLASS_TYPES.UNION + scope_identifiers = self.__split_scope_identifiers( dia_class.name ) + if 1 == len(scope_identifiers): + classes.append( klass ) + #self.global_ns.adopt_declaration( 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 ) + classes.sort( lambda klass1, klass2: cmp( klass1.name, klass2.name ) ) + for i in classes: + print str(i) + declarations.print_declarations( self.global_ns ) + +if __name__ == '__main__': + control_pdb = r'C:\dev\produce_pdb\Debug\produce_pdb.pdb' + reader = pdb_reader_t( control_pdb ) + reader.read() \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |