pygccxml-commit Mailing List for C++ Python language bindings (Page 60)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(190) |
Apr
(166) |
May
(170) |
Jun
(75) |
Jul
(105) |
Aug
(131) |
Sep
(99) |
Oct
(84) |
Nov
(67) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(66) |
Feb
(49) |
Mar
(25) |
Apr
(62) |
May
(21) |
Jun
(34) |
Jul
(9) |
Aug
(21) |
Sep
(5) |
Oct
|
Nov
(63) |
Dec
(34) |
2008 |
Jan
(10) |
Feb
(42) |
Mar
(26) |
Apr
(25) |
May
(6) |
Jun
(40) |
Jul
(18) |
Aug
(29) |
Sep
(6) |
Oct
(32) |
Nov
(14) |
Dec
(56) |
2009 |
Jan
(127) |
Feb
(52) |
Mar
(2) |
Apr
(10) |
May
(29) |
Jun
(3) |
Jul
|
Aug
(16) |
Sep
(4) |
Oct
(11) |
Nov
(8) |
Dec
(14) |
2010 |
Jan
(31) |
Feb
(1) |
Mar
(7) |
Apr
(9) |
May
(1) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
(8) |
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <rom...@us...> - 2006-07-30 08:12:22
|
Revision: 366 Author: roman_yakovenko Date: 2006-07-30 01:12:03 -0700 (Sun, 30 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=366&view=rev Log Message: ----------- adding new functionality. It is possible now to pass operator symbol as a name to query functions Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/namespace.py pygccxml_dev/pygccxml/declarations/scopedef.py pygccxml_dev/unittests/data/core_cache.hpp pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/unittests/data/operators_to_be_exported.hpp pyplusplus_dev/unittests/operators_tester.py Modified: pygccxml_dev/pygccxml/declarations/namespace.py =================================================================== --- pygccxml_dev/pygccxml/declarations/namespace.py 2006-07-30 07:53:27 UTC (rev 365) +++ pygccxml_dev/pygccxml/declarations/namespace.py 2006-07-30 08:12:03 UTC (rev 366) @@ -95,7 +95,7 @@ def free_operator( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): return self._find_single( scopedef.scopedef_t._impl_matchers[ namespace_t.free_operator ] - , name=name + , name=self._build_operator_name( name, function, symbol ) , symbol=symbol , function=function , decl_type=self._impl_decl_types[ namespace_t.free_operator ] @@ -107,7 +107,7 @@ def free_operators( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): return self._find_multiple( scopedef.scopedef_t._impl_matchers[ namespace_t.free_operator ] - , name=name + , name=self._build_operator_name( name, function, symbol ) , symbol=symbol , function=function , decl_type=self._impl_decl_types[ namespace_t.free_operator ] Modified: pygccxml_dev/pygccxml/declarations/scopedef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/scopedef.py 2006-07-30 07:53:27 UTC (rev 365) +++ pygccxml_dev/pygccxml/declarations/scopedef.py 2006-07-30 08:12:03 UTC (rev 366) @@ -1,554 +1,564 @@ -# 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) - -""" -defines base class for L{namespace_t} and L{class_t} classes -""" - -import time -import algorithm -import filtering -import declaration -import mdecl_wrapper -from pygccxml import utils -import matcher as matcher_module - -class scopedef_t( declaration.declaration_t ): - """Base class for L{namespace_t} and L{class_t} classes. - - This is the base class for all declaration classes that may have - children nodes. The children can be accessed via the C{declarations} - property. - - Also this class provides "get/select/find" interface. Using this class you - can get instance or instances of internal declaration(s). - - You can find declaration(s) using next criteria: - 1. name - declaration name, could be full qualified name - 2. header_dir - directory, to which belongs file, that the declaration was declarated in. - header_dir should be absolute path. - 3. header_file - file that the declaration was declarated in. - 4. function - user ( your ) custom criteria. The interesting thing is that - this function will be joined with other arguments ( criteria ). - 5. recursive - the search declaration range, if True will be search in - internal declarations too. - - Every "select" API you can invoke and pass as first argument at declaration - name or function. This class will find out correctly what argument represents. - - Example:: - ns - referrers to global namespace - ns.member_function( "do_something ) - will return reference to member - function named "do_something". If there is no such function exception - will be raised. If there is more then one function exception will be - raised too. - - Example 2:: - ns - referers to global namespace - do_smths = ns.member_functions( "do_something ) - will return instance - of L{mdecl_wrapper_t} object. This object allows you few things: - - 1. To iterate on selected declarations - 2. To set some property to desired value using one line of code only: - do_smths.call_policies = x - 3. To call some function on every instance using one line of code: - do_smths.exclude() - - Pay attention: you can not use "get" functions or properties. - """ - - RECURSIVE_DEFAULT = True - ALLOW_EMPTY_MDECL_WRAPPER = False - - _impl_matchers = {} #this class variable is used to prevent recursive imports - _impl_decl_types = {} #this class variable is used to prevent recursive imports - _impl_all_decl_types = [] #this class variable is used to prevent recursive imports - - def __init__( self, name='', parent=''): - declaration.declaration_t.__init__( self, name, parent ) - - self._optimized = False - self._type2decls = {} - self._type2name2decls = {} - self._type2decls_nr = {} - self._type2name2decls_nr = {} - self._all_decls = None +# 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) +""" +defines base class for L{namespace_t} and L{class_t} classes +""" + +import time +import algorithm +import filtering +import declaration +import mdecl_wrapper +from pygccxml import utils +import matcher as matcher_module + +class scopedef_t( declaration.declaration_t ): + """Base class for L{namespace_t} and L{class_t} classes. + + This is the base class for all declaration classes that may have + children nodes. The children can be accessed via the C{declarations} + property. + + Also this class provides "get/select/find" interface. Using this class you + can get instance or instances of internal declaration(s). + + You can find declaration(s) using next criteria: + 1. name - declaration name, could be full qualified name + 2. header_dir - directory, to which belongs file, that the declaration was declarated in. + header_dir should be absolute path. + 3. header_file - file that the declaration was declarated in. + 4. function - user ( your ) custom criteria. The interesting thing is that + this function will be joined with other arguments ( criteria ). + 5. recursive - the search declaration range, if True will be search in + internal declarations too. + + Every "select" API you can invoke and pass as first argument at declaration + name or function. This class will find out correctly what argument represents. + + Example:: + ns - referrers to global namespace + ns.member_function( "do_something ) - will return reference to member + function named "do_something". If there is no such function exception + will be raised. If there is more then one function exception will be + raised too. + + Example 2:: + ns - referers to global namespace + do_smths = ns.member_functions( "do_something ) - will return instance + of L{mdecl_wrapper_t} object. This object allows you few things: + + 1. To iterate on selected declarations + 2. To set some property to desired value using one line of code only: + do_smths.call_policies = x + 3. To call some function on every instance using one line of code: + do_smths.exclude() + + Pay attention: you can not use "get" functions or properties. + """ + + RECURSIVE_DEFAULT = True + ALLOW_EMPTY_MDECL_WRAPPER = False + + _impl_matchers = {} #this class variable is used to prevent recursive imports + _impl_decl_types = {} #this class variable is used to prevent recursive imports + _impl_all_decl_types = [] #this class variable is used to prevent recursive imports + + def __init__( self, name='', parent=''): + declaration.declaration_t.__init__( self, name, parent ) + + self._optimized = False + self._type2decls = {} + self._type2name2decls = {} + self._type2decls_nr = {} + self._type2name2decls_nr = {} + self._all_decls = None + def _get_logger( self ): return utils.loggers.queries_engine _logger = property( _get_logger ) - - def _get__cmp__scope_items(self): - raise NotImplementedError() - - def _get__cmp__items(self): - items = [ self._sorted_list( self.declarations ) ] - items.extend( self._get__cmp__scope_items() ) - return items - - def __eq__(self, other): - if not declaration.declaration_t.__eq__( self, other ): - return False - return self._sorted_list( self.declarations[:] ) \ - == other._sorted_list( other.declarations[:] ) - - def _get_declarations_impl(self): - raise NotImplementedError() - - def _get_declarations(self): - return self._get_declarations_impl() - declarations = property( _get_declarations, - doc="""A list of children declarations. - @type: list of L{declaration_t} - """) - - def remove_declaration( self, decl ): - raise NotImplementedError() - - - def __decl_types( self, decl ): - types = [] - bases = list( decl.__class__.__bases__ ) - visited = set() - if 'pygccxml' in decl.__class__.__module__: - types.append( decl.__class__ ) - while bases: - base = bases.pop() - if base is declaration.declaration_t: - continue - if base in visited: - continue - if 'pygccxml' not in base.__module__: - continue - types.append( base ) - bases.extend( base.__bases__ ) - return types - - def clear_optimizer(self): - """Cleans query optimizer state""" - self._optimized = False - self._type2decls = {} - self._type2name2decls = {} - self._type2decls_nr = {} - self._type2name2decls_nr = {} - self._all_decls = None - - map( lambda decl: decl.clear_optimizer() - , filter( lambda decl: isinstance( decl, scopedef_t ) - , self.declarations ) ) - - def init_optimizer(self): - """Initializes query optimizer state. - There are 4 internals hash tables: - 1. from type to declarations - 2. from type to declarations for non-recursive queries - 3. from type to name to declarations - 4. from type to name to declarations for non-recursive queries - - Almost every query includes declaration type information. Also very - common query is to search some declaration(s) by name or full name. - Those hashtables allows to search declaration very quick. - """ - if self.name == '::': - self._logger.debug( "preparing data structures for query optimizer - started" ) - start_time = time.clock() - - self.clear_optimizer() - - for dtype in scopedef_t._impl_all_decl_types: - self._type2decls[ dtype ] = [] - self._type2decls_nr[ dtype ] = [] - self._type2name2decls[ dtype ] = {} - self._type2name2decls_nr[ dtype ] = {} - - self._all_decls = algorithm.make_flatten( self.declarations ) - for decl in self._all_decls: - types = self.__decl_types( decl ) - for type_ in types: - self._type2decls[ type_ ].append( decl ) - name2decls = self._type2name2decls[ type_ ] - if not name2decls.has_key( decl.name ): - name2decls[ decl.name ] = [] - name2decls[ decl.name ].append( decl ) - if self is decl.parent: - self._type2decls_nr[ type_ ].append( decl ) - name2decls_nr = self._type2name2decls_nr[ type_ ] - if not name2decls_nr.has_key( decl.name ): - name2decls_nr[ decl.name ] = [] - name2decls_nr[ decl.name ].append( decl ) - - map( lambda decl: decl.init_optimizer() - , filter( lambda decl: isinstance( decl, scopedef_t ), self.declarations ) ) - if self.name == '::': - self._logger.debug( "preparing data structures for query optimizer - done( %f seconds ). " - % ( time.clock() - start_time ) ) - self._optimized = True - - - def __normalize_args( self, **keywds ): - if callable( keywds['name'] ) and None is keywds['function']: - keywds['function'] = keywds['name'] - keywds['name'] = None - return keywds - - def __findout_recursive( self, **keywds ): - if None is keywds[ 'recursive' ]: - return self.RECURSIVE_DEFAULT - else: - return keywds[ 'recursive' ] - - def __findout_allow_empty( self, **keywds ): - if None is keywds[ 'allow_empty' ]: - return self.ALLOW_EMPTY_MDECL_WRAPPER - else: - return keywds[ 'allow_empty' ] - - def __findout_decl_type( self, match_class, **keywds ): - if keywds.has_key( 'decl_type' ): - return keywds['decl_type'] - - matcher_args = keywds.copy() - del matcher_args['function'] - del matcher_args['recursive'] - if matcher_args.has_key('allow_empty'): - del matcher_args['allow_empty'] - - - matcher = match_class( **matcher_args ) - if matcher.decl_type: - return matcher.decl_type - return None - - def __create_matcher( self, match_class, **keywds ): - matcher_args = keywds.copy() - del matcher_args['function'] - del matcher_args['recursive'] - if matcher_args.has_key('allow_empty'): - del matcher_args['allow_empty'] - - matcher = match_class( **matcher_args ) - if keywds['function']: - self._logger.debug( 'running query: %s and <user defined function>' % str( matcher ) ) - return lambda decl: matcher( decl ) and keywds['function'](decl) - else: - self._logger.debug( 'running query: %s' % str( matcher ) ) - return matcher - - def __findout_range( self, name, decl_type, recursive ): - if not self._optimized: - self._logger.debug( 'running non optimized query - optimization has not been done' ) - decls = self.declarations - if recursive: - decls = algorithm.make_flatten( self.declarations ) - return decls - - if name and decl_type: - matcher = scopedef_t._impl_matchers[ scopedef_t.decl ]( name=name ) - if matcher.is_full_name(): - name = matcher.decl_name_only - if recursive: - self._logger.debug( 'query has been optimized on type and name' ) - if self._type2name2decls[decl_type].has_key( name ): - return self._type2name2decls[decl_type][name] - else: - return [] - else: - self._logger.debug( 'non recursive query has been optimized on type and name' ) - if self._type2name2decls_nr[decl_type].has_key( name ): - return self._type2name2decls_nr[decl_type][name] - else: - return [] - elif decl_type: - if recursive: - self._logger.debug( 'query has been optimized on type' ) - return self._type2decls[ decl_type ] - else: - self._logger.debug( 'non recursive query has been optimized on type' ) - return self._type2decls_nr[ decl_type ] - else: - if recursive: - self._logger.debug( 'query has not been optimized ( hint: query does not contain type and/or name )' ) - return self._all_decls - else: - self._logger.debug( 'non recursive query has not been optimized ( hint: query does not contain type and/or name )' ) - return self.declarations - - def _find_single( self, match_class, **keywds ): - self._logger.debug( 'find single query execution - started' ) - start_time = time.clock() - norm_keywds = self.__normalize_args( **keywds ) - matcher = self.__create_matcher( match_class, **norm_keywds ) - dtype = self.__findout_decl_type( match_class, **norm_keywds ) - recursive_ = self.__findout_recursive( **norm_keywds ) - decls = self.__findout_range( norm_keywds['name'], dtype, recursive_ ) - found = matcher_module.matcher.get_single( matcher, decls, False ) - self._logger.debug( 'find single query execution - done( %f seconds )' % ( time.clock() - start_time ) ) - return found - - def _find_multiple( self, match_class, **keywds ): - self._logger.debug( 'find all query execution - started' ) - start_time = time.clock() - norm_keywds = self.__normalize_args( **keywds ) - matcher = self.__create_matcher( match_class, **norm_keywds ) - dtype = self.__findout_decl_type( match_class, **norm_keywds ) - recursive_ = self.__findout_recursive( **norm_keywds ) - allow_empty = self.__findout_allow_empty( **norm_keywds ) - decls = self.__findout_range( norm_keywds['name'], dtype, recursive_ ) - found = matcher_module.matcher.find( matcher, decls, False ) - mfound = mdecl_wrapper.mdecl_wrapper_t( found ) - self._logger.debug( '%d declaration(s) that match query' % len(mfound) ) - self._logger.debug( 'find single query execution - done( %f seconds )' - % ( time.clock() - start_time ) ) - if not mfound and not allow_empty: - raise RuntimeError( "Multi declaration query returned 0 declarations." ) - return mfound - - - def decl( self, name=None, function=None, decl_type=None, header_dir=None, header_file=None, recursive=None ): - """Finds any declaration by criteria. Please see L{scopedef_t} for full explanation.""" - return self._find_single( self._impl_matchers[ scopedef_t.decl ] - , name=name - , function=function - , decl_type=decl_type - , header_dir=header_dir - , header_file=header_file - , recursive=recursive) - - def decls( self, name=None, function=None, decl_type=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.decl ] - , name=name - , function=function - , decl_type=decl_type - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def class_( self, name=None, function=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.class_ ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.class_ ] - , header_dir=header_dir - , header_file=header_file - , recursive=recursive) - - def classes( self, name=None, function=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.class_ ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.class_ ] - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def variable( self, name=None, function=None, type=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.variable ] - , name=name - , function=function - , type=type - , header_dir=header_dir - , header_file=header_file - , recursive=recursive) - - def variables( self, name=None, function=None, type=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.variable ] - , name=name - , function=function - , type=type - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def calldef( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.calldef ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.calldef ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive ) - - def calldefs( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.calldef ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.calldef ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def operator( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.operator ] - , name=name - , symbol=symbol - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.operator ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive ) - - def operators( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.operator ] - , name=name - , symbol=symbol - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.operator ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def member_function( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.member_function ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.member_function ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive ) - - def member_functions( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.member_function ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.member_function ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def constructor( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.constructor ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.constructor ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive ) - - def constructors( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.constructor ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.constructor ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def member_operator( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.member_operator ] - , name=name - , symbol=symbol - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.member_operator ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive ) - - def member_operators( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.member_operator ] - , name=name - , symbol=symbol - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.member_operator ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def casting_operator( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.casting_operator ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.casting_operator ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive ) - - def casting_operators( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.casting_operator ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.casting_operator ] - , return_type=return_type - , arg_types=arg_types - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - - def enumeration( self, name=None, function=None, header_dir=None, header_file=None, recursive=None ): - return self._find_single( self._impl_matchers[ scopedef_t.enumeration ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.enumeration ] - , header_dir=header_dir - , header_file=header_file - , recursive=recursive) - #adding small aliase - enum = enumeration - - def enumerations( self, name=None, function=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.enumeration ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.enumeration ] - , header_dir=header_dir - , header_file=header_file - , recursive=recursive - , allow_empty=allow_empty) - #adding small aliase - enums = enumerations - - def typedef( self, name=None, function=None, header_dir=None, header_file=None, recursive=None ): - """Finds any declaration by criteria. Please see L{scopedef_t} for full explanation.""" - return self._find_single( self._impl_matchers[ scopedef_t.typedef ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.typedef ] - , header_dir=header_dir - , header_file=header_file - , recursive=recursive) - - def typedefs( self, name=None, function=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): - return self._find_multiple( self._impl_matchers[ scopedef_t.typedef ] - , name=name - , function=function - , decl_type=self._impl_decl_types[ scopedef_t.typedef ] - , header_dir=header_dir - , header_file=header_file - , recursive=recursive + + def _get__cmp__scope_items(self): + raise NotImplementedError() + + def _get__cmp__items(self): + items = [ self._sorted_list( self.declarations ) ] + items.extend( self._get__cmp__scope_items() ) + return items + + def __eq__(self, other): + if not declaration.declaration_t.__eq__( self, other ): + return False + return self._sorted_list( self.declarations[:] ) \ + == other._sorted_list( other.declarations[:] ) + + def _get_declarations_impl(self): + raise NotImplementedError() + + def _get_declarations(self): + return self._get_declarations_impl() + declarations = property( _get_declarations, + doc="""A list of children declarations. + @type: list of L{declaration_t} + """) + + def remove_declaration( self, decl ): + raise NotImplementedError() + + + def __decl_types( self, decl ): + types = [] + bases = list( decl.__class__.__bases__ ) + visited = set() + if 'pygccxml' in decl.__class__.__module__: + types.append( decl.__class__ ) + while bases: + base = bases.pop() + if base is declaration.declaration_t: + continue + if base in visited: + continue + if 'pygccxml' not in base.__module__: + continue + types.append( base ) + bases.extend( base.__bases__ ) + return types + + def clear_optimizer(self): + """Cleans query optimizer state""" + self._optimized = False + self._type2decls = {} + self._type2name2decls = {} + self._type2decls_nr = {} + self._type2name2decls_nr = {} + self._all_decls = None + + map( lambda decl: decl.clear_optimizer() + , filter( lambda decl: isinstance( decl, scopedef_t ) + , self.declarations ) ) + + def init_optimizer(self): + """Initializes query optimizer state. + There are 4 internals hash tables: + 1. from type to declarations + 2. from type to declarations for non-recursive queries + 3. from type to name to declarations + 4. from type to name to declarations for non-recursive queries + + Almost every query includes declaration type information. Also very + common query is to search some declaration(s) by name or full name. + Those hashtables allows to search declaration very quick. + """ + if self.name == '::': + self._logger.debug( "preparing data structures for query optimizer - started" ) + start_time = time.clock() + + self.clear_optimizer() + + for dtype in scopedef_t._impl_all_decl_types: + self._type2decls[ dtype ] = [] + self._type2decls_nr[ dtype ] = [] + self._type2name2decls[ dtype ] = {} + self._type2name2decls_nr[ dtype ] = {} + + self._all_decls = algorithm.make_flatten( self.declarations ) + for decl in self._all_decls: + types = self.__decl_types( decl ) + for type_ in types: + self._type2decls[ type_ ].append( decl ) + name2decls = self._type2name2decls[ type_ ] + if not name2decls.has_key( decl.name ): + name2decls[ decl.name ] = [] + name2decls[ decl.name ].append( decl ) + if self is decl.parent: + self._type2decls_nr[ type_ ].append( decl ) + name2decls_nr = self._type2name2decls_nr[ type_ ] + if not name2decls_nr.has_key( decl.name ): + name2decls_nr[ decl.name ] = [] + name2decls_nr[ decl.name ].append( decl ) + + map( lambda decl: decl.init_optimizer() + , filter( lambda decl: isinstance( decl, scopedef_t ), self.declarations ) ) + if self.name == '::': + self._logger.debug( "preparing data structures for query optimizer - done( %f seconds ). " + % ( time.clock() - start_time ) ) + self._optimized = True + + def _build_operator_name( self, name, function, symbol ): + if callable( name ) and None is function: + name = None + if name: + if not 'operator' in name: + name = 'operator' + name + return name + elif symbol: + return 'operator' + symbol + return name #both name and symbol are None + + + def __normalize_args( self, **keywds ): + if callable( keywds['name'] ) and None is keywds['function']: + keywds['function'] = keywds['name'] + keywds['name'] = None + return keywds + + def __findout_recursive( self, **keywds ): + if None is keywds[ 'recursive' ]: + return self.RECURSIVE_DEFAULT + else: + return keywds[ 'recursive' ] + + def __findout_allow_empty( self, **keywds ): + if None is keywds[ 'allow_empty' ]: + return self.ALLOW_EMPTY_MDECL_WRAPPER + else: + return keywds[ 'allow_empty' ] + + def __findout_decl_type( self, match_class, **keywds ): + if keywds.has_key( 'decl_type' ): + return keywds['decl_type'] + + matcher_args = keywds.copy() + del matcher_args['function'] + del matcher_args['recursive'] + if matcher_args.has_key('allow_empty'): + del matcher_args['allow_empty'] + + + matcher = match_class( **matcher_args ) + if matcher.decl_type: + return matcher.decl_type + return None + + def __create_matcher( self, match_class, **keywds ): + matcher_args = keywds.copy() + del matcher_args['function'] + del matcher_args['recursive'] + if matcher_args.has_key('allow_empty'): + del matcher_args['allow_empty'] + + matcher = match_class( **matcher_args ) + if keywds['function']: + self._logger.debug( 'running query: %s and <user defined function>' % str( matcher ) ) + return lambda decl: matcher( decl ) and keywds['function'](decl) + else: + self._logger.debug( 'running query: %s' % str( matcher ) ) + return matcher + + def __findout_range( self, name, decl_type, recursive ): + if not self._optimized: + self._logger.debug( 'running non optimized query - optimization has not been done' ) + decls = self.declarations + if recursive: + decls = algorithm.make_flatten( self.declarations ) + return decls + + if name and decl_type: + matcher = scopedef_t._impl_matchers[ scopedef_t.decl ]( name=name ) + if matcher.is_full_name(): + name = matcher.decl_name_only + if recursive: + self._logger.debug( 'query has been optimized on type and name' ) + if self._type2name2decls[decl_type].has_key( name ): + return self._type2name2decls[decl_type][name] + else: + return [] + else: + self._logger.debug( 'non recursive query has been optimized on type and name' ) + if self._type2name2decls_nr[decl_type].has_key( name ): + return self._type2name2decls_nr[decl_type][name] + else: + return [] + elif decl_type: + if recursive: + self._logger.debug( 'query has been optimized on type' ) + return self._type2decls[ decl_type ] + else: + self._logger.debug( 'non recursive query has been optimized on type' ) + return self._type2decls_nr[ decl_type ] + else: + if recursive: + self._logger.debug( 'query has not been optimized ( hint: query does not contain type and/or name )' ) + return self._all_decls + else: + self._logger.debug( 'non recursive query has not been optimized ( hint: query does not contain type and/or name )' ) + return self.declarations + + def _find_single( self, match_class, **keywds ): + self._logger.debug( 'find single query execution - started' ) + start_time = time.clock() + norm_keywds = self.__normalize_args( **keywds ) + matcher = self.__create_matcher( match_class, **norm_keywds ) + dtype = self.__findout_decl_type( match_class, **norm_keywds ) + recursive_ = self.__findout_recursive( **norm_keywds ) + decls = self.__findout_range( norm_keywds['name'], dtype, recursive_ ) + found = matcher_module.matcher.get_single( matcher, decls, False ) + self._logger.debug( 'find single query execution - done( %f seconds )' % ( time.clock() - start_time ) ) + return found + + def _find_multiple( self, match_class, **keywds ): + self._logger.debug( 'find all query execution - started' ) + start_time = time.clock() + norm_keywds = self.__normalize_args( **keywds ) + matcher = self.__create_matcher( match_class, **norm_keywds ) + dtype = self.__findout_decl_type( match_class, **norm_keywds ) + recursive_ = self.__findout_recursive( **norm_keywds ) + allow_empty = self.__findout_allow_empty( **norm_keywds ) + decls = self.__findout_range( norm_keywds['name'], dtype, recursive_ ) + found = matcher_module.matcher.find( matcher, decls, False ) + mfound = mdecl_wrapper.mdecl_wrapper_t( found ) + self._logger.debug( '%d declaration(s) that match query' % len(mfound) ) + self._logger.debug( 'find single query execution - done( %f seconds )' + % ( time.clock() - start_time ) ) + if not mfound and not allow_empty: + raise RuntimeError( "Multi declaration query returned 0 declarations." ) + return mfound + + def decl( self, name=None, function=None, decl_type=None, header_dir=None, header_file=None, recursive=None ): + """Finds any declaration by criteria. Please see L{scopedef_t} for full explanation.""" + return self._find_single( self._impl_matchers[ scopedef_t.decl ] + , name=name + , function=function + , decl_type=decl_type + , header_dir=header_dir + , header_file=header_file + , recursive=recursive) + + def decls( self, name=None, function=None, decl_type=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.decl ] + , name=name + , function=function + , decl_type=decl_type + , header_dir=header_dir + , header_file=header_file + , recursive=recursive , allow_empty=allow_empty) + def class_( self, name=None, function=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.class_ ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.class_ ] + , header_dir=header_dir + , header_file=header_file + , recursive=recursive) + + def classes( self, name=None, function=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.class_ ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.class_ ] + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def variable( self, name=None, function=None, type=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.variable ] + , name=name + , function=function + , type=type + , header_dir=header_dir + , header_file=header_file + , recursive=recursive) + + def variables( self, name=None, function=None, type=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.variable ] + , name=name + , function=function + , type=type + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def calldef( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.calldef ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.calldef ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive ) + + def calldefs( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.calldef ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.calldef ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def operator( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.operator ] + , name=self._build_operator_name( name, function, symbol ) + , symbol=symbol + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.operator ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive ) + + def operators( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.operator ] + , name=self._build_operator_name( name, function, symbol ) + , symbol=symbol + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.operator ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def member_function( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.member_function ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.member_function ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive ) + + def member_functions( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.member_function ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.member_function ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def constructor( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.constructor ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.constructor ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive ) + + def constructors( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.constructor ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.constructor ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def member_operator( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.member_operator ] + , name=self._build_operator_name( name, function, symbol ) + , symbol=symbol + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.member_operator ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive ) + + def member_operators( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.member_operator ] + , name=self._build_operator_name( name, function, symbol ) + , symbol=symbol + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.member_operator ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def casting_operator( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.casting_operator ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.casting_operator ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive ) + + def casting_operators( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.casting_operator ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.casting_operator ] + , return_type=return_type + , arg_types=arg_types + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + + def enumeration( self, name=None, function=None, header_dir=None, header_file=None, recursive=None ): + return self._find_single( self._impl_matchers[ scopedef_t.enumeration ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.enumeration ] + , header_dir=header_dir + , header_file=header_file + , recursive=recursive) + #adding small aliase + enum = enumeration + + def enumerations( self, name=None, function=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.enumeration ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.enumeration ] + , header_dir=header_dir + , header_file=header_file + , recursive=recursive + , allow_empty=allow_empty) + #adding small aliase + enums = enumerations + + def typedef( self, name=None, function=None, header_dir=None, header_file=None, recursive=None ): + """Finds any declaration by criteria. Please see L{scopedef_t} for full explanation.""" + return self._find_single( self._impl_matchers[ scopedef_t.typedef ] + , name=name + , function=function + , decl_type=self._impl_decl_types[ scopedef_t.typedef ] + , header_dir=header_dir + , header_file=header_file + , recursive=recursive) + + def typedefs( self, name=None, function=None, header_dir=None, header_file=None, recursive=None, allow_empty=None ): + return self._find_multiple( self._impl_matchers[ scopedef_t.typedef ] + , name=name + , function=function + ... [truncated message content] |
From: <rom...@us...> - 2006-07-30 07:53:38
|
Revision: 365 Author: roman_yakovenko Date: 2006-07-30 00:53:27 -0700 (Sun, 30 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=365&view=rev Log Message: ----------- small bug fix for for operator name building functionality Modified Paths: -------------- pygccxml_dev/pygccxml/parser/scanner.py Modified: pygccxml_dev/pygccxml/parser/scanner.py =================================================================== --- pygccxml_dev/pygccxml/parser/scanner.py 2006-07-29 20:02:42 UTC (rev 364) +++ pygccxml_dev/pygccxml/parser/scanner.py 2006-07-30 07:53:27 UTC (rev 365) @@ -419,12 +419,18 @@ def __read_free_operator(self, attrs ): operator = self.__decl_factory.create_free_operator() self.__read_member_function( operator, attrs ) - operator.name = 'operator' + operator.name + if 'new' in operator.name or 'delete' in operator.name: + operator.name = 'operator ' + operator.name + else: + operator.name = 'operator' + operator.name return operator def __read_member_operator(self, attrs): operator = self.__decl_factory.create_member_operator() - self.__read_member_function( operator, attrs ) - operator.name = 'operator' + operator.name + self.__read_member_function( operator, attrs ) + if 'new' in operator.name or 'delete' in operator.name: + operator.name = 'operator ' + operator.name + else: + operator.name = 'operator' + operator.name return operator This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-29 20:02:51
|
Revision: 364 Author: roman_yakovenko Date: 2006-07-29 13:02:42 -0700 (Sat, 29 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=364&view=rev Log Message: ----------- adding "insert code" documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/feedback.rest pyplusplus_dev/docs/documentation/inserting_code.rest Modified: pyplusplus_dev/docs/documentation/feedback.rest =================================================================== --- pyplusplus_dev/docs/documentation/feedback.rest 2006-07-29 13:02:39 UTC (rev 363) +++ pyplusplus_dev/docs/documentation/feedback.rest 2006-07-29 20:02:42 UTC (rev 364) @@ -120,7 +120,7 @@ declarations = _create_logger_( 'pyplusplus.declarations' ) module_builder = _create_logger_( 'pyplusplus.module_builder' ) root = logging.getLogger( 'pyplusplus' ) - all = [ root, file_writer, module_builder ] + all = [ root, file_writer, module_builder, declarations ] You can use these references in the ``logging`` package to complete your task of adjusting individual loggers. Modified: pyplusplus_dev/docs/documentation/inserting_code.rest =================================================================== --- pyplusplus_dev/docs/documentation/inserting_code.rest 2006-07-29 13:02:39 UTC (rev 363) +++ pyplusplus_dev/docs/documentation/inserting_code.rest 2006-07-29 20:02:42 UTC (rev 364) @@ -8,92 +8,154 @@ Introduction ------------ -`pyplusplus`_ is not a magician! Sometimes there is a need to modify or add code -to generated file(s). This document will describe how you can insert your code -to almost any place. +`pyplusplus`_ is not a magician! Sometimes there is a need to add code to +generated file(s). This document will describe how you can insert your code to +almost any place. ------------ -Source code ------------ +--------------------- +Insert code to module +--------------------- -I am going to introduce C++ class ``world_t``. I will use it for all explanations. +Almost every ``boost.python`` module has next structure: :: - struct world_t { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - - std::string msg; - }; + //declarations code + ... + BOOST_PYTHON_MODULE(X) + { + //registration code + ... + } + +Using ``module_builder_t`` you can add code to declaration and registration +sections. More over you can add the code to head or tail of the section. +``module_builder_t`` class provides API, that will help you to complete the task: -If run `pyplusplus`_ on this code it will generate next `boost.python`_ code: +* ``add_declaration_code( self, code, tail=True )`` -:: + This function will add a code to the declaration section. If you want to add + the code to the head of the section, pass ``tail=False`` to the method. + +* ``add_registration_code( self, code, tail=True )`` - bp::class_< world_t, boost::noncopyable >( "world_t" ) - .def( - "greet" - , &::world_t::greet - , bp::default_call_policies() ) - .def( - "set" - , &::world_t::set - , ( bp::arg("msg") ) - , bp::default_call_policies() ) - .def_readwrite( "msg", &world_t::msg ); + This function will ass a code to the registration section. If you want to add + the code to the head of the section, pass ``tail=False`` to the method. + +Both these methods have same precondition: they should be called after +``build_code_creator`` method has been called. Both these methods work directly +with code creators tree, hence the precondition. -It is possible, that `pyplusplus`_ will generate code, that expose class -``world_t``, that will look different. The second form is more verbose, but it -provides solution for few problems. +Example +------- :: - { //::world_t - typedef bp::class_< world_t, boost::noncopyable > world_t_exposer_t; - world_t_exposer_t world_t_exposer = world_t_exposer_t( "world_t" ); - bp::scope world_t_scope( world_t_exposer ); - { //::world_t::greet - - typedef ::std::string ( ::world_t::*function_ptr_t )( ) ; - - world_t_exposer.def( - "greet" - , function_ptr_t( &::world_t::greet ) - , bp::default_call_policies() ); - - } - { //::world_t::set - - typedef void ( ::world_t::*function_ptr_t )( ::std::string ) ; - - world_t_exposer.def( - "set" - , function_ptr_t( &::world_t::set ) - , ( bp::arg("msg") ) - , bp::default_call_policies() ); - - } - world_t_exposer.def_readwrite( "msg", &world_t::msg ); - } + mb = module_builder_t( ... ) + mb.build_code_creator( ... ) + mb.add_declaration_code( '//just a comment' ) + mb.add_registration_code( '//another comment', False ) #adding code to the head + - -------------------- Insert code to class -------------------- -``class_t`` declaration defines ``add_code( self, code, works_on_instance=True )`` -method. +``class_t`` declaration defines few methods adds user code to the generated one. +Lets take a look on next use case: :: + struct window_t{ + ... + void get_size( int& height, int& width ) const; + ... + }; + + + ``int`` is immutable type in Python. So you can not expose ``get_size`` member + function as is. You need to create a wrapper and expose it. + + In the near future ``pyplusplus`` will eliminate the need of creating hand + written wrapper for this use case. + +:: + + boost::python::tuple get_window_size( const window_t& win ){ + int h(0), w(0); + win.get_size( h, w ); + return boost::python::make_tuple( h, w ); + } + +Now you have to register it: + +:: + + using boost::python; + class_< window_t >( ... ) + .def( "get_size", &::get_window_size ) + ... + ; + +How it could be achieved with `pyplusplus`_? Class declaration, has also two +functions: + +* ``add_declaration_code( self, code )`` + + **Not implemented.** + **Feedback is wanted.** + **Please consider the relationship between this code and class wrapper code.** + + This method will add the code to the declaration section within the module. + If you split your module to few files, `pyplusplus`_ will generate code, in a + way, that declarations you added, will be visible to registration code. + +* ``add_registration_code( self, code, works_on_instance=True )`` + + This method will add the code to the registration section of the class. + + What is ``works_on_instance`` argument for? In our case, we added new method + to the class. The first argument of the call will be ``self``. + :: + + #From Python user can call this method like this: + win = window_t( ) + height, width = win.get_size() + + If you will pass ``works_on_instance=False`` next code will be generated: + :: + + { + class_< window_t > window_exporter( "window_t" ); + scope window_scope( window_exporter ); + ... + def( "get_size", &::get_window_size ); + } + + And in this case, user will be forced to pass reference to ``window_t`` object: + + :: + + win = window_t() + height, width = window_t.get_size( win ) + +Example +------- +:: + mb = module_builder_t( ... ) - my_class = mb.class_( 'my_class' ) - my_class.add_code( C++ code ) + window = mb.class_( 'window_t' ) + window.add_declaration_code( get_window_size definition ) + window.add_registration_code( 'def( "get_size", &::get_window_size )' ) + #pyplusplus will add ';' if needed +---------------------------- +Insert code to class wrapper +---------------------------- +I don't know what about you, but I don't like to create free functions in global +namespace.I prefer to add ``get_window_size`` function to - .. _`pyplusplus` : ./../pyplusplus.html .. _`pygccxml` : ./../../pygccxml/pygccxml.html .. _`boost.python`: http://www.boost.org/libs/python/doc/index.html This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-29 13:05:35
|
Revision: 363 Author: allenb Date: 2006-07-29 06:02:39 -0700 (Sat, 29 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=363&view=rev Log Message: ----------- Fix up warning string to make it wrap correctly. Added it in such a way that in the future other non-overridable warnings can be added easily. Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-07-29 12:36:51 UTC (rev 362) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-07-29 13:02:39 UTC (rev 363) @@ -66,19 +66,25 @@ def get_overridable( self ): """ - Virtual functions, that returns const reference, could not be overriden - from Python. The reason is simple: in boost::python::override::operator(...) - result of marshaling (Python 2 C++) is saved on stack, after function - exit, the result will be reference to no where - access violetion. - For example see temporal variable tester + Check if the method can be overridden. """ if None is self._overridable: if isinstance( self, declarations.member_calldef_t ) \ and self.virtuality != declarations.VIRTUALITY_TYPES.NOT_VIRTUAL \ and declarations.is_reference( self.return_type ): self._overridable = False + self._non_overridable_reason = "Virtual functions that return "\ + "const reference can not be overriden from Python. "\ + "Ther is current no way for them to return a reference "\ + "to C++ code that calls them because in "\ + "boost::python::override::operator(...) the result of "\ + "marshaling (Python to C++) is saved on stack, after function "\ + "exit, thus the resulting reference would be a reference to "\ + "a temporary variable and would cause an access violation. "\ + "For an example of this see the temporary_variable_tester." else: self._overridable = True + self._non_overridable_reason = "" return self._overridable def set_overridable( self, overridable ): @@ -141,7 +147,7 @@ msgs.append( ''.join( tmpl ) % ( arg.name, index ) ) if False == self.overridable: - msgs.append( self.get_overridable.__doc__ ) + msgs.append( self._non_overridable_reason) return msgs class member_function_t( declarations.member_function_t, calldef_t ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-29 12:39:28
|
Revision: 362 Author: allenb Date: 2006-07-29 05:36:51 -0700 (Sat, 29 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=362&view=rev Log Message: ----------- Fix spelling error Modified Paths: -------------- pyplusplus_dev/unittests/test_all.py Added Paths: ----------- pyplusplus_dev/unittests/data/temporary_variable_to_be_exported.hpp pyplusplus_dev/unittests/temporary_variable_tester.py Removed Paths: ------------- pyplusplus_dev/unittests/data/temprorary_variable_to_be_exported.hpp pyplusplus_dev/unittests/temprorary_variable_tester.py Copied: pyplusplus_dev/unittests/data/temporary_variable_to_be_exported.hpp (from rev 361, pyplusplus_dev/unittests/data/temprorary_variable_to_be_exported.hpp) =================================================================== --- pyplusplus_dev/unittests/data/temporary_variable_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/temporary_variable_to_be_exported.hpp 2006-07-29 12:36:51 UTC (rev 362) @@ -0,0 +1,90 @@ +// 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) + +#ifndef __temporary_variable_to_be_exported_hpp__ +#define __temporary_variable_to_be_exported_hpp__ + +#include <string> + +namespace temporary_variables{ + +struct named_item_t{ + + named_item_t() : m_name( "no name" ) {} + + virtual const + std::string& name() const + { return m_name; } + +private: + std::string m_name; +}; + +const std::string& get_name( const named_item_t& ni ){ + return ni.name(); +} + +struct pure_virtual_t{ + virtual const std::string& name() const = 0; + virtual std::string& name_ref() = 0; +}; + + +const std::string& get_name( const pure_virtual_t& ni ){ + return ni.name(); +} + +std::string& get_name_ref( pure_virtual_t& ni ){ + return ni.name_ref(); +} + + +struct virtual_t{ + + virtual_t() : m_name( "no name" ){} + virtual const std::string& name() const { return m_name; } + virtual std::string& name_ref() { return m_name; } + +protected: + + virtual const std::string& name_protected() const { return m_name; } + +private: + + virtual const std::string& name_private() const { return m_name; } + +public: + + std::string m_name; +}; + +struct virtual2_t{ + virtual2_t() : m_name( "no name" ){} +protected: + + virtual const std::string& name_protected_pure() const = 0; + virtual const std::string& name_protected() const { return m_name; } + +private: + + virtual const std::string& name_private_pure() const = 0; + virtual const std::string& name_private() const { return m_name; } + +public: + + std::string m_name; +}; + +const std::string& get_name( const virtual_t& ni ){ + return ni.name(); +} + +std::string& get_name_ref( virtual_t& ni ){ + return ni.name_ref(); +} + +} + +#endif//__temporary_variable_to_be_exported_hpp__ Deleted: pyplusplus_dev/unittests/data/temprorary_variable_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/temprorary_variable_to_be_exported.hpp 2006-07-29 11:58:39 UTC (rev 361) +++ pyplusplus_dev/unittests/data/temprorary_variable_to_be_exported.hpp 2006-07-29 12:36:51 UTC (rev 362) @@ -1,90 +0,0 @@ -// 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) - -#ifndef __temprorary_variable_to_be_exported_hpp__ -#define __temprorary_variable_to_be_exported_hpp__ - -#include <string> - -namespace temprorary_variables{ - -struct named_item_t{ - - named_item_t() : m_name( "no name" ) {} - - virtual const - std::string& name() const - { return m_name; } - -private: - std::string m_name; -}; - -const std::string& get_name( const named_item_t& ni ){ - return ni.name(); -} - -struct pure_virtual_t{ - virtual const std::string& name() const = 0; - virtual std::string& name_ref() = 0; -}; - - -const std::string& get_name( const pure_virtual_t& ni ){ - return ni.name(); -} - -std::string& get_name_ref( pure_virtual_t& ni ){ - return ni.name_ref(); -} - - -struct virtual_t{ - - virtual_t() : m_name( "no name" ){} - virtual const std::string& name() const { return m_name; } - virtual std::string& name_ref() { return m_name; } - -protected: - - virtual const std::string& name_protected() const { return m_name; } - -private: - - virtual const std::string& name_private() const { return m_name; } - -public: - - std::string m_name; -}; - -struct virtual2_t{ - virtual2_t() : m_name( "no name" ){} -protected: - - virtual const std::string& name_protected_pure() const = 0; - virtual const std::string& name_protected() const { return m_name; } - -private: - - virtual const std::string& name_private_pure() const = 0; - virtual const std::string& name_private() const { return m_name; } - -public: - - std::string m_name; -}; - -const std::string& get_name( const virtual_t& ni ){ - return ni.name(); -} - -std::string& get_name_ref( virtual_t& ni ){ - return ni.name_ref(); -} - -} - -#endif//__temprorary_variable_to_be_exported_hpp__ Copied: pyplusplus_dev/unittests/temporary_variable_tester.py (from rev 361, pyplusplus_dev/unittests/temprorary_variable_tester.py) =================================================================== --- pyplusplus_dev/unittests/temporary_variable_tester.py (rev 0) +++ pyplusplus_dev/unittests/temporary_variable_tester.py 2006-07-29 12:36:51 UTC (rev 362) @@ -0,0 +1,78 @@ +# 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 os +import sys +import unittest +import fundamental_tester_base +from pyplusplus import code_creators +from pyplusplus import module_builder + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'temporary_variable' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize(self, mb): + functions = mb.calldefs( lambda decl: not decl.call_policies + and 'name' in decl.alias ) + functions.call_policies \ + = module_builder.call_policies.return_value_policy( module_builder.call_policies.copy_non_const_reference ) + + def _create_derived_from_named_item(self, extmodule): + class apple_t( extmodule.named_item_t ): + def __init__( self ): + extmodule.named_item_t.__init__( self ) + def name( self ): #this function will be never called + return "apple" + return apple_t() + + def _create_derived_from_pure_virtual(self, extmodule): + class python_pure_virtual_t( extmodule.pure_virtual_t ): + def __init__( self ): + extmodule.pure_virtual_t.__init__( self ) + def name( self ): #this function will be never called + return "name" + def name_ref( self ): #this function will be never called + return "name_ref" + return python_pure_virtual_t() + + def _create_derived_from_virtual(self, extmodule): + class python_virtual_t( extmodule.virtual_t ): + def __init__( self ): + extmodule.virtual_t.__init__( self ) + def name( self ): #this function will be never called + return "name" + def name_ref( self ): #this function will be never called + return "name_ref" + return python_virtual_t() + + def run_tests(self, extmodule): + apple = self._create_derived_from_named_item( extmodule ) + self.failUnless( extmodule.get_name( apple ) == 'no name' ) + pv = self._create_derived_from_pure_virtual( extmodule ) + + self.failIfNotRaisesAny( extmodule.get_name, pv ) + self.failIfNotRaisesAny( extmodule.get_name_ref, pv ) + + virtual = self._create_derived_from_virtual( extmodule ) + self.failUnless( extmodule.get_name( virtual ) == 'no name' ) + self.failUnless( extmodule.get_name_ref( virtual ) == 'no name' ) + + +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() Deleted: pyplusplus_dev/unittests/temprorary_variable_tester.py =================================================================== --- pyplusplus_dev/unittests/temprorary_variable_tester.py 2006-07-29 11:58:39 UTC (rev 361) +++ pyplusplus_dev/unittests/temprorary_variable_tester.py 2006-07-29 12:36:51 UTC (rev 362) @@ -1,78 +0,0 @@ -# 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 os -import sys -import unittest -import fundamental_tester_base -from pyplusplus import code_creators -from pyplusplus import module_builder - -class tester_t(fundamental_tester_base.fundamental_tester_base_t): - EXTENSION_NAME = 'temprorary_variable' - - def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( - self - , tester_t.EXTENSION_NAME - , *args ) - - def customize(self, mb): - functions = mb.calldefs( lambda decl: not decl.call_policies - and 'name' in decl.alias ) - functions.call_policies \ - = module_builder.call_policies.return_value_policy( module_builder.call_policies.copy_non_const_reference ) - - def _create_derived_from_named_item(self, extmodule): - class apple_t( extmodule.named_item_t ): - def __init__( self ): - extmodule.named_item_t.__init__( self ) - def name( self ): #this function will be never called - return "apple" - return apple_t() - - def _create_derived_from_pure_virtual(self, extmodule): - class python_pure_virtual_t( extmodule.pure_virtual_t ): - def __init__( self ): - extmodule.pure_virtual_t.__init__( self ) - def name( self ): #this function will be never called - return "name" - def name_ref( self ): #this function will be never called - return "name_ref" - return python_pure_virtual_t() - - def _create_derived_from_virtual(self, extmodule): - class python_virtual_t( extmodule.virtual_t ): - def __init__( self ): - extmodule.virtual_t.__init__( self ) - def name( self ): #this function will be never called - return "name" - def name_ref( self ): #this function will be never called - return "name_ref" - return python_virtual_t() - - def run_tests(self, extmodule): - apple = self._create_derived_from_named_item( extmodule ) - self.failUnless( extmodule.get_name( apple ) == 'no name' ) - pv = self._create_derived_from_pure_virtual( extmodule ) - - self.failIfNotRaisesAny( extmodule.get_name, pv ) - self.failIfNotRaisesAny( extmodule.get_name_ref, pv ) - - virtual = self._create_derived_from_virtual( extmodule ) - self.failUnless( extmodule.get_name( virtual ) == 'no name' ) - self.failUnless( extmodule.get_name_ref( virtual ) == 'no name' ) - - -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 Modified: pyplusplus_dev/unittests/test_all.py =================================================================== --- pyplusplus_dev/unittests/test_all.py 2006-07-29 11:58:39 UTC (rev 361) +++ pyplusplus_dev/unittests/test_all.py 2006-07-29 12:36:51 UTC (rev 362) @@ -32,7 +32,7 @@ import special_operators_tester import module_properties_tester import internal_classes_tester -import temprorary_variable_tester +import temporary_variable_tester import recursive_tester import class_order_tester import class_order2_tester @@ -85,7 +85,7 @@ , special_operators_tester , module_properties_tester , internal_classes_tester - , temprorary_variable_tester + , temporary_variable_tester , recursive_tester , class_order_tester , noncopyable_tester @@ -133,4 +133,4 @@ print str( error ) print 'first argument should be integer, it says how many times to run tests.' - run_suite(times) \ No newline at end of file + run_suite(times) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-29 12:01:15
|
Revision: 361 Author: allenb Date: 2006-07-29 04:58:39 -0700 (Sat, 29 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=361&view=rev Log Message: ----------- - Fix grammar - Add note about places to add more text Modified Paths: -------------- pyplusplus_dev/docs/documentation/feedback.rest Modified: pyplusplus_dev/docs/documentation/feedback.rest =================================================================== --- pyplusplus_dev/docs/documentation/feedback.rest 2006-07-28 08:45:13 UTC (rev 360) +++ pyplusplus_dev/docs/documentation/feedback.rest 2006-07-29 11:58:39 UTC (rev 361) @@ -10,18 +10,18 @@ `pyplusplus`_ has been created with few goals in mind: -* to allow users create `Python`_ bindings for big projects, using `boost.python`_ +* to allow users create `Python`_ bindings for large projects using the `boost.python`_ library -* to minimize maintenance time to minimum +* to minimize maintenance time -* to surve as a user guide for `boost.python`_ library +* to serve as a user's guide for `boost.python`_ library -Those goals have something common. In order to achive them, `pyplusplus`_ should -give some kind of feedback to user. `pyplusplus`_ actually understands the -declarations it exports. It scans a declaration for potential problems, reports -them and in some cases prints hints how they could be solved. Few examples: +Those goals all have something in common. In order to achive them, `pyplusplus`_ must +give useful feedback to the user. Because `pyplusplus`_ understands the +declarations it exports, it can scan declarations for potential problems, report +them and in some cases provide hints about how to resolve the problem. Few examples: * :: @@ -34,7 +34,7 @@ ... }; - Member function ``do_smth`` could not be overriden in Python. + Member function ``do_smth`` can not be overriden in Python because... [FILL IN HERE]. * :: @@ -45,26 +45,26 @@ ... }; - Member function ``get_size`` can be exposed to Python, but it will not be callable. + Member function ``get_size`` can be exposed to Python, but it will not be callable because [FILL IN HERE]. * In order to expose free/member function that takes more than 10 arguments user should define ``BOOST_PYTHON_MAX_ARITY`` macro. -For all those problems and many other `pyplusplus`_ gives a nice explanation -and sometimes a link to the relevant information on the internet. +For these problems and many other `pyplusplus`_ gives a nice explanation +and sometimes a link to the relevant information on the Internet. -I hope, that from now you will read every `pyplusplus`_ message :-). +I hope, that from now you will find it helpful to read every `pyplusplus`_ message :-). ------------- How it works? ------------- -In previous paragraph, I described pretty usefull functionality. What should be -done in order to enable it? - *Nothing!* By default, `pyplusplus`_ prints only +In previous paragraph, I described some pretty useful functionality but what should you +do to enable it? - *Nothing!* By default, `pyplusplus`_ only prints the important messages to ``stdout``. More over it prints them onle for declarations that are going to be exported. -`pyplusplus`_ uses standard `logging`_ package to write all user messages. By +`pyplusplus`_ uses the python `logging`_ package to write all user messages. By default, messages with ``DEBUG`` level will be skipped, all other messages will be reported. @@ -75,10 +75,10 @@ Logging API ----------- -If you are here, it means that you are not pleased with default configuration +If you are here, it probably means that you are not pleased with default configuration and want to change it, right? -1. You want to change logged messages level: +1. If you simply want to change the logging message level: :: @@ -90,16 +90,16 @@ module_builder.set_logger_level( logging.DEBUG ) -2. May be do you want to disable some messages and leave others? It is possible. - `pyplusplus`_ and `pygccxml`_ do not use one logger. Almost every internal +2. But what if you want to disable some messages and leave others? This is also possible. + `pyplusplus`_ and `pygccxml`_ do not use a single logger. Almost every internal package has its own logger. So you can enable one logger and disable another one. - `pygccxml`_ package defines all loggers in ``pygccxml.utils`` package. + The `pygccxml`_ package defines all loggers in the ``pygccxml.utils`` package. - `pyplusplus`_ package defines all logers in ``pyplusplus._logging_`` package. + The `pyplusplus`_ package defines all logers in the ``pyplusplus._logging_`` package. - Both packages defines ``loggers`` class. Those classes keep references to - different loggers. ``loggers`` classes look very similar to the next class: + Both packages define a ``loggers`` class. Those classes keep references to + different loggers. The ``loggers`` classes look very similar to the next class: :: @@ -122,11 +122,11 @@ root = logging.getLogger( 'pyplusplus' ) all = [ root, file_writer, module_builder ] - Now, you can use the functionality provided by ``logging`` package to complete - your task. + You can use these references in the ``logging`` package to complete + your task of adjusting individual loggers. - One more thing. `pyplusplus`_ splits long message to few lines, where line - length is 70 characters. Thus it is very convinient to read them on your screen. + One more thing, `pyplusplus`_ automatically splits long message, where line + length defaults to 70 characters. Thus it is very convinient to read them on your screen. If you want to use different tools to monitor those messages, consider to use standard `Formatter`_ class, instead of ``multi_line_formatter_t`` one. @@ -134,13 +134,12 @@ Declarations API ---------------- -Every declaration class has next methods: +Every declaration class has the following methods: * ``why_not_exportable( self )`` This method explains why a declaration could not be exported. The return value - type is string or ``None``. ``None`` will be returned if declaration is - exportable. + is a string or ``None``. ``None`` is returned if the declaration is exportable. Property ``exportable`` will be set to ``True`` if declaration is exportable, and to ``False`` otherwise. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-28 21:46:48
|
Revision: 357 Author: allenb Date: 2006-07-27 12:06:37 -0700 (Thu, 27 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=357&view=rev Log Message: ----------- - Add support for cflags - Replace the creator includes with the list we passed to create the builder. Modified Paths: -------------- pyplusplus_dev/pyplusplus/module_builder/builder.py Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-27 19:05:17 UTC (rev 356) +++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-27 19:06:37 UTC (rev 357) @@ -39,7 +39,8 @@ , cache=None , optimize_queries=True , ignore_gccxml_output=False - , indexing_suite_version=1): + , indexing_suite_version=1 + , cflags=""): """ @param files: list of files, declarations from them you want to export @type files: list of strings or L{file_configuration_t} instances @@ -57,6 +58,8 @@ @param undefine_symbols: list of symbols to be undefined for preprocessor. @param undefine_symbols: list of strings + + @param cflags: Raw string to be added to gccxml command line. """ object.__init__( self ) self.logger = _logging_.loggers.module_builder @@ -67,7 +70,8 @@ , define_symbols=define_symbols , undefine_symbols=undefine_symbols , start_with_declarations=start_with_declarations - , ignore_gccxml_output=ignore_gccxml_output) + , ignore_gccxml_output=ignore_gccxml_output + , cflags=cflags) #may be in future I will add those directories to user_defined_directories #to self.__code_creator. @@ -192,10 +196,12 @@ @param call_policies_resolver_: callable, that will be invoked on every calldef object. It should return call policies. @type call_policies_resolver_: callable - @param doc_extractor: callable, that takes as argument reference to declaration and returns documentation string @type doc_extractor: callable or None + @param decl_headers: If None the headers for the wrapped decls are automatically found. + But you can pass a list of headers here to override that search. + @type decl_headers: list of strings """ creator = mcreator_package.creator_t( self.global_ns , module_name @@ -207,6 +213,7 @@ , enable_indexing_suite , doc_extractor) self.__code_creator = creator.create() + self.__code_creator.replace_included_headers(self.__parsed_files) #I think I should ask users, what they expect #self.__code_creator.user_defined_directories.append( self.__working_dir ) #map( self.__code_creator.user_defined_directories.append @@ -517,4 +524,3 @@ position = -1 creator = code_creators.custom_text_t( code ) self.code_creator.body.adopt_creator( creator, position ) - \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-28 19:42:55
|
Revision: 358 Author: allenb Date: 2006-07-27 12:12:11 -0700 (Thu, 27 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=358&view=rev Log Message: ----------- Remove old comment. Modified Paths: -------------- pyplusplus_dev/pyplusplus/module_builder/builder.py Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-27 19:06:37 UTC (rev 357) +++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-27 19:12:11 UTC (rev 358) @@ -198,10 +198,7 @@ @type call_policies_resolver_: callable @param doc_extractor: callable, that takes as argument reference to declaration and returns documentation string - @type doc_extractor: callable or None - @param decl_headers: If None the headers for the wrapped decls are automatically found. - But you can pass a list of headers here to override that search. - @type decl_headers: list of strings + @type doc_extractor: callable or None """ creator = mcreator_package.creator_t( self.global_ns , module_name This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-07-28 08:45:20
|
Revision: 360 Author: mbaas Date: 2006-07-28 01:45:13 -0700 (Fri, 28 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=360&view=rev Log Message: ----------- Fixed a typo Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-07-28 07:59:18 UTC (rev 359) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-07-28 08:45:13 UTC (rev 360) @@ -106,12 +106,12 @@ dtype = units[-1] if isinstance( dtype.declaration.parent, declarations.class_t ): if dtype.declaration not in dtype.declaration.parent.public_members: - return "pyplusplus can not expose fuction that takes as argument/returns instance of non public class. Generated code will not compile." + return "pyplusplus can not expose function that takes as argument/returns instance of non public class. Generated code will not compile." no_ref = declarations.remove_reference( some_type ) no_ptr = declarations.remove_pointer( no_ref ) no_const = declarations.remove_const( no_ptr ) if declarations.is_array( no_const ): - return "pyplusplus can not expose fuction that takes as argument/returns C++ arrays. This will be changed in near future." + return "pyplusplus can not expose function that takes as argument/returns C++ arrays. This will be changed in near future." return self._exportable_impl_derived() def _readme_impl( self ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-07-28 07:59:42
|
Revision: 359 Author: mbaas Date: 2006-07-28 00:59:18 -0700 (Fri, 28 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=359&view=rev Log Message: ----------- Don't use the full terminal width for the output as this can lead to word wraps into the next line when a line uses the full width. Modified Paths: -------------- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py Modified: pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py 2006-07-27 19:12:11 UTC (rev 358) +++ pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py 2006-07-28 07:59:18 UTC (rev 359) @@ -27,6 +27,9 @@ import curses curses.setupterm() self._width = curses.tigetnum('cols') + # Leave a border of two blanks to prevent that full lines + # wrap to the next line + self._width -= 2 except: self._width = 70 # default to 70 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-27 23:58:58
|
Revision: 350 Author: allenb Date: 2006-07-26 06:08:20 -0700 (Wed, 26 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=350&view=rev Log Message: ----------- - Make matcher exceptions more helpful by adding the str() of the contained matcher. This allows users to see what find failed in their code. Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/matcher.py Modified: pygccxml_dev/pygccxml/declarations/matcher.py =================================================================== --- pygccxml_dev/pygccxml/declarations/matcher.py 2006-07-26 09:49:48 UTC (rev 349) +++ pygccxml_dev/pygccxml/declarations/matcher.py 2006-07-26 13:08:20 UTC (rev 350) @@ -14,7 +14,7 @@ self.matcher = matcher def __str__( self ): - return "Unable to find declaration." + return "Unable to find declaration. matcher: [%s]"%str(self.matcher) class multiple_declarations_found_t( RuntimeError ): def __init__( self, matcher ): @@ -22,7 +22,7 @@ self.matcher = matcher def __str__( self ): - return "Multiple declarations has been found." + return "Multiple declarations has been found. matcher: [%s]"%str(self.matcher) def find( decl_matcher, decls, recursive=True ): where = [] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-27 22:34:49
|
Revision: 353 Author: roman_yakovenko Date: 2006-07-27 02:56:53 -0700 (Thu, 27 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=353&view=rev Log Message: ----------- huge classes functionality has been implemented! Modified Paths: -------------- pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py pyplusplus_dev/pyplusplus/utils/__init__.py pyplusplus_dev/unittests/algorithms_tester.py Modified: pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-07-27 07:18:46 UTC (rev 352) +++ pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-07-27 09:56:53 UTC (rev 353) @@ -10,6 +10,7 @@ from pygccxml import declarations from pyplusplus import decl_wrappers from pyplusplus import code_creators +from pyplusplus import utils as pypp_utils #TODO: to add namespace_alias_t classes class class_multiple_files_t(multiple_files.multiple_files_t): @@ -25,9 +26,10 @@ alias + _main h/cpp this class will contain main registration function. """ - def __init__(self, extmodule, directory_path, huge_classes): + def __init__(self, extmodule, directory_path, huge_classes, num_of_functions_per_file=25): multiple_files.multiple_files_t.__init__(self, extmodule, directory_path) self.huge_classes = huge_classes + self.num_of_functions_per_file = num_of_functions_per_file self.internal_splitters = [ self.split_internal_enums , self.split_internal_unnamed_enums @@ -160,10 +162,21 @@ def split_internal_calldefs( self, class_creator, calldef_types, pattern ): creators = filter( lambda x: isinstance(x, calldef_types ), class_creator.creators ) - for creator in creators: - creator.works_on_instance = False - self.split_internal_creators( class_creator, creators, pattern ) - return pattern + grouped_creators = pypp_utils.split_sequence( creators, self.num_of_functions_per_file ) + if len( grouped_creators ) == 1: + for creator in creators: + creator.works_on_instance = False + self.split_internal_creators( class_creator, creators, pattern ) + return pattern + else: + patterns = [] + for index, group in enumerate( grouped_creators ): + pattern_tmp = pattern + str( index ) + patterns.append( pattern_tmp ) + for creator in group: + creator.works_on_instance = False + self.split_internal_creators( class_creator, group, pattern_tmp ) + return patterns def split_internal_memfuns( self, class_creator ): calldef_types = ( code_creators.mem_fun_t ) @@ -221,8 +234,14 @@ tail_headers = [] for splitter in self.internal_splitters: pattern = splitter( class_creator ) - tail_headers.append( os.path.join( class_creator.alias, pattern + self.HEADER_EXT ) ) - + if not pattern: + continue + if isinstance( pattern, str ): + tail_headers.append( os.path.join( class_creator.alias, pattern + self.HEADER_EXT ) ) + else: + assert( isinstance( pattern, list ) ) + for p in pattern: + tail_headers.append( os.path.join( class_creator.alias, p + self.HEADER_EXT ) ) #writting source file source_code = [] if self.extmodule.license: Modified: pyplusplus_dev/pyplusplus/utils/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/utils/__init__.py 2006-07-27 07:18:46 UTC (rev 352) +++ pyplusplus_dev/pyplusplus/utils/__init__.py 2006-07-27 09:56:53 UTC (rev 353) @@ -7,7 +7,7 @@ This module is a collection of unrelated algorithms, that works on code creators tree. """ - +import math from pygccxml import declarations from pyplusplus import code_creators @@ -38,6 +38,18 @@ for creator in creators: creator.parent.remove_creator( creator ) exclude = staticmethod( exclude ) - - - \ No newline at end of file + + +def split_sequence(seq, bucket_size): + #split sequence to buclets, where every will contain maximum bucket_size items + seq_len = len( seq ) + if seq_len <= bucket_size: + return [ seq ] + buckets = [] + num_of_buckets = int( math.ceil( float( seq_len ) / bucket_size ) ) + for i in range(num_of_buckets): + from_ = i * bucket_size + to = min( ( i + 1) * bucket_size, seq_len ) + buckets.append( seq[ from_ : to ] ) + return buckets + \ No newline at end of file Modified: pyplusplus_dev/unittests/algorithms_tester.py =================================================================== --- pyplusplus_dev/unittests/algorithms_tester.py 2006-07-27 07:18:46 UTC (rev 352) +++ pyplusplus_dev/unittests/algorithms_tester.py 2006-07-27 09:56:53 UTC (rev 353) @@ -13,6 +13,7 @@ from pyplusplus import code_creators from pyplusplus import module_creator from pyplusplus import module_builder +from pyplusplus import utils as pypp_utils class indent_tester_t(unittest.TestCase): def test( self ): @@ -147,6 +148,16 @@ mb.namespace( name='::tester' ).include() mb.build_code_creator('dummy') mb.split_module( autoconfig.build_dir, [ mb.class_( '::tester::X' ) ] ) + + +class split_sequence_tester_t(unittest.TestCase): + def test(self): + seq = [ 1,2,3 ] + split = pypp_utils.split_sequence + self.failUnless( [[1],[2],[3]] == split( seq, 1 ) ) + self.failUnless( [[1,2],[3]] == split( seq, 2 ) ) + self.failUnless( [[1,2,3]] == split( seq, 3 ) ) + self.failUnless( [[1,2,3]] == split( seq, 4 ) ) def create_suite(): suite = unittest.TestSuite() @@ -157,6 +168,7 @@ suite.addTest( unittest.makeSuite(exclude_function_with_array_arg_tester_t)) suite.addTest( unittest.makeSuite(class_multiple_files_tester_t)) suite.addTest( unittest.makeSuite(readme_tester_t)) + suite.addTest( unittest.makeSuite(split_sequence_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...> - 2006-07-27 21:48:52
|
Revision: 352 Author: roman_yakovenko Date: 2006-07-27 00:18:46 -0700 (Thu, 27 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=352&view=rev Log Message: ----------- renaming filters.py to matchers.py Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/type_traits.py Added Paths: ----------- pygccxml_dev/pygccxml/declarations/matchers.py Removed Paths: ------------- pygccxml_dev/pygccxml/declarations/filters.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2006-07-26 14:24:17 UTC (rev 351) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2006-07-27 07:18:46 UTC (rev 352) @@ -199,19 +199,19 @@ from decl_factory import decl_factory_t -from filters import matcher_base_t -from filters import or_matcher_t -from filters import and_matcher_t -from filters import not_matcher_t -from filters import declaration_matcher_t -from filters import calldef_matcher_t -from filters import namespace_matcher_t -from filters import variable_matcher_t -from filters import regex_matcher_t -from filters import access_type_matcher_t -from filters import operator_matcher_t -from filters import custom_matcher_t -from filters import virtuality_type_matcher_t +from matchers import matcher_base_t +from matchers import or_matcher_t +from matchers import and_matcher_t +from matchers import not_matcher_t +from matchers import declaration_matcher_t +from matchers import calldef_matcher_t +from matchers import namespace_matcher_t +from matchers import variable_matcher_t +from matchers import regex_matcher_t +from matchers import access_type_matcher_t +from matchers import operator_matcher_t +from matchers import custom_matcher_t +from matchers import virtuality_type_matcher_t from matcher import matcher from mdecl_wrapper import mdecl_wrapper_t Deleted: pygccxml_dev/pygccxml/declarations/filters.py =================================================================== --- pygccxml_dev/pygccxml/declarations/filters.py 2006-07-26 14:24:17 UTC (rev 351) +++ pygccxml_dev/pygccxml/declarations/filters.py 2006-07-27 07:18:46 UTC (rev 352) @@ -1,520 +0,0 @@ -# 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 os -import re -import types -import algorithm -import variable -import namespace -import calldef -import cpptypes -import templates -import class_declaration -from pygccxml import utils - -class matcher_base_t(object): - """matcher_base_t class defines interface for classes that will implement - compare functionality according to some criteria. - """ - def __init__( self ): - object.__init__( self ) - - def __call__(self, decl): - raise NotImplementedError( "matcher must always implement the __call__() method." ) - - def __invert__(self): - """not-operator (~)""" - return not_matcher_t(self) - - def __and__(self, other): - """and-operator (&)""" - return and_matcher_t([self, other]) - - def __or__(self, other): - """or-operator (|)""" - return or_matcher_t([self, other]) - - def __str__( self ): - return "base class for all matchers" - -class and_matcher_t(matcher_base_t): - """Combine several other matchers with "&". - - For example: find all private functions with name XXX - - C{ matcher = access_type_matcher_t( 'private' ) & calldef_matcher_t( name='XXX' ) } - """ - def __init__(self, matchers): - matcher_base_t.__init__(self) - self.matchers = matchers - - def __call__(self, decl): - for matcher in self.matchers: - if not matcher(decl): - return False - return True - - def __str__(self): - return " & ".join( map( lambda x: "(%s)" % str( x ), self.matchers ) ) - - -class or_matcher_t(matcher_base_t): - """Combine several other matchers with "|". - - For example: find all functions and variables with name 'XXX' - - C{ matcher = variable_matcher_t( name='XXX' ) | calldef_matcher_t( name='XXX' ) } - - """ - def __init__(self, matchers): - matcher_base_t.__init__(self) - self.matchers = matchers - - def __call__(self, decl): - for matcher in self.matchers: - if matcher(decl): - return True - return False - - def __str__(self): - return " | ".join( map( lambda x: "(%s)" % str( x ), self.matchers ) ) - - -class not_matcher_t(matcher_base_t): - """Return the inverse result of matcher, using "~" - - For example: find all private and protected declarations - - C{ matcher = ~access_type_matcher_t( 'private' ) } - - """ - def __init__(self, matcher): - matcher_base_t.__init__(self) - self.matcher = matcher - - def __call__(self, decl): - return not self.matcher(decl) - - def __str__(self): - return "~(%s)"%str(self.matcher) - -class declaration_matcher_t( matcher_base_t ): - """ - Instance of this class will match declarations by next criteria: - - declaration name, also could be fully qualified name - Example: wstring or ::std::wstring - - declaration type - Example: L{class_t}, L{namespace_t}, L{enumeration_t} - - location within file system ( file or directory ) - """ - def __init__( self, name=None, decl_type=None, header_dir=None, header_file=None ): - """ - @param decl_type: declaration type to match by. For example L{enumeration_t}. - @type decl_type: any class that derives from L{declarations.declaration_t} class - - @param name: declaration name, could be full name. - @type name: str - - @param header_dir: absolute directory path - @type header_dir: str - - @param header_file: absolute file path - @type header_file: str - - """ - #An other option is that pygccxml will create absolute path using - #os.path.abspath function. But I think this is just wrong, because abspath - #builds path using current working directory. This behavior is fragile - #and very difficult to find a bug. - matcher_base_t.__init__( self ) - self.decl_type = decl_type - self.__name = None - self.__opt_is_tmpl_inst = None - self.__opt_tmpl_name = None - self.__opt_is_full_name = None - self.__decl_name_only = None - - self._set_name( name ) - - self.header_dir = header_dir - self.header_file = header_file - - if self.header_dir: - self.header_dir = utils.normalize_path( self.header_dir ) - if not os.path.isabs( self.header_dir ): - raise RuntimeError( "Path to header directory should be absolute!" ) - - if self.header_file: - self.header_file = utils.normalize_path( self.header_file ) - if not os.path.isabs( self.header_file ): - raise RuntimeError( "Path to header file should be absolute!" ) - - def _get_name(self): - return self.__name - - def _set_name( self, name ): - self.__name = name - if not self.__name: - self.__opt_is_tmpl_inst = None - self.__opt_tmpl_name = None - self.__opt_is_full_name = None - self.__decl_name_only = None - else: - self.__opt_is_tmpl_inst = templates.is_instantiation( self.__name ) - self.__opt_tmpl_name = templates.name( self.__name ) - if self.__opt_is_tmpl_inst: - if '::' in self.__opt_tmpl_name: - self.__opt_is_full_name = True - self.__decl_name_only = self.__opt_tmpl_name.split('::')[-1] - else: - self.__opt_is_full_name = False - self.__decl_name_only = self.__opt_tmpl_name - else: - if '::' in self.__name: - self.__opt_is_full_name = True - self.__decl_name_only = self.__name.split('::')[-1] - else: - self.__opt_is_full_name = False - self.__decl_name_only = self.__name - - - name = property( _get_name, _set_name ) - - def __str__( self ): - msg = [] - if not None is self.decl_type: - msg.append( '(decl type==%s)' % self.decl_type.__name__ ) - if not None is self.name: - msg.append( '(name==%s)' % self.name ) - if not None is self.header_dir: - msg.append( '(header dir==%s)' % self.header_dir ) - if not None is self.header_file: - msg.append( '(header file==%s)' % self.header_file ) - if not msg: - msg.append( 'any' ) - return ' and '.join( msg ) - - def __call__( self, decl ): - if not None is self.decl_type: - if not isinstance( decl, self.decl_type ): - return False - if not None is self.name: - if not self.check_name( decl ): - return False - if not None is self.header_dir and decl.location: - decl_dir = os.path.abspath( os.path.dirname( decl.location.file_name ) ) - decl_dir = utils.normalize_path( decl_dir ) - if decl_dir[:len(self.header_dir)] != self.header_dir: - return False - if not None is self.header_file and decl.location: - decl_file = os.path.abspath( decl.location.file_name ) - decl_file = utils.normalize_path( decl_file ) - if decl_file != self.header_file: - return False - return True - - def check_name( self, decl ): - assert not None is self.name - - if self.__opt_is_tmpl_inst: - if not self.__opt_is_full_name: - if self.name != decl.name: - return False - else: - if self.name != algorithm.full_name( decl ): - return False - else: - if not self.__opt_is_full_name: - if decl.name != self.name: - return False - else: - if self.name != algorithm.full_name( decl ): - return False - return True - - def is_full_name(self): - return self.__opt_is_full_name - - def _get_decl_name_only(self): - return self.__decl_name_only - decl_name_only = property( _get_decl_name_only ) - -class variable_matcher_t( declaration_matcher_t ): - """ - Instance of this class will match variables by next criteria: - - L{declaration_matcher_t} criteria - - variable type. Example: L{int_t} or 'int' - """ - def __init__( self, name=None, type=None, header_dir=None, header_file=None ): - """ - @param type: variable type - @type type: string or instance of L{type_t} derived class - """ - declaration_matcher_t.__init__( self - , name=name - , decl_type=variable.variable_t - , header_dir=header_dir - , header_file=header_file ) - self.type = type - - def __call__( self, decl ): - if not super( variable_matcher_t, self ).__call__( decl ): - return False - if not None is self.type: - if isinstance( self.type, cpptypes.type_t ): - if self.type != decl.type: - return False - else: - if self.type != decl.type.decl_string: - return False - return True - - def __str__( self ): - msg = [ super( variable_matcher_t, self ).__str__() ] - if msg == [ 'any' ]: - msg = [] - if not None is self.type: - msg.append( '(value type==%s)' % str(self.type) ) - if not msg: - msg.append( 'any' ) - return ' and '.join( msg ) - - -class namespace_matcher_t( declaration_matcher_t ): - """Instance of this class will match namespaces by name.""" - - def __init__( self, name=None ): - declaration_matcher_t.__init__( self, name=name, decl_type=namespace.namespace_t) - - def __call__( self, decl ): - if self.name and decl.name == '': - #unnamed namespace have same name as thier parent, we should prevent - #this happens. The price is: user should search for unnamed namespace - #directly. - return False - return super( namespace_matcher_t, self ).__call__( decl ) - - -class calldef_matcher_t( declaration_matcher_t ): - """ - Instance of this class will match callable by next criteria: - - L{declaration_matcher_t} criteria - - return type. Example: L{int_t} or 'int' - - argument types - """ - - def __init__( self, name=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None): - """ - @param return_type: callable return type - @type return_type: string or instance of L{type_t} derived class - - @param arg_types: list of function argument types. arg_types can contain. - Any item within the list could be string or instance of L{type_t} derived - class. If you don't want some argument to participate in match you can - put None. For example: - - C{ calldef_matcher_t( arg_types=[ 'int &', None ] ) } - - will match all functions that takes 2 arguments, where the first one is - reference to integer and second any - @type arg_types: list - """ - if None is decl_type: - decl_type = calldef.calldef_t - declaration_matcher_t.__init__( self - , name=name - , decl_type=decl_type - , header_dir=header_dir - , header_file=header_file ) - - self.return_type = return_type - self.arg_types = arg_types - - def __call__( self, decl ): - if not super( calldef_matcher_t, self ).__call__( decl ): - return False - if not None is self.return_type \ - and not self.__compare_types( self.return_type, decl.return_type ): - return False - if self.arg_types: - if isinstance( self.arg_types, (types.ListType, types.TupleType)): - if len(self.arg_types) != len( decl.arguments ): - return False - for type_or_str, arg in zip( self.arg_types, decl.arguments ): - if None == type_or_str: - continue - else: - if not self.__compare_types( type_or_str, arg.type ): - return False - return True - - def __compare_types( self, type_or_str, type ): - assert type_or_str - if type is None: - return False - if isinstance( type_or_str, cpptypes.type_t ): - if type_or_str != type: - return False - else: - if type_or_str != type.decl_string: - return False - return True - - def __str__( self ): - msg = [ super( calldef_matcher_t, self ).__str__() ] - if msg == [ 'any' ]: - msg = [] - if not None is self.return_type: - msg.append( '(return type==%s)' % str(self.return_type) ) - if self.arg_types: - for i in range( len( self.arg_types ) ): - if self.arg_types[i] is None: - msg.append( '(arg %d type==any)' % i ) - else: - msg.append( '(arg %d type==%s)' % ( i, str( self.arg_types[i] ) ) ) - if not msg: - msg.append( 'any' ) - return ' and '.join( msg ) - - -class operator_matcher_t( calldef_matcher_t ): - """ - Instance of this class will match operators by next criteria: - - L{calldef_matcher_t} criteria - - operator symbol: =, !=, (), [] and etc - """ - def __init__( self, name=None, symbol=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None): - """ - @param symbol: operator symbol - @type symbol: str - """ - if None is decl_type: - decl_type = calldef.operator_t - calldef_matcher_t.__init__( self - , name=name - , return_type=return_type - , arg_types=arg_types - , decl_type=decl_type - , header_dir=header_dir - , header_file=header_file) - self.symbol = symbol - - def __call__( self, decl ): - if not super( operator_matcher_t, self ).__call__( decl ): - return False - if not None is self.symbol: - if self.symbol != decl.symbol: - return False - return True - - def __str__( self ): - msg = [ super( operator_matcher_t, self ).__str__() ] - if msg == [ 'any' ]: - msg = [] - if not None is self.symbol: - msg.append( '(symbol==%s)' % str(self.symbol) ) - if not msg: - msg.append( 'any' ) - return ' and '.join( msg ) - -class regex_matcher_t( matcher_base_t ): - """ - Instance of this class will match declaration using regular expression. - User should supply a function that will extract from declaration desired - information as string. Later, this matcher will match that string using - user regular expression. - """ - def __init__( self, regex, function=None ): - """ - @param regex: regular expression - @type regex: string, an instance of this class will compile it for you - - @param function: function that will be called to get an information from - declaration as string. As input this function takes 1 argument: reference - to declaration. Return value should be string. If function is None, then - the matcher will use declaration name. - - """ - matcher_base_t.__init__(self) - self.regex = re.compile( regex ) - self.function = function - if None is self.function: - self.function = lambda decl: decl.name - - def __call__( self, decl ): - text = self.function( decl ) - return bool( self.regex.match( text ) ) - - def __str__( self ): - return '(regex=%s)' % self.regex - -class access_type_matcher_t( matcher_base_t ): - """ - Instance of this class will match declaration by its access type: public, - private or protected. If declarations does not have access type, for example - free function, then False will be returned. - """ - - def __init__( self, access_type ): - """ - @param access_type: declaration access type - @type access_type: L{ACCESS_TYPES} defines few consts for your convinience. - Any way you can pass public, private or protected as argument to this function - """ - matcher_base_t.__init__( self ) - self.access_type = access_type - - def __call__( self, decl ): - if not isinstance( decl.parent, class_declaration.class_t ): - return False - return self.access_type == decl.parent.find_out_member_access_type( decl ) - - def __str__( self ): - return '(access type=%s)' % self.access_type - -class virtuality_type_matcher_t( matcher_base_t ): - """ - Instance of this class will match declaration by its virtuality type: not virtual, - virtual or pure virtual. If declarations does not have virtuality type, for example - free function, then False will be returned. - """ - - def __init__( self, virtuality_type ): - """ - @param access_type: declaration access type - @type access_type: L{VIRTUALITY_TYPES} defines few consts for your convinience. - """ - matcher_base_t.__init__( self ) - self.virtuality_type = virtuality_type - - def __call__( self, decl ): - if not isinstance( decl.parent, class_declaration.class_t ): - return False - return self.virtuality_type == decl.virtuality - - def __str__( self ): - return '(virtuality type=%s)' % self.virtuality_type - - -class custom_matcher_t( matcher_base_t ): - """ - Instance of this class will match declaration by user custom criteria. - """ - - def __init__( self, function ): - """ - @param function: callable, that takes single argument - declaration instance - should return True or False - """ - matcher_base_t.__init__( self ) - self.function = function - - def __call__( self, decl ): - return bool( self.function( decl ) ) - - def __str__( self ): - return '(user criteria)' - \ No newline at end of file Copied: pygccxml_dev/pygccxml/declarations/matchers.py (from rev 351, pygccxml_dev/pygccxml/declarations/filters.py) =================================================================== --- pygccxml_dev/pygccxml/declarations/matchers.py (rev 0) +++ pygccxml_dev/pygccxml/declarations/matchers.py 2006-07-27 07:18:46 UTC (rev 352) @@ -0,0 +1,520 @@ +# 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 os +import re +import types +import algorithm +import variable +import namespace +import calldef +import cpptypes +import templates +import class_declaration +from pygccxml import utils + +class matcher_base_t(object): + """matcher_base_t class defines interface for classes that will implement + compare functionality according to some criteria. + """ + def __init__( self ): + object.__init__( self ) + + def __call__(self, decl): + raise NotImplementedError( "matcher must always implement the __call__() method." ) + + def __invert__(self): + """not-operator (~)""" + return not_matcher_t(self) + + def __and__(self, other): + """and-operator (&)""" + return and_matcher_t([self, other]) + + def __or__(self, other): + """or-operator (|)""" + return or_matcher_t([self, other]) + + def __str__( self ): + return "base class for all matchers" + +class and_matcher_t(matcher_base_t): + """Combine several other matchers with "&". + + For example: find all private functions with name XXX + + C{ matcher = access_type_matcher_t( 'private' ) & calldef_matcher_t( name='XXX' ) } + """ + def __init__(self, matchers): + matcher_base_t.__init__(self) + self.matchers = matchers + + def __call__(self, decl): + for matcher in self.matchers: + if not matcher(decl): + return False + return True + + def __str__(self): + return " & ".join( map( lambda x: "(%s)" % str( x ), self.matchers ) ) + + +class or_matcher_t(matcher_base_t): + """Combine several other matchers with "|". + + For example: find all functions and variables with name 'XXX' + + C{ matcher = variable_matcher_t( name='XXX' ) | calldef_matcher_t( name='XXX' ) } + + """ + def __init__(self, matchers): + matcher_base_t.__init__(self) + self.matchers = matchers + + def __call__(self, decl): + for matcher in self.matchers: + if matcher(decl): + return True + return False + + def __str__(self): + return " | ".join( map( lambda x: "(%s)" % str( x ), self.matchers ) ) + + +class not_matcher_t(matcher_base_t): + """Return the inverse result of matcher, using "~" + + For example: find all private and protected declarations + + C{ matcher = ~access_type_matcher_t( 'private' ) } + + """ + def __init__(self, matcher): + matcher_base_t.__init__(self) + self.matcher = matcher + + def __call__(self, decl): + return not self.matcher(decl) + + def __str__(self): + return "~(%s)"%str(self.matcher) + +class declaration_matcher_t( matcher_base_t ): + """ + Instance of this class will match declarations by next criteria: + - declaration name, also could be fully qualified name + Example: wstring or ::std::wstring + - declaration type + Example: L{class_t}, L{namespace_t}, L{enumeration_t} + - location within file system ( file or directory ) + """ + def __init__( self, name=None, decl_type=None, header_dir=None, header_file=None ): + """ + @param decl_type: declaration type to match by. For example L{enumeration_t}. + @type decl_type: any class that derives from L{declarations.declaration_t} class + + @param name: declaration name, could be full name. + @type name: str + + @param header_dir: absolute directory path + @type header_dir: str + + @param header_file: absolute file path + @type header_file: str + + """ + #An other option is that pygccxml will create absolute path using + #os.path.abspath function. But I think this is just wrong, because abspath + #builds path using current working directory. This behavior is fragile + #and very difficult to find a bug. + matcher_base_t.__init__( self ) + self.decl_type = decl_type + self.__name = None + self.__opt_is_tmpl_inst = None + self.__opt_tmpl_name = None + self.__opt_is_full_name = None + self.__decl_name_only = None + + self._set_name( name ) + + self.header_dir = header_dir + self.header_file = header_file + + if self.header_dir: + self.header_dir = utils.normalize_path( self.header_dir ) + if not os.path.isabs( self.header_dir ): + raise RuntimeError( "Path to header directory should be absolute!" ) + + if self.header_file: + self.header_file = utils.normalize_path( self.header_file ) + if not os.path.isabs( self.header_file ): + raise RuntimeError( "Path to header file should be absolute!" ) + + def _get_name(self): + return self.__name + + def _set_name( self, name ): + self.__name = name + if not self.__name: + self.__opt_is_tmpl_inst = None + self.__opt_tmpl_name = None + self.__opt_is_full_name = None + self.__decl_name_only = None + else: + self.__opt_is_tmpl_inst = templates.is_instantiation( self.__name ) + self.__opt_tmpl_name = templates.name( self.__name ) + if self.__opt_is_tmpl_inst: + if '::' in self.__opt_tmpl_name: + self.__opt_is_full_name = True + self.__decl_name_only = self.__opt_tmpl_name.split('::')[-1] + else: + self.__opt_is_full_name = False + self.__decl_name_only = self.__opt_tmpl_name + else: + if '::' in self.__name: + self.__opt_is_full_name = True + self.__decl_name_only = self.__name.split('::')[-1] + else: + self.__opt_is_full_name = False + self.__decl_name_only = self.__name + + + name = property( _get_name, _set_name ) + + def __str__( self ): + msg = [] + if not None is self.decl_type: + msg.append( '(decl type==%s)' % self.decl_type.__name__ ) + if not None is self.name: + msg.append( '(name==%s)' % self.name ) + if not None is self.header_dir: + msg.append( '(header dir==%s)' % self.header_dir ) + if not None is self.header_file: + msg.append( '(header file==%s)' % self.header_file ) + if not msg: + msg.append( 'any' ) + return ' and '.join( msg ) + + def __call__( self, decl ): + if not None is self.decl_type: + if not isinstance( decl, self.decl_type ): + return False + if not None is self.name: + if not self.check_name( decl ): + return False + if not None is self.header_dir and decl.location: + decl_dir = os.path.abspath( os.path.dirname( decl.location.file_name ) ) + decl_dir = utils.normalize_path( decl_dir ) + if decl_dir[:len(self.header_dir)] != self.header_dir: + return False + if not None is self.header_file and decl.location: + decl_file = os.path.abspath( decl.location.file_name ) + decl_file = utils.normalize_path( decl_file ) + if decl_file != self.header_file: + return False + return True + + def check_name( self, decl ): + assert not None is self.name + + if self.__opt_is_tmpl_inst: + if not self.__opt_is_full_name: + if self.name != decl.name: + return False + else: + if self.name != algorithm.full_name( decl ): + return False + else: + if not self.__opt_is_full_name: + if decl.name != self.name: + return False + else: + if self.name != algorithm.full_name( decl ): + return False + return True + + def is_full_name(self): + return self.__opt_is_full_name + + def _get_decl_name_only(self): + return self.__decl_name_only + decl_name_only = property( _get_decl_name_only ) + +class variable_matcher_t( declaration_matcher_t ): + """ + Instance of this class will match variables by next criteria: + - L{declaration_matcher_t} criteria + - variable type. Example: L{int_t} or 'int' + """ + def __init__( self, name=None, type=None, header_dir=None, header_file=None ): + """ + @param type: variable type + @type type: string or instance of L{type_t} derived class + """ + declaration_matcher_t.__init__( self + , name=name + , decl_type=variable.variable_t + , header_dir=header_dir + , header_file=header_file ) + self.type = type + + def __call__( self, decl ): + if not super( variable_matcher_t, self ).__call__( decl ): + return False + if not None is self.type: + if isinstance( self.type, cpptypes.type_t ): + if self.type != decl.type: + return False + else: + if self.type != decl.type.decl_string: + return False + return True + + def __str__( self ): + msg = [ super( variable_matcher_t, self ).__str__() ] + if msg == [ 'any' ]: + msg = [] + if not None is self.type: + msg.append( '(value type==%s)' % str(self.type) ) + if not msg: + msg.append( 'any' ) + return ' and '.join( msg ) + + +class namespace_matcher_t( declaration_matcher_t ): + """Instance of this class will match namespaces by name.""" + + def __init__( self, name=None ): + declaration_matcher_t.__init__( self, name=name, decl_type=namespace.namespace_t) + + def __call__( self, decl ): + if self.name and decl.name == '': + #unnamed namespace have same name as thier parent, we should prevent + #this happens. The price is: user should search for unnamed namespace + #directly. + return False + return super( namespace_matcher_t, self ).__call__( decl ) + + +class calldef_matcher_t( declaration_matcher_t ): + """ + Instance of this class will match callable by next criteria: + - L{declaration_matcher_t} criteria + - return type. Example: L{int_t} or 'int' + - argument types + """ + + def __init__( self, name=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None): + """ + @param return_type: callable return type + @type return_type: string or instance of L{type_t} derived class + + @param arg_types: list of function argument types. arg_types can contain. + Any item within the list could be string or instance of L{type_t} derived + class. If you don't want some argument to participate in match you can + put None. For example: + + C{ calldef_matcher_t( arg_types=[ 'int &', None ] ) } + + will match all functions that takes 2 arguments, where the first one is + reference to integer and second any + @type arg_types: list + """ + if None is decl_type: + decl_type = calldef.calldef_t + declaration_matcher_t.__init__( self + , name=name + , decl_type=decl_type + , header_dir=header_dir + , header_file=header_file ) + + self.return_type = return_type + self.arg_types = arg_types + + def __call__( self, decl ): + if not super( calldef_matcher_t, self ).__call__( decl ): + return False + if not None is self.return_type \ + and not self.__compare_types( self.return_type, decl.return_type ): + return False + if self.arg_types: + if isinstance( self.arg_types, (types.ListType, types.TupleType)): + if len(self.arg_types) != len( decl.arguments ): + return False + for type_or_str, arg in zip( self.arg_types, decl.arguments ): + if None == type_or_str: + continue + else: + if not self.__compare_types( type_or_str, arg.type ): + return False + return True + + def __compare_types( self, type_or_str, type ): + assert type_or_str + if type is None: + return False + if isinstance( type_or_str, cpptypes.type_t ): + if type_or_str != type: + return False + else: + if type_or_str != type.decl_string: + return False + return True + + def __str__( self ): + msg = [ super( calldef_matcher_t, self ).__str__() ] + if msg == [ 'any' ]: + msg = [] + if not None is self.return_type: + msg.append( '(return type==%s)' % str(self.return_type) ) + if self.arg_types: + for i in range( len( self.arg_types ) ): + if self.arg_types[i] is None: + msg.append( '(arg %d type==any)' % i ) + else: + msg.append( '(arg %d type==%s)' % ( i, str( self.arg_types[i] ) ) ) + if not msg: + msg.append( 'any' ) + return ' and '.join( msg ) + + +class operator_matcher_t( calldef_matcher_t ): + """ + Instance of this class will match operators by next criteria: + - L{calldef_matcher_t} criteria + - operator symbol: =, !=, (), [] and etc + """ + def __init__( self, name=None, symbol=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None): + """ + @param symbol: operator symbol + @type symbol: str + """ + if None is decl_type: + decl_type = calldef.operator_t + calldef_matcher_t.__init__( self + , name=name + , return_type=return_type + , arg_types=arg_types + , decl_type=decl_type + , header_dir=header_dir + , header_file=header_file) + self.symbol = symbol + + def __call__( self, decl ): + if not super( operator_matcher_t, self ).__call__( decl ): + return False + if not None is self.symbol: + if self.symbol != decl.symbol: + return False + return True + + def __str__( self ): + msg = [ super( operator_matcher_t, self ).__str__() ] + if msg == [ 'any' ]: + msg = [] + if not None is self.symbol: + msg.append( '(symbol==%s)' % str(self.symbol) ) + if not msg: + msg.append( 'any' ) + return ' and '.join( msg ) + +class regex_matcher_t( matcher_base_t ): + """ + Instance of this class will match declaration using regular expression. + User should supply a function that will extract from declaration desired + information as string. Later, this matcher will match that string using + user regular expression. + """ + def __init__( self, regex, function=None ): + """ + @param regex: regular expression + @type regex: string, an instance of this class will compile it for you + + @param function: function that will be called to get an information from + declaration as string. As input this function takes 1 argument: reference + to declaration. Return value should be string. If function is None, then + the matcher will use declaration name. + + """ + matcher_base_t.__init__(self) + self.regex = re.compile( regex ) + self.function = function + if None is self.function: + self.function = lambda decl: decl.name + + def __call__( self, decl ): + text = self.function( decl ) + return bool( self.regex.match( text ) ) + + def __str__( self ): + return '(regex=%s)' % self.regex + +class access_type_matcher_t( matcher_base_t ): + """ + Instance of this class will match declaration by its access type: public, + private or protected. If declarations does not have access type, for example + free function, then False will be returned. + """ + + def __init__( self, access_type ): + """ + @param access_type: declaration access type + @type access_type: L{ACCESS_TYPES} defines few consts for your convinience. + Any way you can pass public, private or protected as argument to this function + """ + matcher_base_t.__init__( self ) + self.access_type = access_type + + def __call__( self, decl ): + if not isinstance( decl.parent, class_declaration.class_t ): + return False + return self.access_type == decl.parent.find_out_member_access_type( decl ) + + def __str__( self ): + return '(access type=%s)' % self.access_type + +class virtuality_type_matcher_t( matcher_base_t ): + """ + Instance of this class will match declaration by its virtuality type: not virtual, + virtual or pure virtual. If declarations does not have virtuality type, for example + free function, then False will be returned. + """ + + def __init__( self, virtuality_type ): + """ + @param access_type: declaration access type + @type access_type: L{VIRTUALITY_TYPES} defines few consts for your convinience. + """ + matcher_base_t.__init__( self ) + self.virtuality_type = virtuality_type + + def __call__( self, decl ): + if not isinstance( decl.parent, class_declaration.class_t ): + return False + return self.virtuality_type == decl.virtuality + + def __str__( self ): + return '(virtuality type=%s)' % self.virtuality_type + + +class custom_matcher_t( matcher_base_t ): + """ + Instance of this class will match declaration by user custom criteria. + """ + + def __init__( self, function ): + """ + @param function: callable, that takes single argument - declaration instance + should return True or False + """ + matcher_base_t.__init__( self ) + self.function = function + + def __call__( self, decl ): + return bool( self.function( decl ) ) + + def __str__( self ): + return '(user criteria)' + \ No newline at end of file Modified: pygccxml_dev/pygccxml/declarations/type_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/type_traits.py 2006-07-26 14:24:17 UTC (rev 351) +++ pygccxml_dev/pygccxml/declarations/type_traits.py 2006-07-27 07:18:46 UTC (rev 352) @@ -16,7 +16,7 @@ """ import types -import filters +import matchers import typedef import calldef import cpptypes @@ -378,8 +378,8 @@ #In some case compare operators of std::basic_string are not instantiated return True - operators = type.member_operators( function=filters.custom_matcher_t( not_artificial ) \ - & filters.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 ) @@ -400,8 +400,8 @@ 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=filters.custom_matcher_t( not_artificial ) \ - & filters.access_type_matcher_t( 'public' ) + operators = bi.related_class.member_operators( function=matchers.custom_matcher_t( not_artificial ) \ + & matchers.access_type_matcher_t( 'public' ) , symbol=operator_symbol , allow_empty=True , recursive=False ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-27 19:05:46
|
Revision: 356 Author: allenb Date: 2006-07-27 12:05:17 -0700 (Thu, 27 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=356&view=rev Log Message: ----------- Fix grammar. Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-07-27 19:04:38 UTC (rev 355) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-07-27 19:05:17 UTC (rev 356) @@ -99,9 +99,9 @@ def get_exportable( self ): if self._exportable is None: if self.name.startswith( '__' ): - self._exportable_reason = 'pyplusplus, by default, does not exposes internal compilers declarations. Names of those declarations starts with "__".' + self._exportable_reason = 'pyplusplus, by default, does not expose internal compilers declarations. Names of those declarations usually start with "__".' elif self.location and self.location.file_name == "<internal>": - self._exportable_reason = 'pyplusplus, by default, does not exposes declarations, that belongs to "<internal>" header.' + self._exportable_reason = 'pyplusplus, by default, does not expose internal declarations (those that gccxml say belong to "<internal>" header).' else: self._exportable_reason = self._exportable_impl( ) self._exportable = not bool( self._exportable_reason ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <al...@us...> - 2006-07-27 19:05:43
|
Revision: 355 Author: allenb Date: 2006-07-27 12:04:38 -0700 (Thu, 27 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=355&view=rev Log Message: ----------- - When using a Linux console, auto detect the width using curses. Modified Paths: -------------- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py Modified: pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py 2006-07-27 18:47:29 UTC (rev 354) +++ pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py 2006-07-27 19:04:38 UTC (rev 355) @@ -14,7 +14,7 @@ its messages to stdout. """ - def __init__(self, fmt=None, datefmt=None, width=70): + def __init__(self, fmt=None, datefmt=None, width=None): """Constructor. See the Python standard library reference for a documentation @@ -22,7 +22,13 @@ width is the maximum width of the generated text blocks. """ logging.Formatter.__init__(self, fmt, datefmt) - self._width = width + if None == width: + try: + import curses + curses.setupterm() + self._width = curses.tigetnum('cols') + except: + self._width = 70 # default to 70 def format(self, record): """This method overwrites the original one. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-27 18:47:41
|
Revision: 354 Author: roman_yakovenko Date: 2006-07-27 11:47:29 -0700 (Thu, 27 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=354&view=rev Log Message: ----------- fixing small bugs Modified Paths: -------------- pyplusplus_dev/docs/documentation/feedback.rest pyplusplus_dev/pyplusplus/_logging_/__init__.py Modified: pyplusplus_dev/docs/documentation/feedback.rest =================================================================== --- pyplusplus_dev/docs/documentation/feedback.rest 2006-07-27 09:56:53 UTC (rev 353) +++ pyplusplus_dev/docs/documentation/feedback.rest 2006-07-27 18:47:29 UTC (rev 354) @@ -61,7 +61,8 @@ In previous paragraph, I described pretty usefull functionality. What should be done in order to enable it? - *Nothing!* By default, `pyplusplus`_ prints only -important messages to ``stdout``. +important messages to ``stdout``. More over it prints them onle for declarations +that are going to be exported. `pyplusplus`_ uses standard `logging`_ package to write all user messages. By default, messages with ``DEBUG`` level will be skipped, all other messages will Modified: pyplusplus_dev/pyplusplus/_logging_/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/__init__.py 2006-07-27 09:56:53 UTC (rev 353) +++ pyplusplus_dev/pyplusplus/_logging_/__init__.py 2006-07-27 18:47:29 UTC (rev 354) @@ -28,4 +28,4 @@ module_builder = _create_logger_( 'pyplusplus.module_builder' ) #root logger exists for configuration purpose only root = logging.getLogger( 'pyplusplus' ) - all = [ root, file_writer, module_builder ] + all = [ root, file_writer, module_builder, declarations ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-26 19:46:05
|
Revision: 349 Author: roman_yakovenko Date: 2006-07-26 02:49:48 -0700 (Wed, 26 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=349&view=rev Log Message: ----------- updating feedback documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/feedback.rest Modified: pyplusplus_dev/docs/documentation/feedback.rest =================================================================== --- pyplusplus_dev/docs/documentation/feedback.rest 2006-07-26 06:13:19 UTC (rev 348) +++ pyplusplus_dev/docs/documentation/feedback.rest 2006-07-26 09:49:48 UTC (rev 349) @@ -70,6 +70,10 @@ --------------- API Description --------------- + +Logging API +----------- + If you are here, it means that you are not pleased with default configuration and want to change it, right? @@ -82,11 +86,12 @@ :: - module_builder.set_logger_level( logging.INFO ) + module_builder.set_logger_level( logging.DEBUG ) + 2. May be do you want to disable some messages and leave others? It is possible. - `pyplusplus`_ and `pygccxml`_ do not use one logger. Almost every package - has its own logger. So you can enable one logger and disable another one. + `pyplusplus`_ and `pygccxml`_ do not use one logger. Almost every internal + package has its own logger. So you can enable one logger and disable another one. `pygccxml`_ package defines all loggers in ``pygccxml.utils`` package. @@ -94,9 +99,13 @@ Both packages defines ``loggers`` class. Those classes keep references to different loggers. ``loggers`` classes look very similar to the next class: - + :: + import logging #standard Python package + + :: + def _create_logger_( name ): logger = logging.getLogger(name) ... @@ -111,11 +120,39 @@ module_builder = _create_logger_( 'pyplusplus.module_builder' ) root = logging.getLogger( 'pyplusplus' ) all = [ root, file_writer, module_builder ] + + Now, you can use the functionality provided by ``logging`` package to complete + your task. - s + One more thing. `pyplusplus`_ splits long message to few lines, where line + length is 70 characters. Thus it is very convinient to read them on your screen. + If you want to use different tools to monitor those messages, consider to use + standard `Formatter`_ class, instead of ``multi_line_formatter_t`` one. +Declarations API +---------------- +Every declaration class has next methods: + +* ``why_not_exportable( self )`` + + This method explains why a declaration could not be exported. The return value + type is string or ``None``. ``None`` will be returned if declaration is + exportable. + + Property ``exportable`` will be set to ``True`` if declaration is exportable, + and to ``False`` otherwise. + +* ``readme( self )`` + + This method gives you access to all tips/hints/warnings `pyplusplus`_ has about + the declaration. This methods returns a list of strings. If the declaration is + not exportable, than first message within the list is an explanation, why it + is not exportable. + + +.. _`Formatter` : http://docs.python.org/lib/node357.html .. _`logging` : http://docs.python.org/lib/module-logging.html .. _`pyplusplus` : ./../pyplusplus.html .. _`pygccxml` : ./../../pygccxml/pygccxml.html This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-26 14:24:27
|
Revision: 351 Author: roman_yakovenko Date: 2006-07-26 07:24:17 -0700 (Wed, 26 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=351&view=rev Log Message: ----------- adding documentation, that will describe how to add custom code to generated one Modified Paths: -------------- pyplusplus_dev/docs/documentation/www_configuration.py Added Paths: ----------- pyplusplus_dev/docs/documentation/inserting_code.rest Added: pyplusplus_dev/docs/documentation/inserting_code.rest =================================================================== --- pyplusplus_dev/docs/documentation/inserting_code.rest (rev 0) +++ pyplusplus_dev/docs/documentation/inserting_code.rest 2006-07-26 14:24:17 UTC (rev 351) @@ -0,0 +1,109 @@ +============= +Inerting code +============= + +.. contents:: Table of contents + +------------ +Introduction +------------ + +`pyplusplus`_ is not a magician! Sometimes there is a need to modify or add code +to generated file(s). This document will describe how you can insert your code +to almost any place. + +----------- +Source code +----------- + +I am going to introduce C++ class ``world_t``. I will use it for all explanations. + +:: + + struct world_t { + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + + std::string msg; + }; + +If run `pyplusplus`_ on this code it will generate next `boost.python`_ code: + +:: + + bp::class_< world_t, boost::noncopyable >( "world_t" ) + .def( + "greet" + , &::world_t::greet + , bp::default_call_policies() ) + .def( + "set" + , &::world_t::set + , ( bp::arg("msg") ) + , bp::default_call_policies() ) + .def_readwrite( "msg", &world_t::msg ); + +It is possible, that `pyplusplus`_ will generate code, that expose class +``world_t``, that will look different. The second form is more verbose, but it +provides solution for few problems. + +:: + + { //::world_t + typedef bp::class_< world_t, boost::noncopyable > world_t_exposer_t; + world_t_exposer_t world_t_exposer = world_t_exposer_t( "world_t" ); + bp::scope world_t_scope( world_t_exposer ); + { //::world_t::greet + + typedef ::std::string ( ::world_t::*function_ptr_t )( ) ; + + world_t_exposer.def( + "greet" + , function_ptr_t( &::world_t::greet ) + , bp::default_call_policies() ); + + } + { //::world_t::set + + typedef void ( ::world_t::*function_ptr_t )( ::std::string ) ; + + world_t_exposer.def( + "set" + , function_ptr_t( &::world_t::set ) + , ( bp::arg("msg") ) + , bp::default_call_policies() ); + + } + world_t_exposer.def_readwrite( "msg", &world_t::msg ); + } + + +-------------------- +Insert code to class +-------------------- + +``class_t`` declaration defines ``add_code( self, code, works_on_instance=True )`` +method. + +:: + + mb = module_builder_t( ... ) + my_class = mb.class_( 'my_class' ) + my_class.add_code( C++ code ) + + + + +.. _`pyplusplus` : ./../pyplusplus.html +.. _`pygccxml` : ./../../pygccxml/pygccxml.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Modified: pyplusplus_dev/docs/documentation/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/www_configuration.py 2006-07-26 13:08:20 UTC (rev 350) +++ pyplusplus_dev/docs/documentation/www_configuration.py 2006-07-26 14:24:17 UTC (rev 351) @@ -3,5 +3,6 @@ files_to_skip = ['indexing_suite_v2.html'] names = { 'containers' : 'STL containers' , 'how_to' : 'how to ... ?' - , 'doc_string' : 'documentation string' + , 'doc_string' : 'documentation string' + , 'inserting_code' : 'inserting code' } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-26 06:18:40
|
Revision: 348 Author: roman_yakovenko Date: 2006-07-25 23:13:19 -0700 (Tue, 25 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=348&view=rev Log Message: ----------- adding new warning about duplicate values to enum Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py pyplusplus_dev/unittests/data/enums_to_be_exported.hpp Modified: pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py 2006-07-25 17:47:50 UTC (rev 347) +++ pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py 2006-07-26 06:13:19 UTC (rev 348) @@ -59,4 +59,15 @@ no_export_values = property( _get_no_export_values, _set_export_values, doc= """A list of (C++) enumeration names that should not be exported. - @type: list""") + @type: list""") + + def _readme_impl( self ): + msgs = [] + if self.name: + name2value = self.get_name2value_dict() + if len( set( name2value.keys() ) ) != len( set( name2value.values() ) ): + msgs.append( "Boost.Python does not support enums with duplicate values. " + "You can read more about this here: http://boost.org/libs/python/todo.html#support-for-enums-with-duplicate-values . " + "The quick work around is to add new class variable to the exported enum, from Python. " ) + return msgs + Modified: pyplusplus_dev/unittests/data/enums_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/enums_to_be_exported.hpp 2006-07-25 17:47:50 UTC (rev 347) +++ pyplusplus_dev/unittests/data/enums_to_be_exported.hpp 2006-07-26 06:13:19 UTC (rev 348) @@ -12,7 +12,12 @@ red = 1 , green = 2 , blue = 4 }; - + +enum numbers{ + zero = 0 + , noll = 0 +}; + inline int to_int( int x=red ){ return x; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-25 17:47:55
|
Revision: 347 Author: roman_yakovenko Date: 2006-07-25 10:47:50 -0700 (Tue, 25 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=347&view=rev Log Message: ----------- fixing documentation string for multi_line_formatter_t Modified Paths: -------------- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py Modified: pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py 2006-07-25 14:20:27 UTC (rev 346) +++ pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py 2006-07-25 17:47:50 UTC (rev 347) @@ -60,11 +60,9 @@ module or it can be of the form <decl>;<msg> where <decl> is the declaration string and <msg> an arbitrary message. Lines of this form will be separated so that the declaration and the message - appear in individual text blocks separated by the string '->'. + appear in individual text blocks, where every line of message will start + with '>' character. - In any case the return string will be indented except for the first - line. - width is the maximum width of any text blocks (without indendation). """ txts = msgline.split(";") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-25 14:20:37
|
Revision: 346 Author: roman_yakovenko Date: 2006-07-25 07:20:27 -0700 (Tue, 25 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=346&view=rev Log Message: ----------- fixing errors in splitting huge class to files functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-07-25 06:25:20 UTC (rev 345) +++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-07-25 14:20:27 UTC (rev 346) @@ -274,13 +274,17 @@ for x in creators: if x is used_init: - continue + continue if isinstance( x, calldef.calldef_t ): x.works_on_instance = False - result.append( x.create() ) + code = x.create() + if code: + result.append( code ) continue - if not x.works_on_instance: - result.append( x.create() ) + if not x.works_on_instance: + code = x.create() + if code: + result.append( code ) else: result.append( '%s.%s;' % ( self.class_var_name, x.create() ) ) Modified: pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-07-25 06:25:20 UTC (rev 345) +++ pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-07-25 14:20:27 UTC (rev 346) @@ -31,8 +31,11 @@ self.internal_splitters = [ self.split_internal_enums , self.split_internal_unnamed_enums - , self.split_internal_member_functions - , self.split_internal_classes + , self.split_internal_classes + , self.split_internal_memfuns + , self.split_internal_v_memfuns + , self.split_internal_pv_memfuns + , self.split_internal_protected_memfuns #not supported yet #, self.split_internal_member_variables ] @@ -69,7 +72,9 @@ self.split_method_names.append(function_name) def wrapper_header( self, class_creator ): - return os.path.join( class_creator.alias, 'wrapper' + self.HEADER_EXT ) + normalize = code_creators.include_directories_t.normalize + tmp = os.path.join( class_creator.alias, 'wrapper' + self.HEADER_EXT ) + return normalize( tmp ) def write_wrapper( self, class_creator ): answer = [] @@ -152,15 +157,36 @@ , class_creator.creators ) self.split_internal_creators( class_creator, creators, 'unnamed_enums' ) return 'unnamed_enums' - - def split_internal_member_functions( self, class_creator ): - creators = filter( lambda x: isinstance(x, code_creators.mem_fun_t ) - , class_creator.creators ) - for creator in creators: - creator.works_on_instance = False - self.split_internal_creators( class_creator, creators, 'memfuns' ) - return 'memfuns' + def split_internal_calldefs( self, class_creator, calldef_types, pattern ): + creators = filter( lambda x: isinstance(x, calldef_types ), class_creator.creators ) + for creator in creators: + creator.works_on_instance = False + self.split_internal_creators( class_creator, creators, pattern ) + return pattern + + def split_internal_memfuns( self, class_creator ): + calldef_types = ( code_creators.mem_fun_t ) + return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns' ) + + def split_internal_v_memfuns( self, class_creator ): + calldef_types = ( code_creators.mem_fun_v_t ) + return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns_virtual' ) + + def split_internal_pv_memfuns( self, class_creator ): + calldef_types = ( code_creators.mem_fun_pv_t ) + return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns_pvirtual' ) + + def split_internal_protected_memfuns( self, class_creator ): + calldef_types = ( + code_creators.mem_fun_protected_t + , code_creators.mem_fun_protected_s_t + , code_creators.mem_fun_protected_v_t + , code_creators.mem_fun_protected_pv_t ) + + return self.split_internal_calldefs( class_creator, calldef_types, 'protected_memfuns' ) + + def split_internal_classes( self, class_creator ): class_types = ( code_creators.class_t, code_creators.class_declaration_t ) creators = filter( lambda x: isinstance(x, class_types ), class_creator.creators ) @@ -209,11 +235,10 @@ # Write the register() function... source_code.append( '' ) - source_code.append( 'void %s{' % function_name ) + source_code.append( 'void %s(){' % function_name ) source_code.append( '' ) - for creator in class_creator.creators: - source_code.append( code_creators.code_creator_t.indent( creator.create() ) ) - source_code.append( '' ) + source_code.append( class_creator.create() ) + source_code.append( '' ) source_code.append( '}' ) self.write_file( file_path + self.SOURCE_EXT, os.linesep.join( source_code ) ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-25 06:25:46
|
Revision: 345 Author: roman_yakovenko Date: 2006-07-24 23:25:20 -0700 (Mon, 24 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=345&view=rev Log Message: ----------- 1. renaming multilineformatter.py to multi_line_formatter.py 2. removing os.linesep from messages 3. changing a little bit a way multi_line_formatter_t works Modified Paths: -------------- pygccxml_dev/pygccxml/utils/__init__.py pyplusplus_dev/pyplusplus/_logging_/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/module_builder/builder.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/pyplusplus/module_creator/types_database.py Added Paths: ----------- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py Removed Paths: ------------- pyplusplus_dev/pyplusplus/_logging_/multilineformatter.py Modified: pygccxml_dev/pygccxml/utils/__init__.py =================================================================== --- pygccxml_dev/pygccxml/utils/__init__.py 2006-07-24 20:26:03 UTC (rev 344) +++ pygccxml_dev/pygccxml/utils/__init__.py 2006-07-25 06:25:20 UTC (rev 345) @@ -10,9 +10,9 @@ def _create_logger_( name ): logger = logging.getLogger(name) - __handler = logging.StreamHandler(sys.stdout) - __handler.setFormatter( logging.Formatter( os.linesep + '%(levelname)s %(message)s' ) ) - logger.addHandler(__handler) + handler = logging.StreamHandler(sys.stdout) + handler.setFormatter( logging.Formatter( os.linesep + '%(levelname)s %(message)s' ) ) + logger.addHandler(handler) logger.setLevel(logging.INFO) return logger Modified: pyplusplus_dev/pyplusplus/_logging_/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/__init__.py 2006-07-24 20:26:03 UTC (rev 344) +++ pyplusplus_dev/pyplusplus/_logging_/__init__.py 2006-07-25 06:25:20 UTC (rev 345) @@ -12,13 +12,13 @@ import os import sys import logging -from multilineformatter import multi_line_formatter_t +from multi_line_formatter import multi_line_formatter_t def _create_logger_( name ): logger = logging.getLogger(name) - __handler = logging.StreamHandler(sys.stdout) - __handler.setFormatter( multi_line_formatter_t( os.linesep + '%(levelname)s: %(message)s' ) ) - logger.addHandler(__handler) + handler = logging.StreamHandler(sys.stdout) + handler.setFormatter( multi_line_formatter_t( os.linesep + '%(levelname)s: %(message)s' ) ) + logger.addHandler(handler) logger.setLevel(logging.INFO) return logger Copied: pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py (from rev 344, pyplusplus_dev/pyplusplus/_logging_/multilineformatter.py) =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py (rev 0) +++ pyplusplus_dev/pyplusplus/_logging_/multi_line_formatter.py 2006-07-25 06:25:20 UTC (rev 345) @@ -0,0 +1,85 @@ +# 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) + +# Initial version by Matthias Baas (ba...@ir...). + +import os, logging, textwrap + +class multi_line_formatter_t(logging.Formatter): + """Custom log formatter to split long message into several lines. + + This formatter is used for the default stream handler that outputs + its messages to stdout. + """ + + def __init__(self, fmt=None, datefmt=None, width=70): + """Constructor. + + See the Python standard library reference for a documentation + of fmt and datefmt. + width is the maximum width of the generated text blocks. + """ + logging.Formatter.__init__(self, fmt, datefmt) + self._width = width + + def format(self, record): + """This method overwrites the original one. + + The first thing that is done in the original format() method + is the creation of the record.message attribute: + + record.message = record.getMessage() + + Now this method temporarily replaces the getMessage() method of + the record by a version that returns a pregenerated message that + spans several lines. Then the original format() method is called + which will invoke the 'fake' method. + """ + # Get the original single-line message + message = record.getMessage() + # Distribute the message among several lines... + message = self.formatMessage(message, width=self._width) + # ...and temporarily replace the getMessage() method so that the + # reformatted message is used + mth = record.getMessage + record.getMessage = lambda x=message: x + # Invoke the inherited format() method + res = logging.Formatter.format(self, record) + # Restore the original method + record.getMessage = mth + return res + + @staticmethod + def formatMessage(msgline, width=70): + """Format a long single line message so that it is easier to read. + + msgline is a string containing a single message. It can either be + a plain message string which is reformatted using the textwrap + module or it can be of the form <decl>;<msg> where <decl> is the + declaration string and <msg> an arbitrary message. Lines of this + form will be separated so that the declaration and the message + appear in individual text blocks separated by the string '->'. + + In any case the return string will be indented except for the first + line. + + width is the maximum width of any text blocks (without indendation). + """ + txts = msgline.split(";") + # Ensure that there are no more than two items in txts + if len( txts ) != 2: + #If message is not in format we expected, just return it + return os.linesep.join( textwrap.wrap( msgline, width ) ) + + lines = [ txts[0] ] #I don't want to break declaration string to few lines + + # Insert a separator if there are two parts (=decl and msg) + # Apply the text wrapper to shorten the maximum line length + wrapped_lines = textwrap.wrap( txts[1], width ) + lines.extend( map( lambda s: "> " + s.strip(), wrapped_lines ) ) + + return os.linesep.join(lines) + + Deleted: pyplusplus_dev/pyplusplus/_logging_/multilineformatter.py =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/multilineformatter.py 2006-07-24 20:26:03 UTC (rev 344) +++ pyplusplus_dev/pyplusplus/_logging_/multilineformatter.py 2006-07-25 06:25:20 UTC (rev 345) @@ -1,89 +0,0 @@ -# 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) - -# Initial version by Matthias Baas (ba...@ir...). - -import os, logging, textwrap - -class multi_line_formatter_t(logging.Formatter): - """Custom log formatter to split long message into several lines. - - This formatter is used for the default stream handler that outputs - its messages to stdout. - """ - - def __init__(self, fmt=None, datefmt=None, width=70): - """Constructor. - - See the Python standard library reference for a documentation - of fmt and datefmt. - width is the maximum width of the generated text blocks. - """ - logging.Formatter.__init__(self, fmt, datefmt) - self._width = width - - def format(self, record): - """This method overwrites the original one. - - The first thing that is done in the original format() method - is the creation of the record.message attribute: - - record.message = record.getMessage() - - Now this method temporarily replaces the getMessage() method of - the record by a version that returns a pregenerated message that - spans several lines. Then the original format() method is called - which will invoke the 'fake' method. - """ - # Get the original single-line message - message = record.getMessage() - # Distribute the message among several lines... - message = self.formatMessage(message, width=self._width) - # ...and temporarily replace the getMessage() method so that the - # reformatted message is used - mth = record.getMessage - record.getMessage = lambda x=message: x - # Invoke the inherited format() method - res = logging.Formatter.format(self, record) - # Restore the original method - record.getMessage = mth - return res - - @staticmethod - def formatMessage(msgline, width=70): - """Format a long single line message so that it is easier to read. - - msgline is a string containing a single message. It can either be - a plain message string which is reformatted using the textwrap - module or it can be of the form <decl>;<msg> where <decl> is the - declaration string and <msg> an arbitrary message. Lines of this - form will be separated so that the declaration and the message - appear in individual text blocks separated by the string '->'. - - In any case the return string will be indented except for the first - line. - - width is the maximum width of any text blocks (without indendation). - """ - txts = msgline.split(";") - # Ensure that there are no more than two items in txts - if len(txts)>2: - txts = [txts[0], ";".join(txts[1:])] - - # Insert a separator if there are two parts (=decl and msg) - if len(txts)==2: - txts.insert(1, "->") - - # Apply the text wrapper to shorten the maximum line length - lines = [] - for txt in txts: - txt = txt.strip().replace(os.linesep, " ") - lines.extend(textwrap.wrap(txt, width)) - - # Indent the text (except for the first line) - lines[1:] = map(lambda s: (2*" ")+s, lines[1:]) - return os.linesep.join(lines) - - Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-07-24 20:26:03 UTC (rev 344) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-07-25 06:25:20 UTC (rev 345) @@ -6,12 +6,6 @@ import os import decl_wrapper from pygccxml import declarations -##May be in future I will enable this functionality again, right now it seems -##that this is useless -##def is_finalizable(self): - ##if not self.wrapper: - ##return False - ##return self.declaration.virtuality != declarations.VIRTUALITY_TYPES.PURE_VIRTUAL class calldef_t(decl_wrapper.decl_wrapper_t): @@ -131,20 +125,20 @@ #TODO: functions that takes as argument pointer to pointer to smth, could not be exported #see http://www.boost.org/libs/python/doc/v2/faq.html#funcptr if len( self.arguments ) > calldef_t.BOOST_PYTHON_MAX_ARITY: - tmp = [ "Function '%s' has more than %d arguments ( %d ). " ] - tmp.append( os.linesep + "\tYou should adjust BOOST_PYTHON_MAX_ARITY." ) - tmp.append( os.linesep + "\tFor more information see: http://mail.python.org/pipermail/c++-sig/2002-June/001554.html" ) - tmp = ''.join( tmp ) - msgs.append( tmp % ( self.decl_string, calldef_t.BOOST_PYTHON_MAX_ARITY, len( self.arguments ) ) ) + tmp = [ "The function has more than %d arguments ( %d ). " ] + tmp.append( "You should adjust BOOST_PYTHON_MAX_ARITY macro." ) + tmp.append( "For more information see: http://mail.python.org/pipermail/c++-sig/2002-June/001554.html" ) + tmp = ' '.join( tmp ) + msgs.append( tmp % ( calldef_t.BOOST_PYTHON_MAX_ARITY, len( self.arguments ) ) ) if suspicious_type( self.return_type ) and None is self.call_policies: - msgs.append( 'Function "%s" returns non-const reference to C++ fundamental type - value can not be modified from Python.' % str( self ) ) + msgs.append( 'The function "%s" returns non-const reference to C++ fundamental type - value can not be modified from Python.' % str( self ) ) for index, arg in enumerate( self.arguments ): if suspicious_type( arg.type ): - tmpl = 'Function "%s" takes as argument (name=%s, pos=%d ) ' \ - + 'non-const reference to C++ fundamental type - ' \ - + 'function could not be called from Python.' - msgs.append( tmpl % ( str( self ), arg.name, index ) ) + tmpl = [ 'The function takes as argument (name=%s, pos=%d ) ' ] + tmpl.append( 'non-const reference to C++ fundamental type - ' ) + tmpl.append( 'function could not be called from Python.' ) + msgs.append( ''.join( tmpl ) % ( arg.name, index ) ) if False == self.overridable: msgs.append( self.get_overridable.__doc__ ) @@ -200,7 +194,7 @@ if not operators_helper.is_supported( oper ): msg = [ '"operator%s" is not supported. ' % oper.symbol ] msg.append( 'See Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/operators.html#introduction.' ) - return os.linesep.join( msg ) + return ' '.join( msg ) return '' exportable = staticmethod( exportable ) Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-24 20:26:03 UTC (rev 344) +++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-25 06:25:20 UTC (rev 345) @@ -110,7 +110,7 @@ decls = reader.read_files( files, compilation_mode ) self.logger.debug( 'parsing files - done( %f seconds )' % ( time.clock() - start_time ) ) - self.logger.debug( 'settings declarations defaults- started' ) + self.logger.debug( 'settings declarations defaults - started' ) global_ns = decls_package.matcher.get_single( decls_package.namespace_matcher_t( name='::' ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-07-24 20:26:03 UTC (rev 344) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-07-25 06:25:20 UTC (rev 345) @@ -151,12 +151,10 @@ if reason in DO_NOT_REPORT_MSGS: continue readme = readme[1:] - msgstr = "%s;%s"%(decl, reason.replace(os.linesep, " ")) - self.decl_logger.warn( msgstr ) + self.decl_logger.warn( "%s;%s" % ( decl, reason ) ) for msg in readme: - msgstr = "%s;%s"%(decl, msg.replace(os.linesep, " ")) - self.decl_logger.warn( msgstr ) + self.decl_logger.warn( "%s;%s" % ( decl, msg ) ) #leave only declarations defined under namespace, but remove namespaces decls = filter( lambda x: not isinstance( x, declarations.namespace_t ) \ Modified: pyplusplus_dev/pyplusplus/module_creator/types_database.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/types_database.py 2006-07-24 20:26:03 UTC (rev 344) +++ pyplusplus_dev/pyplusplus/module_creator/types_database.py 2006-07-25 06:25:20 UTC (rev 345) @@ -72,13 +72,14 @@ try: check_extraction = container_cls.indexing_suite.element_type - except RuntimeError, error: - msg = [] - msg.append( 'pyplusplus found template class instantiation "%s" declaration ( not definition ). ' % container_cls.name ) - msg.append( '\tpyplusplus can not find out container value_type( mapped_type )!' ) - msg.append( '\tThis class will be exported, but there is a posiblity, that generated code will not compile.' ) - msg.append( '\tThe solution to the problem is to create a variable of the class.' ) - _logging_.loggers.declarations.warn( os.linesep.join( msg ) ) + except RuntimeError, error: + msg = "%s;%s" \ + % ( str(container_cls) + , "pyplusplus can not find out container value_type( mapped_type )." + "The container class is template instantiation declaration and not definition." + "This container class will be exported, but there is a posiblity, that generated code will not compile." + "The solution to the problem is to create a variable of the class." ) + _logging_.loggers.declarations.warn( msg ) self.__containers.add( container_cls ) return True This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-24 20:26:10
|
Revision: 344 Author: roman_yakovenko Date: 2006-07-24 13:26:03 -0700 (Mon, 24 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=344&view=rev Log Message: ----------- adding loggers documentation Added Paths: ----------- pyplusplus_dev/docs/documentation/feedback.rest Added: pyplusplus_dev/docs/documentation/feedback.rest =================================================================== --- pyplusplus_dev/docs/documentation/feedback.rest (rev 0) +++ pyplusplus_dev/docs/documentation/feedback.rest 2006-07-24 20:26:03 UTC (rev 344) @@ -0,0 +1,132 @@ +===================== +pyplusplus feedback +===================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +`pyplusplus`_ has been created with few goals in mind: + +* to allow users create `Python`_ bindings for big projects, using `boost.python`_ + library + +* to minimize maintenance time to minimum + +* to surve as a user guide for `boost.python`_ library + + +Those goals have something common. In order to achive them, `pyplusplus`_ should +give some kind of feedback to user. `pyplusplus`_ actually understands the +declarations it exports. It scans a declaration for potential problems, reports +them and in some cases prints hints how they could be solved. Few examples: + +* + :: + + struct Y{ ... }; + + struct X{ + ... + virtual Y& do_smth(); + ... + }; + + Member function ``do_smth`` could not be overriden in Python. + +* + :: + + struct window{ + ... + void get_size( int& heght, int& widht ) const; + ... + }; + + Member function ``get_size`` can be exposed to Python, but it will not be callable. + +* In order to expose free/member function that takes more than 10 arguments user + should define ``BOOST_PYTHON_MAX_ARITY`` macro. + +For all those problems and many other `pyplusplus`_ gives a nice explanation +and sometimes a link to the relevant information on the internet. + +I hope, that from now you will read every `pyplusplus`_ message :-). + +------------- +How it works? +------------- + +In previous paragraph, I described pretty usefull functionality. What should be +done in order to enable it? - *Nothing!* By default, `pyplusplus`_ prints only +important messages to ``stdout``. + +`pyplusplus`_ uses standard `logging`_ package to write all user messages. By +default, messages with ``DEBUG`` level will be skipped, all other messages will +be reported. + +--------------- +API Description +--------------- +If you are here, it means that you are not pleased with default configuration +and want to change it, right? + +1. You want to change logged messages level: + + :: + + import logging + from pyplusplus import module_builder + + :: + + module_builder.set_logger_level( logging.INFO ) + +2. May be do you want to disable some messages and leave others? It is possible. + `pyplusplus`_ and `pygccxml`_ do not use one logger. Almost every package + has its own logger. So you can enable one logger and disable another one. + + `pygccxml`_ package defines all loggers in ``pygccxml.utils`` package. + + `pyplusplus`_ package defines all logers in ``pyplusplus._logging_`` package. + + Both packages defines ``loggers`` class. Those classes keep references to + different loggers. ``loggers`` classes look very similar to the next class: + + :: + + def _create_logger_( name ): + logger = logging.getLogger(name) + ... + return logger + + + :: + + class loggers: + file_writer = _create_logger_( 'pyplusplus.file_writer' ) + declarations = _create_logger_( 'pyplusplus.declarations' ) + module_builder = _create_logger_( 'pyplusplus.module_builder' ) + root = logging.getLogger( 'pyplusplus' ) + all = [ root, file_writer, module_builder ] + + s + + + +.. _`logging` : http://docs.python.org/lib/module-logging.html +.. _`pyplusplus` : ./../pyplusplus.html +.. _`pygccxml` : ./../../pygccxml/pygccxml.html +.. _`boost.python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-07-24 18:24:58
|
Revision: 343 Author: roman_yakovenko Date: 2006-07-24 11:24:45 -0700 (Mon, 24 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=343&view=rev Log Message: ----------- fixing and improving write class to multiple files functionality Modified Paths: -------------- pygccxml_dev/unittests/data/core_cache.hpp pyplusplus_dev/pyplusplus/_logging_/__init__.py pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py pyplusplus_dev/pyplusplus/file_writers/multiple_files.py Modified: pygccxml_dev/unittests/data/core_cache.hpp =================================================================== --- pygccxml_dev/unittests/data/core_cache.hpp 2006-07-24 15:50:36 UTC (rev 342) +++ pygccxml_dev/unittests/data/core_cache.hpp 2006-07-24 18:24:45 UTC (rev 343) @@ -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 \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/_logging_/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/_logging_/__init__.py 2006-07-24 15:50:36 UTC (rev 342) +++ pyplusplus_dev/pyplusplus/_logging_/__init__.py 2006-07-24 18:24:45 UTC (rev 343) @@ -17,7 +17,6 @@ def _create_logger_( name ): logger = logging.getLogger(name) __handler = logging.StreamHandler(sys.stdout) -# __handler.setFormatter( logging.Formatter( os.linesep + '%(levelname)s %(message)s' ) ) __handler.setFormatter( multi_line_formatter_t( os.linesep + '%(levelname)s: %(message)s' ) ) logger.addHandler(__handler) logger.setLevel(logging.INFO) Modified: pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-07-24 15:50:36 UTC (rev 342) +++ pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-07-24 18:24:45 UTC (rev 343) @@ -32,8 +32,9 @@ self.split_internal_enums , self.split_internal_unnamed_enums , self.split_internal_member_functions - , self.split_internal_classes - , self.split_internal_member_variables + , self.split_internal_classes + #not supported yet + #, self.split_internal_member_variables ] def split_class_impl( self, class_creator): @@ -109,16 +110,17 @@ header_code.append( '' ) header_code.append( function_decl + ';' ) self.write_file( file_path + self.HEADER_EXT - , self.create_header( pattern, os.linesep.join(header_code) ) ) + , self.create_header( class_creator.alias + '_' + pattern + , os.linesep.join(header_code) ) ) #writting source file source_code = [] if self.extmodule.license: source_code.append( self.extmodule.license.create() ) - - head_headers = [ file_path + self.HEADER_EXT ]#relevant header file - tail_headers = [ self.wrapper_header(class_creator) ] - source_code.append( self.create_include_code( creators, head_headers, tail_headers ) ) + + #relevant header file + head_headers = [ os.path.join( class_creator.alias, pattern + self.HEADER_EXT) ] + source_code.append( self.create_include_code( creators, head_headers ) ) source_code.append( '' ) source_code.append( self.create_namespaces_code( creators ) ) @@ -154,6 +156,8 @@ def split_internal_member_functions( self, class_creator ): creators = filter( lambda x: isinstance(x, code_creators.mem_fun_t ) , class_creator.creators ) + for creator in creators: + creator.works_on_instance = False self.split_internal_creators( class_creator, creators, 'memfuns' ) return 'memfuns' Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-07-24 15:50:36 UTC (rev 342) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-07-24 18:24:45 UTC (rev 343) @@ -67,7 +67,7 @@ "#ifndef __%(file_name)s_hpp__pyplusplus_wrapper__" , "#define __%(file_name)s_hpp__pyplusplus_wrapper__" , '' - , "%(code)s;" + , "%(code)s" , '' , "#endif//__%(file_name)s_hpp__pyplusplus_wrapper__" ]) @@ -92,9 +92,11 @@ return self.create_value_traits_header_name( value_class ) def create_include_code( self, creators, head_headers=None, tail_headers=None ): - answer = [] + answer = [] + normalize = code_creators.include_directories_t.normalize if head_headers: - answer.extend( map( lambda header: '#include "%s"' % header, head_headers ) ) + answer.extend( map( lambda header: '#include "%s"' % normalize( header ) + , head_headers ) ) # Include all 'global' include files... includes = filter( lambda creator: isinstance( creator, code_creators.include_t ) @@ -107,7 +109,8 @@ answer.append( '#include "%s"' % header ) if tail_headers: - answer.extend( map( lambda header: '#include "%s"' % header, tail_headers ) ) + answer.extend( map( lambda header: '#include "%s"' % normalize( header ) + , tail_headers ) ) return os.linesep.join( answer ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-07-24 15:50:41
|
Revision: 342 Author: mbaas Date: 2006-07-24 08:50:36 -0700 (Mon, 24 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=342&view=rev Log Message: ----------- Make the multi line formatter class accessible via the pyplusplus package (if a user also wants to use that formatter for his own handler). Modified Paths: -------------- pyplusplus_dev/pyplusplus/__init__.py Modified: pyplusplus_dev/pyplusplus/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/__init__.py 2006-07-24 15:49:30 UTC (rev 341) +++ pyplusplus_dev/pyplusplus/__init__.py 2006-07-24 15:50:36 UTC (rev 342) @@ -32,6 +32,8 @@ import decl_wrappers import module_builder +from _logging_ import multi_line_formatter_t + __version__ = '0.7.1' #Known issues: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |