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