Thread: [pygccxml-commit] SF.net SVN: pygccxml:[1383] pygccxml_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-08-06 13:00:18
|
Revision: 1383 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1383&view=rev Author: roman_yakovenko Date: 2008-08-06 13:00:27 +0000 (Wed, 06 Aug 2008) Log Message: ----------- implement better algorithm for searching template instantiatd classes Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/matchers.py pygccxml_dev/pygccxml/declarations/pattern_parser.py pygccxml_dev/pygccxml/declarations/scopedef.py pygccxml_dev/pygccxml/declarations/templates.py pygccxml_dev/unittests/test_all.py Added Paths: ----------- pygccxml_dev/unittests/better_templates_matcher_tester.py pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp Modified: pygccxml_dev/pygccxml/declarations/matchers.py =================================================================== --- pygccxml_dev/pygccxml/declarations/matchers.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/matchers.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -177,6 +177,7 @@ else: self.__opt_is_full_name = False self.__decl_name_only = self.__opt_tmpl_name + self.__name = templates.normalize( name ) else: if '::' in self.__name: self.__opt_is_full_name = True @@ -225,11 +226,12 @@ assert not None is self.name if self.__opt_is_tmpl_inst: if not self.__opt_is_full_name: - if self.name != decl.name and self.name != decl.partial_name: + if self.name != templates.normalize( decl.name ) \ + and self.name != templates.normalize( decl.partial_name ): return False - else: - if self.name != algorithm.full_name( decl, with_defaults=True ) \ - and self.name != algorithm.full_name( decl, with_defaults=False ): + else: + if self.name != templates.normalize( algorithm.full_name( decl, with_defaults=True ) ) \ + and self.name != templates.normalize( algorithm.full_name( decl, with_defaults=False ) ): return False else: if not self.__opt_is_full_name: Modified: pygccxml_dev/pygccxml/declarations/pattern_parser.py =================================================================== --- pygccxml_dev/pygccxml/declarations/pattern_parser.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/pattern_parser.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -24,7 +24,7 @@ def has_pattern( self, decl_string ): """implementation details""" last_part = decl_string.split( '::' )[-1] - return -1 != last_part.find( self.__end ) + return -1 != decl_string.find( self.__begin ) and -1 != last_part.find( self.__end ) def name( self, decl_string ): """implementation details""" @@ -127,3 +127,14 @@ return ''.join( [ name, self.__begin, args_str, self.__end ] ) + def normalize( self, decl_string, arg_separator=None ): + """implementation details""" + if not self.has_pattern( decl_string ): + return decl_string + name, args = self.split( decl_string ) + for i, arg in enumerate( args ): + args[i] = self.normalize( arg ) + return self.join( name, args, arg_separator ) + + + Modified: pygccxml_dev/pygccxml/declarations/scopedef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/scopedef.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/scopedef.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -10,6 +10,7 @@ import time import algorithm import filtering +import templates import declaration import mdecl_wrapper from pygccxml import utils @@ -301,8 +302,15 @@ decls = self.declarations if recursive: decls = algorithm.make_flatten( self.declarations ) + if decl_type: + decls = filter( lambda d: isinstance( d, decl_type ), decls ) return decls + if name and templates.is_instantiation( name ): + #templates has tricky mode to compare them, so lets check the whole + #range + name = None + if name and decl_type: matcher = scopedef_t._impl_matchers[ scopedef_t.decl ]( name=name ) if matcher.is_full_name(): Modified: pygccxml_dev/pygccxml/declarations/templates.py =================================================================== --- pygccxml_dev/pygccxml/declarations/templates.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/templates.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -64,4 +64,13 @@ def join( name, args ): """returns name< argument_1, argument_2, ..., argument_n >""" global __THE_PARSER - return __THE_PARSER.join( name, args ) \ No newline at end of file + return __THE_PARSER.join( name, args ) + +def normalize( decl_string ): + """returns decl_string, which contains "normalized" spaces + + this functionality allows to implement comparison of 2 different string + which are actually same: x::y< z > and x::y<z> + """ + global __THE_PARSER + return __THE_PARSER.normalize( decl_string ) Added: pygccxml_dev/unittests/better_templates_matcher_tester.py =================================================================== --- pygccxml_dev/unittests/better_templates_matcher_tester.py (rev 0) +++ pygccxml_dev/unittests/better_templates_matcher_tester.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -0,0 +1,44 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import unittest +import autoconfig +import parser_test_case + +from pygccxml import utils +from pygccxml import parser +from pygccxml import declarations + +class tester_t( parser_test_case.parser_test_case_t ): + + global_ns = None + + def __init__(self, *args ): + parser_test_case.parser_test_case_t.__init__( self, *args ) + self.header = 'better_templates_matcher_tester.hpp' + + def setUp(self): + if not tester_t.global_ns: + decls = parser.parse( [self.header], self.config ) + tester_t.global_ns = declarations.get_global_namespace( decls ) + tester_t.global_ns.init_optimizer() + + def test( self ): + classes = [ '::std::vector<Ogre::PlaneBoundedVolume,std::allocator<Ogre::PlaneBoundedVolume>>' + , '::std::vector<Ogre::Plane, std::allocator<Ogre::Plane>>' + , '::Ogre::Singleton< Ogre::PCZoneFactoryManager>' ] + for i in classes: + c = self.global_ns.class_( i ) + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() \ No newline at end of file Added: pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp =================================================================== --- pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp (rev 0) +++ pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp 2008-08-06 13:00:27 UTC (rev 1383) @@ -0,0 +1,31 @@ +// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <vector> +#include <map> + +namespace Ogre{ + struct PlaneBoundedVolume{}; + + struct Plane{}; + + std::vector<PlaneBoundedVolume> do_smth(){ + return std::vector<PlaneBoundedVolume>(); + } + + std::vector<Plane> do_smth2(){ + return std::vector<Plane>(); + } + + template< class X > + struct Singleton{ + }; + + struct PCZoneFactoryManager{}; + + Singleton<PCZoneFactoryManager> do_smth3(){ + return Singleton<PCZoneFactoryManager>(); + } +} Modified: pygccxml_dev/unittests/test_all.py =================================================================== --- pygccxml_dev/unittests/test_all.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/unittests/test_all.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -50,6 +50,7 @@ import copy_constructor_tester import plain_c_tester import function_traits_tester +import better_templates_matcher_tester testers = [ decl_string_tester @@ -96,6 +97,7 @@ , copy_constructor_tester , plain_c_tester , function_traits_tester + , better_templates_matcher_tester ] def create_suite(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-26 08:55:48
|
Revision: 1407 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1407&view=rev Author: roman_yakovenko Date: 2008-08-26 08:55:58 +0000 (Tue, 26 Aug 2008) Log Message: ----------- simplify container_traits functionality Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/container_traits.py pygccxml_dev/unittests/find_container_traits_tester.py Modified: pygccxml_dev/pygccxml/declarations/container_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/container_traits.py 2008-08-26 05:14:49 UTC (rev 1406) +++ pygccxml_dev/pygccxml/declarations/container_traits.py 2008-08-26 08:55:58 UTC (rev 1407) @@ -254,17 +254,31 @@ declaration( and not definition ) it parsers the class name in order to extract all the information. """ - def __init__( self, container_name, element_type_index, element_type_typedef ): + def __init__( self + , container_name + , element_type_index + , element_type_typedef + , defaults_remover + , key_type_index=None + , key_type_typedef=None ): """ container_name - std container name element_type_index - position of value\\mapped type within template arguments list element_type_typedef - class typedef to the value\\mapped type + key_type_index - position of key type within template arguments list + key_type_typedef - class typedef to the key type """ - self.name = container_name + self._name = container_name + self.remove_defaults_impl = defaults_remover self.element_type_index = element_type_index self.element_type_typedef = element_type_typedef + self.key_type_index = key_type_index + self.key_type_typedef = key_type_typedef + def name(self): + return self._name + def get_container_or_none( self, type ): """returns reference to the class declaration or None""" type = type_traits.remove_alias( type ) @@ -280,7 +294,7 @@ else: return - if not cls.name.startswith( self.name + '<' ): + if not cls.name.startswith( self.name() + '<' ): return for ns in std_namespaces: @@ -295,7 +309,7 @@ """returns reference to the class declaration""" cls = self.get_container_or_none( type ) if not cls: - raise TypeError( 'Type "%s" is not instantiation of std::%s' % ( type.decl_string, self.name ) ) + raise TypeError( 'Type "%s" is not instantiation of std::%s' % ( type.decl_string, self.name() ) ) return cls def element_type( self, type ): @@ -309,86 +323,45 @@ ref = type_traits.impl_details.find_value_type( cls.top_parent, value_type_str ) if None is ref: raise RuntimeError( "Unable to find out %s '%s' value type." - % ( self.name, cls.decl_string ) ) + % ( self.name(), cls.decl_string ) ) return ref + def remove_defaults( self, type_or_string ): + name = type_or_string + if not isinstance( type_or_string, types.StringTypes ): + name = self.class_declaration( type_or_string ).name + if not self.remove_defaults_impl: + return name + no_defaults = self.remove_defaults_impl( name ) + if not no_defaults: + return name + else: + return no_defaults +list_traits = container_traits_impl_t( 'list', 0, 'value_type', defaults_eraser.erase_allocator ) -def create_traits_class( container_name - , element_type_index - , element_type_typedef - , remove_defaults_=None ): - """ creates concrete container traits class """ +deque_traits = container_traits_impl_t( 'deque', 0, 'value_type', defaults_eraser.erase_allocator ) - impl_tmp = container_traits_impl_t( container_name, element_type_index, element_type_typedef ) +queue_traits = container_traits_impl_t( 'queue', 0, 'value_type', defaults_eraser.erase_container ) - class xxx_traits: - """extract information from the container""" +priority_queue_traits = container_traits_impl_t( 'priority_queue', 0, 'value_type', defaults_eraser.erase_container_compare ) - impl = None +vector_traits = container_traits_impl_t( 'vector', 0, 'value_type', defaults_eraser.erase_allocator ) - @staticmethod - def name(): - return xxx_traits.impl.name +stack_traits = container_traits_impl_t( 'stack', 0, 'value_type', defaults_eraser.erase_container ) - @staticmethod - def is_my_case( type ): - """returns True if type is the container class, otherwise False""" - return xxx_traits.impl.is_my_case( type ) +map_traits = container_traits_impl_t( 'map', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) +multimap_traits = container_traits_impl_t( 'multimap', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) - @staticmethod - def class_declaration( type ): - """returns reference to the container class""" - return xxx_traits.impl.class_declaration( type ) +hash_map_traits = container_traits_impl_t( 'hash_map', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) +hash_multimap_traits = container_traits_impl_t( 'hash_multimap', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) - @staticmethod - def element_type( type ): - """returns reference to container name value\\mapped type class""" - return xxx_traits.impl.element_type( type ) +set_traits = container_traits_impl_t( 'set', 0, 'value_type', defaults_eraser.erase_compare_allocator) +multiset_traits = container_traits_impl_t( 'multiset', 0, 'value_type', defaults_eraser.erase_compare_allocator ) - @staticmethod - def remove_defaults( type_or_string ): - name = None - if not isinstance( type_or_string, types.StringTypes ): - name = xxx_traits.class_declaration( type_or_string ).name - else: - name = type_or_string - if not remove_defaults_: - return name - no_defaults = remove_defaults_( name ) - if not no_defaults: - return name - else: - return no_defaults - - xxx_traits.impl = impl_tmp - - return xxx_traits +hash_set_traits = container_traits_impl_t( 'hash_set', 0, 'value_type', defaults_eraser.erase_hash_allocator ) +hash_multiset_traits = container_traits_impl_t( 'hash_multiset', 0, 'value_type', defaults_eraser.erase_hash_allocator ) -list_traits = create_traits_class( 'list', 0, 'value_type', defaults_eraser.erase_allocator ) - -deque_traits = create_traits_class( 'deque', 0, 'value_type', defaults_eraser.erase_allocator ) - -queue_traits = create_traits_class( 'queue', 0, 'value_type', defaults_eraser.erase_container ) - -priority_queue_traits = create_traits_class( 'priority_queue', 0, 'value_type', defaults_eraser.erase_container_compare ) - -vector_traits = create_traits_class( 'vector', 0, 'value_type', defaults_eraser.erase_allocator ) - -stack_traits = create_traits_class( 'stack', 0, 'value_type', defaults_eraser.erase_container ) - -map_traits = create_traits_class( 'map', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) -multimap_traits = create_traits_class( 'multimap', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) - -hash_map_traits = create_traits_class( 'hash_map', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) -hash_multimap_traits = create_traits_class( 'hash_multimap', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) - -set_traits = create_traits_class( 'set', 0, 'value_type', defaults_eraser.erase_compare_allocator) -multiset_traits = create_traits_class( 'multiset', 0, 'value_type', defaults_eraser.erase_compare_allocator ) - -hash_set_traits = create_traits_class( 'hash_set', 0, 'value_type', defaults_eraser.erase_hash_allocator ) -hash_multiset_traits = create_traits_class( 'hash_multiset', 0, 'value_type', defaults_eraser.erase_hash_allocator ) - container_traits = ( list_traits , deque_traits Modified: pygccxml_dev/unittests/find_container_traits_tester.py =================================================================== --- pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-26 05:14:49 UTC (rev 1406) +++ pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-26 08:55:58 UTC (rev 1407) @@ -23,14 +23,14 @@ tester_t.global_ns = declarations.get_global_namespace( decls ) tester_t.global_ns.init_optimizer() - def __cmp_traits( self, typedef, expected, partial_name ): + def __cmp_traits( self, typedef, expected, partial_name): if isinstance( typedef, str ): typedef = self.global_ns.typedef( typedef ) traits = declarations.find_container_traits( typedef ) self.failUnless( traits, 'container traits for "%s" not found' % str( typedef ) ) self.failUnless( traits is expected - , 'container "%s", expected %s, got %s' - % ( str(typedef), expected.__name__, traits.__name__ ) ) + , 'container "%s", expected %s_traits, got %s_traits' + % ( str(typedef), expected.name(), traits.name() ) ) cls = declarations.remove_declarated( typedef ) self.failUnless( cls.container_traits is expected ) self.failUnless( cls.partial_name == partial_name ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-26 11:23:47
|
Revision: 1408 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1408&view=rev Author: roman_yakovenko Date: 2008-08-26 11:23:56 +0000 (Tue, 26 Aug 2008) Log Message: ----------- add key_type functionality for container_traits add element_type and key_type caching Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/algorithms_cache.py pygccxml_dev/pygccxml/declarations/container_traits.py pygccxml_dev/unittests/find_container_traits_tester.py pygccxml_dev/unittests/vector_traits_tester.py Modified: pygccxml_dev/pygccxml/declarations/algorithms_cache.py =================================================================== --- pygccxml_dev/pygccxml/declarations/algorithms_cache.py 2008-08-26 08:55:58 UTC (rev 1407) +++ pygccxml_dev/pygccxml/declarations/algorithms_cache.py 2008-08-26 11:23:56 UTC (rev 1408) @@ -17,7 +17,9 @@ self._access_type = None self._demangled_name = None self._declaration_path = None - self._partial_declaration_path = None + self._partial_declaration_path = None + self._container_key_type = None + self._container_element_type = None def disable( self ): self._enabled = False @@ -31,27 +33,22 @@ def _get_full_name( self ): return self._full_name - def _set_full_name( self, fname ): if not self.enabled: fname = None - self._full_name = fname - + self._full_name = fname full_name = property( _get_full_name, _set_full_name ) def _get_full_partial_name( self ): return self._full_partial_name - def _set_full_partial_name( self, fname ): if not self.enabled: fname = None - self._full_partial_name = fname - + self._full_partial_name = fname full_partial_name = property( _get_full_partial_name, _set_full_partial_name ) def _get_access_type( self ): return self._access_type - def _set_access_type( self, access_type ): if not self.enabled: access_type = None @@ -60,35 +57,45 @@ def _get_demangled_name( self ): return self._demangled_name - def _set_demangled_name( self, demangled_name ): if not self.enabled: demangled_name = None - self._demangled_name = demangled_name - + self._demangled_name = demangled_name demangled_name = property( _get_demangled_name, _set_demangled_name ) def _get_declaration_path( self ): return self._declaration_path - def _set_declaration_path( self, declaration_path ): if not self.enabled: declaration_path = None self._declaration_path = declaration_path - declaration_path = property( _get_declaration_path, _set_declaration_path ) def _get_partial_declaration_path( self ): return self._partial_declaration_path - def _set_partial_declaration_path( self, partial_declaration_path ): if not self.enabled: partial_declaration_path = None self._partial_declaration_path = partial_declaration_path - partial_declaration_path = property( _get_partial_declaration_path , _set_partial_declaration_path ) + def _get_container_element_type( self ): + return self._container_element_type + def _set_container_element_type( self, etype ): + if not self.enabled: + etype = None + self._container_element_type = etype + container_element_type = property( _get_container_element_type, _set_container_element_type ) + + def _get_container_key_type( self ): + return self._container_key_type + def _set_container_key_type( self, ktype ): + if not self.enabled: + ktype = None + self._container_key_type = ktype + container_key_type = property( _get_container_key_type, _set_container_key_type ) + def reset( self ): self.full_name = None self.full_partial_name = None @@ -96,6 +103,8 @@ self.demangled_name = None self.declaration_path = None self.partial_declaration_path = None + self.container_key_type = None + self.container_element_type = None def reset_name_based( self ): self.full_name = None @@ -103,6 +112,8 @@ self.demangled_name = None self.declaration_path = None self.partial_declaration_path = None + self.container_key_type = None + self.container_element_type = None def reset_access_type( self ): self.access_type = None @@ -124,7 +135,6 @@ def _get_remove_alias( self ): return self._remove_alias - def _set_remove_alias( self, remove_alias ): if not type_algs_cache_t.enabled: remove_alias = None @@ -134,4 +144,4 @@ def reset(self): self.remove_alias = None - \ No newline at end of file + Modified: pygccxml_dev/pygccxml/declarations/container_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/container_traits.py 2008-08-26 08:55:58 UTC (rev 1407) +++ pygccxml_dev/pygccxml/declarations/container_traits.py 2008-08-26 11:23:56 UTC (rev 1408) @@ -312,21 +312,54 @@ raise TypeError( 'Type "%s" is not instantiation of std::%s' % ( type.decl_string, self.name() ) ) return cls + def is_sequence( self, type ): + #raise exception if type is not container + unused = self.class_declaration( type ) + return self.key_type_index is None + + def is_mapping( self, type ): + return not self.is_sequence( type ) + + def __find_xxx_type( self, type, xxx_index, xxx_typedef, cache_property_name ): + cls = self.class_declaration( type ) + result = getattr( cls.cache, cache_property_name ) + if not result: + if isinstance( cls, class_declaration.class_t ): + xxx_type = cls.typedef( xxx_typedef, recursive=False ).type + result = type_traits.remove_declarated( xxx_type ) + else: + xxx_type_str = templates.args( cls.name )[xxx_index] + result = type_traits.impl_details.find_value_type( cls.top_parent, xxx_type_str ) + if None is result: + raise RuntimeError( "Unable to find out %s '%s' key\\value type." + % ( self.name(), cls.decl_string ) ) + setattr( cls.cache, cache_property_name, result ) + return result + def element_type( self, type ): """returns reference to the class value\\mapped type declaration""" - cls = self.class_declaration( type ) - if isinstance( cls, class_declaration.class_t ): - value_type = cls.typedef( self.element_type_typedef, recursive=False ).type - return type_traits.remove_declarated( value_type ) - else: - value_type_str = templates.args( cls.name )[self.element_type_index] - ref = type_traits.impl_details.find_value_type( cls.top_parent, value_type_str ) - if None is ref: - raise RuntimeError( "Unable to find out %s '%s' value type." - % ( self.name(), cls.decl_string ) ) - return ref + return self.__find_xxx_type( type + , self.element_type_index + , self.element_type_typedef + , 'container_element_type') + def key_type( self, type ): + """returns reference to the class key type declaration""" + if not self.is_mapping( type ): + raise TypeError( 'Type "%s" is not "mapping" container' % str( type ) ) + return self.__find_xxx_type( type + , self.key_type_index + , self.key_type_typedef + , 'container_key_type' ) + def remove_defaults( self, type_or_string ): + """remove template defaults from a template class instantiation + + For example: + std::vector< int, std::allocator< int > > + will become + std::vector< int > + """ name = type_or_string if not isinstance( type_or_string, types.StringTypes ): name = self.class_declaration( type_or_string ).name @@ -338,30 +371,87 @@ else: return no_defaults -list_traits = container_traits_impl_t( 'list', 0, 'value_type', defaults_eraser.erase_allocator ) +create_traits = container_traits_impl_t +list_traits = create_traits( 'list' + , 0 + , 'value_type' + , defaults_eraser.erase_allocator ) -deque_traits = container_traits_impl_t( 'deque', 0, 'value_type', defaults_eraser.erase_allocator ) +deque_traits = create_traits( 'deque' + , 0 + , 'value_type' + , defaults_eraser.erase_allocator ) -queue_traits = container_traits_impl_t( 'queue', 0, 'value_type', defaults_eraser.erase_container ) +queue_traits = create_traits( 'queue' + , 0 + , 'value_type' + , defaults_eraser.erase_container ) -priority_queue_traits = container_traits_impl_t( 'priority_queue', 0, 'value_type', defaults_eraser.erase_container_compare ) +priority_queue_traits = create_traits( 'priority_queue' + , 0 + , 'value_type' + , defaults_eraser.erase_container_compare ) -vector_traits = container_traits_impl_t( 'vector', 0, 'value_type', defaults_eraser.erase_allocator ) +vector_traits = create_traits( 'vector' + , 0 + , 'value_type' + , defaults_eraser.erase_allocator ) -stack_traits = container_traits_impl_t( 'stack', 0, 'value_type', defaults_eraser.erase_container ) +stack_traits = create_traits( 'stack' + , 0 + , 'value_type' + , defaults_eraser.erase_container ) -map_traits = container_traits_impl_t( 'map', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) -multimap_traits = container_traits_impl_t( 'multimap', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) +map_traits = create_traits( 'map' + , 1 + , 'mapped_type' + , defaults_eraser.erase_map_compare_allocator + , key_type_index=0 + , key_type_typedef='key_type') + +multimap_traits = create_traits( 'multimap' + , 1 + , 'mapped_type' + , defaults_eraser.erase_map_compare_allocator + , key_type_index=0 + , key_type_typedef='key_type') -hash_map_traits = container_traits_impl_t( 'hash_map', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) -hash_multimap_traits = container_traits_impl_t( 'hash_multimap', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) -set_traits = container_traits_impl_t( 'set', 0, 'value_type', defaults_eraser.erase_compare_allocator) -multiset_traits = container_traits_impl_t( 'multiset', 0, 'value_type', defaults_eraser.erase_compare_allocator ) +hash_map_traits = create_traits( 'hash_map' + , 1 + , 'mapped_type' + , defaults_eraser.erase_hashmap_compare_allocator + , key_type_index=0 + , key_type_typedef='key_type') + + +hash_multimap_traits = create_traits( 'hash_multimap' + , 1 + , 'mapped_type' + , defaults_eraser.erase_hashmap_compare_allocator + , key_type_index=0 + , key_type_typedef='key_type') -hash_set_traits = container_traits_impl_t( 'hash_set', 0, 'value_type', defaults_eraser.erase_hash_allocator ) -hash_multiset_traits = container_traits_impl_t( 'hash_multiset', 0, 'value_type', defaults_eraser.erase_hash_allocator ) +set_traits = create_traits( 'set' + , 0 + , 'value_type' + , defaults_eraser.erase_compare_allocator) + +multiset_traits = create_traits( 'multiset' + , 0 + , 'value_type' + , defaults_eraser.erase_compare_allocator ) +hash_set_traits = create_traits( 'hash_set' + , 0 + , 'value_type' + , defaults_eraser.erase_hash_allocator ) + +hash_multiset_traits = create_traits( 'hash_multiset' + , 0 + , 'value_type' + , defaults_eraser.erase_hash_allocator ) + container_traits = ( list_traits , deque_traits Modified: pygccxml_dev/unittests/find_container_traits_tester.py =================================================================== --- pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-26 08:55:58 UTC (rev 1407) +++ pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-26 11:23:56 UTC (rev 1408) @@ -23,7 +23,7 @@ tester_t.global_ns = declarations.get_global_namespace( decls ) tester_t.global_ns.init_optimizer() - def __cmp_traits( self, typedef, expected, partial_name): + def __cmp_traits( self, typedef, expected, partial_name, key_type=None): if isinstance( typedef, str ): typedef = self.global_ns.typedef( typedef ) traits = declarations.find_container_traits( typedef ) @@ -34,7 +34,21 @@ cls = declarations.remove_declarated( typedef ) self.failUnless( cls.container_traits is expected ) self.failUnless( cls.partial_name == partial_name ) - + cls = traits.class_declaration( cls ) + + self.failUnless( traits.element_type( typedef ) ) + self.failUnless( cls.cache.container_element_type, "For some reason cache was not updated" ) + + if key_type: + self.failUnless( traits.is_mapping( typedef ) ) + real_key_type = traits.key_type( typedef ) + self.failUnless( real_key_type.decl_string == key_type + , 'Error extracting key type. Expected type "%s", got "%s"' + % ( key_type, real_key_type.decl_string ) ) + self.failUnless( cls.cache.container_key_type, "For some reason cache was not updated" ) + else: + self.failUnless( traits.is_sequence( typedef ) ) + def test_find_traits( self ): self.__cmp_traits( 'v_int', declarations.vector_traits, "vector< int >" ) self.__cmp_traits( 'l_int', declarations.list_traits, "list< int >" ) @@ -43,12 +57,12 @@ self.__cmp_traits( 'pq_int', declarations.priority_queue_traits, "priority_queue< int >") self.__cmp_traits( 's_v_int', declarations.set_traits, "set< std::vector< int > >") self.__cmp_traits( 'ms_v_int', declarations.multiset_traits, "multiset< std::vector< int > >") - self.__cmp_traits( 'm_i2d', declarations.map_traits, "map< int, double >" ) - self.__cmp_traits( 'mm_i2d', declarations.multimap_traits, "multimap< int, double >" ) + self.__cmp_traits( 'm_i2d', declarations.map_traits, "map< int, double >", 'int' ) + self.__cmp_traits( 'mm_i2d', declarations.multimap_traits, "multimap< int, double >", 'int' ) self.__cmp_traits( 'hs_v_int', declarations.hash_set_traits, "hash_set< std::vector< int > >" ) self.__cmp_traits( 'mhs_v_int', declarations.hash_multiset_traits, "hash_multiset< std::vector< int > >" ) - self.__cmp_traits( 'hm_i2d', declarations.hash_map_traits, "hash_map< int, double >" ) - self.__cmp_traits( 'hmm_i2d', declarations.hash_multimap_traits, "hash_multimap< int, double >" ) + self.__cmp_traits( 'hm_i2d', declarations.hash_map_traits, "hash_map< int, double >", 'int' ) + self.__cmp_traits( 'hmm_i2d', declarations.hash_multimap_traits, "hash_multimap< int, double >", 'int' ) def test_multimap( self ): mm = self.global_ns.classes( lambda decl: decl.name.startswith( 'multimap' ) ) Modified: pygccxml_dev/unittests/vector_traits_tester.py =================================================================== --- pygccxml_dev/unittests/vector_traits_tester.py 2008-08-26 08:55:58 UTC (rev 1407) +++ pygccxml_dev/unittests/vector_traits_tester.py 2008-08-26 11:23:56 UTC (rev 1408) @@ -29,6 +29,7 @@ traits = declarations.vector_traits self.failUnless( traits.is_my_case( container ) ) self.failUnless( declarations.is_same( value_type, traits.element_type( container ) ) ) + self.failUnless( traits.is_sequence( container ) ) def test_global_ns( self ): value_type = self.global_ns.class_( '_0_' ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-16 12:56:40
|
Revision: 1469 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1469&view=rev Author: roman_yakovenko Date: 2008-12-16 12:56:36 +0000 (Tue, 16 Dec 2008) Log Message: ----------- adding new functionality and improving initial environment handling Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/common_utils.py pygccxml_dev/pygccxml/utils/__init__.py pygccxml_dev/unittests/autoconfig.py Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-16 08:51:37 UTC (rev 1468) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-16 12:56:36 UTC (rev 1469) @@ -37,7 +37,7 @@ #__unDName definition was taken from: #http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/2006-02/msg00754.html -msvcrxx = ctypes.CDLL( msvc_cfg.msvcr_path, mode=ctypes.RTLD_GLOBAL) +msvcrxx = ctypes.windll.msvcr71 #ctypes.CDLL( msvc_cfg.msvcr_path, mode=ctypes.RTLD_GLOBAL) free_type = ctypes.CFUNCTYPE( None, ctypes.c_void_p ) #free type malloc_type = ctypes.CFUNCTYPE( ctypes.c_void_p, ctypes.c_uint ) #malloc type Modified: pygccxml_dev/pygccxml/utils/__init__.py =================================================================== --- pygccxml_dev/pygccxml/utils/__init__.py 2008-12-16 08:51:37 UTC (rev 1468) +++ pygccxml_dev/pygccxml/utils/__init__.py 2008-12-16 12:56:36 UTC (rev 1469) @@ -119,38 +119,50 @@ def fdel(s): del s.__dict__[private] super(cached, self).__init__(fget, fdel=fdel) - + @staticmethod def reset(self): cls = self.__class__ for name in dir(cls): attr = getattr(cls, name) if isinstance(attr, cached): - delattr(self, name) + delattr(self, name) class enum( object ): """Usage example: class fruits(enum): apple = 0 orange = 1 - + fruits.has_value( 1 ) fruits.name_of( 1 ) """ - + @classmethod def has_value( cls, enum_numeric_value ): - for name, value in cls.__dict__.iteritems(): + for name, value in cls.__dict__.iteritems(): if enum_numeric_value == value: return True else: return False - + @classmethod def name_of( cls, enum_numeric_value ): - for name, value in cls.__dict__.iteritems(): + for name, value in cls.__dict__.iteritems(): if enum_numeric_value == value: return name else: raise RuntimeError( 'Unable to find name for value(%d) in enumeration "%s"' % ( enum_numeric_value, cls.__name__ ) ) + +class native_compiler: + """provides information about "native compiler", which was used to build this Python executable""" + + @staticmethod + def get_version(): + if 'win' not in sys.platform: + return None #not implemented yet + from distutils import msvccompiler + return ( 'msvc', str( msvccompiler.get_build_version() ) ) + + Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2008-12-16 08:51:37 UTC (rev 1468) +++ pygccxml_dev/unittests/autoconfig.py 2008-12-16 12:56:36 UTC (rev 1469) @@ -12,24 +12,13 @@ this_module_dir_path = os.path.abspath ( os.path.dirname( sys.modules[__name__].__file__) ) -compiler = None + data_directory = os.path.join( this_module_dir_path, 'data' ) build_directory = os.path.join( this_module_dir_path, 'temp' ) -gccxml_07_path = os.path.join( this_module_dir_path, '..', '..', 'gccxml_bin', 'v07', sys.platform, 'bin' ) -gccxml_09_path = os.path.join( this_module_dir_path, '..', '..', 'gccxml_bin', 'v09', sys.platform, 'bin' ) +gccxml_path = os.path.join( this_module_dir_path, '..', '..', 'gccxml_bin', 'v09', sys.platform, 'bin' ) +gccxml_version = '__GCCXML_09__' -gccxml_path = gccxml_09_path - -gccxml_version = '__GCCXML_07__' -if '09' in gccxml_path: - gccxml_version = '__GCCXML_09__' - -print 'compiler: ', gccxml_version - -if sys.platform == 'win32': - compiler = 'msvc71' - try: import pygccxml print 'unittests will run on INSTALLED version' @@ -38,25 +27,31 @@ import pygccxml print 'unittests will run on DEVELOPMENT version' +compiler = pygccxml.utils.native_compiler.get_version() +if compiler: + compiler = compiler[0] + compiler[1].replace( '.', '' ) + +print 'GCCXML configured to simulate compiler ', compiler + pygccxml.declarations.class_t.USE_DEMANGLED_AS_NAME = True class cxx_parsers_cfg: - + keywd = { 'working_directory' : data_directory , 'define_symbols' : [ gccxml_version ] , 'compiler' : compiler } - + if os.path.exists( os.path.join( gccxml_path, 'gccxml' ) ) \ or os.path.exists( os.path.join( gccxml_path, 'gccxml.exe' ) ): keywd[ 'gccxml_path'] = gccxml_path gccxml = pygccxml.parser.gccxml_configuration_t( **keywd ) - + pdb_loader = None if sys.platform == 'win32': - from pygccxml.msvc import pdb + from pygccxml.msvc import mspdb pdb_file = os.path.join( data_directory, 'msvc_build', 'Debug', 'msvc_build.pdb' ) if os.path.exists( pdb_file ): - pdb_loader = pdb.decl_loader_t( pdb_file ) + pdb_loader = mspdb.decl_loader_t( pdb_file ) pdb_loader.read() def get_pdb_global_ns(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-17 09:05:48
|
Revision: 1472 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1472&view=rev Author: roman_yakovenko Date: 2008-12-17 09:05:44 +0000 (Wed, 17 Dec 2008) Log Message: ----------- functionality, which returns compiler name as gccxml expects was added Modified Paths: -------------- pygccxml_dev/pygccxml/utils/__init__.py pygccxml_dev/unittests/autoconfig.py Modified: pygccxml_dev/pygccxml/utils/__init__.py =================================================================== --- pygccxml_dev/pygccxml/utils/__init__.py 2008-12-16 22:16:38 UTC (rev 1471) +++ pygccxml_dev/pygccxml/utils/__init__.py 2008-12-17 09:05:44 UTC (rev 1472) @@ -165,4 +165,12 @@ from distutils import msvccompiler return ( 'msvc', str( msvccompiler.get_build_version() ) ) + @staticmethod + def get_gccxml_compiler(): + compiler = native_compiler.get_version() + if not compiler: + return None + else: + return compiler[0] + compiler[1].replace( '.', '' ) + Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2008-12-16 22:16:38 UTC (rev 1471) +++ pygccxml_dev/unittests/autoconfig.py 2008-12-17 09:05:44 UTC (rev 1472) @@ -27,9 +27,7 @@ import pygccxml print 'unittests will run on DEVELOPMENT version' -compiler = pygccxml.utils.native_compiler.get_version() -if compiler: - compiler = compiler[0] + compiler[1].replace( '.', '' ) +compiler = pygccxml.utils.native_compiler.get_gccxml_compiler() print 'GCCXML configured to simulate compiler ', compiler This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-19 22:50:38
|
Revision: 1478 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1478&view=rev Author: roman_yakovenko Date: 2008-12-19 22:50:32 +0000 (Fri, 19 Dec 2008) Log Message: ----------- commit few changes, which allow to extract all public(exported) symbols Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/common_utils.py pygccxml_dev/pygccxml/msvc/mspdb/enums.py pygccxml_dev/pygccxml/msvc/mspdb/loader.py pygccxml_dev/unittests/autoconfig.py Added Paths: ----------- pygccxml_dev/unittests/mspdb_playground.py Property Changed: ---------------- pygccxml_dev/pygccxml/msvc/ Property changes on: pygccxml_dev/pygccxml/msvc ___________________________________________________________________ Added: svn:ignore + *.pyc Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-18 06:51:01 UTC (rev 1477) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-19 22:50:32 UTC (rev 1478) @@ -1,28 +1,23 @@ import ctypes -import ctypes.wintypes -import config as msvc_cfg class UNDECORATE_NAME_OPTIONS: - UNDNAME_COMPLETE = 0x0000 #Enables full undecoration. - UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 #Removes leading underscores from Microsoft extended keywords. - UNDNAME_NO_MS_KEYWORDS = 0x0002 #Disables expansion of Microsoft extended keywords. - UNDNAME_NO_FUNCTION_RETURNS = 0x0004 #Disables expansion of return type for primary declaration. - UNDNAME_NO_ALLOCATION_MODEL = 0x0008 #Disables expansion of the declaration model. - UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 #Disables expansion of the declaration language specifier. - UNDNAME_RESERVED1 = 0x0020 #RESERVED. - UNDNAME_RESERVED2 = 0x0040 #RESERVED. - UNDNAME_NO_THISTYPE = 0x0060 #Disables all modifiers on the this type. - UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 #Disables expansion of access specifiers for members. - UNDNAME_NO_THROW_SIGNATURES = 0x0100 #Disables expansion of "throw-signatures" for functions and pointers to functions. - UNDNAME_NO_MEMBER_TYPE = 0x0200 #Disables expansion of static or virtual members. - UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 #Disables expansion of the Microsoft model for UDT returns. - UNDNAME_32_BIT_DECODE = 0x0800 #Undecorates 32-bit decorated names. - UNDNAME_NAME_ONLY = 0x1000 #Gets only the name for primary declaration; returns just [scope::]name. Expands template params. - UNDNAME_TYPE_ONLY = 0x2000 #Input is just a type encoding; composes an abstract declarator. - UNDNAME_HAVE_PARAMETERS = 0x4000 #The real template parameters are available. - UNDNAME_NO_ECSU = 0x8000 #Suppresses enum/class/struct/union. - UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000 #Suppresses check for valid identifier characters. - UNDNAME_NO_PTR64 = 0x20000 #Does not include ptr64 in output. + UNDNAME_COMPLETE = 0 + UNDNAME_NO_LEADING_UNDERSCORES = 1 + UNDNAME_NO_MS_KEYWORDS = 2 + UNDNAME_NO_FUNCTION_RETURNS = 4 + UNDNAME_NO_ALLOCATION_MODEL = 8 + UNDNAME_NO_ALLOCATION_LANGUAGE = 16 + UNDNAME_NO_MS_THISTYPE = 32 + UNDNAME_NO_CV_THISTYPE = 64 + UNDNAME_NO_THISTYPE = 96 + UNDNAME_NO_ACCESS_SPECIFIERS = 128 + UNDNAME_NO_THROW_SIGNATURES = 256 + UNDNAME_NO_MEMBER_TYPE = 512 + UNDNAME_NO_RETURN_UDT_MODEL = 1024 + UNDNAME_32_BIT_DECODE = 2048 + UNDNAME_NAME_ONLY = 4096 + UNDNAME_NO_ARGUMENTS = 8192 + UNDNAME_NO_SPECIAL_SYMS = 16384 UNDNAME_SCOPES_ONLY = UNDNAME_NO_LEADING_UNDERSCORES \ | UNDNAME_NO_MS_KEYWORDS \ @@ -31,40 +26,18 @@ | UNDNAME_NO_ALLOCATION_LANGUAGE \ | UNDNAME_NO_ACCESS_SPECIFIERS \ | UNDNAME_NO_THROW_SIGNATURES \ - | UNDNAME_NO_MEMBER_TYPE \ - | UNDNAME_NO_ECSU \ - | UNDNAME_NO_IDENT_CHAR_CHECK + | UNDNAME_NO_MEMBER_TYPE -#__unDName definition was taken from: -#http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/2006-02/msg00754.html -msvcrxx = ctypes.windll.msvcr71 #ctypes.CDLL( msvc_cfg.msvcr_path, mode=ctypes.RTLD_GLOBAL) -free_type = ctypes.CFUNCTYPE( None, ctypes.c_void_p ) #free type -malloc_type = ctypes.CFUNCTYPE( ctypes.c_void_p, ctypes.c_uint ) #malloc type +undecorate_name_impl = ctypes.windll.dbghelp.UnDecorateSymbolName +undecorate_name_impl.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint] - -__unDName = msvcrxx.__unDName -__unDName.argtypes = [ ctypes.c_char_p #undecorated name - , ctypes.c_char_p #decorated name - , ctypes.c_int #sizeof undecorated name - , malloc_type - , free_type - , ctypes.c_ushort #flags - ] -__unDName.restype = ctypes.c_char_p - - def undecorate_name( name, options=None ): - if not name: - return '' if options is None: - options = UNDECORATE_NAME_OPTIONS.UNDNAME_NO_ECSU - buffer_size = 1024 * 32 - undecorated_name = ctypes.create_string_buffer('\0' * buffer_size) #should be enouph for any symbol - __unDName( undecorated_name - , name - , buffer_size - , malloc_type( msvcrxx.malloc ) - , free_type( msvcrxx.free ) - , options ) - return undecorated_name.value + options = UNDECORATE_NAME_OPTIONS.UNDNAME_COMPLETE + buffer = ctypes.create_string_buffer(1024*16) + res = undecorate_name_impl(name, buffer, ctypes.sizeof(buffer), options) + if res: + return str(buffer[:res]) + else: + return name Modified: pygccxml_dev/pygccxml/msvc/mspdb/enums.py =================================================================== --- pygccxml_dev/pygccxml/msvc/mspdb/enums.py 2008-12-18 06:51:01 UTC (rev 1477) +++ pygccxml_dev/pygccxml/msvc/mspdb/enums.py 2008-12-19 22:50:32 UTC (rev 1478) @@ -58,3 +58,46 @@ DataIsStaticMember = 8 DataIsConstant = 9 + +class UNDECORATE_NAME_OPTIONS: + UNDNAME_COMPLETE = 0x0000 #Enables full undecoration. + UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 #Removes leading underscores from Microsoft extended keywords. + UNDNAME_NO_MS_KEYWORDS = 0x0002 #Disables expansion of Microsoft extended keywords. + UNDNAME_NO_FUNCTION_RETURNS = 0x0004 #Disables expansion of return type for primary declaration. + UNDNAME_NO_ALLOCATION_MODEL = 0x0008 #Disables expansion of the declaration model. + UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 #Disables expansion of the declaration language specifier. + UNDNAME_RESERVED1 = 0x0020 #RESERVED. + UNDNAME_RESERVED2 = 0x0040 #RESERVED. + UNDNAME_NO_THISTYPE = 0x0060 #Disables all modifiers on the this type. + UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 #Disables expansion of access specifiers for members. + UNDNAME_NO_THROW_SIGNATURES = 0x0100 #Disables expansion of "throw-signatures" for functions and pointers to functions. + UNDNAME_NO_MEMBER_TYPE = 0x0200 #Disables expansion of static or virtual members. + UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 #Disables expansion of the Microsoft model for UDT returns. + UNDNAME_32_BIT_DECODE = 0x0800 #Undecorates 32-bit decorated names. + UNDNAME_NAME_ONLY = 0x1000 #Gets only the name for primary declaration; returns just [scope::]name. Expands template params. + UNDNAME_TYPE_ONLY = 0x2000 #Input is just a type encoding; composes an abstract declarator. + UNDNAME_HAVE_PARAMETERS = 0x4000 #The real template parameters are available. + UNDNAME_NO_ECSU = 0x8000 #Suppresses enum/class/struct/union. + UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000 #Suppresses check for valid identifier characters. + UNDNAME_NO_PTR64 = 0x20000 #Does not include ptr64 in output. + + UNDNAME_SCOPES_ONLY = UNDNAME_NO_LEADING_UNDERSCORES \ + | UNDNAME_NO_MS_KEYWORDS \ + | UNDNAME_NO_FUNCTION_RETURNS \ + | UNDNAME_NO_ALLOCATION_MODEL \ + | UNDNAME_NO_ALLOCATION_LANGUAGE \ + | UNDNAME_NO_ACCESS_SPECIFIERS \ + | UNDNAME_NO_THROW_SIGNATURES \ + | UNDNAME_NO_MEMBER_TYPE \ + | UNDNAME_NO_ECSU \ + | UNDNAME_NO_IDENT_CHAR_CHECK + + UNDNAME_SHORT_UNIQUE = UNDNAME_NO_LEADING_UNDERSCORES \ + | UNDNAME_NO_MS_KEYWORDS \ + | UNDNAME_NO_ALLOCATION_MODEL \ + | UNDNAME_NO_ALLOCATION_LANGUAGE \ + | UNDNAME_NO_ACCESS_SPECIFIERS \ + | UNDNAME_NO_THROW_SIGNATURES \ + | UNDNAME_NO_MEMBER_TYPE \ + | UNDNAME_NO_ECSU \ + | UNDNAME_NO_IDENT_CHAR_CHECK Modified: pygccxml_dev/pygccxml/msvc/mspdb/loader.py =================================================================== --- pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-18 06:51:01 UTC (rev 1477) +++ pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-19 22:50:32 UTC (rev 1478) @@ -83,13 +83,37 @@ smbls = {} for smbl in itertools.imap( as_symbol, as_enum_variant( self.symbols_table._NewEnum ) ): smbl.uname = msvc_utils.undecorate_name( smbl.name, msvc_utils.UNDECORATE_NAME_OPTIONS.UNDNAME_SCOPES_ONLY ) - def smbl_undecorate_name( options = None ): + def smbl_undecorate_name( options=None ): return msvc_utils.undecorate_name( smbl.name, options ) smbl.undecorate_name = smbl_undecorate_name smbls[ smbl.symIndexId ] = smbl self.logger.info( 'loading symbols(%d) from the file - done', len( smbls ) ) return smbls + @utils.cached + def public_symbols( self ): + self.logger.info( 'loading public symbols from the file' ) + smbls = {} + for smbl in self.symbols.itervalues(): + if not smbl.function: + continue + if not smbl.name: + continue + undecorated_name = smbl.get_undecoratedNameEx( enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SCOPES_ONLY ) + if not undecorated_name: + continue + if smbl.name.startswith( '__' ): + continue + if undecorated_name.startswith( '__' ): + continue + if undecorated_name.startswith( '@' ): + continue + if undecorated_name.startswith( 'type_info::' ): + continue + smbls[ smbl.symIndexId ] = smbl + self.logger.info( 'loading public symbols(%d) from the file - done', len( smbls ) ) + return smbls + def __load_nss(self): def ns_filter( smbl ): self.logger.debug( '__load_ns.ns_filter, %s', smbl.uname ) @@ -701,3 +725,4 @@ if not isinstance( my_type, declarations.volatile_t ): my_type = declarations.volatile_t( my_type ) return my_type + Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2008-12-18 06:51:01 UTC (rev 1477) +++ pygccxml_dev/unittests/autoconfig.py 2008-12-19 22:50:32 UTC (rev 1478) @@ -44,13 +44,13 @@ keywd[ 'gccxml_path'] = gccxml_path gccxml = pygccxml.parser.gccxml_configuration_t( **keywd ) - pdb_loader = None - if sys.platform == 'win32': - from pygccxml.msvc import mspdb - pdb_file = os.path.join( data_directory, 'msvc_build', 'Debug', 'msvc_build.pdb' ) - if os.path.exists( pdb_file ): - pdb_loader = mspdb.decl_loader_t( pdb_file ) - pdb_loader.read() + #~ pdb_loader = None + #~ if sys.platform == 'win32': + #~ from pygccxml.msvc import mspdb + #~ pdb_file = os.path.join( data_directory, 'msvc_build', 'Debug', 'msvc_build.pdb' ) + #~ if os.path.exists( pdb_file ): + #~ pdb_loader = mspdb.decl_loader_t( pdb_file ) + #~ pdb_loader.read() def get_pdb_global_ns(): if cxx_parsers_cfg.pdb_loader: Added: pygccxml_dev/unittests/mspdb_playground.py =================================================================== --- pygccxml_dev/unittests/mspdb_playground.py (rev 0) +++ pygccxml_dev/unittests/mspdb_playground.py 2008-12-19 22:50:32 UTC (rev 1478) @@ -0,0 +1,37 @@ +import os +import unittest +import autoconfig + +import pprint +from pygccxml.msvc import mspdb +from pygccxml import declarations +from pygccxml.msvc import common_utils as msvc_utils + +pdb_file = r'E:\development\language-binding\pyplusplus_dev\pyplusplus\cpptypes\mydll\release\mydll.pdb' + +reader = mspdb.decl_loader_t( pdb_file ) +opt = mspdb.enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE + +d = {} +for smbl in reader.public_symbols.itervalues(): + name = smbl.name + undecorated_name = smbl.get_undecoratedNameEx(opt).strip() + if undecorated_name.endswith( ')const' ): + undecorated_name = undecorated_name[ : -len('const')] + d[ name ] = undecorated_name + d[ undecorated_name ] = name + +pprint.pprint( d ) + +#~ reader.read() +#~ f = file( 'decls.cpp', 'w+' ) +#~ declarations.print_declarations( reader.global_ns, writer=lambda line: f.write(line+'\n') ) +#~ f.close() + +#~ f = file( 'symbols.txt', 'w+') +#~ for smbl in reader.symbols.itervalues(): + #~ f.write( smbl.uname ) + #~ f.write( os.linesep ) + #~ f.write( '\t' + str(smbl.name) ) +#~ f.close() + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-21 22:28:20
|
Revision: 1483 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1483&view=rev Author: roman_yakovenko Date: 2008-12-21 22:28:17 +0000 (Sun, 21 Dec 2008) Log Message: ----------- adding ability to dump exported classes Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/mspdb/loader.py pygccxml_dev/unittests/mspdb_playground.py Modified: pygccxml_dev/pygccxml/msvc/mspdb/loader.py =================================================================== --- pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-21 19:02:08 UTC (rev 1482) +++ pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-21 22:28:17 UTC (rev 1483) @@ -81,7 +81,14 @@ def symbols(self): self.logger.info( 'loading symbols from the file' ) smbls = {} + useless = ( msdia.SymTagAnnotation + , msdia.SymTagBlock + , msdia.SymTagFuncDebugStart + , msdia.SymTagFuncDebugEnd + , msdia.SymTagManagedType ) for smbl in itertools.imap( as_symbol, as_enum_variant( self.symbols_table._NewEnum ) ): + if smbl.symTag in useless: + continue smbl.uname = msvc_utils.undecorate_name( smbl.name, msvc_utils.UNDECORATE_NAME_OPTIONS.UNDNAME_SCOPES_ONLY ) def smbl_undecorate_name( options=None ): return msvc_utils.undecorate_name( smbl.name, options ) @@ -92,47 +99,64 @@ @utils.cached def public_symbols( self ): - self.logger.info( 'loading public symbols from the file' ) - smbls = {} + """dictionary, where key is reference to public symbol, and value is symbol itself""" + self.logger.info( 'loading public symbols' ) + self.logger.info( 'looking for public symbols' ) + public_smbls = {} + undname_flags = enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE for smbl in self.symbols.itervalues(): - if not smbl.function: + if not smbl.function or not smbl.name or smbl.name.startswith( '__' ): continue - if not smbl.name: + undecorated_name = smbl.get_undecoratedNameEx( undname_flags ) + if not undecorated_name: continue - undecorated_name = smbl.get_undecoratedNameEx( enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SCOPES_ONLY ) + for prefix in ( '__', '@', 'type_info::' ): + if undecorated_name.startswith( prefix ): + break + else: + assert undecorated_name not in public_smbls + public_smbls[ undecorated_name ] = smbl + self.logger.info( 'looking for public symbols(%d) - done', len(public_smbls) ) + self.logger.info( 'mapping public symbols to real symbols') + smbls = {} + for smbl in self.symbols.itervalues(): + undecorated_name = smbl.get_undecoratedNameEx( undname_flags ) if not undecorated_name: continue - if smbl.name.startswith( '__' ): + undecorated_name = undecorated_name.strip() + if undecorated_name not in public_smbls: continue - if undecorated_name.startswith( '__' ): - continue - if undecorated_name.startswith( '@' ): - continue - if undecorated_name.startswith( 'type_info::' ): - continue - smbls[ smbl.symIndexId ] = smbl - self.logger.info( 'loading public symbols(%d) from the file - done', len( smbls ) ) + smbls[ public_smbls[undecorated_name] ] = smbl + self.logger.info( 'mapping public symbols(%d) to real symbols - done', len( smbls ) ) + self.logger.info( 'loading public symbols(%d) - done', len( smbls ) ) return smbls + @utils.cached + def public_classes( self ): + """returns set of public classes, which derives from the set of public symbols""" + self.logger.info( 'loading public classes' ) + classes = {} + for smbl in self.public_symbols.itervalues(): + parent = smbl.classParent + while parent: + classes[ parent.symIndexId ] = self.symbols[ parent.symIndexId ] + parent = parent.classParent + self.logger.info( 'loading public classes(%d) - done', len(classes) ) + return classes + def __load_nss(self): def ns_filter( smbl ): self.logger.debug( '__load_ns.ns_filter, %s', smbl.uname ) tags = ( msdia.SymTagFunction , msdia.SymTagBlock , msdia.SymTagData - #~ , msdia.SymTagAnnotation - #~ , msdia.SymTagPublicSymbol , msdia.SymTagUDT , msdia.SymTagEnum - #~ , msdia.SymTagFunctionType - #~ , msdia.SymTagPointerType , msdia.SymTagArrayType , msdia.SymTagBaseType , msdia.SymTagTypedef , msdia.SymTagBaseClass , msdia.SymTagFriend - #~ , msdia.SymTagFunctionArgType - #~ , msdia.SymTagUsingNamespace ) if smbl.symTag not in tags: self.logger.debug( 'smbl.symTag not in tags, %s', smbl.uname ) @@ -142,9 +166,6 @@ elif not smbl.name: self.logger.debug( 'not smbl.name, %s', smbl.uname ) return False - #~ elif '-' in smbl.name: - #~ self.logger.debug( '"-" in smbl.name, %s', smbl.uname ) - #~ return False elif smbl.classParent: parent_smbl = self.symbols[ smbl.classParentId ] while parent_smbl: @@ -291,25 +312,6 @@ self.__parent_exist.add( parent_name ) return bool( found ) - def __clear_symbols(self): - self.logger.info( 'clearing symbols' ) - to_be_deleted = [] - useless_tags = ( - msdia.SymTagAnnotation - , msdia.SymTagPublicSymbol - , msdia.SymTagBlock - , msdia.SymTagFuncDebugStart - , msdia.SymTagFuncDebugEnd - ) - for smbl_id, smbl in self.symbols.iteritems(): - if smbl.symTag in useless_tags \ - or ( smbl.symTag == msdia.SymTagData and not self.__is_my_var( smbl ) ): - to_be_deleted.append( smbl_id ) - - map( lambda smbl_id: self.symbols.pop( smbl_id ), to_be_deleted ) - self.logger.info( 'clearing symbols(%d) - done', len( to_be_deleted ) ) - - def __normalize_name( self, decl ): if decl.name == '<unnamed-tag>': decl.name = '' @@ -333,18 +335,23 @@ map( self.__join_unnamed_nss , ns_parent.namespaces( recursive=False, allow_empty=True ) ) + def __remove_empty_nss( self, ns_parent ): + for ns in ns_parent.namespaces( recursive=False, allow_empty=True ): + self.__remove_empty_nss( ns ) + if 0 == len( ns.decls( recursive=False, allow_empty=True ) ): + ns_parent.remove_declaration( ns ) def read(self): - self.__clear_symbols() self.__load_nss() self.__load_classes() self.__load_base_classes() - self.__load_enums() - self.__load_vars() - self.__load_typedefs() - self.__load_calldefs() + #~ self.__load_enums() + #~ self.__load_vars() + #~ self.__load_typedefs() + #~ self.__load_calldefs() map( self.__normalize_name, self.global_ns.decls(recursive=True) ) self.__join_unnamed_nss( self.global_ns ) + self.__remove_empty_nss( self.global_ns ) #join unnamed namespaces @property @@ -400,14 +407,15 @@ def __load_classes( self ): - classes = {}#unique symbol id : class decl - is_udt = lambda smbl: smbl.symTag == msdia.SymTagUDT + classes = {} + #~ is_udt = lambda smbl: smbl.symTag == msdia.SymTagUDT self.logger.info( 'building udt objects' ) - for udt_smbl in itertools.ifilter( is_udt, self.symbols.itervalues() ): + #for udt_smbl in itertools.ifilter( is_udt, self.symbols.itervalues() ): + for udt_smbl in self.public_classes.itervalues(): classes[udt_smbl.symIndexId] = self.__create_class(udt_smbl) self.logger.info( 'building udt objects(%d) - done', len(classes) ) - self.logger.info( 'integrating udt objects with namespaces' ) + self.logger.info( 'integrating class objects with namespaces' ) does_parent_exists = self.parent_exists_t( self.global_ns, classes, self.__id2decl ) while classes: to_be_integrated = len( classes ) @@ -431,6 +439,9 @@ base_id = smbl.type.symIndexId derived_id = smbl.classParentId + if base_id not in self.public_classes or derived_id not in self.public_classes: + continue + hi_base = make_hi( self.__id2decl[base_id] , self.__guess_access_type( smbl ) , bool( smbl.virtualBaseClass ) ) @@ -530,6 +541,8 @@ self.logger.info( 'building function objects' ) is_function = lambda smbl: smbl.symTag == msdia.SymTagFunction for functions_count, function_smbl in enumerate( itertools.ifilter( is_function, self.symbols.itervalues() ) ): + if function_smbl.classParent and function_smbl.classParentId not in self.public_classes: #what about base classes + continue function_decl = self.__create_calldef(function_smbl) if function_decl: self.__update_decls_tree( function_decl ) @@ -562,15 +575,13 @@ def __create_calldef( self, smbl ): self.logger.debug( 'creating calldef "%s"', smbl.uname ) - #~ if smbl.uname == 'some_function': - #~ pdb.set_trace() name_splitter = impl_details.get_name_splitter( smbl.uname ) calldef_type = self.create_type( smbl.type ) #what does happen with constructor? decl = None if isinstance( calldef_type, declarations.member_function_type_t ): could_be_static = False could_be_const = False - if smbl.uname.startswith( '~' ): + if '~' in smbl.uname: decl = declarations.destructor_t() if not decl: #may be operator decl = self.__guess_operator_type(smbl, calldef_type) Modified: pygccxml_dev/unittests/mspdb_playground.py =================================================================== --- pygccxml_dev/unittests/mspdb_playground.py 2008-12-21 19:02:08 UTC (rev 1482) +++ pygccxml_dev/unittests/mspdb_playground.py 2008-12-21 22:28:17 UTC (rev 1483) @@ -12,21 +12,37 @@ reader = mspdb.decl_loader_t( pdb_file ) opt = mspdb.enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE -d = {} -for smbl in reader.public_symbols.itervalues(): +public_smbls = {} +for smbl in reader.public_symbols.iterkeys(): name = smbl.name undecorated_name = smbl.get_undecoratedNameEx(opt).strip() if undecorated_name.endswith( ')const' ): undecorated_name = undecorated_name[ : -len('const')] - d[ name ] = undecorated_name - d[ undecorated_name ] = name + public_smbls[ name ] = undecorated_name + public_smbls[ undecorated_name ] = name -pprint.pprint( d ) +pprint.pprint( public_smbls ) -#~ reader.read() -#~ f = file( 'decls.cpp', 'w+' ) -#~ declarations.print_declarations( reader.global_ns, writer=lambda line: f.write(line+'\n') ) -#~ f.close() +#~ for smbl in reader.symbols.itervalues(): + #~ if not smbl.classParent: + #~ continue + #~ undecorated_name = smbl.get_undecoratedNameEx(opt) + #~ if not undecorated_name: + #~ continue + #~ undecorated_name = undecorated_name.strip() + #~ if undecorated_name not in public_smbls: + #~ continue + #~ print '--------------------------------------' + #~ print 'mem fun: ', undecorated_name + #~ if smbl.classParent: + #~ print 'parent class: ', smbl.classParent.name + #~ else: + #~ print 'no parent' + #~ print '======================================' +reader.read() +f = file( 'decls.cpp', 'w+' ) +declarations.print_declarations( reader.global_ns, writer=lambda line: f.write(line+'\n') ) +f.close() #~ f = file( 'symbols.txt', 'w+') #~ for smbl in reader.symbols.itervalues(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-22 22:52:25
|
Revision: 1485 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1485&view=rev Author: roman_yakovenko Date: 2008-12-22 22:52:20 +0000 (Mon, 22 Dec 2008) Log Message: ----------- adding ability to format function names, so they will be similar to ones, ctreated by UnDecorateSymbolName Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/calldef.py pygccxml_dev/pygccxml/msvc/mspdb/enums.py pygccxml_dev/pygccxml/msvc/mspdb/loader.py pygccxml_dev/pygccxml/utils/__init__.py pygccxml_dev/unittests/mspdb_playground.py Added Paths: ----------- pygccxml_dev/unittests/data/msvc/ pygccxml_dev/unittests/data/msvc/mydll.90.vcproj pygccxml_dev/unittests/data/msvc/mydll.cpp pygccxml_dev/unittests/data/msvc/mydll.h Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2008-12-22 22:11:51 UTC (rev 1484) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2008-12-22 22:52:20 UTC (rev 1485) @@ -104,7 +104,9 @@ from calldef import casting_operator_t from calldef import free_function_t from calldef import free_operator_t +from calldef import create_undecorated_name + from decl_visitor import decl_visitor_t from type_visitor import type_visitor_t Modified: pygccxml_dev/pygccxml/declarations/calldef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/calldef.py 2008-12-22 22:11:51 UTC (rev 1484) +++ pygccxml_dev/pygccxml/declarations/calldef.py 2008-12-22 22:52:20 UTC (rev 1485) @@ -19,6 +19,7 @@ import cpptypes import algorithm +import templates import declaration import type_traits import dependencies @@ -44,11 +45,11 @@ self._name = name self._default_value = default_value self._type = type - self._attributes = attributes + self._attributes = attributes def clone( self, **keywd ): """constructs new argument_t instance - + return argument_t( name=keywd.get( 'name', self.name ) , type=keywd.get( 'type', self.type ) , default_value=keywd.get( 'default_value', self.default_value ) @@ -59,7 +60,7 @@ , type=keywd.get( 'type', self.type ) , default_value=keywd.get( 'default_value', self.default_value ) , attributes=keywd.get( 'attributes', self.attributes ) ) - + def __str__(self): if self.ellipsis: return "..." @@ -114,7 +115,7 @@ type = property( _get_type, _set_type , doc="""The type of the argument. @type: L{type_t}""") - + def _get_attributes( self ): return self._attributes def _set_attributes( self, attributes ): @@ -203,7 +204,7 @@ self._does_throw = does_throw does_throw = property( _get_does_throw, _set_does_throw, doc="""If False, than function does not throw any exception. - In this case, function was declared with empty throw + In this case, function was declared with empty throw statement. """) @@ -226,9 +227,9 @@ @property def overloads(self): """A list of overloaded "callables" (i.e. other callables with the same name within the same scope. - + @type: list of L{calldef_t} - """ + """ if not self.parent: return [] # finding all functions with the same name @@ -313,7 +314,7 @@ report_dependency = lambda *args, **keywd: dependencies.dependency_info_t( self, *args, **keywd ) answer = [] if self.return_type: - answer.append( report_dependency( self.return_type, hint="return type" ) ) + answer.append( report_dependency( self.return_type, hint="return type" ) ) map( lambda arg: answer.append( report_dependency( arg.type ) ) , self.arguments ) map( lambda exception: answer.append( report_dependency( exception, hint="exception" ) ) @@ -506,12 +507,12 @@ if not isinstance( unaliased.base, cpptypes.declarated_t ): return False return id(unaliased.base.declaration) == id(self.parent) - + @property def is_trivial_constructor(self): return not bool( self.arguments ) - + class destructor_t( member_calldef_t ): """describes deconstructor declaration""" def __init__( self, *args, **keywords ): @@ -541,7 +542,7 @@ free_calldef_t.__init__( self, *args, **keywords ) operator_t.__init__( self, *args, **keywords ) self.__class_types = None - + @property def class_types( self ): """list of class/class declaration types, extracted from the operator arguments""" @@ -559,3 +560,56 @@ if decl: self.__class_types.append( decl ) return self.__class_types + + +def __remove_leading_scope( s ): + if s and s.startswith( '::' ): + return s[2:] + else: + return s + +def __format_type_as_undecorated( type_ ): + result = [] + type_ = type_traits.remove_alias( type_ ) + base_type_ = type_traits.base_type( type_ ) + base_type_ = type_traits.remove_declarated( base_type_ ) + if type_traits.is_class( base_type_ ) and base_type_.class_type == "struct": + result.append('struct ') + result.append( __remove_leading_scope( type_.decl_string ) ) + return ' '.join( result ) + +def __format_args_as_undecorated( argtypes ): + if not argtypes: + return 'void' + else: + return ','.join( map( __format_type_as_undecorated, argtypes ) ) + +def create_undecorated_name(calldef): + """returns string, which contains full function name formatted exactly as + result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU + options. + """ + calldef_type = calldef.function_type() + + result = [] + is_mem_fun = isinstance( calldef, member_calldef_t ) + if is_mem_fun and calldef.virtuality != VIRTUALITY_TYPES.NOT_VIRTUAL: + result.append( 'virtual ' ) + if calldef_type.return_type: + result.append( __format_type_as_undecorated( calldef.return_type ) ) + result.append( ' ' ) + if isinstance( calldef, member_calldef_t ): + result.append( __remove_leading_scope( calldef.parent.decl_string ) + '::') + + result.append( calldef.name ) + if isinstance( calldef, ( constructor_t, destructor_t) ) \ + and templates.is_instantiation( calldef.parent.name ): + result.append( '<%s>' % ','.join( templates.args( calldef.parent.name ) ) ) + + result.append( '(%s)' % __format_args_as_undecorated( calldef_type.arguments_types ) ) + if is_mem_fun and calldef.has_const: + result.append( 'const' ) + return ''.join( result ) + + + Modified: pygccxml_dev/pygccxml/msvc/mspdb/enums.py =================================================================== --- pygccxml_dev/pygccxml/msvc/mspdb/enums.py 2008-12-22 22:11:51 UTC (rev 1484) +++ pygccxml_dev/pygccxml/msvc/mspdb/enums.py 2008-12-22 22:52:20 UTC (rev 1485) @@ -92,12 +92,11 @@ | UNDNAME_NO_ECSU \ | UNDNAME_NO_IDENT_CHAR_CHECK - UNDNAME_SHORT_UNIQUE = UNDNAME_NO_LEADING_UNDERSCORES \ - | UNDNAME_NO_MS_KEYWORDS \ - | UNDNAME_NO_ALLOCATION_MODEL \ - | UNDNAME_NO_ALLOCATION_LANGUAGE \ - | UNDNAME_NO_ACCESS_SPECIFIERS \ - | UNDNAME_NO_THROW_SIGNATURES \ - | UNDNAME_NO_MEMBER_TYPE \ - | UNDNAME_NO_ECSU \ - | UNDNAME_NO_IDENT_CHAR_CHECK + UNDNAME_SHORT_UNIQUE = UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS + #~ UNDNAME_NO_LEADING_UNDERSCORES \ + #~ | UNDNAME_NO_ALLOCATION_MODEL \ + #~ | UNDNAME_NO_ALLOCATION_LANGUAGE \ + #~ | UNDNAME_NO_THROW_SIGNATURES \ + #~ | UNDNAME_NO_MEMBER_TYPE \ + #~ | UNDNAME_NO_ECSU \ + #~ | UNDNAME_NO_IDENT_CHAR_CHECK Modified: pygccxml_dev/pygccxml/msvc/mspdb/loader.py =================================================================== --- pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-22 22:11:51 UTC (rev 1484) +++ pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-22 22:52:20 UTC (rev 1485) @@ -1,6 +1,5 @@ import os import re -import pdb import sys import ctypes import pprint @@ -89,10 +88,9 @@ for smbl in itertools.imap( as_symbol, as_enum_variant( self.symbols_table._NewEnum ) ): if smbl.symTag in useless: continue - smbl.uname = msvc_utils.undecorate_name( smbl.name, msvc_utils.UNDECORATE_NAME_OPTIONS.UNDNAME_SCOPES_ONLY ) - def smbl_undecorate_name( options=None ): - return msvc_utils.undecorate_name( smbl.name, options ) - smbl.undecorate_name = smbl_undecorate_name + smbl.uname = smbl.get_undecoratedNameEx( enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE ) + if smbl.uname is None: + smbl.uname = smbl.name smbls[ smbl.symIndexId ] = smbl self.logger.info( 'loading symbols(%d) from the file - done', len( smbls ) ) return smbls @@ -223,8 +221,6 @@ self.logger.debug( 'scanning symbols table - done' ) def __update_decls_tree( self, decl ): - #~ if decl.name == 'money_base' and isinstance( decl, declarations.class_t ): - #~ pdb.set_trace() smbl = decl.dia_symbols[0] if smbl.classParentId in self.__id2decl: self.__adopt_declaration( self.__id2decl[smbl.classParentId], decl ) @@ -236,13 +232,14 @@ parent_name = '::' + name_splitter.scope_names[-1] try: parent = self.global_ns.decl( parent_name ) - except: - declarations.print_declarations( self.global_ns ) - print 'identifiers:' - for index, identifier in enumerate(name_splitter.identifiers): - print index, ':', identifier - raise - self.__adopt_declaration( parent, decl ) + self.__adopt_declaration( parent, decl ) + except declarations.matcher.declaration_not_found_t: + pass + #~ declarations.print_declarations( self.global_ns ) + #~ print 'identifiers:' + #~ for index, identifier in enumerate(name_splitter.identifiers): + #~ print index, ':', identifier + #~ raise def __adopt_declaration( self, parent, decl ): smbl = decl.dia_symbols[0] @@ -272,10 +269,11 @@ elif enums.CV_access_e.CV_protected == smbl.access: return declarations.ACCESS_TYPES.PROTECTED else: - fully_undecorated_name = smbl.undecorate_name() - if fully_undecorated_name.startswith( 'private:' ): + if not smbl.undecoratedName: + return declarations.ACCESS_TYPES.PUBLIC + elif smbl.undecoratedName.startswith( 'private:' ): declarations.ACCESS_TYPES.PRIVATE - elif fully_undecorated_name.startswith( 'protected:' ): + elif smbl.undecoratedName.startswith( 'protected:' ): declarations.ACCESS_TYPES.PROTECTED else: return declarations.ACCESS_TYPES.PUBLIC @@ -348,7 +346,7 @@ #~ self.__load_enums() #~ self.__load_vars() #~ self.__load_typedefs() - #~ self.__load_calldefs() + self.__load_calldefs() map( self.__normalize_name, self.global_ns.decls(recursive=True) ) self.__join_unnamed_nss( self.global_ns ) self.__remove_empty_nss( self.global_ns ) @@ -538,11 +536,15 @@ return decl def __load_calldefs( self ): + compiler_defined_mmem_funs = [ '__vecDelDtor' + , + ] self.logger.info( 'building function objects' ) is_function = lambda smbl: smbl.symTag == msdia.SymTagFunction for functions_count, function_smbl in enumerate( itertools.ifilter( is_function, self.symbols.itervalues() ) ): if function_smbl.classParent and function_smbl.classParentId not in self.public_classes: #what about base classes continue + if function_decl = self.__create_calldef(function_smbl) if function_decl: self.__update_decls_tree( function_decl ) @@ -579,6 +581,8 @@ calldef_type = self.create_type( smbl.type ) #what does happen with constructor? decl = None if isinstance( calldef_type, declarations.member_function_type_t ): + if isinstance( calldef_type.class_inst, declarations.unknown_t ): + return could_be_static = False could_be_const = False if '~' in smbl.uname: @@ -630,7 +634,6 @@ try: class_ = self.create_type( smbl.objectPointerType ) class_ = declarations.base_type( class_ ) - #~ pdb.set_trace() return declarations.member_function_type_t( class_, return_type, args_types ) except: self.logger.warning( 'unable to find out the type of the object pointer for a class method.' ) Modified: pygccxml_dev/pygccxml/utils/__init__.py =================================================================== --- pygccxml_dev/pygccxml/utils/__init__.py 2008-12-22 22:11:51 UTC (rev 1484) +++ pygccxml_dev/pygccxml/utils/__init__.py 2008-12-22 22:52:20 UTC (rev 1485) @@ -171,6 +171,9 @@ if not compiler: return None else: - return compiler[0] + compiler[1].replace( '.', '' ) + n = compiler[1].replace( '.', '' ) + if n.endswith('0'): + n = n[:-1] + return compiler[0] + n.replace( '.', '' ) Added: pygccxml_dev/unittests/data/msvc/mydll.90.vcproj =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.90.vcproj (rev 0) +++ pygccxml_dev/unittests/data/msvc/mydll.90.vcproj 2008-12-22 22:52:20 UTC (rev 1485) @@ -0,0 +1,182 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="mydll" + ProjectGUID="{E7A34C45-534F-43A6-AF95-3CA2428619E2}" + RootNamespace="mydll" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MYDLL_EXPORTS" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="2" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MYDLL_EXPORTS" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + BrowseInformation="1" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + GenerateMapFile="true" + MapExports="true" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\mydll.cpp" + > + </File> + <File + RelativePath=".\mydll.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> Added: pygccxml_dev/unittests/data/msvc/mydll.cpp =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.cpp (rev 0) +++ pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-22 22:52:20 UTC (rev 1485) @@ -0,0 +1,59 @@ +#include "mydll.h" +#include "windows.h" +#include <iostream> + +number_t::number_t() +: m_value(0) +{ +// std::cout << "{C++} number_t( 0 )" << std::endl; +} + + +number_t::number_t(int value) +: m_value(value) +{ +// std::cout << "{C++} number_t( " << value << " )" << std::endl; +} + +number_t::~number_t() { +// std::cout << "{C++} ~number_t()" << std::endl; +} +void number_t::print_it() const { + std::cout << "{C++} value: " << m_value << std::endl; +} + +int number_t::get_value() const{ + return m_value; +} + +void number_t::set_value(int x){ + m_value = x; +} + +number_t number_t::clone() const{ + return number_t(*this); +} + +std::auto_ptr<number_t> number_t::clone_ptr() const{ + return std::auto_ptr<number_t>( new number_t( *this ) ); +} + +void do_smth( number_aptr_t& ){ +} + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + Added: pygccxml_dev/unittests/data/msvc/mydll.h =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.h (rev 0) +++ pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-22 22:52:20 UTC (rev 1485) @@ -0,0 +1,25 @@ +#pragma once + +#include <memory> + +class __declspec(dllexport) number_t{ +public: + number_t(); + explicit number_t(int value); + virtual ~number_t(); + void print_it() const; + int get_value() const; + int get_value(){ return m_value; } + void set_value(int x); + + number_t clone() const; + std::auto_ptr<number_t> clone_ptr() const; +private: + int m_value; +}; + +template class __declspec(dllexport) std::auto_ptr< number_t >; + +typedef std::auto_ptr< number_t > number_aptr_t; + +void __declspec(dllexport) do_smth( number_aptr_t& ); \ No newline at end of file Modified: pygccxml_dev/unittests/mspdb_playground.py =================================================================== --- pygccxml_dev/unittests/mspdb_playground.py 2008-12-22 22:11:51 UTC (rev 1484) +++ pygccxml_dev/unittests/mspdb_playground.py 2008-12-22 22:52:20 UTC (rev 1485) @@ -11,6 +11,7 @@ reader = mspdb.decl_loader_t( pdb_file ) opt = mspdb.enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE +opt = 0 public_smbls = {} for smbl in reader.public_symbols.iterkeys(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-23 08:45:17
|
Revision: 1486 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1486&view=rev Author: roman_yakovenko Date: 2008-12-23 08:45:12 +0000 (Tue, 23 Dec 2008) Log Message: ----------- adding functionality which maps decorated and undecorated names between gccxml and MSVC Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/calldef.py pygccxml_dev/pygccxml/msvc/__init__.py pygccxml_dev/pygccxml/msvc/common_utils.py pygccxml_dev/unittests/data/msvc/mydll.cpp pygccxml_dev/unittests/data/msvc/mydll.h pygccxml_dev/unittests/mspdb_playground.py pygccxml_dev/unittests/test_all.py Added Paths: ----------- pygccxml_dev/unittests/data/msvc/mydll.80.vcproj pygccxml_dev/unittests/undname_creator_tester.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2008-12-23 08:45:12 UTC (rev 1486) @@ -104,9 +104,7 @@ from calldef import casting_operator_t from calldef import free_function_t from calldef import free_operator_t -from calldef import create_undecorated_name - from decl_visitor import decl_visitor_t from type_visitor import type_visitor_t Modified: pygccxml_dev/pygccxml/declarations/calldef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/calldef.py 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/pygccxml/declarations/calldef.py 2008-12-23 08:45:12 UTC (rev 1486) @@ -560,56 +560,3 @@ if decl: self.__class_types.append( decl ) return self.__class_types - - -def __remove_leading_scope( s ): - if s and s.startswith( '::' ): - return s[2:] - else: - return s - -def __format_type_as_undecorated( type_ ): - result = [] - type_ = type_traits.remove_alias( type_ ) - base_type_ = type_traits.base_type( type_ ) - base_type_ = type_traits.remove_declarated( base_type_ ) - if type_traits.is_class( base_type_ ) and base_type_.class_type == "struct": - result.append('struct ') - result.append( __remove_leading_scope( type_.decl_string ) ) - return ' '.join( result ) - -def __format_args_as_undecorated( argtypes ): - if not argtypes: - return 'void' - else: - return ','.join( map( __format_type_as_undecorated, argtypes ) ) - -def create_undecorated_name(calldef): - """returns string, which contains full function name formatted exactly as - result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU - options. - """ - calldef_type = calldef.function_type() - - result = [] - is_mem_fun = isinstance( calldef, member_calldef_t ) - if is_mem_fun and calldef.virtuality != VIRTUALITY_TYPES.NOT_VIRTUAL: - result.append( 'virtual ' ) - if calldef_type.return_type: - result.append( __format_type_as_undecorated( calldef.return_type ) ) - result.append( ' ' ) - if isinstance( calldef, member_calldef_t ): - result.append( __remove_leading_scope( calldef.parent.decl_string ) + '::') - - result.append( calldef.name ) - if isinstance( calldef, ( constructor_t, destructor_t) ) \ - and templates.is_instantiation( calldef.parent.name ): - result.append( '<%s>' % ','.join( templates.args( calldef.parent.name ) ) ) - - result.append( '(%s)' % __format_args_as_undecorated( calldef_type.arguments_types ) ) - if is_mem_fun and calldef.has_const: - result.append( 'const' ) - return ''.join( result ) - - - Modified: pygccxml_dev/pygccxml/msvc/__init__.py =================================================================== --- pygccxml_dev/pygccxml/msvc/__init__.py 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/pygccxml/msvc/__init__.py 2008-12-23 08:45:12 UTC (rev 1486) @@ -0,0 +1,9 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from common_utils import undecorate_blob +from common_utils import undecorate_decl +from common_utils import exported_symbols +from common_utils import UNDECORATE_NAME_OPTIONS Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-23 08:45:12 UTC (rev 1486) @@ -1,23 +1,34 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import re import ctypes +import ctypes.wintypes +from .. import declarations class UNDECORATE_NAME_OPTIONS: - UNDNAME_COMPLETE = 0 - UNDNAME_NO_LEADING_UNDERSCORES = 1 - UNDNAME_NO_MS_KEYWORDS = 2 - UNDNAME_NO_FUNCTION_RETURNS = 4 - UNDNAME_NO_ALLOCATION_MODEL = 8 - UNDNAME_NO_ALLOCATION_LANGUAGE = 16 - UNDNAME_NO_MS_THISTYPE = 32 - UNDNAME_NO_CV_THISTYPE = 64 - UNDNAME_NO_THISTYPE = 96 - UNDNAME_NO_ACCESS_SPECIFIERS = 128 - UNDNAME_NO_THROW_SIGNATURES = 256 - UNDNAME_NO_MEMBER_TYPE = 512 - UNDNAME_NO_RETURN_UDT_MODEL = 1024 - UNDNAME_32_BIT_DECODE = 2048 - UNDNAME_NAME_ONLY = 4096 - UNDNAME_NO_ARGUMENTS = 8192 - UNDNAME_NO_SPECIAL_SYMS = 16384 + UNDNAME_COMPLETE = 0x0000 #Enables full undecoration. + UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 #Removes leading underscores from Microsoft extended keywords. + UNDNAME_NO_MS_KEYWORDS = 0x0002 #Disables expansion of Microsoft extended keywords. + UNDNAME_NO_FUNCTION_RETURNS = 0x0004 #Disables expansion of return type for primary declaration. + UNDNAME_NO_ALLOCATION_MODEL = 0x0008 #Disables expansion of the declaration model. + UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 #Disables expansion of the declaration language specifier. + UNDNAME_RESERVED1 = 0x0020 #RESERVED. + UNDNAME_RESERVED2 = 0x0040 #RESERVED. + UNDNAME_NO_THISTYPE = 0x0060 #Disables all modifiers on the this type. + UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 #Disables expansion of access specifiers for members. + UNDNAME_NO_THROW_SIGNATURES = 0x0100 #Disables expansion of "throw-signatures" for functions and pointers to functions. + UNDNAME_NO_MEMBER_TYPE = 0x0200 #Disables expansion of static or virtual members. + UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 #Disables expansion of the Microsoft model for UDT returns. + UNDNAME_32_BIT_DECODE = 0x0800 #Undecorates 32-bit decorated names. + UNDNAME_NAME_ONLY = 0x1000 #Gets only the name for primary declaration; returns just [scope::]name. Expands template params. + UNDNAME_TYPE_ONLY = 0x2000 #Input is just a type encoding; composes an abstract declarator. + UNDNAME_HAVE_PARAMETERS = 0x4000 #The real template parameters are available. + UNDNAME_NO_ECSU = 0x8000 #Suppresses enum/class/struct/union. + UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000 #Suppresses check for valid identifier characters. + UNDNAME_NO_PTR64 = 0x20000 #Does not include ptr64 in output. UNDNAME_SCOPES_ONLY = UNDNAME_NO_LEADING_UNDERSCORES \ | UNDNAME_NO_MS_KEYWORDS \ @@ -26,18 +37,135 @@ | UNDNAME_NO_ALLOCATION_LANGUAGE \ | UNDNAME_NO_ACCESS_SPECIFIERS \ | UNDNAME_NO_THROW_SIGNATURES \ - | UNDNAME_NO_MEMBER_TYPE + | UNDNAME_NO_MEMBER_TYPE \ + | UNDNAME_NO_ECSU \ + | UNDNAME_NO_IDENT_CHAR_CHECK + SHORT_UNIQUE_NAME = UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU -undecorate_name_impl = ctypes.windll.dbghelp.UnDecorateSymbolName -undecorate_name_impl.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint] +#~ The following code doesn't work - access violation -def undecorate_name( name, options=None ): - if options is None: - options = UNDECORATE_NAME_OPTIONS.UNDNAME_COMPLETE - buffer = ctypes.create_string_buffer(1024*16) - res = undecorate_name_impl(name, buffer, ctypes.sizeof(buffer), options) - if res: - return str(buffer[:res]) - else: - return name +#~__unDName definition was taken from: +#~http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/2006-02/msg00754.html + +#~ msvcrxx = ctypes.windll.msvcr90 +#~ free_type = ctypes.CFUNCTYPE( None, ctypes.c_void_p ) #free type +#~ malloc_type = ctypes.CFUNCTYPE( ctypes.c_void_p, ctypes.c_uint ) #malloc type +#~ __unDName = msvcrxx.__unDName +#~ __unDName.argtypes = [ ctypes.c_char_p #undecorated name + #~ , ctypes.c_char_p #decorated name + #~ , ctypes.c_int #sizeof undecorated name + #~ , malloc_type + #~ , free_type + #~ , ctypes.c_ushort #flags + #~ ] +#~ __unDName.restype = ctypes.c_char_p +#~ def undecorate_name( name, options=None ): + #~ if not name: + #~ return '' + #~ if options is None: + #~ options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME + #~ buffer_size = 1024 * 32 + #~ undecorated_name = ctypes.create_string_buffer('\0' * buffer_size) #should be enouph for any symbol + #~ __unDName( undecorated_name + #~ , str(name) + #~ , buffer_size + #~ , malloc_type( msvcrxx.malloc ) + #~ , free_type( msvcrxx.free ) + #~ , options ) + #~ return undecorated_name.value + +class undname_creator: + __undname = ctypes.windll.dbghelp.UnDecorateSymbolName + __undname.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint] + __clean_ecsu = re.compile( r'(?:(^|\W))(?:(class|enum|struct|union))' ) + + def undecorate_blob( self, name, options=None ): + if options is None: + options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME + buffer = ctypes.create_string_buffer(1024*16) + res = self.__undname( str(name), buffer, ctypes.sizeof(buffer), options) + if res: + undname = str(buffer[:res]) + if UNDECORATE_NAME_OPTIONS.UNDNAME_NO_ECSU & options: + undname = self.__clean_ecsu.sub( '', undname ) + return undname.strip() + else: + return name + + def __remove_leading_scope( self, s ): + if s and s.startswith( '::' ): + return s[2:] + else: + return s + + def __format_type_as_undecorated( self, type_ ): + result = [] + type_ = declarations.remove_alias( type_ ) + result.append( self.__remove_leading_scope( type_.decl_string ) ) + return ' '.join( result ) + + def __format_args_as_undecorated( self, argtypes ): + if not argtypes: + return 'void' + else: + return ','.join( map( self.__format_type_as_undecorated, argtypes ) ) + + def undecorated_decl(self, calldef): + """returns string, which contains full function name formatted exactly as + result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU + options. + """ + calldef_type = calldef.function_type() + + result = [] + is_mem_fun = isinstance( calldef, declarations.member_calldef_t ) + if is_mem_fun and calldef.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: + result.append( 'virtual ' ) + if calldef_type.return_type: + result.append( self.__format_type_as_undecorated( calldef.return_type ) ) + result.append( ' ' ) + if is_mem_fun: + result.append( self.__remove_leading_scope( calldef.parent.decl_string ) + '::') + + result.append( calldef.name ) + if isinstance( calldef, ( declarations.constructor_t, declarations.destructor_t) ) \ + and declarations.templates.is_instantiation( calldef.parent.name ): + result.append( '<%s>' % ','.join( declarations.templates.args( calldef.parent.name ) ) ) + + result.append( '(%s)' % self.__format_args_as_undecorated( calldef_type.arguments_types ) ) + if is_mem_fun and calldef.has_const: + result.append( 'const' ) + return ''.join( result ) + +undecorate_blob = undname_creator().undecorate_blob +undecorate_decl = undname_creator().undecorated_decl + +class exported_symbols: + map_file_re = re.compile( r' +\d+ (?P<decorated>.+) \((?P<undecorated>.+)\)$' ) + @staticmethod + def load_from_map_file( fname ): + """returns dictionary { decorated symbol : orignal declaration name }""" + result = {} + f = open( fname ) + exports_started = False + for line in f: + if not exports_started: + exports_started = bool( 'Exports' == line.strip() ) + if not exports_started: + continue + line = line.rstrip() + found = exported_symbols.map_file_re.match( line ) + if found: + result[ found.group( 'decorated' ) ] = found.group( 'undecorated' ) + return result + +#~ quick & dirty test +#~ symbols = exported_symbols.load_from_map_file( r'D:\dev\language-binding\sources\pygccxml_dev\unittests\data\msvc\Release\mydll.map' ) +#~ for decorated, undecorated in symbols.iteritems(): + #~ print '---------------------------------------------------------------------' + #~ print decorated + #~ print undecorated + #~ print undecorate_blob( decorated ) + #~ print '=====================================================================' + Added: pygccxml_dev/unittests/data/msvc/mydll.80.vcproj =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.80.vcproj (rev 0) +++ pygccxml_dev/unittests/data/msvc/mydll.80.vcproj 2008-12-23 08:45:12 UTC (rev 1486) @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="windows-1255"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="mydll" + ProjectGUID="{0B9466BC-60F8-4FC2-A1A9-6A01577690E5}" + RootNamespace="mydll" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MYDLL_EXPORTS" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MYDLL_EXPORTS" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + BrowseInformation="1" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + GenerateMapFile="true" + MapExports="true" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\mydll.cpp" + > + </File> + <File + RelativePath=".\mydll.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> Modified: pygccxml_dev/unittests/data/msvc/mydll.cpp =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-23 08:45:12 UTC (rev 1486) @@ -2,15 +2,15 @@ #include "windows.h" #include <iostream> -number_t::number_t() -: m_value(0) -{ +number_t::number_t() +: m_value(0) +{ // std::cout << "{C++} number_t( 0 )" << std::endl; } -number_t::number_t(int value) -: m_value(value) +number_t::number_t(int value) +: m_value(value) { // std::cout << "{C++} number_t( " << value << " )" << std::endl; } @@ -19,7 +19,7 @@ // std::cout << "{C++} ~number_t()" << std::endl; } void number_t::print_it() const { - std::cout << "{C++} value: " << m_value << std::endl; + std::cout << "{C++} value: " << m_value << std::endl; } int number_t::get_value() const{ @@ -57,3 +57,72 @@ return TRUE; } + +/* +static int myclass::myStaticMember +const int myclass::myconstStaticMember +volatile int myclass::myvolatileStaticMember +x myfnptr; +int myglobal; +volatile int myvolatile; +int myarray[10]; +void **Fv_PPv(void) +void *Fv_Pv(void) +int FA10_i_i(int a[10]) +int FPi_i(int *a) +int Fc_i(char bar) +int Ff_i(float bar) +int Fg_i(double bar) +int Fi_i(int bar) +int Fie_i(int bar, ...) +int Fii_i(int bar, int goo) +int Fiii_i(int bar, int goo, int hoo) +void Fmxmx_v(myclass arg1, x arg2, myclass arg3, x arg4) +void Fmyclass_v(myclass m) +const int Fv_Ci(void) +long double Fv_Lg(void) +int& Fv_Ri(void) +signed char Fv_Sc(void) +unsigned char Fv_Uc(void) +unsigned int Fv_Ui(void) +unsigned long Fv_Ul(void) +unsigned short Fv_Us(void) +volatile int Fv_Vi(void) +char Fv_c(void) +float Fv_f(void) +double Fv_g(void) +int Fv_i(void) +long Fv_l(void) +short Fv_s(void) +void Fv_v(void) +void __cdecl Fv_v_cdecl(void) +void __fastcall Fv_v_fastcall(void) +void __stdcall Fv_v_stdcall(void) +int Fx_i(x fnptr) +int Fxix_i(x fnptr, int i, x fnptr3) +int Fxx_i(x fnptr, x fnptr2) +int Fxxi_i(x fnptr, x fnptr2, x fnptr3, int i) +int Fxxx_i(x fnptr, x fnptr2, x fnptr3) +int Fxyxy_i(x fnptr, y fnptr2, x fnptr3, y fnptr4) +void myclass::operator delete(void *p) +int myclass::Fi_i(int bar) +static int myclass::Fis_i(int bar) +void __cdecl myclass::Fv_v_cdecl(void) +void __fastcall myclass::Fv_v_fastcall(void) +void __stdcall myclass::Fv_v_stdcall(void) +myclass::myclass(int x) +myclass::myclass(void) +int myclass::nested::Fi_i(int bar) +myclass::nested::nested(void) +myclass::nested::~nested() +myclass myclass::operator+(int x) +myclass myclass::operator++() +myclass myclass::operator++(int) +myclass& myclass::operator=(const myclass& from) +myclass::~myclass() +int nested::Fi_i(int bar) +nested::nested(void) +nested::~nested() +void* myclass::operator new(size_t size) +*/ + Modified: pygccxml_dev/unittests/data/msvc/mydll.h =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-23 08:45:12 UTC (rev 1486) @@ -22,4 +22,6 @@ typedef std::auto_ptr< number_t > number_aptr_t; -void __declspec(dllexport) do_smth( number_aptr_t& ); \ No newline at end of file +enum{ auto_ptr_size = sizeof( number_aptr_t ) }; + +void __declspec(dllexport) do_smth( number_aptr_t& ); Modified: pygccxml_dev/unittests/mspdb_playground.py =================================================================== --- pygccxml_dev/unittests/mspdb_playground.py 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/unittests/mspdb_playground.py 2008-12-23 08:45:12 UTC (rev 1486) @@ -8,7 +8,7 @@ from pygccxml.msvc import common_utils as msvc_utils pdb_file = r'E:\development\language-binding\pyplusplus_dev\pyplusplus\cpptypes\mydll\release\mydll.pdb' - +pdb_file = r'D:\AC_SERVER_4_VS2005\libs\Debug\SPDBLib_d.pdb' reader = mspdb.decl_loader_t( pdb_file ) opt = mspdb.enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE opt = 0 Modified: pygccxml_dev/unittests/test_all.py =================================================================== --- pygccxml_dev/unittests/test_all.py 2008-12-22 22:52:20 UTC (rev 1485) +++ pygccxml_dev/unittests/test_all.py 2008-12-23 08:45:12 UTC (rev 1486) @@ -52,6 +52,7 @@ import function_traits_tester import better_templates_matcher_tester import declaration_matcher_tester +import undname_creator_tester testers = [ decl_string_tester @@ -100,6 +101,7 @@ , function_traits_tester , better_templates_matcher_tester , declaration_matcher_tester + , undname_creator_tester ] def create_suite(): Added: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py (rev 0) +++ pygccxml_dev/unittests/undname_creator_tester.py 2008-12-23 08:45:12 UTC (rev 1486) @@ -0,0 +1,82 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import sys +import unittest +import autoconfig +import parser_test_case + +import pprint +from pygccxml import msvc +from pygccxml import utils +from pygccxml import parser +from pygccxml import declarations + +class tester_t( parser_test_case.parser_test_case_t ): + + global_ns = None + + def __init__(self, *args ): + parser_test_case.parser_test_case_t.__init__( self, *args ) + self.header = r'msvc\mydll.h' + + def setUp(self): + if not tester_t.global_ns: + decls = parser.parse( [self.header], self.config ) + tester_t.global_ns = declarations.get_global_namespace( decls ) + tester_t.global_ns.init_optimizer() + + def is_included( self, decl ): + for suffix in [ self.header, 'memory' ]: + if decl.location.file_name.endswith( suffix ): + return True + else: + return False + + + def test( self ): + map_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.map' ) + symbols = msvc.exported_symbols.load_from_map_file( map_file ) + + undecorated_blob_names = set() + for blob in symbols.iterkeys(): + undname = msvc.undecorate_blob( blob ) + if "`" in undname: + continue + undecorated_blob_names.add( undname ) + + undecorated_decl_names = set() + for f in self.global_ns.calldefs(self.is_included): + undecorated_decl_names.add( msvc.undecorate_decl( f ) ) + + issuperset = undecorated_decl_names.issuperset( undecorated_blob_names ) + if not issuperset: + common = undecorated_decl_names.intersection( undecorated_blob_names ) + + undecorated_decl_names.difference_update(common) + undecorated_blob_names.difference_update(common) + + msg = [ "undecorate_decl - failed" ] + msg.append( "undecorated_decl_names :" ) + for i in undecorated_decl_names: + msg.append( '\t==>%s<==' % i ) + msg.append( "undecorated_blob_names :" ) + for i in undecorated_blob_names: + msg.append( '\t==>%s<==' % i ) + + self.fail( os.linesep.join(msg) ) + +def create_suite(): + suite = unittest.TestSuite() + if 'win' in sys.platform: + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-23 13:27:32
|
Revision: 1487 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1487&view=rev Author: roman_yakovenko Date: 2008-12-23 13:27:29 +0000 (Tue, 23 Dec 2008) Log Message: ----------- adding another set of tests Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/common_utils.py pygccxml_dev/unittests/data/msvc/mydll.80.vcproj pygccxml_dev/unittests/data/msvc/mydll.cpp pygccxml_dev/unittests/data/msvc/mydll.h pygccxml_dev/unittests/undname_creator_tester.py Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-23 08:45:12 UTC (rev 1486) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-23 13:27:29 UTC (rev 1487) @@ -111,11 +111,7 @@ else: return ','.join( map( self.__format_type_as_undecorated, argtypes ) ) - def undecorated_decl(self, calldef): - """returns string, which contains full function name formatted exactly as - result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU - options. - """ + def __undecorated_calldef( self, calldef ): calldef_type = calldef.function_type() result = [] @@ -138,11 +134,34 @@ result.append( 'const' ) return ''.join( result ) + def __undecorated_variable( self, decl ): + result = [] + if decl.type_qualifiers.has_static: + result.append( 'static ' ) + result.append( self.__format_type_as_undecorated( decl.type ) ) + result.append( ' ' ) + if isinstance( decl.parent, declarations.class_t ): + result.append( self.__remove_leading_scope( decl.parent.decl_string ) + '::' ) + result.append( decl.name ) + return ''.join( result ) + + def undecorated_decl(self, decl): + """returns string, which contains full function name formatted exactly as + result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU + options. + """ + if isinstance( decl, declarations.calldef_t ): + return self.__undecorated_calldef( decl ) + elif isinstance( decl, declarations.variable_t ): + return self.__undecorated_variable( decl ) + else: + raise NotImplementedError() + undecorate_blob = undname_creator().undecorate_blob undecorate_decl = undname_creator().undecorated_decl class exported_symbols: - map_file_re = re.compile( r' +\d+ (?P<decorated>.+) \((?P<undecorated>.+)\)$' ) + map_file_re = re.compile( r' +\d+ (?P<decorated>.+?) \((?P<undecorated>.+)\)$' ) @staticmethod def load_from_map_file( fname ): """returns dictionary { decorated symbol : orignal declaration name }""" Modified: pygccxml_dev/unittests/data/msvc/mydll.80.vcproj =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.80.vcproj 2008-12-23 08:45:12 UTC (rev 1486) +++ pygccxml_dev/unittests/data/msvc/mydll.80.vcproj 2008-12-23 13:27:29 UTC (rev 1487) @@ -137,6 +137,7 @@ LinkIncremental="1" GenerateDebugInformation="true" GenerateMapFile="true" + MapFileName="$(TargetDir)$(TargetName).map" MapExports="true" SubSystem="2" OptimizeReferences="2" Modified: pygccxml_dev/unittests/data/msvc/mydll.cpp =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-23 08:45:12 UTC (rev 1486) +++ pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-23 13:27:29 UTC (rev 1487) @@ -41,6 +41,16 @@ void do_smth( number_aptr_t& ){ } + +int myclass_t::my_static_member = 99; +const int myclass_t::my_const_static_member = 10009; +int my_global_int = 90; +volatile int my_volatile_global_variable = 9; +int my_global_array[10] = {0,1,2,3,4,5,6,7,8,9}; + +void* get_pvoid(void*){ return 0;} +void** get_ppvoid(void){return 0;} + BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved Modified: pygccxml_dev/unittests/data/msvc/mydll.h =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-23 08:45:12 UTC (rev 1486) +++ pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-23 13:27:29 UTC (rev 1487) @@ -2,6 +2,7 @@ #include <memory> + class __declspec(dllexport) number_t{ public: number_t(); @@ -24,4 +25,27 @@ enum{ auto_ptr_size = sizeof( number_aptr_t ) }; -void __declspec(dllexport) do_smth( number_aptr_t& ); +__declspec(dllexport) void do_smth( number_aptr_t& ); + +__declspec(dllexport) extern int my_global_int; + +typedef void(*do_smth_type)( number_aptr_t& ); + +__declspec(dllexport) extern volatile int my_volatile_global_variable; + +__declspec(dllexport) extern int my_global_array[10]; + +__declspec(dllexport) void* get_pvoid(void*); +__declspec(dllexport) void** get_ppvoid(void); + + +class __declspec(dllexport) myclass_t{ +public: + static int my_static_member; + static const int my_const_static_member; + volatile int my_volatile_member; + + do_smth_type* get_do_smth(){ return 0; } + void set_do_smth(do_smth_type*){}; + +}; \ No newline at end of file Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2008-12-23 08:45:12 UTC (rev 1486) +++ pygccxml_dev/unittests/undname_creator_tester.py 2008-12-23 13:27:29 UTC (rev 1487) @@ -30,6 +30,8 @@ tester_t.global_ns.init_optimizer() def is_included( self, decl ): + if not isinstance( decl, ( declarations.calldef_t, declarations.variable_t) ): + return False for suffix in [ self.header, 'memory' ]: if decl.location.file_name.endswith( suffix ): return True @@ -49,7 +51,7 @@ undecorated_blob_names.add( undname ) undecorated_decl_names = set() - for f in self.global_ns.calldefs(self.is_included): + for f in self.global_ns.decls(self.is_included): undecorated_decl_names.add( msvc.undecorate_decl( f ) ) issuperset = undecorated_decl_names.issuperset( undecorated_blob_names ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-23 20:45:27
|
Revision: 1489 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1489&view=rev Author: roman_yakovenko Date: 2008-12-23 20:45:17 +0000 (Tue, 23 Dec 2008) Log Message: ----------- commenting out pdb tests Modified Paths: -------------- pygccxml_dev/unittests/autoconfig.py pygccxml_dev/unittests/core_tester.py pygccxml_dev/unittests/declarations_tester.py Property Changed: ---------------- pygccxml_dev/pygccxml/msvc/bsc/ pygccxml_dev/pygccxml/msvc/mspdb/ Property changes on: pygccxml_dev/pygccxml/msvc/bsc ___________________________________________________________________ Added: svn:ignore + *.pyc Property changes on: pygccxml_dev/pygccxml/msvc/mspdb ___________________________________________________________________ Added: svn:ignore + *.pyc Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2008-12-23 20:43:00 UTC (rev 1488) +++ pygccxml_dev/unittests/autoconfig.py 2008-12-23 20:45:17 UTC (rev 1489) @@ -34,11 +34,16 @@ pygccxml.declarations.class_t.USE_DEMANGLED_AS_NAME = True class cxx_parsers_cfg: - keywd = { 'working_directory' : data_directory - , 'define_symbols' : [ gccxml_version ] + , 'define_symbols' : [ gccxml_version ]#, '_HAS_TR1 0' ] , 'compiler' : compiler } + if 'win' in sys.platform: + keywd['define_symbols'].append( '__PYGCCXML_%s__' % compiler.upper() ) + if 'msvc9' == compiler: + keywd['define_symbols'].append( '_HAS_TR1=0' ) + + if os.path.exists( os.path.join( gccxml_path, 'gccxml' ) ) \ or os.path.exists( os.path.join( gccxml_path, 'gccxml.exe' ) ): keywd[ 'gccxml_path'] = gccxml_path @@ -52,9 +57,9 @@ #~ pdb_loader = mspdb.decl_loader_t( pdb_file ) #~ pdb_loader.read() -def get_pdb_global_ns(): - if cxx_parsers_cfg.pdb_loader: - return cxx_parsers_cfg.pdb_loader.global_ns +#~ def get_pdb_global_ns(): + #~ if cxx_parsers_cfg.pdb_loader: + #~ return cxx_parsers_cfg.pdb_loader.global_ns #~ try: #~ import pydsc Modified: pygccxml_dev/unittests/core_tester.py =================================================================== --- pygccxml_dev/unittests/core_tester.py 2008-12-23 20:43:00 UTC (rev 1488) +++ pygccxml_dev/unittests/core_tester.py 2008-12-23 20:45:17 UTC (rev 1489) @@ -21,8 +21,8 @@ root = normalize_path( root ) some_path = normalize_path( some_path ) return some_path.startswith( root ) - + class core_t( parser_test_case.parser_test_case_t ): """Tests core algorithms of GCC-XML and GCC-XML file reader. Those most white-box testing. @@ -392,8 +392,8 @@ suite.addTest( unittest.makeSuite(core_all_at_once_no_opt_t)) suite.addTest( unittest.makeSuite(core_file_by_file_t)) suite.addTest( unittest.makeSuite(core_file_by_file_no_opt_t)) - if autoconfig.cxx_parsers_cfg.pdb_loader: - suite.addTest( unittest.makeSuite(pdb_based_core_tester_t)) + #~ if autoconfig.cxx_parsers_cfg.pdb_loader: + #~ suite.addTest( unittest.makeSuite(pdb_based_core_tester_t)) return suite def run_suite(): Modified: pygccxml_dev/unittests/declarations_tester.py =================================================================== --- pygccxml_dev/unittests/declarations_tester.py 2008-12-23 20:43:00 UTC (rev 1488) +++ pygccxml_dev/unittests/declarations_tester.py 2008-12-23 20:45:17 UTC (rev 1489) @@ -198,8 +198,8 @@ suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(file_by_file_tester_t)) suite.addTest( unittest.makeSuite(all_at_once_tester_t)) - if sys.platform == 'win32' and autoconfig.get_pdb_global_ns(): - suite.addTest( unittest.makeSuite(pdb_based_tester_t)) + #~ if sys.platform == 'win32' and autoconfig.get_pdb_global_ns(): + #~ suite.addTest( unittest.makeSuite(pdb_based_tester_t)) return suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-23 20:54:53
|
Revision: 1490 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1490&view=rev Author: roman_yakovenko Date: 2008-12-23 20:54:48 +0000 (Tue, 23 Dec 2008) Log Message: ----------- adding few new test cases to test MSVC & GCCXML name mangling interoperability Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/cpptypes.py pygccxml_dev/pygccxml/msvc/common_utils.py pygccxml_dev/unittests/data/msvc/mydll.90.vcproj pygccxml_dev/unittests/data/msvc/mydll.cpp pygccxml_dev/unittests/data/msvc/mydll.h pygccxml_dev/unittests/undname_creator_tester.py Property Changed: ---------------- pygccxml_dev/unittests/data/ Modified: pygccxml_dev/pygccxml/declarations/cpptypes.py =================================================================== --- pygccxml_dev/pygccxml/declarations/cpptypes.py 2008-12-23 20:45:17 UTC (rev 1489) +++ pygccxml_dev/pygccxml/declarations/cpptypes.py 2008-12-23 20:54:48 UTC (rev 1490) @@ -373,7 +373,7 @@ compound_t.__init__( self, base) def build_decl_string(self, with_defaults=True): - return 'volatile ' + self.base.build_decl_string(with_defaults) + return self.base.build_decl_string(with_defaults) + ' volatile' def _clone_impl( self ): return volatile_t( self.base.clone() ) Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-23 20:45:17 UTC (rev 1489) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-23 20:54:48 UTC (rev 1490) @@ -79,6 +79,12 @@ __undname = ctypes.windll.dbghelp.UnDecorateSymbolName __undname.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint] __clean_ecsu = re.compile( r'(?:(^|\W))(?:(class|enum|struct|union))' ) + __fundamental_types = ( + ( 'short unsigned int', 'unsigned short') + , ( 'short int', 'short' ) + , ( 'long int', 'long' ) + , ( 'long unsigned int', 'unsigned long' ) + ) def undecorate_blob( self, name, options=None ): if options is None: @@ -99,17 +105,30 @@ else: return s - def __format_type_as_undecorated( self, type_ ): + def __format_type_as_undecorated( self, type_, is_argument ): result = [] type_ = declarations.remove_alias( type_ ) - result.append( self.__remove_leading_scope( type_.decl_string ) ) + if declarations.is_array( type_ ): + result.append( declarations.array_item_type( type_ ).decl_string ) + result.append( '*' ) + if is_argument: + result.append( 'const' ) + else: + result.append( self.__remove_leading_scope( type_.decl_string ) ) return ' '.join( result ) + def __normalize( self, name ): + for what, with_ in self.__fundamental_types: + name = name.replace( what, with_ ) + name = name.replace( ', ', ',' ) + return name + def __format_args_as_undecorated( self, argtypes ): if not argtypes: return 'void' else: - return ','.join( map( self.__format_type_as_undecorated, argtypes ) ) + formater = lambda type_: self.__format_type_as_undecorated( type_, True ) + return ','.join( map( formater, argtypes ) ) def __undecorated_calldef( self, calldef ): calldef_type = calldef.function_type() @@ -118,8 +137,10 @@ is_mem_fun = isinstance( calldef, declarations.member_calldef_t ) if is_mem_fun and calldef.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: result.append( 'virtual ' ) + if is_mem_fun and calldef.has_static: + result.append( 'static ' ) if calldef_type.return_type: - result.append( self.__format_type_as_undecorated( calldef.return_type ) ) + result.append( self.__format_type_as_undecorated( calldef.return_type, False ) ) result.append( ' ' ) if is_mem_fun: result.append( self.__remove_leading_scope( calldef.parent.decl_string ) + '::') @@ -136,11 +157,12 @@ def __undecorated_variable( self, decl ): result = [] - if decl.type_qualifiers.has_static: + is_mem_var = isinstance( decl.parent, declarations.class_t ) + if is_mem_var and decl.type_qualifiers.has_static: result.append( 'static ' ) - result.append( self.__format_type_as_undecorated( decl.type ) ) + result.append( self.__format_type_as_undecorated( decl.type, False ) ) result.append( ' ' ) - if isinstance( decl.parent, declarations.class_t ): + if is_mem_var: result.append( self.__remove_leading_scope( decl.parent.decl_string ) + '::' ) result.append( decl.name ) return ''.join( result ) @@ -150,13 +172,16 @@ result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU options. """ + name = None if isinstance( decl, declarations.calldef_t ): - return self.__undecorated_calldef( decl ) + name = self.__undecorated_calldef( decl ) elif isinstance( decl, declarations.variable_t ): - return self.__undecorated_variable( decl ) + name = self.__undecorated_variable( decl ) else: raise NotImplementedError() + return self.__normalize( name ) + undecorate_blob = undname_creator().undecorate_blob undecorate_decl = undname_creator().undecorated_decl @@ -179,6 +204,15 @@ result[ found.group( 'decorated' ) ] = found.group( 'undecorated' ) return result + @staticmethod + def load_from_dll_file( fname ): + import get_exports + result = {} + blobs = get_exports.read_export_table( fname ) + for blob in blobs: + result[ blob ] = undecorate_blob( blob ) + return result + #~ quick & dirty test #~ symbols = exported_symbols.load_from_map_file( r'D:\dev\language-binding\sources\pygccxml_dev\unittests\data\msvc\Release\mydll.map' ) #~ for decorated, undecorated in symbols.iteritems(): Property changes on: pygccxml_dev/unittests/data ___________________________________________________________________ Modified: svn:ignore - *.cache + *.cache *.bak Modified: pygccxml_dev/unittests/data/msvc/mydll.90.vcproj =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.90.vcproj 2008-12-23 20:45:17 UTC (rev 1489) +++ pygccxml_dev/unittests/data/msvc/mydll.90.vcproj 2008-12-23 20:54:48 UTC (rev 1490) @@ -45,7 +45,7 @@ MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" - UsePrecompiledHeader="2" + UsePrecompiledHeader="0" WarningLevel="3" DebugInformationFormat="4" /> @@ -118,6 +118,7 @@ RuntimeLibrary="2" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" + AssemblerOutput="4" BrowseInformation="1" WarningLevel="3" DebugInformationFormat="3" Modified: pygccxml_dev/unittests/data/msvc/mydll.cpp =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-23 20:45:17 UTC (rev 1489) +++ pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-23 20:54:48 UTC (rev 1490) @@ -51,6 +51,36 @@ void* get_pvoid(void*){ return 0;} void** get_ppvoid(void){return 0;} +int FA10_i_i(int a[10]){ return 0;} +int FPi_i(int *a){ return 0;} +int Fc_i(char bar){ return 0;} +int Ff_i(float bar){ return 0;} +int Fg_i(double bar){ return 0;} +int Fi_i(int bar){ return 0;} +int Fie_i(int bar, ...){ return 0;} +int Fii_i(int bar, int goo){ return 0;} +int Fiii_i(int bar, int goo, int hoo){ return 0;} +void Fmxmx_v(myclass_t arg1, X arg2, myclass_t arg3, X arg4){} +void Fmyclass_v(myclass_t m){} + +const int Fv_Ci(void){ return 0;} +long double Fv_Lg(void){ return 0.0;} +int& Fv_Ri(void){ return my_global_int;} +signed char Fv_Sc(void){ return 0;} +unsigned char Fv_Uc(void){ return 0;} +unsigned int Fv_Ui(void){ return 0;} +unsigned long Fv_Ul(void){ return 0;} +unsigned short Fv_Us(void){ return 0;} +volatile int Fv_Vi(void){ return 0;} +char Fv_c(void){ return 0;} +float Fv_f(void){ return 0.0;} +double Fv_g(void){ return 0.0;} +int Fv_i(void){ return 0;} +long Fv_l(void){ return 0;} +short Fv_s(void){ return 0;} +void Fv_v(void){ return;} + + BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved @@ -69,42 +99,6 @@ /* -static int myclass::myStaticMember -const int myclass::myconstStaticMember -volatile int myclass::myvolatileStaticMember -x myfnptr; -int myglobal; -volatile int myvolatile; -int myarray[10]; -void **Fv_PPv(void) -void *Fv_Pv(void) -int FA10_i_i(int a[10]) -int FPi_i(int *a) -int Fc_i(char bar) -int Ff_i(float bar) -int Fg_i(double bar) -int Fi_i(int bar) -int Fie_i(int bar, ...) -int Fii_i(int bar, int goo) -int Fiii_i(int bar, int goo, int hoo) -void Fmxmx_v(myclass arg1, x arg2, myclass arg3, x arg4) -void Fmyclass_v(myclass m) -const int Fv_Ci(void) -long double Fv_Lg(void) -int& Fv_Ri(void) -signed char Fv_Sc(void) -unsigned char Fv_Uc(void) -unsigned int Fv_Ui(void) -unsigned long Fv_Ul(void) -unsigned short Fv_Us(void) -volatile int Fv_Vi(void) -char Fv_c(void) -float Fv_f(void) -double Fv_g(void) -int Fv_i(void) -long Fv_l(void) -short Fv_s(void) -void Fv_v(void) void __cdecl Fv_v_cdecl(void) void __fastcall Fv_v_fastcall(void) void __stdcall Fv_v_stdcall(void) @@ -114,25 +108,8 @@ int Fxxi_i(x fnptr, x fnptr2, x fnptr3, int i) int Fxxx_i(x fnptr, x fnptr2, x fnptr3) int Fxyxy_i(x fnptr, y fnptr2, x fnptr3, y fnptr4) -void myclass::operator delete(void *p) -int myclass::Fi_i(int bar) -static int myclass::Fis_i(int bar) void __cdecl myclass::Fv_v_cdecl(void) void __fastcall myclass::Fv_v_fastcall(void) void __stdcall myclass::Fv_v_stdcall(void) -myclass::myclass(int x) -myclass::myclass(void) -int myclass::nested::Fi_i(int bar) -myclass::nested::nested(void) -myclass::nested::~nested() -myclass myclass::operator+(int x) -myclass myclass::operator++() -myclass myclass::operator++(int) -myclass& myclass::operator=(const myclass& from) -myclass::~myclass() -int nested::Fi_i(int bar) -nested::nested(void) -nested::~nested() void* myclass::operator new(size_t size) */ - Modified: pygccxml_dev/unittests/data/msvc/mydll.h =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-23 20:45:17 UTC (rev 1489) +++ pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-23 20:54:48 UTC (rev 1490) @@ -1,8 +1,9 @@ #pragma once #include <memory> +#include <string> +#include <vector> - class __declspec(dllexport) number_t{ public: number_t(); @@ -41,11 +42,65 @@ class __declspec(dllexport) myclass_t{ public: + myclass_t(int x){} + myclass_t(void){} + virtual ~myclass_t(){} static int my_static_member; static const int my_const_static_member; volatile int my_volatile_member; do_smth_type* get_do_smth(){ return 0; } void set_do_smth(do_smth_type*){}; - -}; \ No newline at end of file + + int Fi_i(int bar){ return 0; } + static int Fis_i(int bar){ return 0; } + + myclass_t operator+(int x){ return myclass_t(); } + myclass_t operator++(){ return myclass_t(); } + myclass_t operator++(int){ return myclass_t(); } + myclass_t& operator=(const myclass_t& from){ return *this;} + + struct nested{ + nested(){} + ~nested(){} + int Fi_i(int bar){ return 0;} + }; + + typedef std::vector< std::wstring > wstring_collection_t; + + wstring_collection_t create_wstring_collection(){ return wstring_collection_t(); } + void fill_wstring_collection( wstring_collection_t& ){}; + void print__wstring_collection( const wstring_collection_t& ){} + + +}; + +struct __declspec(dllexport) X{}; + +__declspec(dllexport) int FA10_i_i(int a[10]); +__declspec(dllexport) int FPi_i(int *a); +__declspec(dllexport) int Fc_i(char bar); +__declspec(dllexport) int Ff_i(float bar); +__declspec(dllexport) int Fg_i(double bar); +__declspec(dllexport) int Fi_i(int bar); +__declspec(dllexport) int Fie_i(int bar, ...); +__declspec(dllexport) int Fii_i(int bar, int goo); +__declspec(dllexport) int Fiii_i(int bar, int goo, int hoo); +__declspec(dllexport) void Fmxmx_v(myclass_t arg1, X arg2, myclass_t arg3, X arg4); +__declspec(dllexport) void Fmyclass_v(myclass_t m); +__declspec(dllexport) const int Fv_Ci(void); +__declspec(dllexport) long double Fv_Lg(void); +__declspec(dllexport) int& Fv_Ri(void); +__declspec(dllexport) signed char Fv_Sc(void); +__declspec(dllexport) unsigned char Fv_Uc(void); +__declspec(dllexport) unsigned int Fv_Ui(void); +__declspec(dllexport) unsigned long Fv_Ul(void); +__declspec(dllexport) unsigned short Fv_Us(void); +__declspec(dllexport) volatile int Fv_Vi(void); +__declspec(dllexport) char Fv_c(void); +__declspec(dllexport) float Fv_f(void); +__declspec(dllexport) double Fv_g(void); +__declspec(dllexport) int Fv_i(void); +__declspec(dllexport) long Fv_l(void); +__declspec(dllexport) short Fv_s(void); +__declspec(dllexport) void Fv_v(void); Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2008-12-23 20:45:17 UTC (rev 1489) +++ pygccxml_dev/unittests/undname_creator_tester.py 2008-12-23 20:54:48 UTC (rev 1490) @@ -19,6 +19,14 @@ global_ns = None + known_issues = set([ + #pointer to functions + 'void (** myclass_t::get_do_smth(void))(std::auto_ptr<number_t> &)' + , 'void myclass_t::set_do_smth(void (**)(std::auto_ptr<number_t> &))' + # array as function argument + , 'int FA10_i_i(int * const)' + ]) + def __init__(self, *args ): parser_test_case.parser_test_case_t.__init__( self, *args ) self.header = r'msvc\mydll.h' @@ -38,11 +46,7 @@ else: return False - - def test( self ): - map_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.map' ) - symbols = msvc.exported_symbols.load_from_map_file( map_file ) - + def __tester_impl( self, symbols ): undecorated_blob_names = set() for blob in symbols.iterkeys(): undname = msvc.undecorate_blob( blob ) @@ -60,17 +64,29 @@ undecorated_decl_names.difference_update(common) undecorated_blob_names.difference_update(common) + if undecorated_blob_names != self.known_issues: + undecorated_blob_names.difference_update( self.known_issues ) + msg = [ "undecorate_decl - failed" ] + msg.append( "undecorated_decl_names :" ) + for i in undecorated_decl_names: + msg.append( '\t==>%s<==' % i ) + msg.append( "undecorated_blob_names :" ) + for i in undecorated_blob_names: + msg.append( '\t==>%s<==' % i ) - msg = [ "undecorate_decl - failed" ] - msg.append( "undecorated_decl_names :" ) - for i in undecorated_decl_names: - msg.append( '\t==>%s<==' % i ) - msg.append( "undecorated_blob_names :" ) - for i in undecorated_blob_names: - msg.append( '\t==>%s<==' % i ) + self.fail( os.linesep.join(msg) ) - self.fail( os.linesep.join(msg) ) + def test_map_file( self ): + map_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.map' ) + symbols = msvc.exported_symbols.load_from_map_file( map_file ) + self.__tester_impl( symbols ) + + def test_dll_file( self ): + dll_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.dll' ) + symbols = msvc.exported_symbols.load_from_dll_file( dll_file ) + self.__tester_impl( symbols ) + def create_suite(): suite = unittest.TestSuite() if 'win' in sys.platform: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-24 20:44:07
|
Revision: 1493 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1493&view=rev Author: roman_yakovenko Date: 2008-12-24 20:44:03 +0000 (Wed, 24 Dec 2008) Log Message: ----------- add convenience function - exported_symbols.load_from_file Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/common_utils.py pygccxml_dev/unittests/autoconfig.py pygccxml_dev/unittests/undname_creator_tester.py Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-24 08:16:07 UTC (rev 1492) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-24 20:44:03 UTC (rev 1493) @@ -3,6 +3,7 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +import os import re import ctypes import ctypes.wintypes @@ -225,3 +226,14 @@ for blob in blobs: result[ blob ] = undecorate_blob( blob ) return result + + @staticmethod + def load_from_file( fname ): + ext = os.path.splitext( fname )[1] + if '.dll' == ext: + return exported_symbols.load_from_dll_file( fname ) + elif '.map' == ext: + return exported_symbols.load_from_map_file( fname ) + else: + raise RuntimeError( "Don't know how to read exported symbols from file '%s'" + % fname ) Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2008-12-24 08:16:07 UTC (rev 1492) +++ pygccxml_dev/unittests/autoconfig.py 2008-12-24 20:44:03 UTC (rev 1493) @@ -35,7 +35,7 @@ class cxx_parsers_cfg: keywd = { 'working_directory' : data_directory - , 'define_symbols' : [ gccxml_version ]#, '_HAS_TR1 0' ] + , 'define_symbols' : [ gccxml_version ] , 'compiler' : compiler } if 'win' in sys.platform: Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2008-12-24 08:16:07 UTC (rev 1492) +++ pygccxml_dev/unittests/undname_creator_tester.py 2008-12-24 20:44:03 UTC (rev 1493) @@ -48,7 +48,9 @@ else: return False - def __tester_impl( self, symbols ): + def __tester_impl( self, fname ): + symbols = msvc.exported_symbols.load_from_file( fname ) + undecorated_blob_names = set() for blob in symbols.iterkeys(): undname = msvc.undecorate_blob( blob ) @@ -80,14 +82,11 @@ def test_map_file( self ): map_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.map' ) - symbols = msvc.exported_symbols.load_from_map_file( map_file ) - self.__tester_impl( symbols ) + self.__tester_impl( map_file ) - def test_dll_file( self ): dll_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.dll' ) - symbols = msvc.exported_symbols.load_from_dll_file( dll_file ) - self.__tester_impl( symbols ) + self.__tester_impl( dll_file ) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-12-28 12:09:53
|
Revision: 1509 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1509&view=rev Author: roman_yakovenko Date: 2008-12-28 12:09:49 +0000 (Sun, 28 Dec 2008) Log Message: ----------- add handling for "C" functions Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/algorithm.py pygccxml_dev/pygccxml/msvc/common_utils.py pygccxml_dev/unittests/data/msvc/mydll.cpp pygccxml_dev/unittests/data/msvc/mydll.h pygccxml_dev/unittests/undname_creator_tester.py Modified: pygccxml_dev/pygccxml/declarations/algorithm.py =================================================================== --- pygccxml_dev/pygccxml/declarations/algorithm.py 2008-12-27 21:16:17 UTC (rev 1508) +++ pygccxml_dev/pygccxml/declarations/algorithm.py 2008-12-28 12:09:49 UTC (rev 1509) @@ -331,4 +331,4 @@ fname = 'visit_' + decl_inst.__class__.__name__[:-2] #removing '_t' from class name if not hasattr(visitor, fname ): raise visit_function_has_not_been_found_t( visitor, decl_inst ) - getattr( visitor, fname )() + return getattr( visitor, fname )() Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-27 21:16:17 UTC (rev 1508) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-28 12:09:49 UTC (rev 1509) @@ -199,22 +199,38 @@ exceptions.UserWarning.__init__( self, *args, **keywd ) class exported_symbols: - map_file_re = re.compile( r' +\d+ (?P<decorated>.+?) \((?P<undecorated>.+)\)$' ) + map_file_re_c = re.compile( r' +\d+ (?P<internall>.+?)(?:\s+exported name\:\s(?P<name>.*)$)') + map_file_re_cpp = re.compile( r' +\d+ (?P<decorated>.+?) \((?P<undecorated>.+)\)$' ) + @staticmethod def load_from_map_file( fname ): """returns dictionary { decorated symbol : orignal declaration name }""" result = {} f = open( fname ) - exports_started = False + lines = [] + was_exports = False for line in f: - if not exports_started: - exports_started = bool( 'Exports' == line.strip() ) - if not exports_started: - continue - line = line.rstrip() - found = exported_symbols.map_file_re.match( line ) + if was_exports: + lines.append( line ) + elif 'Exports' == line.strip(): + was_exports = True + else: + pass + index = 0 + while index < len( lines ): + line = lines[index].rstrip() + found = exported_symbols.map_file_re_cpp.match( line ) if found: result[ found.group( 'decorated' ) ] = found.group( 'undecorated' ) + elif index + 1 < len( lines ): + two_lines = line + lines[index+1].rstrip() + found = exported_symbols.map_file_re_c.match( two_lines ) + if found: + result[ found.group( 'name' ) ] = found.group( 'name' ) + index += 1 + else: + pass + index += 1 return result @staticmethod @@ -244,3 +260,7 @@ else: raise RuntimeError( "Don't know how to read exported symbols from file '%s'" % fname ) + + @staticmethod + def is_c_function( decl, blob, undecorated_blob ): + return decl.name == blob == undecorated_blob Modified: pygccxml_dev/unittests/data/msvc/mydll.cpp =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-27 21:16:17 UTC (rev 1508) +++ pygccxml_dev/unittests/data/msvc/mydll.cpp 2008-12-28 12:09:49 UTC (rev 1509) @@ -97,6 +97,9 @@ return TRUE; } +int identity( int i){ + return i; +} /* void __cdecl Fv_v_cdecl(void) Modified: pygccxml_dev/unittests/data/msvc/mydll.h =================================================================== --- pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-27 21:16:17 UTC (rev 1508) +++ pygccxml_dev/unittests/data/msvc/mydll.h 2008-12-28 12:09:49 UTC (rev 1509) @@ -104,3 +104,7 @@ __declspec(dllexport) long Fv_l(void); __declspec(dllexport) short Fv_s(void); __declspec(dllexport) void Fv_v(void); + +extern "C"{ + int __declspec(dllexport) identity( int ); +} \ No newline at end of file Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2008-12-27 21:16:17 UTC (rev 1508) +++ pygccxml_dev/unittests/undname_creator_tester.py 2008-12-28 12:09:49 UTC (rev 1509) @@ -15,6 +15,8 @@ from pygccxml import parser from pygccxml import declarations +print msvc.undecorate_blob( '?make_flatten@algorithms@reflection@engine_objects@@YAXAEBVinstance_info_t@23@V?$back_insert_iterator@V?$vector@Vinstance_info_t@reflection@engine_objects@@V?$allocator@Vinstance_info_t@reflection@engine_objects@@@std@@@std@@@std@@@Z' ) + class tester_t( parser_test_case.parser_test_case_t ): global_ns = None @@ -50,6 +52,7 @@ def __tester_impl( self, fname ): symbols = msvc.exported_symbols.load_from_file( fname ) + self.failUnless( 'identity' in symbols ) undecorated_blob_names = set() for blob in symbols.iterkeys(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-05 13:29:47
|
Revision: 1529 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1529&view=rev Author: roman_yakovenko Date: 2009-01-05 13:29:42 +0000 (Mon, 05 Jan 2009) Log Message: ----------- adding calling_convention property Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/calldef.py pygccxml_dev/pygccxml/declarations/decl_printer.py pygccxml_dev/unittests/test_all.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2009-01-04 20:29:35 UTC (rev 1528) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2009-01-05 13:29:42 UTC (rev 1529) @@ -92,6 +92,7 @@ from calldef import VIRTUALITY_TYPES from calldef import FUNCTION_VIRTUALITY_TYPES +from calldef import CALLING_CONVENTION_TYPES from calldef import argument_t from calldef import calldef_t from calldef import member_calldef_t Modified: pygccxml_dev/pygccxml/declarations/calldef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/calldef.py 2009-01-04 20:29:35 UTC (rev 1528) +++ pygccxml_dev/pygccxml/declarations/calldef.py 2009-01-05 13:29:42 UTC (rev 1529) @@ -16,7 +16,7 @@ - constructor - destructor """ - +import re import cpptypes import algorithm import templates @@ -34,6 +34,32 @@ #preserving backward compatebility FUNCTION_VIRTUALITY_TYPES = VIRTUALITY_TYPES +class CALLING_CONVENTION_TYPES: + """class that defines "calling convention" constants""" + UNKNOWN = '' + CDECL = 'cdecl' + STDCALL = 'stdcall' + THISCALL = 'thiscall' + FASTCALL = 'fastcall' + SYSTEM_DEFAULT = '<<<system default>>>' + + ALL = ( UNKNOWN, CDECL, STDCALL, THISCALL, FASTCALL ) + + pattern = re.compile( r'.*(?:^|\s)(?:__)?(?P<cc>cdecl|stdcall|thiscall|fastcall)(?:__)?.*' ) + + @staticmethod + def extract( text, default=UNKNOWN ): + """extracts calling convention from the text. If the calling convention could not be found, the "default"is used""" + if not text: + return default + found = CALLING_CONVENTION_TYPES.pattern.match( text ) + if found: + return found.group( 'cc' ) + else: + return default + + + #First level in hierarchy of calldef class argument_t(object): """ @@ -140,6 +166,7 @@ self._return_type = return_type self._has_extern = has_extern self._demangled_name = None + self._calling_convention = None def _get__cmp__call_items(self): """implementation details""" @@ -321,6 +348,25 @@ , self.exceptions ) return answer + def guess_calling_convention( self ): + """This function should be overriden in the derived classes and return + more-or-less successfull guess about calling convention""" + return CALLING_CONVENTION_TYPES.UNKNOWN + + def get_calling_convention( self ): + if self._calling_convention is None: + self._calling_convention = CALLING_CONVENTION_TYPES.extract( self.attributes ) + if not self._calling_convention: + self._calling_convention = self.guess_calling_convention() + return self._calling_convention + + def set_calling_convention( self, cc ): + self._calling_convention = cc + + calling_convention = property( get_calling_convention, set_calling_convention + , doc="function calling convention. See L{CALLING_CONVENTION_TYPES} class for possible values" ) + + #Second level in hierarchy of calldef class member_calldef_t( calldef_t ): """base class for "callable" declarations that defined within C++ class or struct""" @@ -412,6 +458,12 @@ else: return f_type.partial_decl_string + def guess_calling_convention( self ): + if self.has_static: + return CALLING_CONVENTION_TYPES.SYSTEM_DEFAULT + else: + return CALLING_CONVENTION_TYPES.THISCALL + class free_calldef_t( calldef_t ): """base class for "callable" declarations that defined within C++ namespace""" def __init__( self, *args, **keywords ): @@ -454,7 +506,12 @@ else: return f_type.partial_decl_string + def guess_calling_convention( self ): + """This function should be overriden in the derived classes and return + more-or-less successfull guess about calling convention""" + return CALLING_CONVENTION_TYPES.UNKNOWN + class operator_t(object): """base class for "operator" declarations""" OPERATOR_WORD_LEN = len( 'operator' ) Modified: pygccxml_dev/pygccxml/declarations/decl_printer.py =================================================================== --- pygccxml_dev/pygccxml/declarations/decl_printer.py 2009-01-04 20:29:35 UTC (rev 1528) +++ pygccxml_dev/pygccxml/declarations/decl_printer.py 2009-01-05 13:29:42 UTC (rev 1529) @@ -136,6 +136,7 @@ self.writer( indent + "is extern: " + str(decl.has_extern) + os.linesep) self.writer( indent + "return type: " + str(retval) + os.linesep) self.writer( indent + "arguments type: " + ', '.join(args) + os.linesep) + self.writer( indent + "calling convention: __%s__" % decl.calling_convention + os.linesep) if isinstance( decl, calldef.member_calldef_t ): self.writer( indent + "virtual: " + str(decl.virtuality) + os.linesep) self.writer( indent + "is const: " + str(decl.has_const) + os.linesep) Modified: pygccxml_dev/unittests/test_all.py =================================================================== --- pygccxml_dev/unittests/test_all.py 2009-01-04 20:29:35 UTC (rev 1528) +++ pygccxml_dev/unittests/test_all.py 2009-01-05 13:29:42 UTC (rev 1529) @@ -53,6 +53,7 @@ import better_templates_matcher_tester import declaration_matcher_tester import undname_creator_tester +import calling_convention_tester testers = [ decl_string_tester @@ -102,6 +103,7 @@ , better_templates_matcher_tester , declaration_matcher_tester , undname_creator_tester + , calling_convention_tester ] def create_suite(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-05 22:58:45
|
Revision: 1537 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1537&view=rev Author: roman_yakovenko Date: 2009-01-05 22:58:43 +0000 (Mon, 05 Jan 2009) Log Message: ----------- fix bug "pygccxml parses const volatile variable args as just const" Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/type_traits.py pygccxml_dev/pygccxml/parser/linker.py pygccxml_dev/pygccxml/parser/scanner.py pygccxml_dev/unittests/autoconfig.py pygccxml_dev/unittests/test_all.py pygccxml_dev/unittests/type_traits_tester.py Added Paths: ----------- pygccxml_dev/unittests/const_volatile_arg_tester.py pygccxml_dev/unittests/data/const_volatile_arg.hpp Modified: pygccxml_dev/pygccxml/declarations/type_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/type_traits.py 2009-01-05 22:06:06 UTC (rev 1536) +++ pygccxml_dev/pygccxml/declarations/type_traits.py 2009-01-05 22:58:43 UTC (rev 1537) @@ -104,7 +104,14 @@ elif 3 <= len( types ): classes = set( [tp.__class__ for tp in types[:3]] ) desired = set( [main] + list( secondary ) ) - return classes == desired + diff = classes.symmetric_difference( desired ) + if not diff: + return True + if len( diff ) == 2: + items = list( diff ) + return issubclass( items[0], items[1] ) or issubclass( items[1], items[0] ) + else: + return False else: return False @@ -152,17 +159,16 @@ def is_pointer(type): """returns True, if type represents C++ pointer type, False otherwise""" - return does_match_definition( type - , cpptypes.pointer_t - , (cpptypes.const_t, cpptypes.volatile_t) ) + return does_match_definition( type, cpptypes.pointer_t, (cpptypes.const_t, cpptypes.volatile_t) ) \ + or does_match_definition( type, cpptypes.pointer_t, (cpptypes.volatile_t, cpptypes.const_t) ) + def is_calldef_pointer(type): """returns True, if type represents pointer to free/member function, False otherwise""" if not is_pointer(type): return False nake_type = remove_alias( type ) - nake_type = remove_const( nake_type ) - nake_type = remove_volatile( nake_type ) + nake_type = remove_cv( nake_type ) return isinstance( nake_type, cpptypes.compound_t ) \ and isinstance( nake_type.base, cpptypes.calldef_type_t ) @@ -178,6 +184,10 @@ return cpptypes.volatile_t( nake_type.base.base ) elif isinstance( nake_type, cpptypes.const_t ) and isinstance( nake_type.base, cpptypes.pointer_t ): return cpptypes.const_t( nake_type.base.base ) + elif isinstance( nake_type, cpptypes.volatile_t ) \ + and isinstance( nake_type.base, cpptypes.const_t ) \ + and isinstance( nake_type.base.base, cpptypes.pointer_t ): + return cpptypes.volatile_t( ctypes.const_t( nake_type.base.base.base ) ) elif isinstance( nake_type.base, cpptypes.calldef_type_t ): return type else: @@ -285,13 +295,14 @@ result = nake_type.base if is_volatile( result ): result = result.base + if is_const( result ): + result = result.base return result def is_fundamental(type): """returns True, if type represents C++ fundamental type""" - return does_match_definition( type - , cpptypes.fundamental_t - , (cpptypes.const_t, cpptypes.volatile_t) ) + return does_match_definition( type, cpptypes.fundamental_t, (cpptypes.const_t, cpptypes.volatile_t) ) \ + or does_match_definition( type, cpptypes.fundamental_t, (cpptypes.volatile_t, cpptypes.const_t) ) \ class declaration_xxx_traits: """this class implements the functionality needed for convinient work with Modified: pygccxml_dev/pygccxml/parser/linker.py =================================================================== --- pygccxml_dev/pygccxml/parser/linker.py 2009-01-05 22:06:06 UTC (rev 1536) +++ pygccxml_dev/pygccxml/parser/linker.py 2009-01-05 22:58:43 UTC (rev 1537) @@ -18,13 +18,13 @@ self.__membership = membership self.__files = files self.__inst = None - - self.__compiler = None + + self.__compiler = None if self.__decls: for d in self.__decls.itervalues(): self.__compiler = d.compiler break - + def _get_inst(self): return self.__inst def _set_inst(self, inst): @@ -48,12 +48,12 @@ else: return unknown_t() - def __link_compound_type(self): + def __link_compound_type(self): self.__inst.base = self.__link_type( self.__inst.base ) def __link_members(self): if not self.__membership.has_key( id(self.__inst) ): - return + return for member in self.__membership[ id(self.__inst) ]: if not self.__access.has_key( member ): continue @@ -85,7 +85,7 @@ def visit_constructor( self ): self.__link_calldef() - + def visit_destructor( self ): self.__link_calldef() @@ -109,13 +109,13 @@ def visit_class(self ): self.__link_members() #GCC-XML sometimes generates constructors with names that does not match - #class name. I think this is because those constructors are compiler - #generated. I need to find out more about this and to talk with Brad + #class name. I think this is because those constructors are compiler + #generated. I need to find out more about this and to talk with Brad new_name = self.__inst._name if templates.is_instantiation( new_name ): new_name = templates.name( new_name ) - + for decl in self.__inst.declarations: if not isinstance( decl, constructor_t ): continue @@ -133,7 +133,7 @@ access = data[0] self.__inst.bases.append( hierarchy_info_t( base_decl, access ) ) base_decl.derived.append( hierarchy_info_t( self.__inst, access ) ) - + def visit_enumeration(self ): pass @@ -208,30 +208,34 @@ def visit_jbyte(self): pass - + def visit_jshort(self): pass - + def visit_jint(self): pass - + def visit_jlong(self): pass - + def visit_jfloat(self): pass - + def visit_jdouble(self): pass - + def visit_jchar(self): pass - + def visit_jboolean(self): pass def visit_volatile( self ): - self.__link_compound_type() + if isinstance( self.__inst.base, const_t ): + const_type_inst = self.__inst.base + const_type_inst.base = self.__link_type( const_type_inst.base ) + else: + self.__link_compound_type() def visit_const( self ): self.__link_compound_type() @@ -239,7 +243,7 @@ def visit_pointer( self ): if '0.9' in self.__compiler and isinstance( self.__inst.base, member_variable_type_t ): original_inst = self.__inst - self.__inst = self.__inst.base + self.__inst = self.__inst.base self.visit_member_variable_type() self.__inst = original_inst else: Modified: pygccxml_dev/pygccxml/parser/scanner.py =================================================================== --- pygccxml_dev/pygccxml/parser/scanner.py 2009-01-05 22:06:06 UTC (rev 1536) +++ pygccxml_dev/pygccxml/parser/scanner.py 2009-01-05 22:58:43 UTC (rev 1537) @@ -338,7 +338,9 @@ return array_t( type_, size + 1 ) def __read_cv_qualified_type( self, attrs ): - if attrs.has_key( XML_AN_CONST ): + if attrs.has_key( XML_AN_CONST ) and attrs.has_key( XML_AN_VOLATILE ): + return volatile_t( const_t( attrs[XML_AN_TYPE] ) ) + elif attrs.has_key( XML_AN_CONST ): return const_t( attrs[XML_AN_TYPE] ) elif attrs.has_key( XML_AN_VOLATILE ): return volatile_t( attrs[XML_AN_TYPE] ) Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2009-01-05 22:06:06 UTC (rev 1536) +++ pygccxml_dev/unittests/autoconfig.py 2009-01-05 22:58:43 UTC (rev 1537) @@ -28,7 +28,6 @@ print 'unittests will run on DEVELOPMENT version' compiler = pygccxml.utils.native_compiler.get_gccxml_compiler() -compiler = 'msvc71' print 'GCCXML configured to simulate compiler ', compiler pygccxml.declarations.class_t.USE_DEMANGLED_AS_NAME = True Added: pygccxml_dev/unittests/const_volatile_arg_tester.py =================================================================== --- pygccxml_dev/unittests/const_volatile_arg_tester.py (rev 0) +++ pygccxml_dev/unittests/const_volatile_arg_tester.py 2009-01-05 22:58:43 UTC (rev 1537) @@ -0,0 +1,46 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import unittest +import autoconfig +import parser_test_case + +from pygccxml import utils +from pygccxml import parser +from pygccxml import declarations + +class tester_t( parser_test_case.parser_test_case_t ): + global_ns = None + def __init__(self, *args ): + parser_test_case.parser_test_case_t.__init__( self, *args ) + self.header = 'const_volatile_arg.hpp' + self.global_ns = None + + def setUp(self): + if not tester_t.global_ns: + decls = parser.parse( [self.header], self.config ) + tester_t.global_ns = declarations.get_global_namespace( decls ) + tester_t.global_ns.init_optimizer() + self.global_ns = tester_t.global_ns + + def test( self ): + f = self.global_ns.free_fun( 'pygccxml_bug' ) + t = f.arguments[0].type + self.failUnless( isinstance( t, declarations.pointer_t ) ) + self.failUnless( isinstance( t.base, declarations.volatile_t ) ) + self.failUnless( isinstance( t.base.base, declarations.const_t ) ) + self.failUnless( declarations.is_integral( t.base.base.base ) ) + + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() Added: pygccxml_dev/unittests/data/const_volatile_arg.hpp =================================================================== --- pygccxml_dev/unittests/data/const_volatile_arg.hpp (rev 0) +++ pygccxml_dev/unittests/data/const_volatile_arg.hpp 2009-01-05 22:58:43 UTC (rev 1537) @@ -0,0 +1,12 @@ +// Copyright 2004-2008 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __const_volatile_arg_hpp__ +#define __const_volatile_arg_hpp__ + +void pygccxml_bug(int const volatile* icv); + +#endif//__const_volatile_arg_hpp__ + Modified: pygccxml_dev/unittests/test_all.py =================================================================== --- pygccxml_dev/unittests/test_all.py 2009-01-05 22:06:06 UTC (rev 1536) +++ pygccxml_dev/unittests/test_all.py 2009-01-05 22:58:43 UTC (rev 1537) @@ -54,6 +54,7 @@ import declaration_matcher_tester import undname_creator_tester import calling_convention_tester +import const_volatile_arg_tester testers = [ decl_string_tester @@ -104,6 +105,7 @@ , declaration_matcher_tester , undname_creator_tester , calling_convention_tester + , const_volatile_arg_tester ] def create_suite(): Modified: pygccxml_dev/unittests/type_traits_tester.py =================================================================== --- pygccxml_dev/unittests/type_traits_tester.py 2009-01-05 22:06:06 UTC (rev 1536) +++ pygccxml_dev/unittests/type_traits_tester.py 2009-01-05 22:58:43 UTC (rev 1537) @@ -12,19 +12,19 @@ from pygccxml import declarations class tester_t( parser_test_case.parser_test_case_t ): - COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE + COMPILATION_MODE = parser.COMPILATION_MODE.ALL_AT_ONCE declarations = None def __init__(self, *args ): parser_test_case.parser_test_case_t.__init__( self, *args ) self.header = 'type_traits.hpp' self.declarations = None - + def setUp(self): if not tester_t.declarations: tester_t.declarations = parser.parse( [self.header], self.config ) self.declarations = tester_t.declarations - - def __test_type_category( self, ns_name, controller ): + + def __test_type_category( self, ns_name, controller ): ns_control = declarations.find_declaration( self.declarations , type=declarations.namespace_t , name=ns_name ) @@ -37,23 +37,26 @@ , type=declarations.namespace_t , name='no' ) self.failUnless( ns_no, "unable to find 'no' namespace" ) - for decl in ns_yes.declarations: + for decl in ns_yes.declarations: if isinstance( decl, declarations.variable_t ): self.failUnless( controller( decl.type ) - , 'for type "%s" the answer to the question "%s" should be True' + , 'for type "%s" the answer to the question "%s" should be True' % ( decl.type.decl_string, ns_name ) ) elif isinstance( decl, declarations.calldef_t ) and decl.name.startswith( 'test_' ): continue else: + #~ if 'mf1_type_const_volatile_t' in decl.name: + #~ import pdb + #~ pdb.set_trace() self.failUnless( controller( decl ) - , 'for type "%s" the answer to the question "%s" should be True' + , 'for type "%s" the answer to the question "%s" should be True' % ( decl.decl_string, ns_name ) ) for decl in ns_no.declarations: if isinstance( decl, declarations.calldef_t ) and decl.name.startswith( 'test_' ): continue self.failIf( controller( decl ) - , 'for type "%s" the answer to the question "%s" should be False' + , 'for type "%s" the answer to the question "%s" should be False' % ( decl.decl_string, ns_name ) ) def __test_type_transformation( self, ns_name, transformer ): @@ -69,8 +72,8 @@ , type=declarations.namespace_t , name='after' ) self.failUnless( ns_after, "unable to find 'after' namespace" ) - - for tbefore in ns_before.declarations: + + for tbefore in ns_before.declarations: tafter = declarations.find_declaration( ns_after, name=tbefore.name ) self.failUnless( tafter, "unable to find transformed type definition for type '%s'" % tbefore.decl_string ) transformed = transformer( tbefore ) @@ -151,14 +154,14 @@ unrelated1 = declarations.find_declaration( ns.declarations , type=declarations.class_t , name='unrelated1' ) - + unrelated2 = declarations.find_declaration( ns.declarations , type=declarations.class_t , name='unrelated2' ) self.failUnless( base and derived and not declarations.is_base_and_derived( unrelated1, unrelated2 ) ) def test_is_same(self): - self.failUnless( declarations.is_same( declarations.int_t, declarations.int_t ) ) + self.failUnless( declarations.is_same( declarations.int_t, declarations.int_t ) ) self.failIf( declarations.is_same( declarations.int_t, declarations.float_t ) ) def test_remove_const(self): @@ -183,21 +186,21 @@ self.failUnless( operator_not, 'operator! was not found' ) self.failUnless( declarations.is_unary_operator( operator_not ), 'operator! should be idenitified as unary operator' ) self.failUnless( not declarations.is_binary_operator( operator_not ), 'operator! should be idenitified as unary operator' ) - + operator_class_p = declarations.find_declaration( self.declarations , type=declarations.operator_t , fullname='::is_unary_operator::dummy::operator+' ) self.failUnless( operator_class_p, 'operator+ was not found' ) self.failUnless( not declarations.is_unary_operator( operator_class_p ), 'operator+ should be idenitified as binary operator' ) self.failUnless( declarations.is_binary_operator( operator_class_p ), 'operator! should be idenitified as binary operator' ) - + operator_class_pp = declarations.find_declaration( self.declarations , type=declarations.operator_t , fullname='::is_unary_operator::dummy::operator++' ) self.failUnless( operator_class_pp, 'operator++ was not found' ) self.failUnless( declarations.is_unary_operator( operator_class_pp ), 'operator++ should be idenitified as unary operator' ) self.failUnless( not declarations.is_binary_operator( operator_class_pp ), 'operator++ should be idenitified as unary operator' ) - + operator_pp = declarations.find_declaration( self.declarations , type=declarations.operator_t , fullname='::is_unary_operator::operator++' ) @@ -229,16 +232,16 @@ expected_value = bool( expected_type.get_name2value_dict()['value'] ) self.failUnless( expected_value == declarations.is_convertible( source_type, target_type ) , 'Check conversion failed for ' + decl.name ) - + def test_is_convertible( self ): ns_is_convertible = declarations.find_declaration( self.declarations , type=declarations.namespace_t , name="is_convertible" ) - + self.failUnless( ns_is_convertible, "namespace is_convertible was not found" ) for tester in filter( lambda decl: decl.name.startswith( 'x' ), ns_is_convertible.declarations ): self.__is_convertible_impl( tester ) - + class missing_decls_tester_t(unittest.TestCase): def __init__(self, *args ): unittest.TestCase.__init__(self, *args) @@ -249,9 +252,9 @@ ci = global_ns.class_( 'const_item' ) self.failUnless( len( ci.declarations ) == 3 ) #copy constructor, destructor, variable - + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) suite.addTest( unittest.makeSuite(missing_decls_tester_t)) return suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-06 08:38:34
|
Revision: 1538 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1538&view=rev Author: roman_yakovenko Date: 2009-01-06 08:38:32 +0000 (Tue, 06 Jan 2009) Log Message: ----------- small refactoring, which allows to merge information from binary files to the declarations tree Modified Paths: -------------- pygccxml_dev/pygccxml/binary_parsers/__init__.py pygccxml_dev/pygccxml/declarations/decl_printer.py pygccxml_dev/pygccxml/declarations/declaration.py pygccxml_dev/unittests/data/core_cache.hpp pygccxml_dev/unittests/undname_creator_tester.py Added Paths: ----------- pygccxml_dev/pygccxml/binary_parsers/parsers.py pygccxml_dev/pygccxml/binary_parsers/undname.py Removed Paths: ------------- pygccxml_dev/pygccxml/binary_parsers/common_utils.py Modified: pygccxml_dev/pygccxml/binary_parsers/__init__.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/__init__.py 2009-01-05 22:58:43 UTC (rev 1537) +++ pygccxml_dev/pygccxml/binary_parsers/__init__.py 2009-01-06 08:38:32 UTC (rev 1538) @@ -3,7 +3,9 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -from common_utils import undecorate_blob -from common_utils import undecorate_decl -from common_utils import exported_symbols -from common_utils import UNDECORATE_NAME_OPTIONS +import sys +import undname +from parsers import merge_information + +def undecorate_blob( blob ): + return undname.undname_creator_t().undecorate_blob( blob ) Deleted: pygccxml_dev/pygccxml/binary_parsers/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/common_utils.py 2009-01-05 22:58:43 UTC (rev 1537) +++ pygccxml_dev/pygccxml/binary_parsers/common_utils.py 2009-01-06 08:38:32 UTC (rev 1538) @@ -1,285 +0,0 @@ -# Copyright 2004-2008 Roman Yakovenko. -# Distributed under the Boost Software License, Version 1.0. (See -# accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import os -import re -import sys -import ctypes -from .. import declarations - -class UNDECORATE_NAME_OPTIONS: - UNDNAME_COMPLETE = 0x0000 #Enables full undecoration. - UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 #Removes leading underscores from Microsoft extended keywords. - UNDNAME_NO_MS_KEYWORDS = 0x0002 #Disables expansion of Microsoft extended keywords. - UNDNAME_NO_FUNCTION_RETURNS = 0x0004 #Disables expansion of return type for primary declaration. - UNDNAME_NO_ALLOCATION_MODEL = 0x0008 #Disables expansion of the declaration model. - UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 #Disables expansion of the declaration language specifier. - UNDNAME_RESERVED1 = 0x0020 #RESERVED. - UNDNAME_RESERVED2 = 0x0040 #RESERVED. - UNDNAME_NO_THISTYPE = 0x0060 #Disables all modifiers on the this type. - UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 #Disables expansion of access specifiers for members. - UNDNAME_NO_THROW_SIGNATURES = 0x0100 #Disables expansion of "throw-signatures" for functions and pointers to functions. - UNDNAME_NO_MEMBER_TYPE = 0x0200 #Disables expansion of static or virtual members. - UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 #Disables expansion of the Microsoft model for UDT returns. - UNDNAME_32_BIT_DECODE = 0x0800 #Undecorates 32-bit decorated names. - UNDNAME_NAME_ONLY = 0x1000 #Gets only the name for primary declaration; returns just [scope::]name. Expands template params. - UNDNAME_TYPE_ONLY = 0x2000 #Input is just a type encoding; composes an abstract declarator. - UNDNAME_HAVE_PARAMETERS = 0x4000 #The real template parameters are available. - UNDNAME_NO_ECSU = 0x8000 #Suppresses enum/class/struct/union. - UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000 #Suppresses check for valid identifier characters. - UNDNAME_NO_PTR64 = 0x20000 #Does not include ptr64 in output. - - UNDNAME_SCOPES_ONLY = UNDNAME_NO_LEADING_UNDERSCORES \ - | UNDNAME_NO_MS_KEYWORDS \ - | UNDNAME_NO_FUNCTION_RETURNS \ - | UNDNAME_NO_ALLOCATION_MODEL \ - | UNDNAME_NO_ALLOCATION_LANGUAGE \ - | UNDNAME_NO_ACCESS_SPECIFIERS \ - | UNDNAME_NO_THROW_SIGNATURES \ - | UNDNAME_NO_MEMBER_TYPE \ - | UNDNAME_NO_ECSU \ - | UNDNAME_NO_IDENT_CHAR_CHECK - - SHORT_UNIQUE_NAME = UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU - -#~ The following code doesn't work - access violation - -#~__unDName definition was taken from: -#~http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/2006-02/msg00754.html - -#~ msvcrxx = ctypes.windll.msvcr90 -#~ free_type = ctypes.CFUNCTYPE( None, ctypes.c_void_p ) #free type -#~ malloc_type = ctypes.CFUNCTYPE( ctypes.c_void_p, ctypes.c_uint ) #malloc type -#~ __unDName = msvcrxx.__unDName -#~ __unDName.argtypes = [ ctypes.c_char_p #undecorated name - #~ , ctypes.c_char_p #decorated name - #~ , ctypes.c_int #sizeof undecorated name - #~ , malloc_type - #~ , free_type - #~ , ctypes.c_ushort #flags - #~ ] -#~ __unDName.restype = ctypes.c_char_p -#~ def undecorate_name( name, options=None ): - #~ if not name: - #~ return '' - #~ if options is None: - #~ options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME - #~ buffer_size = 1024 * 32 - #~ undecorated_name = ctypes.create_string_buffer('\0' * buffer_size) #should be enouph for any symbol - #~ __unDName( undecorated_name - #~ , str(name) - #~ , buffer_size - #~ , malloc_type( msvcrxx.malloc ) - #~ , free_type( msvcrxx.free ) - #~ , options ) - #~ return undecorated_name.value - -class undname_creator: - 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] - self.__clean_ecsu = re.compile( r'(?:(^|\W))(?:(class|enum|struct|union))' ) - self.__fundamental_types = ( - ( 'short unsigned int', 'unsigned short') - , ( 'short int', 'short' ) - , ( 'long int', 'long' ) - , ( 'long unsigned int', 'unsigned long' ) - ) - self.__calling_conventions = re.compile( r'(?:(^|\s))(?:__(cdecl|clrcall|stdcall|fastcall|thiscall)\s)' ) - - def normalize_undecorated( self, undname, options=None ): - if options is None: - options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME - if UNDECORATE_NAME_OPTIONS.UNDNAME_NO_ECSU & options: - undname = self.__clean_ecsu.sub( '', undname ) - if UNDECORATE_NAME_OPTIONS.UNDNAME_NO_ACCESS_SPECIFIERS & options: - for prefix in ( 'public: ', 'private: ', 'protected: ' ): - if undname.startswith( prefix ): - undname = undname[ len(prefix): ] - break - if UNDECORATE_NAME_OPTIONS.UNDNAME_NO_MS_KEYWORDS & options: - undname = self.__calling_conventions.sub( ' ', undname) - return undname.strip() - - def undecorate_blob( self, name, options=None ): - if options is None: - options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME - buffer = ctypes.create_string_buffer(1024*16) - res = self.__undname( str(name), buffer, ctypes.sizeof(buffer), options) - if res: - return self.normalize_undecorated( str(buffer[:res]) ) - else: - return name - - def __remove_leading_scope( self, s ): - if s and s.startswith( '::' ): - return s[2:] - else: - return s - - def __format_type_as_undecorated( self, type_, is_argument ): - result = [] - type_ = declarations.remove_alias( type_ ) - if declarations.is_array( type_ ): - result.append( declarations.array_item_type( type_ ).decl_string ) - result.append( '*' ) - if is_argument: - result.append( 'const' ) - else: - result.append( self.__remove_leading_scope( type_.decl_string ) ) - return ' '.join( result ) - - def __normalize( self, name ): - for what, with_ in self.__fundamental_types: - name = name.replace( what, with_ ) - name = name.replace( ', ', ',' ) - return name - - def undecorate_argtypes( self, argtypes ): - if not argtypes: - return 'void' - else: - formater = lambda type_: self.__format_type_as_undecorated( type_, True ) - return ','.join( map( formater, argtypes ) ) - - def __undecorated_calldef( self, calldef ): - calldef_type = calldef.function_type() - - result = [] - is_mem_fun = isinstance( calldef, declarations.member_calldef_t ) - if is_mem_fun and calldef.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: - result.append( 'virtual ' ) - if is_mem_fun and calldef.has_static: - result.append( 'static ' ) - if calldef_type.return_type: - result.append( self.__format_type_as_undecorated( calldef.return_type, False ) ) - result.append( ' ' ) - if is_mem_fun: - result.append( self.__remove_leading_scope( calldef.parent.decl_string ) + '::') - - result.append( calldef.name ) - if isinstance( calldef, ( declarations.constructor_t, declarations.destructor_t) ) \ - and declarations.templates.is_instantiation( calldef.parent.name ): - result.append( '<%s>' % ','.join( declarations.templates.args( calldef.parent.name ) ) ) - - result.append( '(%s)' % self.undecorate_argtypes( calldef_type.arguments_types ) ) - if is_mem_fun and calldef.has_const: - result.append( 'const' ) - return ''.join( result ) - - def __undecorated_variable( self, decl ): - result = [] - is_mem_var = isinstance( decl.parent, declarations.class_t ) - if is_mem_var and decl.type_qualifiers.has_static: - result.append( 'static ' ) - result.append( self.__format_type_as_undecorated( decl.type, False ) ) - result.append( ' ' ) - if is_mem_var: - result.append( self.__remove_leading_scope( decl.parent.decl_string ) + '::' ) - result.append( decl.name ) - return ''.join( result ) - - def undecorated_decl(self, decl): - """returns string, which contains full function name formatted exactly as - result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU - options. - """ - name = None - if isinstance( decl, declarations.calldef_t ): - name = self.__undecorated_calldef( decl ) - elif isinstance( decl, declarations.variable_t ): - name = self.__undecorated_variable( decl ) - else: - raise NotImplementedError() - return self.__normalize( name ) - -if 'win' in sys.platform: - undecorate_blob = undname_creator().undecorate_blob - undecorate_decl = undname_creator().undecorated_decl - undecorate_argtypes = undname_creator().undecorate_argtypes - normalize_undecorated = undname_creator().normalize_undecorated -else: - def undecorate_blob( x ): - raise NotImplementedError() - def undecorate_decl( x ): - raise NotImplementedError() - def undecorate_argtypes( x ): - raise NotImplementedError() - def normalize_undecorated( *args ): - raise NotImplementedError() - -import exceptions -class LicenseWarning( exceptions.UserWarning ): - def __init__( self, *args, **keywd ): - exceptions.UserWarning.__init__( self, *args, **keywd ) - -class exported_symbols: - map_file_re_c = re.compile( r' +\d+ (?P<internall>.+?)(?:\s+exported name\:\s(?P<name>.*)$)') - map_file_re_cpp = re.compile( r' +\d+ (?P<decorated>.+?) \((?P<undecorated>.+)\)$' ) - - @staticmethod - def load_from_map_file( fname ): - """returns dictionary { decorated symbol : orignal declaration name }""" - result = {} - f = open( fname ) - lines = [] - was_exports = False - for line in f: - if was_exports: - lines.append( line ) - elif 'Exports' == line.strip(): - was_exports = True - else: - pass - index = 0 - - while index < len( lines ): - line = lines[index].rstrip() - found = exported_symbols.map_file_re_cpp.match( line ) - if found: - result[ found.group( 'decorated' ) ] = normalize_undecorated( found.group( 'undecorated' ) ) - elif index + 1 < len( lines ): - two_lines = line + lines[index+1].rstrip() - found = exported_symbols.map_file_re_c.match( two_lines ) - if found: - result[ found.group( 'name' ) ] = found.group( 'name' ) - index += 1 - else: - pass - index += 1 - return result - - @staticmethod - def load_from_dll_file( fname ): - import warnings - warnings.warn( '\n'*2 + '-' * 30 + '>>LICENSE WARNING<<' + '-'*30 - + '\n"load_from_dll_file" functionality uses code licensed under MIT license.' - + '\npygccxml project uses Boost Software License, Version 1.0. ' - + '\nFor more information about this functionality take a look on get_dll_exported_symbols.py file.' - + '\n' + '='*79 - + '\n' * 2 - , LicenseWarning ) - import get_dll_exported_symbols - result = {} - blobs = get_dll_exported_symbols.read_export_table( fname ) - for blob in blobs: - result[ blob ] = undecorate_blob( blob ) - return result - - @staticmethod - def load_from_file( fname ): - ext = os.path.splitext( fname )[1] - if '.dll' == ext: - return exported_symbols.load_from_dll_file( fname ) - elif '.map' == ext: - return exported_symbols.load_from_map_file( fname ) - else: - raise RuntimeError( "Don't know how to read exported symbols from file '%s'" - % fname ) - - @staticmethod - def is_c_function( decl, blob ): - return decl.name == blob Copied: pygccxml_dev/pygccxml/binary_parsers/parsers.py (from rev 1537, pygccxml_dev/pygccxml/binary_parsers/common_utils.py) =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/parsers.py (rev 0) +++ pygccxml_dev/pygccxml/binary_parsers/parsers.py 2009-01-06 08:38:32 UTC (rev 1538) @@ -0,0 +1,193 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import re +import sys +import ctypes +import undname +import warnings +import exceptions +from .. import declarations + +class LicenseWarning( exceptions.UserWarning ): + def __init__( self, *args, **keywd ): + exceptions.UserWarning.__init__( self, *args, **keywd ) + + +dll_file_parser_warning = \ +""" + +----------------------------->> LICENSE WARNING <<----------------------------- +"dll_file_parser_t" functionality uses code licensed under MIT license. +pygccxml project uses Boost Software License, Version 1.0. +For more information about this functionality take a look on +get_dll_exported_symbols.py file. +================================================================================ + + +""" + +class libparser_t( object ): + def __init__( self, global_ns, binary_file ): + self.__global_ns = global_ns + self.__binary_file = binary_file + self.__loaded_symbols = None + + @property + def global_ns( self ): + """reference to global namespace""" + return self.__global_ns + + @property + def binary_file( self ): + """binary file path""" + return self.__binary_file + + @property + def loaded_symbols( self ): + """list of symbols, which were loaded from the binary file""" + return self.__loaded_symbols + + def load_symbols( self ): + raise NotImplementedError() + + def merge( self ): + raise NotImplementedError() + + def parse( self ): + self.__loaded_symbols = self.load_symbols() + result = {} + for smbl in self.__loaded_symbols: + decorated, decl = self.merge( smbl ) + if decl: + decl.decorated_name = decorated + result[ decorated ] = decl + return result + +CCTS = declarations.CALLING_CONVENTION_TYPES + + +CCTS = declarations.CALLING_CONVENTION_TYPES + +class msvc_libparser_t( libparser_t ): + def __init__( self, global_ns, binary_file ): + libparser_t.__init__( self, global_ns, binary_file ) + self.__formated_decls = {} + self.undname_creator = undname.undname_creator_t() + + for f in self.global_ns.calldefs( allow_empty=True, recursive=True ): + self.__formated_decls[ self.undname_creator.undecorated_decl( f ) ] = f + + for v in self.global_ns.variables( allow_empty=True, recursive=True ): + self.__formated_decls[ self.undname_creator.undecorated_decl( v ) ] = v + + @property + def formated_decls( self ): + return self.__formated_decls + +class map_file_parser_t( msvc_libparser_t ): + c_entry = re.compile( r' +\d+ (?P<internall>.+?)(?:\s+exported name\:\s(?P<name>.*)$)') + cpp_entry = re.compile( r' +\d+ (?P<decorated>.+?) \((?P<undecorated>.+)\)$' ) + + def __init__( self, global_ns, map_file_path ): + msvc_libparser_t.__init__( self, global_ns, map_file_path ) + + def load_symbols( self ): + """returns dictionary { decorated symbol : orignal declaration name }""" + f = file( self.binary_file ) + lines = [] + was_exports = False + for line in f: + if was_exports: + lines.append( line ) + elif 'Exports' == line.strip(): + was_exports = True + else: + pass + + index = 0 + result = [] + while index < len( lines ): + line = lines[index].rstrip() + found = self.cpp_entry.match( line ) + if found: + result.append( ( found.group( 'decorated' ), found.group( 'undecorated' ) ) ) + elif index + 1 < len( lines ): + two_lines = line + lines[index+1].rstrip() + found = self.c_entry.match( two_lines ) + if found: + result.append( ( found.group( 'name' ), found.group( 'name' ) ) ) + index += 1 + else: + pass + index += 1 + return result + + def merge( self, smbl ): + decorated, undecorated = smbl + if decorated == undecorated: + #we deal with C function ( or may be we deal with variable?, I have to check the latest + 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 + 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 + + +class dll_file_parser_t( msvc_libparser_t ): + def __init__( self, global_ns, map_file_path ): + global dll_file_parser_warning + warnings.warn( dll_file_parser_warning, LicenseWarning ) + msvc_libparser_t.__init__( self, global_ns, map_file_path ) + + def load_symbols( self ): + import get_dll_exported_symbols + return get_dll_exported_symbols.read_export_table( self.binary_file ) + + def merge( self, smbl ): + blob = smbl + blob_undecorated = self.undname_creator.undecorate_blob( blob, undname.UNDECORATE_NAME_OPTIONS.UNDNAME_COMPLETE ) + blob_undecorated_normalized = self.undname_creator.undecorate_blob( blob ) + if blob == blob_undecorated == blob_undecorated_normalized: + #we deal with C function ( or may be we deal with variable?, I have to check the latest + f = self.global_ns.free_fun( blob ) + #TODO create usecase, where C function uses different calling convention + f.calling_convention = CCTS.CDECL + return blob, f + else: + if blob_undecorated_normalized not in self.formated_decls: + return None, None + decl = self.formated_decls[ blob_undecorated_normalized ] + if isinstance( decl, declarations.calldef_t ): + decl.calling_convention = CCTS.extract( blob_undecorated, CCTS.CDECL ) + return blob, decl + + +def merge_information( global_ns, fname, runs_under_unittest=False ): + ext = os.path.splitext( fname )[1] + parser = None + if '.dll' == ext: + parser = dll_file_parser_t( global_ns, fname ) + elif '.map' == ext: + parser = map_file_parser_t( global_ns, fname ) + else: + raise RuntimeError( "Don't know how to read exported symbols from file '%s'" + % fname ) + symbols = parser.parse() + if runs_under_unittest: + return symbols, parser + else: + return symbols + + + Added: pygccxml_dev/pygccxml/binary_parsers/undname.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/undname.py (rev 0) +++ pygccxml_dev/pygccxml/binary_parsers/undname.py 2009-01-06 08:38:32 UTC (rev 1538) @@ -0,0 +1,201 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import re +import sys +import ctypes +from pygccxml import declarations + +class UNDECORATE_NAME_OPTIONS: + UNDNAME_COMPLETE = 0x0000 #Enables full undecoration. + UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 #Removes leading underscores from Microsoft extended keywords. + UNDNAME_NO_MS_KEYWORDS = 0x0002 #Disables expansion of Microsoft extended keywords. + UNDNAME_NO_FUNCTION_RETURNS = 0x0004 #Disables expansion of return type for primary declaration. + UNDNAME_NO_ALLOCATION_MODEL = 0x0008 #Disables expansion of the declaration model. + UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 #Disables expansion of the declaration language specifier. + UNDNAME_RESERVED1 = 0x0020 #RESERVED. + UNDNAME_RESERVED2 = 0x0040 #RESERVED. + UNDNAME_NO_THISTYPE = 0x0060 #Disables all modifiers on the this type. + UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 #Disables expansion of access specifiers for members. + UNDNAME_NO_THROW_SIGNATURES = 0x0100 #Disables expansion of "throw-signatures" for functions and pointers to functions. + UNDNAME_NO_MEMBER_TYPE = 0x0200 #Disables expansion of static or virtual members. + UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 #Disables expansion of the Microsoft model for UDT returns. + UNDNAME_32_BIT_DECODE = 0x0800 #Undecorates 32-bit decorated names. + UNDNAME_NAME_ONLY = 0x1000 #Gets only the name for primary declaration; returns just [scope::]name. Expands template params. + UNDNAME_TYPE_ONLY = 0x2000 #Input is just a type encoding; composes an abstract declarator. + UNDNAME_HAVE_PARAMETERS = 0x4000 #The real template parameters are available. + UNDNAME_NO_ECSU = 0x8000 #Suppresses enum/class/struct/union. + UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000 #Suppresses check for valid identifier characters. + UNDNAME_NO_PTR64 = 0x20000 #Does not include ptr64 in output. + + UNDNAME_SCOPES_ONLY = UNDNAME_NO_LEADING_UNDERSCORES \ + | UNDNAME_NO_MS_KEYWORDS \ + | UNDNAME_NO_FUNCTION_RETURNS \ + | UNDNAME_NO_ALLOCATION_MODEL \ + | UNDNAME_NO_ALLOCATION_LANGUAGE \ + | UNDNAME_NO_ACCESS_SPECIFIERS \ + | UNDNAME_NO_THROW_SIGNATURES \ + | UNDNAME_NO_MEMBER_TYPE \ + | UNDNAME_NO_ECSU \ + | UNDNAME_NO_IDENT_CHAR_CHECK + + SHORT_UNIQUE_NAME = UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU + +#~ The following code doesn't work - access violation + +#~__unDName definition was taken from: +#~http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/2006-02/msg00754.html + +#~ msvcrxx = ctypes.windll.msvcr90 +#~ free_type = ctypes.CFUNCTYPE( None, ctypes.c_void_p ) #free type +#~ malloc_type = ctypes.CFUNCTYPE( ctypes.c_void_p, ctypes.c_uint ) #malloc type +#~ __unDName = msvcrxx.__unDName +#~ __unDName.argtypes = [ ctypes.c_char_p #undecorated name + #~ , ctypes.c_char_p #decorated name + #~ , ctypes.c_int #sizeof undecorated name + #~ , malloc_type + #~ , free_type + #~ , ctypes.c_ushort #flags + #~ ] +#~ __unDName.restype = ctypes.c_char_p +#~ def undecorate_name( name, options=None ): + #~ if not name: + #~ return '' + #~ if options is None: + #~ options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME + #~ buffer_size = 1024 * 32 + #~ undecorated_name = ctypes.create_string_buffer('\0' * buffer_size) #should be enouph for any symbol + #~ __unDName( undecorated_name + #~ , str(name) + #~ , buffer_size + #~ , malloc_type( msvcrxx.malloc ) + #~ , free_type( msvcrxx.free ) + #~ , options ) + #~ return undecorated_name.value + +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] + self.__clean_ecsu = ( re.compile( r'(?P<startswith>^|\W)(?:(class|enum|struct|union)\s)' ) + , '%(startswith)s' ) + self.__fundamental_types = ( + ( 'short unsigned int', 'unsigned short') + , ( 'short int', 'short' ) + , ( 'long int', 'long' ) + , ( 'long unsigned int', 'unsigned long' ) + ) + self.__calling_conventions = ( re.compile( r'(?P<startswith>^|\s)(?:__(cdecl|clrcall|stdcall|fastcall|thiscall)\s)' ) + , '%(startswith)s' ) + + def normalize_undecorated( self, undname, options=None ): + if options is None: + options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME + if UNDECORATE_NAME_OPTIONS.UNDNAME_NO_ECSU & options: + expr, substitute = self.__clean_ecsu + undname = expr.sub( lambda m: substitute % m.groupdict(), undname ) + if UNDECORATE_NAME_OPTIONS.UNDNAME_NO_ACCESS_SPECIFIERS & options: + for prefix in ( 'public: ', 'private: ', 'protected: ' ): + if undname.startswith( prefix ): + undname = undname[ len(prefix): ] + break + if UNDECORATE_NAME_OPTIONS.UNDNAME_NO_MS_KEYWORDS & options: + expr, substitute = self.__calling_conventions + undname = expr.sub( lambda m: substitute % m.groupdict(), undname ) + return undname.strip() + + def undecorate_blob( self, name, options=None ): + if options is None: + options = UNDECORATE_NAME_OPTIONS.SHORT_UNIQUE_NAME + buffer = ctypes.create_string_buffer(1024*16) + res = self.__undname( str(name), buffer, ctypes.sizeof(buffer), options) + if res: + return self.normalize_undecorated( str(buffer[:res]) ) + else: + return name + + def __remove_leading_scope( self, s ): + if s and s.startswith( '::' ): + return s[2:] + else: + return s + + def __format_type_as_undecorated( self, type_, is_argument ): + result = [] + type_ = declarations.remove_alias( type_ ) + if declarations.is_array( type_ ): + result.append( declarations.array_item_type( type_ ).decl_string ) + result.append( '*' ) + if is_argument: + result.append( 'const' ) + else: + result.append( self.__remove_leading_scope( type_.decl_string ) ) + return ' '.join( result ) + + def __normalize( self, name ): + for what, with_ in self.__fundamental_types: + name = name.replace( what, with_ ) + name = name.replace( ', ', ',' ) + return name + + def undecorate_argtypes( self, argtypes ): + if not argtypes: + return 'void' + else: + formater = lambda type_: self.__format_type_as_undecorated( type_, True ) + return ','.join( map( formater, argtypes ) ) + + def __undecorated_calldef( self, calldef ): + calldef_type = calldef.function_type() + + result = [] + is_mem_fun = isinstance( calldef, declarations.member_calldef_t ) + if is_mem_fun and calldef.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: + result.append( 'virtual ' ) + if is_mem_fun and calldef.has_static: + result.append( 'static ' ) + if calldef_type.return_type: + result.append( self.__format_type_as_undecorated( calldef.return_type, False ) ) + result.append( ' ' ) + if is_mem_fun: + result.append( self.__remove_leading_scope( calldef.parent.decl_string ) + '::') + + result.append( calldef.name ) + if isinstance( calldef, ( declarations.constructor_t, declarations.destructor_t) ) \ + and declarations.templates.is_instantiation( calldef.parent.name ): + result.append( '<%s>' % ','.join( declarations.templates.args( calldef.parent.name ) ) ) + + result.append( '(%s)' % self.undecorate_argtypes( calldef_type.arguments_types ) ) + if is_mem_fun and calldef.has_const: + result.append( 'const' ) + return ''.join( result ) + + def __undecorated_variable( self, decl ): + result = [] + is_mem_var = isinstance( decl.parent, declarations.class_t ) + if is_mem_var and decl.type_qualifiers.has_static: + result.append( 'static ' ) + result.append( self.__format_type_as_undecorated( decl.type, False ) ) + result.append( ' ' ) + if is_mem_var: + result.append( self.__remove_leading_scope( decl.parent.decl_string ) + '::' ) + result.append( decl.name ) + return ''.join( result ) + + def undecorated_decl(self, decl): + """returns string, which contains full function name formatted exactly as + result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU + options. + """ + name = None + if isinstance( decl, declarations.calldef_t ): + name = self.__undecorated_calldef( decl ) + elif isinstance( decl, declarations.variable_t ): + name = self.__undecorated_variable( decl ) + else: + raise NotImplementedError() + return self.__normalize( name ) Modified: pygccxml_dev/pygccxml/declarations/decl_printer.py =================================================================== --- pygccxml_dev/pygccxml/declarations/decl_printer.py 2009-01-05 22:58:43 UTC (rev 1537) +++ pygccxml_dev/pygccxml/declarations/decl_printer.py 2009-01-06 08:38:32 UTC (rev 1538) @@ -123,9 +123,6 @@ if self.verbose and self.__inst.decorated_name: decorated_name = 'decorated name: %s'%(self.__inst.decorated_name) self.writer( ' ' * curr_level * self.INDENT_SIZE + decorated_name + os.linesep) - if self.verbose and self.__inst.undecorated_name: - undecorated_name = 'undecorated name: %s' % (self.__inst.undecorated_name) - self.writer( ' ' * curr_level * self.INDENT_SIZE + undecorated_name + os.linesep) def print_calldef_info(self, decl=None): """ Returns function signature: [retval, [arg1, ..., argN]]. """ Modified: pygccxml_dev/pygccxml/declarations/declaration.py =================================================================== --- pygccxml_dev/pygccxml/declarations/declaration.py 2009-01-05 22:58:43 UTC (rev 1537) +++ pygccxml_dev/pygccxml/declarations/declaration.py 2009-01-06 08:38:32 UTC (rev 1538) @@ -69,7 +69,6 @@ self._compiler = None self._partial_name = None self._decorated_name = None - self._undecorated_name = None def __str__(self): """Default __str__ method. @@ -244,15 +243,6 @@ @type: str """ ) - def _get_undecorated_name( self ): - return self._undecorated_name - def _set_undecorated_name( self, undecorated_name ): - self._undecorated_name = undecorated_name - undecorated_name = property( _get_undecorated_name, _set_undecorated_name - , doc="""declaration name, which was created by pygccxml, for matching ( source code <==> binary ) purpose - @type: str - """ ) - def _get_attributes( self ): return self._attributes def _set_attributes( self, attributes ): Modified: pygccxml_dev/unittests/data/core_cache.hpp =================================================================== --- pygccxml_dev/unittests/data/core_cache.hpp 2009-01-05 22:58:43 UTC (rev 1537) +++ pygccxml_dev/unittests/data/core_cache.hpp 2009-01-06 08:38:32 UTC (rev 1538) @@ -22,4 +22,4 @@ #endif//__core_cache_hpp__ -//touch//touch//touch//touch//touch \ No newline at end of file +//touch//touch//touch//touch//touch//touch//touch//touch \ No newline at end of file Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2009-01-05 22:58:43 UTC (rev 1537) +++ pygccxml_dev/unittests/undname_creator_tester.py 2009-01-06 08:38:32 UTC (rev 1538) @@ -20,19 +20,24 @@ global_ns = None known_issues = set([ - #pointer to functions - 'void (** myclass_t::get_do_smth(void))(std::auto_ptr<number_t> &)' - , 'void myclass_t::set_do_smth(void (**)(std::auto_ptr<number_t> &))' - # array as function argument - , 'int FA10_i_i(int * const)' + # 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(): - known_issues.add( 'std::auto_ptr<number_t> & std::auto_ptr<number_t>::operator=(std::auto_ptr_ref<number_t>)' ) + #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' ) def __init__(self, *args ): parser_test_case.parser_test_case_t.__init__( self, *args ) self.header = r'msvc\mydll.h' + self.map_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.map' ) + self.dll_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.dll' ) + def setUp(self): if not tester_t.global_ns: decls = parser.parse( [self.header], self.config ) @@ -49,46 +54,61 @@ return False def __tester_impl( self, fname ): - symbols = binary_parsers.exported_symbols.load_from_file( fname ) + symbols, parser = binary_parsers.merge_information( self.global_ns, fname, runs_under_unittest=True ) self.failUnless( 'identity' in symbols ) - undecorated_blob_names = set() - for blob in symbols.iterkeys(): + blob_names = set() + for blob in parser.loaded_symbols: + if isinstance( blob, tuple ): + blob = blob[0] undname = binary_parsers.undecorate_blob( blob ) if "`" in undname: continue - undecorated_blob_names.add( undname ) + blob_names.add( blob ) - undecorated_decl_names = set() - for f in self.global_ns.decls(self.is_included): - undecorated_decl_names.add( binary_parsers.undecorate_decl( f ) ) + decl_blob_names = set( symbols.keys() ) - issuperset = undecorated_decl_names.issuperset( undecorated_blob_names ) + issuperset = decl_blob_names.issuperset( blob_names ) if not issuperset: - common = undecorated_decl_names.intersection( undecorated_blob_names ) + common = decl_blob_names.intersection( blob_names ) - undecorated_decl_names.difference_update(common) - undecorated_blob_names.difference_update(common) - if not self.known_issues.issubset( undecorated_blob_names ): - undecorated_blob_names.difference_update( self.known_issues ) + decl_blob_names.difference_update(common) + blob_names.difference_update(common) + if not self.known_issues.issubset( blob_names ): + blob_names.difference_update( self.known_issues ) msg = [ "undecorate_decl - failed" ] - msg.append( "undecorated_decl_names :" ) - for i in undecorated_decl_names: + msg.append( "decl_blob_names :" ) + for i in decl_blob_names: msg.append( '\t==>%s<==' % i ) - msg.append( "undecorated_blob_names :" ) - for i in undecorated_blob_names: + msg.append( "blob_names :" ) + for i in blob_names: msg.append( '\t==>%s<==' % i ) self.fail( os.linesep.join(msg) ) def test_map_file( self ): - map_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.map' ) - self.__tester_impl( map_file ) + self.__tester_impl( self.map_file ) def test_dll_file( self ): - dll_file = os.path.join( autoconfig.data_directory, 'msvc', 'release', 'mydll.dll' ) - self.__tester_impl( dll_file ) + self.__tester_impl( self.dll_file ) + def test_compare_parsers( self ): + dsymbols, dparser = binary_parsers.merge_information( self.global_ns, self.dll_file, runs_under_unittest=True ) + msymbols, mparser = binary_parsers.merge_information( self.global_ns, self.map_file, runs_under_unittest=True ) + + self.failUnless( len( dparser.loaded_symbols ) == len( mparser.loaded_symbols ) ) + + was_error = False + for blob, decl in dsymbols.iteritems(): + if blob not in msymbols: + was_error = True + print '\n%s could not be found in map file loaded symbols' % binary_parsers.undecorate_blob( blob ) + #~ self.failUnless( blob in msymbols, binary_parsers.undecorate_blob( blob ) ) + else: + mdecl = msymbols[ blob ] + self.failUnless( mdecl is decl ) + self.failUnless( was_error == False ) + def create_suite(): suite = unittest.TestSuite() if 'win' in sys.platform: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-07 22:23:15
|
Revision: 1549 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1549&view=rev Author: roman_yakovenko Date: 2009-01-07 22:23:11 +0000 (Wed, 07 Jan 2009) Log Message: ----------- adding .so file parser Modified Paths: -------------- pygccxml_dev/pygccxml/binary_parsers/parsers.py pygccxml_dev/unittests/autoconfig.py pygccxml_dev/unittests/data/binary_parsers/mydll.cpp pygccxml_dev/unittests/data/binary_parsers/mydll.h pygccxml_dev/unittests/data/binary_parsers/sconstruct pygccxml_dev/unittests/undname_creator_tester.py Modified: pygccxml_dev/pygccxml/binary_parsers/parsers.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/parsers.py 2009-01-07 22:21:28 UTC (rev 1548) +++ pygccxml_dev/pygccxml/binary_parsers/parsers.py 2009-01-07 22:23:11 UTC (rev 1549) @@ -18,6 +18,7 @@ import undname import warnings import exceptions +import subprocess from .. import declarations class LicenseWarning( exceptions.UserWarning ): @@ -204,6 +205,52 @@ decl.calling_convention = CCTS.extract( blob_undecorated, CCTS.CDECL ) return blob, decl + +class so_file_parser_t( libparser_t ): + def __init__( self, global_ns, binary_file ): + libparser_t.__init__( self, global_ns, binary_file ) + self.__mangled2decls = {} + + 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 load_symbols( self ): + cmd = 'nm --extern-only --dynamic --defined-only %s' % self.binary_file + process = subprocess.Popen( args=cmd + , shell=True + , stdin=subprocess.PIPE + , stdout=subprocess.PIPE + , stderr=subprocess.STDOUT + , cwd=os.path.dirname( self.binary_file ) ) + process.stdin.close() + + output = [] + while process.poll() is None: + output.append( process.stdout.readline() ) + #the process already finished, read th rest of the output + for line in process.stdout.readlines(): + output.append( line ) + if process.returncode: + msg = ["Unable to extract public\\exported symbols from '%s' file." % self.binary_file ] + msg.append( 'The command line, which was used to extract symbols, is "%s"' % cmd ) + raise RuntimeError( os.linesep.join(msg) ) + + result = [] + for line in output: + line = line.strip() + if line: + result.append( line.split( ' ' )[-1] ) + return result + + def merge( self, smbl ): + if smbl in self.__mangled2decls: + return smbl, self.__mangled2decls[smbl] + else: + return (None, None) + def merge_information( global_ns, fname, runs_under_unittest=False ): """high level function - select the appropriate binary file parser and integrates the information from the file to the declarations tree. """ @@ -213,6 +260,8 @@ parser = dll_file_parser_t( global_ns, fname ) elif '.map' == ext: parser = map_file_parser_t( global_ns, fname ) + elif '.so' == ext: + parser = so_file_parser_t( global_ns, fname ) else: raise RuntimeError( "Don't know how to read exported symbols from file '%s'" % fname ) Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2009-01-07 22:21:28 UTC (rev 1548) +++ pygccxml_dev/unittests/autoconfig.py 2009-01-07 22:23:11 UTC (rev 1549) @@ -28,7 +28,6 @@ print 'unittests will run on DEVELOPMENT version' compiler = pygccxml.utils.native_compiler.get_gccxml_compiler() -compiler = "msvc71" print 'GCCXML configured to simulate compiler ', compiler pygccxml.declarations.class_t.USE_DEMANGLED_AS_NAME = True Modified: pygccxml_dev/unittests/data/binary_parsers/mydll.cpp =================================================================== --- pygccxml_dev/unittests/data/binary_parsers/mydll.cpp 2009-01-07 22:21:28 UTC (rev 1548) +++ pygccxml_dev/unittests/data/binary_parsers/mydll.cpp 2009-01-07 22:23:11 UTC (rev 1549) @@ -1,5 +1,4 @@ #include "mydll.h" -#include "windows.h" #include <iostream> number_t::number_t() @@ -80,23 +79,6 @@ short Fv_s(void){ return 0;} void Fv_v(void){ return;} - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} - int identity( int i){ return i; } Modified: pygccxml_dev/unittests/data/binary_parsers/mydll.h =================================================================== --- pygccxml_dev/unittests/data/binary_parsers/mydll.h 2009-01-07 22:21:28 UTC (rev 1548) +++ pygccxml_dev/unittests/data/binary_parsers/mydll.h 2009-01-07 22:23:11 UTC (rev 1549) @@ -1,10 +1,12 @@ #pragma once +#include "libconfig.h" + #include <memory> #include <string> #include <vector> -class __declspec(dllexport) number_t{ +class EXPORT_SYMBOL number_t{ public: number_t(); explicit number_t(int value); @@ -20,27 +22,27 @@ int m_value; }; -template class __declspec(dllexport) std::auto_ptr< number_t >; +template class EXPORT_SYMBOL std::auto_ptr< number_t >; typedef std::auto_ptr< number_t > number_aptr_t; enum{ auto_ptr_size = sizeof( number_aptr_t ) }; -__declspec(dllexport) void do_smth( number_aptr_t& ); +EXPORT_SYMBOL void do_smth( number_aptr_t& ); -__declspec(dllexport) extern int my_global_int; +EXPORT_SYMBOL extern int my_global_int; typedef void(*do_smth_type)( number_aptr_t& ); -__declspec(dllexport) extern volatile int my_volatile_global_variable; +EXPORT_SYMBOL extern volatile int my_volatile_global_variable; -__declspec(dllexport) extern int my_global_array[10]; +EXPORT_SYMBOL extern int my_global_array[10]; -__declspec(dllexport) void* get_pvoid(void*); -__declspec(dllexport) void** get_ppvoid(void); +EXPORT_SYMBOL void* get_pvoid(void*); +EXPORT_SYMBOL void** get_ppvoid(void); -class __declspec(dllexport) myclass_t{ +class EXPORT_SYMBOL myclass_t{ public: myclass_t(int x){} myclass_t(void){} @@ -75,36 +77,36 @@ }; -struct __declspec(dllexport) X{}; +struct EXPORT_SYMBOL X{}; -__declspec(dllexport) int FA10_i_i(int a[10]); -__declspec(dllexport) int FPi_i(int *a); -__declspec(dllexport) int Fc_i(char bar); -__declspec(dllexport) int Ff_i(float bar); -__declspec(dllexport) int Fg_i(double bar); -__declspec(dllexport) int Fi_i(int bar); -__declspec(dllexport) int Fie_i(int bar, ...); -__declspec(dllexport) int Fii_i(int bar, int goo); -__declspec(dllexport) int Fiii_i(int bar, int goo, int hoo); -__declspec(dllexport) void Fmxmx_v(myclass_t arg1, X arg2, myclass_t arg3, X arg4); -__declspec(dllexport) void Fmyclass_v(myclass_t m); -__declspec(dllexport) const int Fv_Ci(void); -__declspec(dllexport) long double Fv_Lg(void); -__declspec(dllexport) int& Fv_Ri(void); -__declspec(dllexport) signed char Fv_Sc(void); -__declspec(dllexport) unsigned char Fv_Uc(void); -__declspec(dllexport) unsigned int Fv_Ui(void); -__declspec(dllexport) unsigned long Fv_Ul(void); -__declspec(dllexport) unsigned short Fv_Us(void); -__declspec(dllexport) volatile int Fv_Vi(void); -__declspec(dllexport) char Fv_c(void); -__declspec(dllexport) float Fv_f(void); -__declspec(dllexport) double Fv_g(void); -__declspec(dllexport) int Fv_i(void); -__declspec(dllexport) long Fv_l(void); -__declspec(dllexport) short Fv_s(void); -__declspec(dllexport) void Fv_v(void); +EXPORT_SYMBOL int FA10_i_i(int a[10]); +EXPORT_SYMBOL int FPi_i(int *a); +EXPORT_SYMBOL int Fc_i(char bar); +EXPORT_SYMBOL int Ff_i(float bar); +EXPORT_SYMBOL int Fg_i(double bar); +EXPORT_SYMBOL int Fi_i(int bar); +EXPORT_SYMBOL int Fie_i(int bar, ...); +EXPORT_SYMBOL int Fii_i(int bar, int goo); +EXPORT_SYMBOL int Fiii_i(int bar, int goo, int hoo); +EXPORT_SYMBOL void Fmxmx_v(myclass_t arg1, X arg2, myclass_t arg3, X arg4); +EXPORT_SYMBOL void Fmyclass_v(myclass_t m); +EXPORT_SYMBOL const int Fv_Ci(void); +EXPORT_SYMBOL long double Fv_Lg(void); +EXPORT_SYMBOL int& Fv_Ri(void); +EXPORT_SYMBOL signed char Fv_Sc(void); +EXPORT_SYMBOL unsigned char Fv_Uc(void); +EXPORT_SYMBOL unsigned int Fv_Ui(void); +EXPORT_SYMBOL unsigned long Fv_Ul(void); +EXPORT_SYMBOL unsigned short Fv_Us(void); +EXPORT_SYMBOL volatile int Fv_Vi(void); +EXPORT_SYMBOL char Fv_c(void); +EXPORT_SYMBOL float Fv_f(void); +EXPORT_SYMBOL double Fv_g(void); +EXPORT_SYMBOL int Fv_i(void); +EXPORT_SYMBOL long Fv_l(void); +EXPORT_SYMBOL short Fv_s(void); +EXPORT_SYMBOL void Fv_v(void); extern "C"{ - int __declspec(dllexport) identity( int ); -} \ No newline at end of file + int EXPORT_SYMBOL identity( int ); +} Modified: pygccxml_dev/unittests/data/binary_parsers/sconstruct =================================================================== --- pygccxml_dev/unittests/data/binary_parsers/sconstruct 2009-01-07 22:21:28 UTC (rev 1548) +++ pygccxml_dev/unittests/data/binary_parsers/sconstruct 2009-01-07 22:23:11 UTC (rev 1549) @@ -29,7 +29,8 @@ env.Append( CPPPATH=[r"E:\Program Files\Microsoft SDKs\Windows\v6.0A\Include" , r"E:\Program Files\Microsoft Visual Studio 9.0\VC\include"]) -env.AppendUnique( CCFLAGS=[ r"/MD",r"/EHsc",r"/GR",r"/Zc:wchar_t",r"/Zc:forScope" ] ) -env.AppendUnique( LINKFLAGS=[r"/MAP:${TARGET.base}.map", r"/MAPINFO:EXPORTS"] ) +if 'win32' in sys.platform: + env.AppendUnique( CCFLAGS=[ r"/MD",r"/EHsc",r"/GR",r"/Zc:wchar_t",r"/Zc:forScope" ] ) + env.AppendUnique( LINKFLAGS=[r"/MAP:${TARGET.base}.map", r"/MAPINFO:EXPORTS"] ) SConscript( 'sconscript', variant_dir='#binaries', duplicate=0, exports=["env"] ) Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2009-01-07 22:21:28 UTC (rev 1548) +++ pygccxml_dev/unittests/undname_creator_tester.py 2009-01-07 22:23:11 UTC (rev 1549) @@ -37,6 +37,7 @@ self.header = os.path.join( self.binary_parsers_dir, r'mydll.h' ) self.map_file = os.path.join( self.binary_parsers_dir, 'binaries', 'mydll.map' ) self.dll_file = os.path.join( self.binary_parsers_dir, 'binaries', 'mydll.dll' ) + self.so_file = os.path.join( self.binary_parsers_dir, 'binaries', 'libmydll.so' ) def setUp(self): if not tester_t.global_ns: @@ -44,7 +45,8 @@ tester_t.global_ns = declarations.get_global_namespace( decls ) tester_t.global_ns.init_optimizer() - + declarations.print_declarations( tester_t.global_ns ) + process = subprocess.Popen( args='scons msvc_compiler=%s' % autoconfig.compiler , shell=True , stdin=subprocess.PIPE @@ -78,9 +80,11 @@ for blob in parser.loaded_symbols: if isinstance( blob, tuple ): blob = blob[0] - undname = binary_parsers.undecorate_blob( blob ) - if "`" in undname: - continue + if 'win32' in sys.platform: + #TODO: find out where undecorate function is exposed on linux + undname = binary_parsers.undecorate_blob( blob ) + if "`" in undname: + continue blob_names.add( blob ) decl_blob_names = set( symbols.keys() ) @@ -104,12 +108,16 @@ self.fail( os.linesep.join(msg) ) def test_map_file( self ): - self.__tester_impl( self.map_file ) + if 'win32' in sys.platform: + self.__tester_impl( self.map_file ) def test_dll_file( self ): - self.__tester_impl( self.dll_file ) + if 'win32' in sys.platform: + self.__tester_impl( self.dll_file ) - def test_compare_parsers( self ): + def test_z_compare_parsers( self ): + if 'win32' not in sys.platform: + return dsymbols, dparser = binary_parsers.merge_information( self.global_ns, self.dll_file, runs_under_unittest=True ) msymbols, mparser = binary_parsers.merge_information( self.global_ns, self.map_file, runs_under_unittest=True ) @@ -126,10 +134,13 @@ self.failUnless( mdecl is decl ) self.failUnless( was_error == False ) + def test_so_file( self ): + if 'linux2' in sys.platform: + self.__tester_impl( self.so_file ) + def create_suite(): suite = unittest.TestSuite() - if 'win' in sys.platform: - suite.addTest( unittest.makeSuite(tester_t)) + suite.addTest( unittest.makeSuite(tester_t)) return suite def run_suite(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-08 12:32:03
|
Revision: 1551 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1551&view=rev Author: roman_yakovenko Date: 2009-01-08 12:31:59 +0000 (Thu, 08 Jan 2009) Log Message: ----------- improving support of .so binary file parser Modified Paths: -------------- pygccxml_dev/pygccxml/binary_parsers/__init__.py 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/__init__.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/__init__.py 2009-01-07 22:25:48 UTC (rev 1550) +++ pygccxml_dev/pygccxml/binary_parsers/__init__.py 2009-01-08 12:31:59 UTC (rev 1551) @@ -14,3 +14,7 @@ def undecorate_blob( blob ): """returns undecorated\unmangled string, created from blob""" return undname.undname_creator_t().undecorate_blob( blob ) + +def format_decl( decl, hint=None ): + """returns string, that represents formatted decl, according to some rules""" + return undname.undname_creator_t().format_decl( decl, hint=hint ) Modified: pygccxml_dev/pygccxml/binary_parsers/parsers.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/parsers.py 2009-01-07 22:25:48 UTC (rev 1550) +++ pygccxml_dev/pygccxml/binary_parsers/parsers.py 2009-01-08 12:31:59 UTC (rev 1551) @@ -102,30 +102,32 @@ CCTS = declarations.CALLING_CONVENTION_TYPES -class msvc_libparser_t( libparser_t ): +class formated_mapping_parser_t( libparser_t ): """base parser class for few MSVC binary files""" - def __init__( self, global_ns, binary_file ): + def __init__( self, global_ns, binary_file, hint ): libparser_t.__init__( self, global_ns, binary_file ) self.__formated_decls = {} self.undname_creator = undname.undname_creator_t() + formatter = lambda decl: self.undname_creator.format_decl( f, hint ) + for f in self.global_ns.calldefs( allow_empty=True, recursive=True ): - self.__formated_decls[ self.undname_creator.undecorated_decl( f ) ] = f + self.__formated_decls[ formatter( f ) ] = f for v in self.global_ns.variables( allow_empty=True, recursive=True ): - self.__formated_decls[ self.undname_creator.undecorated_decl( v ) ] = v + self.__formated_decls[ formatter( v ) ] = v @property def formated_decls( self ): return self.__formated_decls -class map_file_parser_t( msvc_libparser_t ): +class map_file_parser_t( formated_mapping_parser_t ): """parser for MSVC .map file""" c_entry = re.compile( r' +\d+ (?P<internall>.+?)(?:\s+exported name\:\s(?P<name>.*)$)') cpp_entry = re.compile( r' +\d+ (?P<decorated>.+?) \((?P<undecorated>.+)\)$' ) def __init__( self, global_ns, map_file_path ): - msvc_libparser_t.__init__( self, global_ns, map_file_path ) + formated_mapping_parser_t.__init__( self, global_ns, map_file_path, 'msvc' ) def load_symbols( self ): """returns dictionary { decorated symbol : orignal declaration name }""" @@ -176,12 +178,12 @@ return decorated, decl -class dll_file_parser_t( msvc_libparser_t ): +class dll_file_parser_t( formated_mapping_parser_t ): """parser for Windows .dll file""" def __init__( self, global_ns, map_file_path ): global dll_file_parser_warning warnings.warn( dll_file_parser_warning, LicenseWarning ) - msvc_libparser_t.__init__( self, global_ns, map_file_path ) + formated_mapping_parser_t.__init__( self, global_ns, map_file_path, 'msvc' ) def load_symbols( self ): import get_dll_exported_symbols @@ -207,18 +209,23 @@ class so_file_parser_t( libparser_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' + cmd_demangled = '%(nm)s --extern-only --dynamic --defined-only --demangle --numeric-sort %(lib)s' + 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 = {} - + 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 load_symbols( self ): - cmd = 'nm --extern-only --dynamic --defined-only %s' % self.binary_file + + def __execute_nm( self, cmd ): process = subprocess.Popen( args=cmd , shell=True , stdin=subprocess.PIPE @@ -231,26 +238,39 @@ while process.poll() is None: output.append( process.stdout.readline() ) #the process already finished, read th rest of the output - for line in process.stdout.readlines(): - output.append( line ) + output.extend( process.stdout.readlines() ) if process.returncode: msg = ["Unable to extract public\\exported symbols from '%s' file." % self.binary_file ] msg.append( 'The command line, which was used to extract symbols, is "%s"' % cmd ) raise RuntimeError( os.linesep.join(msg) ) - - result = [] + return output + + def __extract_symbols( self, cmd ): + output = self.__execute_nm( cmd ) + result = {} for line in output: - line = line.strip() - if line: - result.append( line.split( ' ' )[-1] ) + found = self.entry.match( line ) + if found: + result[ found.group( 'address' ) ] = found.group( 'symbol' ) return result - + + def load_symbols( self ): + tmpl_args = dict( nm=self.nm_executable, lib=self.binary_file ) + mangled_smbls = self.__extract_symbols( self.cmd_mangled % tmpl_args ) + demangled_smbls = self.__extract_symbols( self.cmd_demangled % tmpl_args ) + result = [] + for address, blob in mangled_smbls.iteritems(): + if address in demangled_smbls: + result.append( blob, demangled_smbls[address] ) + return result + def merge( self, smbl ): - if smbl in self.__mangled2decls: - return smbl, self.__mangled2decls[smbl] - else: - return (None, None) - + decorated, undecorated = smbl + if undecorated not in self.formated_decls: + return None, None + decl = self.formated_decls[ undecorated ] + return decorated, decl + def merge_information( global_ns, fname, runs_under_unittest=False ): """high level function - select the appropriate binary file parser and integrates the information from the file to the declarations tree. """ Modified: pygccxml_dev/pygccxml/binary_parsers/undname.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/undname.py 2009-01-07 22:25:48 UTC (rev 1550) +++ pygccxml_dev/pygccxml/binary_parsers/undname.py 2009-01-08 12:31:59 UTC (rev 1551) @@ -128,7 +128,7 @@ else: return s - def __format_type_as_undecorated( self, type_, is_argument ): + def __format_type_as_undecorated( self, type_, is_argument, hint ): result = [] type_ = declarations.remove_alias( type_ ) if declarations.is_array( type_ ): @@ -138,32 +138,42 @@ result.append( 'const' ) else: result.append( self.__remove_leading_scope( type_.decl_string ) ) - return ' '.join( result ) + result = ' '.join( result ) + if hint == 'nm': + for x in ( '*', '&' ): + result = result.replace( ' ' + x, x ) + return result + + def __normalize( self, name ): for what, with_ in self.__fundamental_types: name = name.replace( what, with_ ) name = name.replace( ', ', ',' ) return name - def undecorate_argtypes( self, argtypes ): + def format_argtypes( self, argtypes, hint ): if not argtypes: - return 'void' + if hint == 'msvc': + return 'void' + else: + return '' else: - formater = lambda type_: self.__format_type_as_undecorated( type_, True ) + formater = lambda type_: self.__format_type_as_undecorated( type_, True, hint ) return ','.join( map( formater, argtypes ) ) - def __undecorated_calldef( self, calldef ): + 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 calldef.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: + if is_mem_fun and hint == 'msvc' and calldef.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: result.append( 'virtual ' ) - if is_mem_fun and calldef.has_static: + if is_mem_fun and hint == 'msvc'and calldef.has_static: result.append( 'static ' ) - if calldef_type.return_type: - result.append( self.__format_type_as_undecorated( calldef.return_type, False ) ) + if hint == 'msvc' and calldef_type.return_type: + #nm doesn't dump return type information + result.append( self.__format_type_as_undecorated( calldef.return_type, False, hint ) ) result.append( ' ' ) if is_mem_fun: result.append( self.__remove_leading_scope( calldef.parent.decl_string ) + '::') @@ -171,35 +181,50 @@ result.append( calldef.name ) if isinstance( calldef, ( declarations.constructor_t, declarations.destructor_t) ) \ and declarations.templates.is_instantiation( calldef.parent.name ): - result.append( '<%s>' % ','.join( declarations.templates.args( calldef.parent.name ) ) ) + if hint == 'msvc': + result.append( '<%s>' % ','.join( declarations.templates.args( calldef.parent.name ) ) ) - result.append( '(%s)' % self.undecorate_argtypes( calldef_type.arguments_types ) ) + result.append( '(%s)' % self.format_argtypes( calldef_type.arguments_types, hint ) ) if is_mem_fun and calldef.has_const: - result.append( 'const' ) + if hint == 'msvc': + result.append( 'const' ) + else: + result.append( ' const' ) return ''.join( result ) - def __undecorated_variable( self, decl ): + 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: result.append( 'static ' ) - result.append( self.__format_type_as_undecorated( decl.type, False ) ) - result.append( ' ' ) + if hint == 'msvc': + result.append( self.__format_type_as_undecorated( decl.type, False, hint ) ) + result.append( ' ' ) if is_mem_var: result.append( self.__remove_leading_scope( decl.parent.decl_string ) + '::' ) result.append( decl.name ) return ''.join( result ) - def undecorated_decl(self, decl): + def format_decl(self, decl, hint=None): """returns string, which contains full function name formatted exactly as result of dbghelp.UnDecorateSymbolName, with UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_ECSU options. + + Different compilers\utilities undecorate/demangle magled string ( unique names ) in a different way. + hint argument will tell pygccxml how to format declarations, so it couls be mapped later to the blob. + The valid options are" msvc, nm """ name = None + if hint is None: + if 'win32' in sys.platform: + hint = 'msvc' + else: + hint = 'nm' + if isinstance( decl, declarations.calldef_t ): - name = self.__undecorated_calldef( decl ) + name = self.format_calldef( decl, hint ) elif isinstance( decl, declarations.variable_t ): - name = self.__undecorated_variable( decl ) + name = self.format_var( decl, hint ) else: raise NotImplementedError() return self.__normalize( name ) Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2009-01-07 22:25:48 UTC (rev 1550) +++ pygccxml_dev/unittests/undname_creator_tester.py 2009-01-08 12:31:59 UTC (rev 1551) @@ -45,8 +45,6 @@ tester_t.global_ns = declarations.get_global_namespace( decls ) tester_t.global_ns.init_optimizer() - declarations.print_declarations( tester_t.global_ns ) - process = subprocess.Popen( args='scons msvc_compiler=%s' % autoconfig.compiler , shell=True , stdin=subprocess.PIPE @@ -117,7 +115,7 @@ def test_z_compare_parsers( self ): if 'win32' not in sys.platform: - return + return dsymbols, dparser = binary_parsers.merge_information( self.global_ns, self.dll_file, runs_under_unittest=True ) msymbols, mparser = binary_parsers.merge_information( self.global_ns, self.map_file, runs_under_unittest=True ) @@ -127,7 +125,7 @@ for blob, decl in dsymbols.iteritems(): if blob not in msymbols: was_error = True - print '\n%s could not be found in map file loaded symbols' % binary_parsers.undecorate_blob( blob ) + print '\n%s could not be found in .map file' % binary_parsers.undecorate_blob( blob ) #~ self.failUnless( blob in msymbols, binary_parsers.undecorate_blob( blob ) ) else: mdecl = msymbols[ blob ] @@ -138,6 +136,12 @@ if 'linux2' in sys.platform: self.__tester_impl( self.so_file ) + 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 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. |
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. |
From: <rom...@us...> - 2009-01-15 07:06:31
|
Revision: 1575 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1575&view=rev Author: roman_yakovenko Date: 2009-01-15 07:06:24 +0000 (Thu, 15 Jan 2009) Log Message: ----------- update load_gccxml_configuration functionality and integrate it with tests Modified Paths: -------------- pygccxml_dev/pygccxml/parser/config.py pygccxml_dev/unittests/autoconfig.py pygccxml_dev/unittests/undname_creator_tester.py Modified: pygccxml_dev/pygccxml/parser/config.py =================================================================== --- pygccxml_dev/pygccxml/parser/config.py 2009-01-15 07:04:23 UTC (rev 1574) +++ pygccxml_dev/pygccxml/parser/config.py 2009-01-15 07:06:24 UTC (rev 1575) @@ -194,7 +194,7 @@ config_t = gccxml_configuration_t #backward computability -def load_gccxml_configuration( configuration ): +def load_gccxml_configuration( configuration, **defaults ): """loads GCC-XML configuration from a file Configuration file sceleton: @@ -230,7 +230,16 @@ gccxml_cfg = gccxml_configuration_t() if not parser.has_section( 'gccxml' ): return gccxml_cfg + + values = defaults + if not values: + values = {} + for name, value in parser.items( 'gccxml' ): + if value.strip(): + values[ name ] = value + + for name, value in values.iteritems(): value = value.strip() if name == 'gccxml_path': gccxml_cfg.gccxml_path = value Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2009-01-15 07:04:23 UTC (rev 1574) +++ pygccxml_dev/unittests/autoconfig.py 2009-01-15 07:06:24 UTC (rev 1575) @@ -27,77 +27,19 @@ import pygccxml print 'unittests will run on DEVELOPMENT version' -compiler = pygccxml.utils.native_compiler.get_gccxml_compiler() -print 'GCCXML configured to simulate compiler ', compiler pygccxml.declarations.class_t.USE_DEMANGLED_AS_NAME = True class cxx_parsers_cfg: - keywd = { 'working_directory' : data_directory - , 'define_symbols' : [ gccxml_version ] - , 'compiler' : compiler } + gccxml = pygccxml.parser.load_gccxml_configuration( 'gccxml.cfg' + , gccxml_path=gccxml_path + , working_directory=data_directory + , compiler=pygccxml.utils.native_compiler.get_gccxml_compiler() ) + gccxml.define_symbols.append( gccxml_version ) if 'win' in sys.platform: - keywd['define_symbols'].append( '__PYGCCXML_%s__' % compiler.upper() ) - if 'msvc9' == compiler: - keywd['define_symbols'].append( '_HAS_TR1=0' ) + gccxml.define_symbols.append( '__PYGCCXML_%s__' % gccxml.compiler.upper() ) + if 'msvc9' == gccxml.compiler: + gccxml.define_symbols.append( '_HAS_TR1=0' ) - - if os.path.exists( os.path.join( gccxml_path, 'gccxml' ) ) \ - or os.path.exists( os.path.join( gccxml_path, 'gccxml.exe' ) ): - keywd[ 'gccxml_path'] = gccxml_path - gccxml = pygccxml.parser.gccxml_configuration_t( **keywd ) - - #~ pdb_loader = None - #~ if sys.platform == 'win32': - #~ from pygccxml.msvc import mspdb - #~ pdb_file = os.path.join( data_directory, 'msvc_build', 'Debug', 'msvc_build.pdb' ) - #~ if os.path.exists( pdb_file ): - #~ pdb_loader = mspdb.decl_loader_t( pdb_file ) - #~ pdb_loader.read() - -#~ def get_pdb_global_ns(): - #~ if cxx_parsers_cfg.pdb_loader: - #~ return cxx_parsers_cfg.pdb_loader.global_ns - -#~ try: - #~ import pydsc - #~ pydsc.include( r'D:\pygccxml_sources\sources\pygccxml_dev' ) - #~ pydsc.ignore( [ 'Yakovenko' - #~ , 'Bierbaum' - #~ , 'org' - #~ , 'http' - #~ , 'bool' - #~ , 'str' - #~ , 'www' - #~ , 'param' - #~ , 'txt' - #~ , 'decl' - #~ , 'decls' - #~ , 'namespace' - #~ , 'namespaces' - #~ , 'enum' - #~ , 'const' - #~ , 'GCC' - #~ , 'xcc' - #~ , 'TODO' - #~ , 'typedef' - #~ , 'os' - #~ , 'normcase' - #~ , 'normpath' - #~ , 'scopedef' - #~ , 'ira'#part of Matthias mail address - #~ , 'uka'#part of Matthias mail address - #~ , 'de'#part of Matthias mail address - #~ , 'dat'#file extension of directory cache - #~ , 'config'#parameter description - #~ , 'gccxml'#parameter description - #~ , 'Py++' - #~ , 'pygccxml' - #~ , 'calldef' - #~ , 'XXX' - #~ , 'wstring' - #~ , 'py' - #~ ] ) -#~ except ImportError: - #~ pass +print 'GCCXML configured to simulate compiler ', cxx_parsers_cfg.gccxml.compiler Modified: pygccxml_dev/unittests/undname_creator_tester.py =================================================================== --- pygccxml_dev/unittests/undname_creator_tester.py 2009-01-15 07:04:23 UTC (rev 1574) +++ pygccxml_dev/unittests/undname_creator_tester.py 2009-01-15 07:06:24 UTC (rev 1575) @@ -41,7 +41,7 @@ #typeinfo name for number_t , '_ZTI8number_t' , '_ZTV8number_t' - , '_ZTS8number_t' + , '_ZTS8number_t' #it seems that gccxml doesn't report this one , '_ZNSt12auto_ptr_refI8number_tEC1EPS0_' #the following are some global symbols @@ -65,7 +65,7 @@ tester_t.global_ns = declarations.get_global_namespace( decls ) tester_t.global_ns.init_optimizer() - process = subprocess.Popen( args='scons msvc_compiler=%s' % autoconfig.compiler + process = subprocess.Popen( args='scons msvc_compiler=%s' % autoconfig.cxx_parsers_cfg.gccxml.compiler , shell=True , stdin=subprocess.PIPE , stdout=subprocess.PIPE @@ -94,7 +94,7 @@ 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) ) ) + % ( expected_symbols, len(symbols) ) ) self.failUnless( 'identity' in symbols ) blob_names = set() @@ -118,7 +118,9 @@ blob_names.difference_update(common) if not self.known_issues.issubset( blob_names ): blob_names.difference_update( self.known_issues ) - msg = [ "undecorate_decl - failed" ] + if sys.version_info[0] == 2 and sys.version_info[1] == 5: + if 0 == len(decl_blob_names) and 0 ==len(blob_names): + return msg.append( "decl_blob_names :" ) for i in decl_blob_names: msg.append( '\t==>%s<==' % i ) @@ -130,11 +132,11 @@ def test_map_file( self ): if 'win32' in sys.platform: - self.__tester_impl( self.map_file ) + self.__tester_impl( self.map_file, 71 ) def test_dll_file( self ): if 'win32' in sys.platform: - self.__tester_impl( self.dll_file ) + self.__tester_impl( self.dll_file, 71 ) def test_z_compare_parsers( self ): if 'win32' not in sys.platform: @@ -159,7 +161,7 @@ if 'linux2' in sys.platform: self.__tester_impl( self.so_file, 64 ) - def dont_test_print( self ): + 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 ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-20 12:33:52
|
Revision: 1605 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1605&view=rev Author: roman_yakovenko Date: 2009-01-20 12:33:42 +0000 (Tue, 20 Jan 2009) Log Message: ----------- bsc and mspdb packages were deprecated Modified Paths: -------------- pygccxml_dev/pygccxml/parser/scanner.py pygccxml_dev/setup.py Added Paths: ----------- pygccxml_dev/deprecated/ pygccxml_dev/deprecated/bsc/ pygccxml_dev/deprecated/mspdb/ Removed Paths: ------------- pygccxml_dev/pygccxml/binary_parsers/bsc/ pygccxml_dev/pygccxml/binary_parsers/mspdb/ Modified: pygccxml_dev/pygccxml/parser/scanner.py =================================================================== --- pygccxml_dev/pygccxml/parser/scanner.py 2009-01-20 12:25:25 UTC (rev 1604) +++ pygccxml_dev/pygccxml/parser/scanner.py 2009-01-20 12:33:42 UTC (rev 1605) @@ -530,18 +530,18 @@ def __read_version(self, attrs): logger = utils.loggers.cxx_parser - - version = float( attrs.get(XML_AN_CVS_REVISION, 0.6) ) + version_str = attrs.get(XML_AN_CVS_REVISION, 0.6) + version = float( version_str ) if version is None: logger.info ( 'GCCXML version - 0.6' ) self.__compiler = compilers.GCC_XML_06 elif version <= 1.114: logger.info ( 'GCCXML version - 0.7' ) self.__compiler = compilers.GCC_XML_07 - elif version in ( 1.115, 1.116, 1.117, 1.118, 1.119, 1.120, 1.121 ): - logger.info ( 'GCCXML version - 0.9 BUGGY' ) + elif 1.115 <= version <= 1.126: + logger.info ( 'GCCXML version - 0.9 BUGGY( %s )', version_str ) self.__compiler = compilers.GCC_XML_09_BUGGY else: - logger.info ( 'GCCXML version - 0.9' ) + logger.info ( 'GCCXML version - 0.9( %s )', version_str ) self.__compiler = compilers.GCC_XML_09 Modified: pygccxml_dev/setup.py =================================================================== --- pygccxml_dev/setup.py 2009-01-20 12:25:25 UTC (rev 1604) +++ pygccxml_dev/setup.py 2009-01-20 12:33:42 UTC (rev 1605) @@ -61,8 +61,9 @@ 'pygccxml.declarations', 'pygccxml.parser', 'pygccxml.binary_parsers', - 'pygccxml.binary_parsers.bsc', - 'pygccxml.binary_parsers.mspdb', + #~ deprecated + #~ 'pygccxml.binary_parsers.bsc', + #~ 'pygccxml.binary_parsers.mspdb', 'pygccxml.utils' ], cmdclass = {"doc" : doc_cmd} ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-26 09:11:36
|
Revision: 1617 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1617&view=rev Author: roman_yakovenko Date: 2009-01-26 09:11:26 +0000 (Mon, 26 Jan 2009) Log Message: ----------- moving config.py file to deprecated directory Added Paths: ----------- pygccxml_dev/deprecated/config.py Removed Paths: ------------- pygccxml_dev/pygccxml/binary_parsers/config.py Copied: pygccxml_dev/deprecated/config.py (from rev 1607, pygccxml_dev/pygccxml/binary_parsers/config.py) =================================================================== --- pygccxml_dev/deprecated/config.py (rev 0) +++ pygccxml_dev/deprecated/config.py 2009-01-26 09:11:26 UTC (rev 1617) @@ -0,0 +1,73 @@ +import os +import sys +import comtypes +from pygccxml import utils +import comtypes.client +import _winreg as win_registry +from distutils import msvccompiler + +class binaries_searcher_t: + + def get_msbsc_path( self ): + relative_path = os.path.dirname( sys.modules[__name__].__file__) + absolute_path = os.path.abspath (relative_path) + return os.path.join( absolute_path, 'msbsc70.dll' ) + + def get_msvcr70_path( self ): + relative_path = os.path.dirname( sys.modules[__name__].__file__) + absolute_path = os.path.abspath (relative_path) + return os.path.join( absolute_path, 'msvcr70.dll' ) + + + def get_msvcr_path( self ): + vss_installed = self.__get_installed_vs_dirs() + for f in utils.files_walker( vss_installed, ["*.dll"], ): + f_path, f_name = os.path.split( f.upper() ) + if f_name.startswith( 'MSVCR' ): + return f + else: + raise RuntimeError( 'Unable to find msvcrXX.dll. Search path is: %s' % vss_installed ) + + def get_msdia_path( self ): + vss_installed = self.__get_installed_vs_dirs() + msdia_dlls = self.__get_msdia_dll_paths( vss_installed ) + if 1 == len(msdia_dlls): + return msdia_dlls[0] + else: + #TODO find the highest version and use it. + pass + + def __get_msdia_dll_paths( self, vss_installed ): + msdia_dlls = [] + for vs in vss_installed: + 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: + continue + msdia_dlls.extend([ os.path.join( debug_dir, f ) for f in files ]) + if not msdia_dlls: + raise RuntimeError( 'pygccxml unable to find out msdiaXX.dll location' ) + return msdia_dlls + + def __get_installed_vs_dirs( self ): + vs_reg_path = 'Software\Microsoft\VisualStudio\SxS\VS7' + values = self.read_values( win_registry.HKEY_LOCAL_MACHINE, vs_reg_path ) + return [ values.values()[0] ] + + def read_keys(self, base, key): + return msvccompiler.read_keys(base, key) + + def read_values(self, base, key): + return msvccompiler.read_values(base, key) + +bs = binaries_searcher_t() + +msdia_path = bs.get_msdia_path() +print 'msdia path: ', msdia_path + +msbsc_path = bs.get_msbsc_path() +print 'msbsc path: ', msbsc_path + +msvcr_path = bs.get_msvcr_path() +print 'msvcr path: ', msvcr_path Deleted: pygccxml_dev/pygccxml/binary_parsers/config.py =================================================================== --- pygccxml_dev/pygccxml/binary_parsers/config.py 2009-01-26 07:55:08 UTC (rev 1616) +++ pygccxml_dev/pygccxml/binary_parsers/config.py 2009-01-26 09:11:26 UTC (rev 1617) @@ -1,73 +0,0 @@ -import os -import sys -import comtypes -from pygccxml import utils -import comtypes.client -import _winreg as win_registry -from distutils import msvccompiler - -class binaries_searcher_t: - - def get_msbsc_path( self ): - relative_path = os.path.dirname( sys.modules[__name__].__file__) - absolute_path = os.path.abspath (relative_path) - return os.path.join( absolute_path, 'msbsc70.dll' ) - - def get_msvcr70_path( self ): - relative_path = os.path.dirname( sys.modules[__name__].__file__) - absolute_path = os.path.abspath (relative_path) - return os.path.join( absolute_path, 'msvcr70.dll' ) - - - def get_msvcr_path( self ): - vss_installed = self.__get_installed_vs_dirs() - for f in utils.files_walker( vss_installed, ["*.dll"], ): - f_path, f_name = os.path.split( f.upper() ) - if f_name.startswith( 'MSVCR' ): - return f - else: - raise RuntimeError( 'Unable to find msvcrXX.dll. Search path is: %s' % vss_installed ) - - def get_msdia_path( self ): - vss_installed = self.__get_installed_vs_dirs() - msdia_dlls = self.__get_msdia_dll_paths( vss_installed ) - if 1 == len(msdia_dlls): - return msdia_dlls[0] - else: - #TODO find the highest version and use it. - pass - - def __get_msdia_dll_paths( self, vss_installed ): - msdia_dlls = [] - for vs in vss_installed: - 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: - continue - msdia_dlls.extend([ os.path.join( debug_dir, f ) for f in files ]) - if not msdia_dlls: - raise RuntimeError( 'pygccxml unable to find out msdiaXX.dll location' ) - return msdia_dlls - - def __get_installed_vs_dirs( self ): - vs_reg_path = 'Software\Microsoft\VisualStudio\SxS\VS7' - values = self.read_values( win_registry.HKEY_LOCAL_MACHINE, vs_reg_path ) - return [ values.values()[0] ] - - def read_keys(self, base, key): - return msvccompiler.read_keys(base, key) - - def read_values(self, base, key): - return msvccompiler.read_values(base, key) - -bs = binaries_searcher_t() - -msdia_path = bs.get_msdia_path() -print 'msdia path: ', msdia_path - -msbsc_path = bs.get_msbsc_path() -print 'msbsc path: ', msbsc_path - -msvcr_path = bs.get_msvcr_path() -print 'msvcr path: ', msvcr_path This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-26 11:22:44
|
Revision: 1620 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1620&view=rev Author: roman_yakovenko Date: 2009-01-26 11:22:43 +0000 (Mon, 26 Jan 2009) Log Message: ----------- updating version and history Modified Paths: -------------- pygccxml_dev/docs/history/history.rest pygccxml_dev/pygccxml/__init__.py Modified: pygccxml_dev/docs/history/history.rest =================================================================== --- pygccxml_dev/docs/history/history.rest 2009-01-26 10:59:16 UTC (rev 1619) +++ pygccxml_dev/docs/history/history.rest 2009-01-26 11:22:43 UTC (rev 1620) @@ -26,6 +26,18 @@ ----------- +Version 1.1 +----------- + +1. Experimental back-ends based on ``.pdb`` and ``.bsc`` files were removed. + +2. Ability to extract different information from binary files ( ``.pdb``, ``.so``, + ``.map`` ) and merge it with a declarations tree was added. + +3. Ability to load `GCC-XML`_ configuration from ``.ini`` like file was added + + +----------- Version 1.0 ----------- @@ -47,7 +59,7 @@ which describe callables, have new property ``has_ellipsis``. It the value of the property is ``True``, than the function has ellipsis in its definition. -2. New expiremental back-end, based on ``.pdb`` (progam database file), was added. +2. New experimental back-end, based on ``.pdb`` (progam database file), was added. 3. New high-level API wrapper for ``.bsc`` (browse source code file) was added. Modified: pygccxml_dev/pygccxml/__init__.py =================================================================== --- pygccxml_dev/pygccxml/__init__.py 2009-01-26 10:59:16 UTC (rev 1619) +++ pygccxml_dev/pygccxml/__init__.py 2009-01-26 11:22:43 UTC (rev 1620) @@ -36,6 +36,6 @@ #TODO: # 1. Add "explicit" property for constructors -__version__ = '1.0.0' +__version__ = '1.1.0' __revision__ = 1080 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2009-01-26 15:03:06
|
Revision: 1621 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1621&view=rev Author: roman_yakovenko Date: 2009-01-26 15:03:04 +0000 (Mon, 26 Jan 2009) Log Message: ----------- fixing problems found by pychecker Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/algorithms_cache.py pygccxml_dev/pygccxml/declarations/class_declaration.py pygccxml_dev/pygccxml/declarations/container_traits.py pygccxml_dev/pygccxml/declarations/cpptypes.py pygccxml_dev/pygccxml/declarations/decl_printer.py pygccxml_dev/pygccxml/declarations/dependencies.py pygccxml_dev/pygccxml/declarations/function_traits.py pygccxml_dev/pygccxml/declarations/scopedef.py pygccxml_dev/pygccxml/declarations/type_traits.py pygccxml_dev/pygccxml/parser/config.py pygccxml_dev/pygccxml/parser/project_reader.py pygccxml_dev/pygccxml/parser/source_reader.py pygccxml_dev/pygccxml/utils/__init__.py pygccxml_dev/unittests/autoconfig.py Modified: pygccxml_dev/pygccxml/declarations/algorithms_cache.py =================================================================== --- pygccxml_dev/pygccxml/declarations/algorithms_cache.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/algorithms_cache.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -17,8 +17,8 @@ self._access_type = None self._demangled_name = None self._declaration_path = None - self._partial_declaration_path = None - self._container_key_type = None + self._partial_declaration_path = None + self._container_key_type = None self._container_element_type = None def disable( self ): @@ -36,7 +36,7 @@ def _set_full_name( self, fname ): if not self.enabled: fname = None - self._full_name = fname + self._full_name = fname full_name = property( _get_full_name, _set_full_name ) def _get_full_partial_name( self ): @@ -44,7 +44,7 @@ def _set_full_partial_name( self, fname ): if not self.enabled: fname = None - self._full_partial_name = fname + self._full_partial_name = fname full_partial_name = property( _get_full_partial_name, _set_full_partial_name ) def _get_access_type( self ): @@ -59,8 +59,8 @@ return self._demangled_name def _set_demangled_name( self, demangled_name ): if not self.enabled: - demangled_name = None - self._demangled_name = demangled_name + demangled_name = None + self._demangled_name = demangled_name demangled_name = property( _get_demangled_name, _set_demangled_name ) def _get_declaration_path( self ): @@ -87,14 +87,14 @@ etype = None self._container_element_type = etype container_element_type = property( _get_container_element_type, _set_container_element_type ) - + def _get_container_key_type( self ): return self._container_key_type def _set_container_key_type( self, ktype ): if not self.enabled: ktype = None self._container_key_type = ktype - container_key_type = property( _get_container_key_type, _set_container_key_type ) + container_key_type = property( _get_container_key_type, _set_container_key_type ) def reset( self ): self.full_name = None @@ -120,13 +120,13 @@ class type_algs_cache_t( object ): enabled = True - + @staticmethod def disable(): type_algs_cache_t.enabled = False @staticmethod - def enable( self ): + def enable(): type_algs_cache_t.enabled = True def __init__( self ): @@ -139,9 +139,9 @@ if not type_algs_cache_t.enabled: remove_alias = None self._remove_alias = remove_alias - + remove_alias = property( _get_remove_alias, _set_remove_alias ) def reset(self): self.remove_alias = None - + Modified: pygccxml_dev/pygccxml/declarations/class_declaration.py =================================================================== --- pygccxml_dev/pygccxml/declarations/class_declaration.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/class_declaration.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -13,7 +13,6 @@ """ import scopedef -import itertools import compilers import algorithm import declaration Modified: pygccxml_dev/pygccxml/declarations/container_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/container_traits.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/container_traits.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -258,7 +258,7 @@ , container_name , element_type_index , element_type_typedef - , defaults_remover + , defaults_remover , key_type_index=None , key_type_typedef=None ): """ @@ -267,7 +267,7 @@ arguments list element_type_typedef - class typedef to the value\\mapped type key_type_index - position of key type within template arguments list - key_type_typedef - class typedef to the key type + key_type_typedef - class typedef to the key type """ self._name = container_name self.remove_defaults_impl = defaults_remover @@ -279,18 +279,18 @@ def name(self): return self._name - def get_container_or_none( self, type ): + def get_container_or_none( self, type_ ): """returns reference to the class declaration or None""" - type = type_traits.remove_alias( type ) - type = type_traits.remove_cv( type ) + type_ = type_traits.remove_alias( type_ ) + type_ = type_traits.remove_cv( type_ ) cls = None - if isinstance( type, cpptypes.declarated_t ): - cls = type_traits.remove_alias( type.declaration ) - elif isinstance( type, class_declaration.class_t ): - cls = type - elif isinstance( type, class_declaration.class_declaration_t ): - cls = type + if isinstance( type_, cpptypes.declarated_t ): + cls = type_traits.remove_alias( type_.declaration ) + elif isinstance( type_, class_declaration.class_t ): + cls = type_ + elif isinstance( type_, class_declaration.class_declaration_t ): + cls = type_ else: return @@ -301,29 +301,29 @@ if type_traits.impl_details.is_defined_in_xxx( ns, cls ): return cls - def is_my_case( self, type ): + def is_my_case( self, type_ ): """checks, whether type is STD container or not""" - return bool( self.get_container_or_none( type ) ) + return bool( self.get_container_or_none( type_ ) ) - def class_declaration( self, type ): + def class_declaration( self, type_ ): """returns reference to the class declaration""" - cls = self.get_container_or_none( type ) + cls = self.get_container_or_none( type_ ) if not cls: - raise TypeError( 'Type "%s" is not instantiation of std::%s' % ( type.decl_string, self.name() ) ) + raise TypeError( 'Type "%s" is not instantiation of std::%s' % ( type_.decl_string, self.name() ) ) return cls - def is_sequence( self, type ): + def is_sequence( self, type_ ): #raise exception if type is not container - unused = self.class_declaration( type ) + unused = self.class_declaration( type_ ) return self.key_type_index is None - - def is_mapping( self, type ): - return not self.is_sequence( type ) - def __find_xxx_type( self, type, xxx_index, xxx_typedef, cache_property_name ): - cls = self.class_declaration( type ) + def is_mapping( self, type_ ): + return not self.is_sequence( type_ ) + + def __find_xxx_type( self, type_, xxx_index, xxx_typedef, cache_property_name ): + cls = self.class_declaration( type_ ) result = getattr( cls.cache, cache_property_name ) - if not result: + if not result: if isinstance( cls, class_declaration.class_t ): xxx_type = cls.typedef( xxx_typedef, recursive=False ).type result = type_traits.remove_declarated( xxx_type ) @@ -336,29 +336,29 @@ setattr( cls.cache, cache_property_name, result ) return result - def element_type( self, type ): + def element_type( self, type_ ): """returns reference to the class value\\mapped type declaration""" - return self.__find_xxx_type( type + return self.__find_xxx_type( type_ , self.element_type_index , self.element_type_typedef , 'container_element_type') - def key_type( self, type ): - """returns reference to the class key type declaration""" - if not self.is_mapping( type ): - raise TypeError( 'Type "%s" is not "mapping" container' % str( type ) ) - return self.__find_xxx_type( type + def key_type( self, type_ ): + """returns reference to the class key type declaration""" + if not self.is_mapping( type_ ): + raise TypeError( 'Type "%s" is not "mapping" container' % str( type_ ) ) + return self.__find_xxx_type( type_ , self.key_type_index , self.key_type_typedef , 'container_key_type' ) def remove_defaults( self, type_or_string ): """remove template defaults from a template class instantiation - + For example: - std::vector< int, std::allocator< int > > + std::vector< int, std::allocator< int > > will become - std::vector< int > + std::vector< int > """ name = type_or_string if not isinstance( type_or_string, types.StringTypes ): @@ -408,11 +408,11 @@ , defaults_eraser.erase_map_compare_allocator , key_type_index=0 , key_type_typedef='key_type') - + multimap_traits = create_traits( 'multimap' , 1 , 'mapped_type' - , defaults_eraser.erase_map_compare_allocator + , defaults_eraser.erase_map_compare_allocator , key_type_index=0 , key_type_typedef='key_type') @@ -420,15 +420,15 @@ hash_map_traits = create_traits( 'hash_map' , 1 , 'mapped_type' - , defaults_eraser.erase_hashmap_compare_allocator + , defaults_eraser.erase_hashmap_compare_allocator , key_type_index=0 , key_type_typedef='key_type') - - + + hash_multimap_traits = create_traits( 'hash_multimap' , 1 , 'mapped_type' - , defaults_eraser.erase_hashmap_compare_allocator + , defaults_eraser.erase_hashmap_compare_allocator , key_type_index=0 , key_type_typedef='key_type') @@ -436,7 +436,7 @@ , 0 , 'value_type' , defaults_eraser.erase_compare_allocator) - + multiset_traits = create_traits( 'multiset' , 0 , 'value_type' @@ -446,7 +446,7 @@ , 0 , 'value_type' , defaults_eraser.erase_hash_allocator ) - + hash_multiset_traits = create_traits( 'hash_multiset' , 0 , 'value_type' Modified: pygccxml_dev/pygccxml/declarations/cpptypes.py =================================================================== --- pygccxml_dev/pygccxml/declarations/cpptypes.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/cpptypes.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -501,10 +501,10 @@ @return: L{free_function_type_t} """ + f = lambda x: x.build_decl_string( with_defaults ) return free_function_type_t.NAME_TEMPLATE % { 'return_type' : return_type.build_decl_string( with_defaults ) - , 'arguments' : ','.join( map( lambda x: x.build_decl_string( with_defaults ) - , arguments_types ) ) } + , 'arguments' : ','.join( map( f, arguments_types ) ) } def build_decl_string(self, with_defaults=True): return self.create_decl_string( self.return_type, self.arguments_types, with_defaults ) @@ -523,11 +523,11 @@ @param name: the desired name of typedef """ #unused argument simplifies user code + f = lambda x: x.build_decl_string( with_defaults ) return free_function_type_t.TYPEDEF_NAME_TEMPLATE % { 'typedef_name' : typedef_name , 'return_type' : self.return_type.build_decl_string( with_defaults ) - , 'arguments' : ','.join( map( lambda x: x.build_decl_string( with_defaults ) - , self.arguments_types ) ) } + , 'arguments' : ','.join( map( f, self.arguments_types ) ) } class member_function_type_t( type_t, calldef_type_t ): """describes member function type""" @@ -569,12 +569,12 @@ class_alias = self.class_inst.decl_string else: class_alias = self.class_inst.partial_decl_string + f = lambda x: x.build_decl_string(with_defaults) return member_function_type_t.TYPEDEF_NAME_TEMPLATE % { 'typedef_name' : typedef_name , 'return_type' : self.return_type.build_decl_string( with_defaults ) , 'class' : class_alias - , 'arguments' : ','.join( map( lambda x: x.build_decl_string(with_defaults) - , self.arguments_types ) ) + , 'arguments' : ','.join( map( f, self.arguments_types ) ) , 'has_const' : has_const_str } def create(self): @@ -592,11 +592,11 @@ return_type_decl_string = '' if return_type: return_type_decl_string = return_type.build_decl_string( with_defaults ) + f = lambda x: x.build_decl_string(with_defaults) return member_function_type_t.NAME_TEMPLATE % { 'return_type' : return_type_decl_string , 'class' : class_decl_string - , 'arguments' : ','.join( map( lambda x: x.build_decl_string(with_defaults) - , arguments_types ) ) + , 'arguments' : ','.join( map( f, arguments_types ) ) , 'has_const' : has_const_str } def build_decl_string(self, with_defaults=True): Modified: pygccxml_dev/pygccxml/declarations/decl_printer.py =================================================================== --- pygccxml_dev/pygccxml/declarations/decl_printer.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/decl_printer.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -240,7 +240,7 @@ self.writer( value_level + "%s : %s"% (name, value) + os.linesep) def visit_namespace(self ): - if self.verbose == False and not self.__inst.declarations: + if not self.verbose and not self.__inst.declarations: return #don't print info about empty namespaces self.print_decl_header() if self.__recursive: Modified: pygccxml_dev/pygccxml/declarations/dependencies.py =================================================================== --- pygccxml_dev/pygccxml/declarations/dependencies.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/dependencies.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -79,9 +79,8 @@ def we_depend_on_them( decls ): """returns set of declarations. every item in the returned set, depends on a declaration from the input""" - import class_declaration #prevent cyclic imports to_be_included = set() for decl in decls: - to_be_included.update( dependency_info_t.they_depend_on_me( decl ) ) + to_be_included.update( dependency_info_t.i_depend_on_them( decl ) ) return to_be_included Modified: pygccxml_dev/pygccxml/declarations/function_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/function_traits.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/function_traits.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -13,17 +13,17 @@ def is_same_return_type( f1, f2 ): #covariant returns - #The return type of an overriding function shall be either identical to the - #return type of the overridden function or covariant with the classes of the - #functions. If a function D::f overrides a function B::f, the return types + #The return type of an overriding function shall be either identical to the + #return type of the overridden function or covariant with the classes of the + #functions. If a function D::f overrides a function B::f, the return types #of the functions are covariant if they satisfy the following criteria: #* both are pointers to classes or references to classes - #* the class in the return type of B::f is the same class as the class in - # the return type of D::f or, is an unambiguous direct or indirect base + #* the class in the return type of B::f is the same class as the class in + # the return type of D::f or, is an unambiguous direct or indirect base # class of the class in the return type of D::f and is accessible in D - #* both pointers or references have the same cv-qualification and the class - # type in the return type of D::f has the same cv-qualification as or less + #* both pointers or references have the same cv-qualification and the class + # type in the return type of D::f has the same cv-qualification as or less # cv-qualification than the class type in the return type of B::f. if not f1.__class__ is f2.__class__: @@ -43,11 +43,11 @@ rt2 = type_traits.remove_pointer( rt2 ) elif type_traits.is_reference( rt1 ) and type_traits.is_reference( rt2 ): rt1 = type_traits.remove_reference( rt1 ) - rt2 = type_traits.remove_reference( rt2 ) + rt2 = type_traits.remove_reference( rt2 ) else: return type_traits.is_same( f1.return_type, f2.return_type) if ( type_traits.is_const( rt1 ) and type_traits.is_const( rt2 ) ) \ - or ( False == type_traits.is_const( rt1 ) and False == type_traits.is_const( rt2 ) ): + or ( not type_traits.is_const( rt1 ) and not type_traits.is_const( rt2 ) ): rt1 = type_traits.remove_const( rt1 ) rt2 = type_traits.remove_const( rt2 ) else: @@ -62,8 +62,8 @@ return type_traits.is_same( c1, c2 ) \ or type_traits.is_base_and_derived( c1, c2 ) \ or type_traits.is_base_and_derived( c2, c1 ) - + def is_same_function( f1, f2 ): """returns true if f1 and f2 is same function Modified: pygccxml_dev/pygccxml/declarations/scopedef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/scopedef.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/scopedef.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -117,7 +117,7 @@ raise NotImplementedError() def _get_declarations(self): - if True == self._optimized: + if self._optimized: return self._all_decls_not_recursive else: return self._get_declarations_impl() @@ -309,7 +309,7 @@ #templates has tricky mode to compare them, so lets check the whole #range name = None - + if name and decl_type: matcher = scopedef_t._impl_matchers[ scopedef_t.decl ]( name=name ) if matcher.is_full_name(): Modified: pygccxml_dev/pygccxml/declarations/type_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/type_traits.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/declarations/type_traits.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -16,7 +16,6 @@ """ import os -import types import matchers import typedef import calldef @@ -187,7 +186,7 @@ elif isinstance( nake_type, cpptypes.volatile_t ) \ and isinstance( nake_type.base, cpptypes.const_t ) \ and isinstance( nake_type.base.base, cpptypes.pointer_t ): - return cpptypes.volatile_t( ctypes.const_t( nake_type.base.base.base ) ) + return cpptypes.volatile_t( cpptypes.const_t( nake_type.base.base.base ) ) elif isinstance( nake_type.base, cpptypes.calldef_type_t ): return type else: @@ -222,7 +221,7 @@ elif is_pointer( type_ ): return remove_pointer( type_ ) else: - assert 0 + raise RuntimeError( "array_item_type functions takes as argument array or pointer types" ) def remove_reference(type): """removes reference from the type definition @@ -252,15 +251,15 @@ else: return nake_type.base -def remove_declarated( type ): - """removes type-declaration class-binder L{declarated_t} from the type +def remove_declarated( type_ ): + """removes type-declaration class-binder L{declarated_t} from the type_ - If type is not L{declarated_t}, it will be returned as is + If type_ is not L{declarated_t}, it will be returned as is """ - type = remove_alias( type ) - if isinstance( type, cpptypes.declarated_t ): - type = type.declaration - return type + type_ = remove_alias( type_ ) + if isinstance( type_, cpptypes.declarated_t ): + type_ = type_.declaration + return type_ def is_same(type1, type2): """returns True, if type1 and type2 are same types""" @@ -316,22 +315,22 @@ def __init__( self, declaration_class ): self.declaration_class = declaration_class - def __apply_sequence( self, type ): + def __apply_sequence( self, type_ ): for f in self.sequence: - type = f( type ) - return type + type_ = f( type_ ) + return type_ - def is_my_case( self, type ): + def is_my_case( self, type_ ): """returns True, if type represents the desired declaration, False otherwise""" - return isinstance( self.__apply_sequence( type ), self.declaration_class ) + return isinstance( self.__apply_sequence( type_ ), self.declaration_class ) - def get_declaration( self, type ): + def get_declaration( self, type_ ): """returns reference to the declaration Precondition: self.is_my_case( type ) == True """ - assert self.is_my_case( type ) - return self.__apply_sequence( type ) + assert self.is_my_case( type_ ) + return self.__apply_sequence( type_ ) enum_traits = declaration_xxx_traits( enumeration.enumeration_t ) """implements functionality, needed for convinient work with C++ enums""" @@ -354,10 +353,10 @@ is_class_declaration = class_declaration_traits.is_my_case """returns True, if type represents C++ class declaration, False otherwise""" -def find_trivial_constructor( type ): +def find_trivial_constructor( type_ ): """returns reference to trivial constructor or None""" - assert isinstance( type, class_declaration.class_t ) - return type.find_trivial_constructor() + assert isinstance( type_, class_declaration.class_t ) + return type_.find_trivial_constructor() def has_trivial_constructor( class_ ): """if class has public trivial constructor, this function will return reference to it, None otherwise""" @@ -425,42 +424,42 @@ if decls: return decls -def has_public_binary_operator( type, operator_symbol ): - """returns True, if type has public binary operator, otherwise False""" - not_artificial = lambda decl: decl.is_artificial == False - type = remove_alias( type ) - type = remove_cv( type ) - type = remove_declarated( type ) - assert isinstance( type, class_declaration.class_t ) +def has_public_binary_operator( type_, operator_symbol ): + """returns True, if type_ has public binary operator, otherwise False""" + not_artificial = lambda decl: not decl.is_artificial + type_ = remove_alias( type_ ) + type_ = remove_cv( type_ ) + type_ = remove_declarated( type_ ) + assert isinstance( type_, class_declaration.class_t ) - if is_std_string( type ) or is_std_wstring( type ): + if is_std_string( type_ ) or is_std_wstring( type_ ): #In some case compare operators of std::basic_string are not instantiated return True - operators = type.member_operators( function=matchers.custom_matcher_t( not_artificial ) \ - & matchers.access_type_matcher_t( 'public' ) + operators = type_.member_operators( function=matchers.custom_matcher_t( not_artificial ) \ + & matchers.access_type_matcher_t( 'public' ) , symbol=operator_symbol , allow_empty=True , recursive=False ) if operators: return True - t = cpptypes.declarated_t( type ) + t = cpptypes.declarated_t( type_ ) t = cpptypes.const_t( t ) t = cpptypes.reference_t( t ) - operators = type.top_parent.operators( function=not_artificial + operators = type_.top_parent.operators( function=not_artificial , arg_types=[t, None] , symbol=operator_symbol , allow_empty=True , recursive=True ) if operators: return True - for bi in type.recursive_bases: + for bi in type_.recursive_bases: assert isinstance( bi, class_declaration.hierarchy_info_t ) if bi.access_type != class_declaration.ACCESS_TYPES.PUBLIC: continue operators = bi.related_class.member_operators( function=matchers.custom_matcher_t( not_artificial ) \ - & matchers.access_type_matcher_t( 'public' ) + & matchers.access_type_matcher_t( 'public' ) , symbol=operator_symbol , allow_empty=True , recursive=False ) @@ -843,7 +842,7 @@ class_ = class_traits.get_declaration( class_ ) true_header = "is_noncopyable(TRUE) - %s - " % class_.decl_string - false_header = "is_noncopyable(false) - %s - " % class_.decl_string + #~ false_header = "is_noncopyable(false) - %s - " % class_.decl_string if class_.class_type == class_declaration.CLASS_TYPES.UNION: return False @@ -989,12 +988,12 @@ """small convenience class, which provides access to internal types""" #TODO: add exists function @staticmethod - def get_by_name( type, name ): - if class_traits.is_my_case( type ): - cls = class_traits.declaration_class( type ) + def get_by_name( type_, name ): + if class_traits.is_my_case( type_ ): + cls = class_traits.declaration_class( type_ ) return remove_declarated( cls.typedef( name, recursive=False ).type ) - elif class_declaration_traits.is_my_case( type ): - cls = class_declaration_traits.get_declaration( type ) + elif class_declaration_traits.is_my_case( type_ ): + cls = class_declaration_traits.get_declaration( type_ ) value_type_str = templates.args( cls.name )[0] ref = impl_details.find_value_type( cls.top_parent, value_type_str ) if ref: @@ -1004,102 +1003,102 @@ % ( name, cls.decl_string ) ) else: raise RuntimeError( "Unable to find reference to internal type '%s' in type '%s'." - % ( name, type.decl_string ) ) + % ( name, type_.decl_string ) ) class smart_pointer_traits: """implements functionality, needed for convinient work with smart pointers""" @staticmethod - def is_smart_pointer( type ): + def is_smart_pointer( type_ ): """returns True, if type represents instantiation of C{boost::shared_ptr}, False otherwise""" - type = remove_alias( type ) - type = remove_cv( type ) - type = remove_declarated( type ) - if not isinstance( type, ( class_declaration.class_declaration_t, class_declaration.class_t ) ): + type_ = remove_alias( type_ ) + type_ = remove_cv( type_ ) + type_ = remove_declarated( type_ ) + if not isinstance( type_, ( class_declaration.class_declaration_t, class_declaration.class_t ) ): return False - if not impl_details.is_defined_in_xxx( 'boost', type ): + if not impl_details.is_defined_in_xxx( 'boost', type_ ): return False - return type.decl_string.startswith( '::boost::shared_ptr<' ) + return type_.decl_string.startswith( '::boost::shared_ptr<' ) @staticmethod - def value_type( type ): + def value_type( type_ ): """returns reference to boost::shared_ptr value type""" - if not smart_pointer_traits.is_smart_pointer( type ): - raise TypeError( 'Type "%s" is not instantiation of boost::shared_ptr' % type.decl_string ) - return internal_type_traits.get_by_name( type, "value_type" ) + if not smart_pointer_traits.is_smart_pointer( type_ ): + raise TypeError( 'Type "%s" is not instantiation of boost::shared_ptr' % type_.decl_string ) + return internal_type_traits.get_by_name( type_, "value_type" ) class auto_ptr_traits: """implements functionality, needed for convinient work with std::auto_ptr pointers""" @staticmethod - def is_smart_pointer( type ): + def is_smart_pointer( type_ ): """returns True, if type represents instantiation of C{boost::shared_ptr}, False otherwise""" - type = remove_alias( type ) - type = remove_cv( type ) - type = remove_declarated( type ) - if not isinstance( type, ( class_declaration.class_declaration_t, class_declaration.class_t ) ): + type_ = remove_alias( type_ ) + type_ = remove_cv( type_ ) + type_ = remove_declarated( type_ ) + if not isinstance( type_, ( class_declaration.class_declaration_t, class_declaration.class_t ) ): return False - if not impl_details.is_defined_in_xxx( 'std', type ): + if not impl_details.is_defined_in_xxx( 'std', type_ ): return False - return type.decl_string.startswith( '::std::auto_ptr<' ) + return type_.decl_string.startswith( '::std::auto_ptr<' ) @staticmethod - def value_type( type ): + def value_type( type_ ): """returns reference to boost::shared_ptr value type""" - if not auto_ptr_traits.is_smart_pointer( type ): - raise TypeError( 'Type "%s" is not instantiation of std::auto_ptr' % type.decl_string ) - return internal_type_traits.get_by_name( type, "element_type" ) + if not auto_ptr_traits.is_smart_pointer( type_ ): + raise TypeError( 'Type "%s" is not instantiation of std::auto_ptr' % type_.decl_string ) + return internal_type_traits.get_by_name( type_, "element_type" ) -def is_std_string( type ): +def is_std_string( type_ ): """returns True, if type represents C++ std::string, False otherwise""" decl_strings = [ '::std::basic_string<char,std::char_traits<char>,std::allocator<char> >' , '::std::basic_string<char, std::char_traits<char>, std::allocator<char> >' , '::std::string' ] - if isinstance( type, types.StringTypes ): - return type in decl_strings + if isinstance( type_, build_in_types.StringTypes ): + return type_ in decl_strings else: - type = remove_alias( type ) - return remove_cv( type ).decl_string in decl_strings + type_ = remove_alias( type_ ) + return remove_cv( type_ ).decl_string in decl_strings -def is_std_wstring( type ): +def is_std_wstring( type_ ): """returns True, if type represents C++ std::wstring, False otherwise""" decl_strings = [ '::std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >' , '::std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >' , '::std::wstring' ] - if isinstance( type, types.StringTypes ): - return type in decl_strings + if isinstance( type_, build_in_types.StringTypes ): + return type_ in decl_strings else: - type = remove_alias( type ) - return remove_cv( type ).decl_string in decl_strings + type_ = remove_alias( type_ ) + return remove_cv( type_ ).decl_string in decl_strings -def is_std_ostream( type ): +def is_std_ostream( type_ ): """returns True, if type represents C++ std::string, False otherwise""" decl_strings = [ '::std::basic_ostream<char, std::char_traits<char> >' , '::std::basic_ostream<char,std::char_traits<char> >' , '::std::ostream' ] - if isinstance( type, types.StringTypes ): - return type in decl_strings + if isinstance( type_, build_in_types.StringTypes ): + return type_ in decl_strings else: - type = remove_alias( type ) - return remove_cv( type ).decl_string in decl_strings + type_ = remove_alias( type_ ) + return remove_cv( type_ ).decl_string in decl_strings -def is_std_wostream( type ): +def is_std_wostream( type_ ): """returns True, if type represents C++ std::string, False otherwise""" decl_strings = [ '::std::basic_ostream<wchar_t, std::char_traits<wchar_t> >' , '::std::basic_ostream<wchar_t,std::char_traits<wchar_t> >' , '::std::wostream' ] - if isinstance( type, types.StringTypes ): - return type in decl_strings + if isinstance( type_, build_in_types.StringTypes ): + return type_ in decl_strings else: - type = remove_alias( type ) - return remove_cv( type ).decl_string in decl_strings + type_ = remove_alias( type_ ) + return remove_cv( type_ ).decl_string in decl_strings Modified: pygccxml_dev/pygccxml/parser/config.py =================================================================== --- pygccxml_dev/pygccxml/parser/config.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/parser/config.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -98,7 +98,6 @@ def __ensure_dir_exists( self, dir_path, meaning ): if os.path.isdir( dir_path ): return - msg = None if os.path.exists( self.working_directory ): raise RuntimeError( '%s("%s") does not exist!' % ( meaning, dir_path ) ) else: @@ -219,9 +218,9 @@ Configuration file sceleton: >>> start <<< - + %s - + >>> end <<< configuration could be string( configuration file path ) or instance of Modified: pygccxml_dev/pygccxml/parser/project_reader.py =================================================================== --- pygccxml_dev/pygccxml/parser/project_reader.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/parser/project_reader.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -330,8 +330,8 @@ if dir_ and not os.path.exists( dir_ ): os.makedirs( dir_ ) self.logger.info( 'Creating xml file "%s" from source file "%s" ... ' - % ( fc.cached_source_file, header ) ) - xml_file_path = reader.create_xml_file( header, fc.cached_source_file ) + % ( fc.cached_source_file, fc.data ) ) + xml_file_path = reader.create_xml_file( fc.data, fc.cached_source_file ) else: xml_file_path = fc.cached_source_file else: Modified: pygccxml_dev/pygccxml/parser/source_reader.py =================================================================== --- pygccxml_dev/pygccxml/parser/source_reader.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/parser/source_reader.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -193,10 +193,7 @@ return gccxml_file def read_file( self, source_file ): - if isinstance( self.__config, config.gccxml_configuration_t ): - return self.read_gccxml_file( source_file ) - else: - return self.read_synopsis_file( source_file ) + return self.read_gccxml_file( source_file ) def read_gccxml_file(self, source_file): """ @@ -205,7 +202,7 @@ @param source_file: path to C++ source file @type source_file: str """ - declarations, types = None, None + declarations = None gccxml_file = '' try: ffname = self.__file_full_name(source_file) Modified: pygccxml_dev/pygccxml/utils/__init__.py =================================================================== --- pygccxml_dev/pygccxml/utils/__init__.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/pygccxml/utils/__init__.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -79,7 +79,7 @@ This function is a wrapper aroung Python built-in function - tempfile.mkstemp """ if not prefix: - prefix = tempfile.template + prefix = tempfile.gettempprefix() fd, name = tempfile.mkstemp( suffix=suffix, prefix=prefix, dir=dir ) file_obj = os.fdopen( fd ) file_obj.close() @@ -93,7 +93,8 @@ """returns bool( filter( lambda dir: fpath.startswith( dir ), dirs ) ) precondition: dirs and fpath should be normalize_path'ed before calling this function """ - return bool( filter( lambda dir: fpath.startswith( dir ), dirs ) ) + f = lambda dir_: fpath.startswith( dir_ ) + return bool( filter( f, dirs ) ) def get_architecture(): Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2009-01-26 11:22:43 UTC (rev 1620) +++ pygccxml_dev/unittests/autoconfig.py 2009-01-26 15:03:04 UTC (rev 1621) @@ -7,8 +7,8 @@ import sys import getpass -#__pychecker__ = 'limit=1000' -#import pychecker.checker +#~ os.environ['PYCHECKER'] = '--limit=1000 -q --no-argsused' +#~ import pychecker.checker this_module_dir_path = os.path.abspath ( os.path.dirname( sys.modules[__name__].__file__) ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |