Thread: [pygccxml-commit] SF.net SVN: pygccxml: [15] pyplusplus_dev/pyplusplus
Brought to you by:
mbaas,
roman_yakovenko
From: <mb...@us...> - 2006-04-28 16:15:05
|
Revision: 15 Author: mbaas Date: 2006-04-28 09:14:47 -0700 (Fri, 28 Apr 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=15&view=rev Log Message: ----------- Added *.pyc to the ignore list Property Changed: ---------------- pyplusplus_dev/pyplusplus/ pyplusplus_dev/pyplusplus/_logging_/ pyplusplus_dev/pyplusplus/code_creators/ pyplusplus_dev/pyplusplus/code_repository/ pyplusplus_dev/pyplusplus/decl_wrappers/ pyplusplus_dev/pyplusplus/file_writers/ pyplusplus_dev/pyplusplus/gui/ pyplusplus_dev/pyplusplus/module_builder/ pyplusplus_dev/pyplusplus/module_creator/ pyplusplus_dev/pyplusplus/utils/ Property changes on: pyplusplus_dev/pyplusplus ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/_logging_ ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/code_creators ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/code_repository ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/decl_wrappers ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/file_writers ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/gui ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/module_builder ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/module_creator ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: pyplusplus_dev/pyplusplus/utils ___________________________________________________________________ Name: svn:ignore + *.pyc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-03 18:41:21
|
Revision: 511 http://svn.sourceforge.net/pygccxml/?rev=511&view=rev Author: roman_yakovenko Date: 2006-09-03 11:41:14 -0700 (Sun, 03 Sep 2006) Log Message: ----------- improving treatment of unrelevant files. Only files with ext .pypp.[h|c]pp will be removed Modified Paths: -------------- pyplusplus_dev/pyplusplus/file_writers/__init__.py pyplusplus_dev/pyplusplus/module_builder/builder.py Modified: pyplusplus_dev/pyplusplus/file_writers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/__init__.py 2006-09-03 11:37:31 UTC (rev 510) +++ pyplusplus_dev/pyplusplus/file_writers/__init__.py 2006-09-03 18:41:14 UTC (rev 511) @@ -22,6 +22,13 @@ from multiple_files import multiple_files_t from class_multiple_files import class_multiple_files_t +def has_pypp_extenstion( fname ): + """returns True if file has Py++ specific extension, otherwise False""" + for ext in ( multiple_files_t.HEADER_EXT, multiple_files_t.SOURCE_EXT ): + if fname.endswith( ext ): + return True + return False + def write_file( data, file_path ): """writes data to file""" if isinstance( data, types.StringTypes ): Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-09-03 11:37:31 UTC (rev 510) +++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-09-03 18:41:14 UTC (rev 511) @@ -313,9 +313,7 @@ all_files = os.listdir( dir_name ) all_files = map( lambda fname: os.path.join( dir_name, fname ), all_files ) - all_files = filter( lambda fname: os.path.isfile( fname ) \ - and os.path.splitext( fname )[1] in ( '.cpp', '.hpp' ) - , all_files ) + all_files = filter( file_writers.has_pypp_extenstion, all_files ) unused_files = set( all_files ).difference( set( written_files ) ) for fpath in unused_files: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-04 06:49:44
|
Revision: 516 http://svn.sourceforge.net/pygccxml/?rev=516&view=rev Author: roman_yakovenko Date: 2006-09-03 23:49:35 -0700 (Sun, 03 Sep 2006) Log Message: ----------- small refactoring before introducing "function transformation" functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-04 06:17:49 UTC (rev 515) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-04 06:49:35 UTC (rev 516) @@ -74,6 +74,9 @@ from calldef import copy_constructor_wrapper_t from calldef import null_constructor_wrapper_t +from calldef import mem_fun_v_transformed_t +from calldef import mem_fun_v_transformed_wrapper_t + from global_variable import global_variable_base_t from global_variable import global_variable_t from global_variable import array_gv_t @@ -116,3 +119,49 @@ from exception_translator import exception_translator_t from exception_translator import exception_translator_register_t +from pygccxml import declarations + +ACCESS_TYPES = declarations.ACCESS_TYPES +VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES + + +def guess_mem_fun_creator_classes( decl ): + """return tuple of ( registration, declaration ) code creator classes""" + maker_cls = None + fwrapper_cls = None + access_level = decl.parent.find_out_member_access_type( decl ) + if access_level == ACCESS_TYPES.PUBLIC: + if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + maker_cls = mem_fun_t + elif decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: + fwrapper_cls = mem_fun_pv_wrapper_t + maker_cls = mem_fun_pv_t + else: + if decl.overridable: + fwrapper_cls = mem_fun_v_wrapper_t + maker_cls = mem_fun_v_t + elif access_level == ACCESS_TYPES.PROTECTED: + if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + if decl.has_static: + fwrapper_cls = mem_fun_protected_s_wrapper_t + maker_cls = mem_fun_protected_s_t + else: + fwrapper_cls = mem_fun_protected_wrapper_t + maker_cls = mem_fun_protected_t + elif decl.virtuality == VIRTUALITY_TYPES.VIRTUAL: + if decl.overridable: + fwrapper_cls = mem_fun_protected_v_wrapper_t + maker_cls = mem_fun_protected_v_t + else: + fwrapper_cls = mem_fun_protected_pv_wrapper_t + maker_cls = mem_fun_protected_pv_t + else: #private + if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + pass#in general we should not come here + elif decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: + fwrapper_cls = mem_fun_private_pv_wrapper_t + else: + if decl.overridable: + fwrapper_cls = mem_fun_v_wrapper_t + maker_cls = mem_fun_v_t + return ( maker_cls, fwrapper_cls ) Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-04 06:17:49 UTC (rev 515) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-04 06:49:35 UTC (rev 516) @@ -439,7 +439,130 @@ answer.append( self.create_default_function() ) return os.linesep.join( answer ) +class mem_fun_v_transformed_t( calldef_t ): + def __init__( self, function, wrapper=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper ) + self.default_function_type_alias = 'default_' + self.function_type_alias + def create_function_type_alias_code( self, exported_class_alias=None ): + result = [] + + ftype = self.declaration.function_type() + result.append( 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) ) + if self.wrapper: + result.append( os.linesep ) + ftype = self.wrapper.function_type() + result.append( 'typedef %s;' % ftype.create_typedef( self.default_function_type_alias ) ) + return ''.join( result ) + + def create_doc(self): + return None + + def create_function_ref_code(self, use_function_alias=False): + result = [] + if use_function_alias: + result.append( '%s(&%s)' + % ( self.function_type_alias, declarations.full_name( self.declaration ) ) ) + if self.wrapper: + result.append( self.param_sep() ) + result.append( '%s(&%s)' + % ( self.default_function_type_alias, self.wrapper.default_full_name() ) ) + elif self.declaration.create_with_signature: + result.append( '(%s)(&%s)' + % ( self.declaration.function_type().decl_string + , declarations.full_name( self.declaration ) ) ) + if self.wrapper: + result.append( self.param_sep() ) + result.append( '(%s)(&%s)' + % ( self.wrapper.function_type().decl_string, self.wrapper.default_full_name() ) ) + else: + result.append( '&%s'% declarations.full_name( self.declaration ) ) + if self.wrapper: + result.append( self.param_sep() ) + result.append( '&%s' % self.wrapper.default_full_name() ) + return ''.join( result ) + +class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): + def __init__( self, function ): + calldef_wrapper_t.__init__( self, function=function ) + + def default_full_name(self): + return self.parent.full_name + '::default_' + self.declaration.alias + + def function_type(self): + return declarations.member_function_type_t( + return_type=self.declaration.return_type + , class_inst=declarations.dummy_type_t( self.parent.full_name ) + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) + , has_const=self.declaration.has_const ) + + def create_declaration(self, name, has_virtual=True): + template = '%(virtual)s%(return_type)s %(name)s( %(args)s )%(constness)s %(throw)s' + + virtual = 'virtual ' + if not has_virtual: + virtual = '' + + constness = '' + if self.declaration.has_const: + constness = ' const ' + + return template % { + 'virtual' : virtual + , 'return_type' : self.declaration.return_type.decl_string + , 'name' : name + , 'args' : self.args_declaration() + , 'constness' : constness + , 'throw' : self.throw_specifier_code() + } + + def create_virtual_body(self): + template = [] + template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' ) + template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') ) + template.append( 'else' ) + template.append( self.indent('%(return_)s%(wrapped_class)s::%(name)s( %(args)s );') ) + template = os.linesep.join( template ) + + return_ = '' + if not declarations.is_void( self.declaration.return_type ): + return_ = 'return ' + + return template % { + 'override' : self.override_identifier() + , 'name' : self.declaration.name + , 'alias' : self.declaration.alias + , 'return_' : return_ + , 'args' : self.function_call_args() + , 'wrapped_class' : self.wrapped_class_identifier() + } + + def create_default_body(self): + function_call = declarations.call_invocation.join( self.declaration.name + , [ self.function_call_args() ] ) + body = self.wrapped_class_identifier() + '::' + function_call + ';' + if not declarations.is_void( self.declaration.return_type ): + body = 'return ' + body + return body + + def create_function(self): + answer = [ self.create_declaration(self.declaration.name) + '{' ] + answer.append( self.indent( self.create_virtual_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def create_default_function( self ): + answer = [ self.create_declaration('default_' + self.declaration.alias, False) + '{' ] + answer.append( self.indent( self.create_default_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def _create_impl(self): + answer = [ self.create_function() ] + answer.append( os.linesep ) + answer.append( self.create_default_function() ) + return os.linesep.join( answer ) + class mem_fun_protected_t( calldef_t ): def __init__( self, function, wrapper ): calldef_t.__init__( self, function=function, wrapper=wrapper ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-04 06:17:49 UTC (rev 515) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-04 06:49:35 UTC (rev 516) @@ -568,53 +568,13 @@ include = code_creators.include_t( header=fn ) self.__extmodule.adopt_include(include) - def guess_functions_code_creators( self ): - maker_cls = None - fwrapper_cls = None - access_level = self.curr_decl.parent.find_out_member_access_type( self.curr_decl ) - if access_level == ACCESS_TYPES.PUBLIC: - if self.curr_decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - maker_cls = code_creators.mem_fun_t - elif self.curr_decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: - fwrapper_cls = code_creators.mem_fun_pv_wrapper_t - maker_cls = code_creators.mem_fun_pv_t - else: - if self.curr_decl.overridable: - fwrapper_cls = code_creators.mem_fun_v_wrapper_t - maker_cls = code_creators.mem_fun_v_t - elif access_level == ACCESS_TYPES.PROTECTED: - if self.curr_decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - if self.curr_decl.has_static: - fwrapper_cls = code_creators.mem_fun_protected_s_wrapper_t - maker_cls = code_creators.mem_fun_protected_s_t - else: - fwrapper_cls = code_creators.mem_fun_protected_wrapper_t - maker_cls = code_creators.mem_fun_protected_t - elif self.curr_decl.virtuality == VIRTUALITY_TYPES.VIRTUAL: - if self.curr_decl.overridable: - fwrapper_cls = code_creators.mem_fun_protected_v_wrapper_t - maker_cls = code_creators.mem_fun_protected_v_t - else: - fwrapper_cls = code_creators.mem_fun_protected_pv_wrapper_t - maker_cls = code_creators.mem_fun_protected_pv_t - else: #private - if self.curr_decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - pass#in general we should not come here - elif self.curr_decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: - fwrapper_cls = code_creators.mem_fun_private_pv_wrapper_t - else: - if self.curr_decl.overridable: - fwrapper_cls = code_creators.mem_fun_v_wrapper_t - maker_cls = code_creators.mem_fun_v_t - return ( maker_cls, fwrapper_cls ) - def visit_member_function( self ): fwrapper = None self.__types_db.update( self.curr_decl ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - maker_cls, fwrapper_cls = self.guess_functions_code_creators() + maker_cls, fwrapper_cls = code_creators.guess_mem_fun_creator_classes( self.curr_decl ) maker = None fwrapper = None @@ -678,7 +638,7 @@ and not self.curr_decl.has_const: #TODO: move this code to decl_wrappers return #only const casting operators can generate implicitly_convertible - + if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-04 07:03:26
|
Revision: 517 http://svn.sourceforge.net/pygccxml/?rev=517&view=rev Author: roman_yakovenko Date: 2006-09-04 00:03:18 -0700 (Mon, 04 Sep 2006) Log Message: ----------- splittingsmall refactoring before introducing "function transformation" functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-04 06:49:35 UTC (rev 516) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-04 07:03:18 UTC (rev 517) @@ -137,9 +137,13 @@ fwrapper_cls = mem_fun_pv_wrapper_t maker_cls = mem_fun_pv_t else: - if decl.overridable: - fwrapper_cls = mem_fun_v_wrapper_t - maker_cls = mem_fun_v_t + if decl.function_transformers: + fwrapper_cls = mem_fun_v_transformed_wrapper_t + maker_cls = mem_fun_v_transformed_t + else: + if decl.overridable: + fwrapper_cls = mem_fun_v_wrapper_t + maker_cls = mem_fun_v_t elif access_level == ACCESS_TYPES.PROTECTED: if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: if decl.has_static: Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-09-04 06:49:35 UTC (rev 516) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-09-04 07:03:18 UTC (rev 517) @@ -28,7 +28,7 @@ self._use_default_arguments = True self._create_with_signature = False self._overridable = None - self._function_transformers = [] + self._function_transformers = None def get_call_policies(self): return self._call_policies @@ -121,12 +121,16 @@ Returns a reference to the internal list (which may be modified). """ + if None is self._function_transformers: + #TODO: for trivial cases get_size( int&, int& ) Py++ should guess + #function transformers + self._function_transformers = [] return self._function_transformers - + def _set_function_transformers(self, function_transformers): """Set method for property 'function_transformers'.""" self._function_transformers = function_transformers - + function_transformers = property( _get_function_transformers, _set_function_transformers, doc = """A list of function transformer objects that should be applied to the generated C++ code (default: []). The returned list is the internal list (not a copy) which may be modified. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-13 11:08:29
|
Revision: 538 http://svn.sourceforge.net/pygccxml/?rev=538&view=rev Author: roman_yakovenko Date: 2006-09-13 04:08:13 -0700 (Wed, 13 Sep 2006) Log Message: ----------- preventing default_call_policies to be generated Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/array_1_registrator.py pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/code_creators/global_variable.py pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py pyplusplus_dev/pyplusplus/code_creators/member_variable.py pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py Modified: pyplusplus_dev/pyplusplus/code_creators/array_1_registrator.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/array_1_registrator.py 2006-09-13 09:24:37 UTC (rev 537) +++ pyplusplus_dev/pyplusplus/code_creators/array_1_registrator.py 2006-09-13 11:08:13 UTC (rev 538) @@ -21,7 +21,7 @@ self._array_type = array_type self._call_policies = self._guess_call_policies() self.works_on_instance = False - + def _get_array_type( self ): return self._array_type def _set_array_type( self, new_array_type ): @@ -37,8 +37,8 @@ def _create_name( self ): item_type = declarations.array_item_type(self.array_type) return "__array_1_%(type)s_%(size)d" \ - % dict( type=algorithm.create_valid_name( item_type.decl_string ) - , size=declarations.array_size(self.array_type) ) + % dict( type=algorithm.create_valid_name( item_type.decl_string ) + , size=declarations.array_size(self.array_type) ) def _guess_call_policies(self): item_type = declarations.array_item_type( self.array_type ) @@ -55,8 +55,10 @@ fn_name = 'register_const_array_1' else: fn_name = 'register_array_1' - fn_def = templates.join( '::'.join( [ns_name, fn_name] ) - , [ declarations.array_item_type(self.array_type).decl_string - , str( declarations.array_size(self.array_type) ) - , self.call_policies.create(self, call_policies.CREATION_POLICY.AS_TEMPLATE_ARGUMENT )]) - return call_invocation.join( fn_def, [ '"%s"' % self._create_name() ] ) + ';' \ No newline at end of file + + fn_def_tmpl_args = [ declarations.array_item_type(self.array_type).decl_string + , str( declarations.array_size(self.array_type) ) + , self.call_policies.create(self, call_policies.CREATION_POLICY.AS_TEMPLATE_ARGUMENT )] + + fn_def = templates.join( '::'.join( [ns_name, fn_name] ), fn_def_tmpl_args ) + return call_invocation.join( fn_def, [ '"%s"' % self._create_name() ] ) + ';' Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-13 09:24:37 UTC (rev 537) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-13 11:08:13 UTC (rev 538) @@ -9,7 +9,7 @@ import declaration_based import class_declaration from pygccxml import declarations -from pyplusplus.decl_wrappers import python_traits +from pyplusplus import decl_wrappers import pyplusplus.function_transformers as function_transformers #virtual functions that returns const reference to something @@ -120,8 +120,11 @@ result.append( self.keywords_args() ) if self.declaration.call_policies: - result.append( self.param_sep() ) - result.append( self.declaration.call_policies.create( self ) ) + if not self.declaration.call_policies.is_default(): + result.append( self.param_sep() ) + result.append( self.declaration.call_policies.create( self ) ) + else: + pass#don't generate default_call_policies else: result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) @@ -175,11 +178,11 @@ params = [] for index in range( len( self.declaration.arguments ) ): arg_type = declarations.remove_alias( self.declaration.arguments[index].type ) - if python_traits.is_immutable( arg_type ): + if decl_wrappers.python_traits.is_immutable( arg_type ): params.append( self.argument_name( index ) ) elif declarations.is_reference( arg_type ): no_ref = declarations.remove_reference( arg_type ) - if python_traits.is_immutable( no_ref ): + if decl_wrappers.python_traits.is_immutable( no_ref ): #pass by value params.append( self.argument_name( index ) ) else: @@ -187,7 +190,7 @@ params.append( 'boost::ref(%s)' % self.argument_name( index ) ) elif declarations.is_pointer( arg_type ) \ and not declarations.is_pointer( arg_type.base ) \ - and not python_traits.is_immutable( arg_type.base ): + and not decl_wrappers.python_traits.is_immutable( arg_type.base ): params.append( 'boost::python::ptr(%s)' % self.argument_name( index ) ) else: params.append( self.argument_name( index ) ) @@ -1130,11 +1133,8 @@ answer.append( ', ' ) answer.append( self.documentation ) answer.append( ')' ) - if self.declaration.call_policies: + if self.declaration.call_policies and not self.declaration.call_policies.is_default(): answer.append('[%s]' % self.declaration.call_policies.create( self ) ) - #I think it better not to print next line - #else: - # answer.append( '/*[ undefined call policies ]*/' ) return ''.join( answer ) def _create_impl( self ): @@ -1369,7 +1369,6 @@ def __init__( self, operator ): declaration_based.declaration_based_t.__init__( self, declaration=operator ) - self._call_policies = None def _create_impl(self): template = 'def( "%(function_name)s", &%(class_name)s::operator %(destination_type)s %(call_policies)s%(doc)s )' @@ -1377,9 +1376,12 @@ class_name = algorithm.create_identifier( self , declarations.full_name( self.declaration.parent ) ) - policies = '/*, undefined call policies */' + policies = '' if self.declaration.call_policies: - policies = ',' + self.declaration.call_policies.create( self ) + if not self.declaration.call_policies.is_default(): + policies = ',' + self.declaration.call_policies.create( self ) + else: + policies = '/*, undefined call policies */' doc = '' if self.documentation: @@ -1537,7 +1539,8 @@ result.append( os.linesep + self.indent( self.PARAM_SEPARATOR, 3 ) ) result.append( self.overloads_class.max_function.documentation ) result.append( ' )' ) - if self.overloads_class.max_function.call_policies: + if self.overloads_class.max_function.call_policies \ + and not self.overloads_class.max_function.call_policies.is_default(): result.append( os.linesep + self.indent('', 3) ) result.append('[ %s ]' % self.overloads_class.max_function.call_policies.create( self ) ) return ''.join( result ) Modified: pyplusplus_dev/pyplusplus/code_creators/global_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2006-09-13 09:24:37 UTC (rev 537) +++ pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2006-09-13 11:08:13 UTC (rev 538) @@ -9,31 +9,30 @@ import declaration_based from pygccxml import declarations from pyplusplus import code_repository -from pyplusplus.decl_wrappers import call_policies #TODO: if variable is not const, then export it using boost::python::ptr class global_variable_base_t( declaration_based.declaration_based_t ): """ - Base class for all global variables code creators. Mainly exists to + Base class for all global variables code creators. Mainly exists to simplify file writers algorithms. """ def __init__(self, variable, wrapper=None ): declaration_based.declaration_based_t.__init__( self, declaration=variable) - self._wrapper = wrapper + self._wrapper = wrapper def _get_wrapper( self ): return self._wrapper def _set_wrapper( self, new_wrapper ): self._wrapper = new_wrapper wrapper = property( _get_wrapper, _set_wrapper ) - + class global_variable_t( global_variable_base_t ): """ Creates boost.python code that exposes global variable. """ def __init__(self, variable ): global_variable_base_t.__init__( self, variable=variable ) - + def _create_impl(self): assert isinstance( self.declaration, pygccxml.declarations.variable_t ) result = [] @@ -42,7 +41,7 @@ full_name = pygccxml.declarations.full_name( self.declaration ) result.append( ' = %s;' % algorithm.create_identifier( self, full_name ) ) return ''.join( result ) - + class array_gv_t( global_variable_base_t ): """ Creates boost.python code that exposes array global variable. @@ -51,7 +50,7 @@ _PARAM_SEPARATOR = ', ' def __init__(self, variable, wrapper ): global_variable_base_t.__init__( self, variable=variable, wrapper=wrapper ) - + def _create_impl( self ): answer = [] answer.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) @@ -60,7 +59,7 @@ answer.append( self.wrapper.wrapper_creator_full_name ) answer.append( '();' ) return ''.join( answer ) - + class array_gv_wrapper_t( declaration_based.declaration_based_t ): """ Creates C++ code that register array class. @@ -75,22 +74,22 @@ class_name = 'const_array_1_t' else: class_name = 'array_1_t' - - decl_string = declarations.templates.join( + + decl_string = declarations.templates.join( '::'.join( [ns_name, class_name] ) , [ declarations.array_item_type( self.declaration.type ).decl_string , str( declarations.array_size( self.declaration.type ) ) ]) - + return declarations.dummy_type_t( decl_string ) wrapper_type = property( _get_wrapper_type ) - + def _get_wrapper_creator_type(self): return declarations.free_function_type_t.create_decl_string( return_type=self.wrapper_type , arguments_types=[] ) wrapper_creator_type = property( _get_wrapper_creator_type ) - + def _get_wrapper_creator_name(self): return '_'.join( [self.declaration.name, 'wrapper'] ) wrapper_creator_name = property( _get_wrapper_creator_name ) @@ -100,7 +99,7 @@ if len(ns_names) > 1 and ns_names[0] == '::': ns_names = ns_names[1:] return ns_names - + def _get_wrapper_creator_full_name(self): names = self._create_namespaces() names.append( self.wrapper_creator_name ) @@ -112,7 +111,7 @@ for ns_name in self._create_namespaces(): temp.append( ''.join( ['namespace ', ns_name, '{ '] ) ) return ''.join( temp ) - + def _create_impl( self ): answer = [self._create_namespaces_name()] answer.append( self.wrapper_type.decl_string ) @@ -126,4 +125,3 @@ answer.append('}') answer.append( '}' * len( self._create_namespaces() ) ) return os.linesep.join( answer ) - \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py 2006-09-13 09:24:37 UTC (rev 537) +++ pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py 2006-09-13 11:08:13 UTC (rev 538) @@ -5,21 +5,21 @@ import os import types -import algorithm +import algorithm import code_creator import declaration_based from pygccxml import declarations class indexing_suite1_t( declaration_based.declaration_based_t ): - def __init__(self, container ): + def __init__(self, container ): declaration_based.declaration_based_t.__init__( self, declaration=container ) - + def _get_configuration( self ): return self.declaration.indexing_suite configuration = property( _get_configuration ) def _get_container( self ): - return self.declaration + return self.declaration container = property( _get_container ) def guess_suite_name( self ): @@ -40,19 +40,19 @@ args.append( self.configuration.derived_policies ) else: if 'true' == no_proxy: - args.append( no_proxy) - return declarations.templates.join( suite_identifier, args ) + args.append( no_proxy) + return declarations.templates.join( suite_identifier, args ) def _create_impl(self): return "def( %s() )" % self._create_suite_declaration() - + class indexing_suite2_t( declaration_based.declaration_based_t ): - def __init__(self, container ): + def __init__(self, container ): declaration_based.declaration_based_t.__init__( self, declaration=container ) self.__method_mask_var_name = "methods_mask" self.works_on_instance = not self.does_user_disable_methods() - + def does_user_disable_methods( self ): return bool( self.declaration.indexing_suite.disabled_methods_groups ) \ or bool( self.declaration.indexing_suite.disable_methods ) @@ -76,7 +76,7 @@ answer.append( ' ) ' ) answer.append( ';' ) return ''.join( answer ) - + def _create_impl( self ): answer = [] if self.does_user_disable_methods(): @@ -93,8 +93,9 @@ answer.append( self.PARAM_SEPARATOR ) answer.append( self.__method_mask_var_name ) answer.append( ' >' ) - if self.declaration.indexing_suite.call_policies: - answer.append( '::with_policies(%s)' + if self.declaration.indexing_suite.call_policies \ + and not self.declaration.indexing_suite.call_policies.is_default(): + answer.append( '::with_policies(%s)' % self.declaration.indexing_suite.call_policies.create( self ) ) else: answer.append( '()' ) @@ -121,7 +122,7 @@ , self.indent( "%(less)s" ) , "" , self.indent( "template<typename PythonClass, typename Policy>" ) - , self.indent( "static void visit_container_class(PythonClass &, Policy const &){" ) + , self.indent( "static void visit_container_class(PythonClass &, Policy const &){" ) , self.indent( "%(visitor_helper_body)s", 2 ) , self.indent( "}" ) , "" @@ -147,7 +148,7 @@ def generate_value_class_fwd_declaration( self ): pass # for inner class this code will generate error :-(((( - + def _create_impl( self ): return self.generate_value_traits() Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-09-13 09:24:37 UTC (rev 537) +++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-09-13 11:08:13 UTC (rev 538) @@ -13,20 +13,20 @@ class member_variable_base_t( declaration_based.declaration_based_t ): """ - Base class for all member variables code creators. Mainly exists to + Base class for all member variables code creators. Mainly exists to simplify file writers algorithms. """ def __init__(self, variable, wrapper=None ): declaration_based.declaration_based_t.__init__( self, declaration=variable) - self._wrapper = wrapper + self._wrapper = wrapper def _get_wrapper( self ): return self._wrapper def _set_wrapper( self, new_wrapper ): self._wrapper = new_wrapper wrapper = property( _get_wrapper, _set_wrapper ) - + class member_variable_t( member_variable_base_t ): """ Creates boost.python code that exposes member variable. @@ -36,7 +36,7 @@ #> On Wednesday, 19. April 2006 23:05, Ralf W. Grosse-Kunstleve wrote: #> .add_property("p", make_function(&A::get_p, return_value_policy<reference_existing_object>())) - def _generate_for_pointer( self ): + def _generate_for_pointer( self ): doc = '' #static property does not support documentation if self.declaration.type_qualifiers.has_static: add_property = 'add_static_property' @@ -48,11 +48,11 @@ answer.append( '( ' ) answer.append('"%s"' % self.alias) answer.append( self.PARAM_SEPARATOR ) - + call_pol = call_policies.return_value_policy( call_policies.reference_existing_object ).create( self ) make_function = algorithm.create_identifier( self, '::boost::python::make_function' ) - answer.append( '%(mk_func)s( (%(getter_type)s)(&%(wfname)s), %(call_pol)s )' + answer.append( '%(mk_func)s( (%(getter_type)s)(&%(wfname)s), %(call_pol)s )' % { 'mk_func' : make_function , 'getter_type' : self.wrapper.getter_type , 'wfname' : self.wrapper.getter_full_name @@ -61,11 +61,10 @@ #don't generate setter method, right now I don't know how to do it. if False and self.wrapper.has_setter: answer.append( self.PARAM_SEPARATOR ) - if self.declaration.type_qualifiers.has_static: - call_pol = call_policies.default_call_policies().create(self) - else: - call_pol = call_policies.with_custodian_and_ward_postcall( 0, 1 ).create(self) - answer.append( '%(mk_func)s( (%(setter_type)s)(&%(wfname)s), %(call_pol)s )' + call_pol = '' + if not self.declaration.type_qualifiers.has_static: + call_pol = ", " + call_policies.with_custodian_and_ward_postcall( 0, 1 ).crate(self) + answer.append( '%(mk_func)s( (%(setter_type)s)(&%(wfname)s)%(call_pol)s )' % { 'mk_func' : make_function , 'setter_type' : self.wrapper.setter_type , 'wfname' : self.wrapper.setter_full_name @@ -74,7 +73,7 @@ answer.append( self.PARAM_SEPARATOR ) answer.append( doc ) answer.append( ' ) ' ) - + code = ''.join( answer ) if len( code ) <= self.LINE_LENGTH: return code @@ -82,27 +81,27 @@ for i in range( len( answer ) ): if answer[i] == self.PARAM_SEPARATOR: answer[i] = os.linesep + self.indent( self.indent( self.indent( answer[i] ) ) ) - return ''.join( answer ) - + return ''.join( answer ) + def _generate_for_none_pointer( self ): tmpl = None if self.declaration.type_qualifiers.has_static: - tmpl = '%(access)s( "%(alias)s", %(name)s%(doc)s )' + tmpl = '%(access)s( "%(alias)s", %(name)s%(doc)s )' else: tmpl = '%(access)s( "%(alias)s", &%(name)s%(doc)s )' - + access = 'def_readwrite' if self.is_read_only(): access = 'def_readonly' doc = '' if self.documentation: - doc = ', %s' % self.documentation - result = tmpl % { + doc = ', %s' % self.documentation + result = tmpl % { 'access' : access , 'alias' : self.alias , 'name' : algorithm.create_identifier( self, self.declaration.decl_string ) , 'doc' : doc } - + return result def is_read_only( self ): @@ -110,13 +109,13 @@ if declarations.is_pointer( type_ ): type_ = declarations.remove_pointer( type_ ) return isinstance( type_, declarations.const_t ) - + if declarations.is_reference( type_ ): - type_ = declarations.remove_reference( type_ ) + type_ = declarations.remove_reference( type_ ) if isinstance( type_, declarations.const_t ): return True - + if isinstance( type_, declarations.declarated_t ) \ and isinstance( type_.declaration, declarations.class_t ) \ and not declarations.has_public_assign( type_.declaration ): @@ -142,29 +141,29 @@ MV_GET_TEMPLATE = os.linesep.join([ 'static %(type)s get_%(name)s(%(cls_type)s inst ){' , indent( 'return inst.%(name)s;' ) - , '}' + , '}' , '' ]) MV_STATIC_GET_TEMPLATE = os.linesep.join([ 'static %(type)s get_%(name)s(){' , indent( 'return %(cls_type)s::%(name)s;' ) - , '}' + , '}' , '' ]) MV_SET_TEMPLATE = os.linesep.join([ 'static void set_%(name)s( %(cls_type)s inst, %(type)s new_value ){ ' , indent( 'inst.%(name)s = new_value;' ) - , '}' - , '' + , '}' + , '' ]) MV_STATIC_SET_TEMPLATE = os.linesep.join([ 'static void set_%(name)s( %(type)s new_value ){ ' , indent( '%(cls_type)s::%(name)s = new_value;' ) - , '}' - , '' + , '}' + , '' ]) def __init__(self, variable ): @@ -180,28 +179,28 @@ inst_arg_type = declarations.const_t(inst_arg_type) inst_arg_type = declarations.reference_t(inst_arg_type) return inst_arg_type - + def _get_getter_type(self): if self.declaration.type_qualifiers.has_static: - arguments_types=[] + arguments_types=[] else: - arguments_types=[ self.inst_arg_type(True) ] - + arguments_types=[ self.inst_arg_type(True) ] + return declarations.free_function_type_t.create_decl_string( return_type=self.declaration.type , arguments_types=arguments_types ) getter_type = property( _get_getter_type ) - + def _get_setter_full_name(self): return self.parent.full_name + '::' + 'set_' + self.declaration.name setter_full_name = property(_get_setter_full_name) - + def _get_setter_type(self): if self.declaration.type_qualifiers.has_static: - arguments_types=[ self.declaration.type ] + arguments_types=[ self.declaration.type ] else: - arguments_types=[ self.inst_arg_type(False), self.declaration.type ] - + arguments_types=[ self.inst_arg_type(False), self.declaration.type ] + return declarations.free_function_type_t.create_decl_string( return_type=declarations.void_t() , arguments_types=arguments_types ) @@ -210,14 +209,14 @@ def _get_has_setter( self ): return not declarations.is_const( self.declaration.type ) has_setter = property( _get_has_setter ) - + def _create_impl(self): answer = [] if self.declaration.type_qualifiers.has_static: substitutions = { 'type' : self.declaration.type.decl_string , 'name' : self.declaration.name - , 'cls_type' : declarations.full_name( self.declaration.parent ) + , 'cls_type' : declarations.full_name( self.declaration.parent ) } answer.append( self.MV_STATIC_GET_TEMPLATE % substitutions) if self.has_setter: @@ -253,18 +252,18 @@ answer.append( '( ' ) answer.append('"%s"' % self.alias) answer.append( self.PARAM_SEPARATOR ) - answer.append( '(%s)(&%s)' + answer.append( '(%s)(&%s)' % ( self.wrapper.getter_type, self.wrapper.getter_full_name ) ) if self.wrapper.has_setter: answer.append( self.PARAM_SEPARATOR ) - answer.append( '(%s)(&%s)' + answer.append( '(%s)(&%s)' % ( self.wrapper.setter_type, self.wrapper.setter_full_name ) ) if doc: answer.append( self.PARAM_SEPARATOR ) answer.append( doc ) answer.append( ' ) ' ) - + code = ''.join( answer ) if len( code ) <= self.LINE_LENGTH: return code @@ -283,15 +282,15 @@ BF_GET_TEMPLATE = os.linesep.join([ '%(type)s get_%(name)s() const {' , indent( 'return %(name)s;' ) - , '}' + , '}' , '' ]) - + BF_SET_TEMPLATE = os.linesep.join([ 'void set_%(name)s( %(type)s new_value ){ ' , indent( '%(name)s = new_value;' ) - , '}' - , '' + , '}' + , '' ]) def __init__(self, variable ): @@ -300,7 +299,7 @@ def _get_getter_full_name(self): return self.parent.full_name + '::' + 'get_' + self.declaration.name getter_full_name = property( _get_getter_full_name ) - + def _get_getter_type(self): return declarations.member_function_type_t.create_decl_string( return_type=self.declaration.type @@ -308,11 +307,11 @@ , arguments_types=[] , has_const=True ) getter_type = property( _get_getter_type ) - + def _get_setter_full_name(self): return self.parent.full_name + '::' + 'set_' + self.declaration.name setter_full_name = property(_get_setter_full_name) - + def _get_setter_type(self): return declarations.member_function_type_t.create_decl_string( return_type=declarations.void_t() @@ -324,11 +323,11 @@ def _get_has_setter( self ): return not declarations.is_const( self.declaration.type ) has_setter = property( _get_has_setter ) - + def _create_impl(self): answer = [] substitutions = dict( type=self.declaration.type.decl_string - , name=self.declaration.name ) + , name=self.declaration.name ) answer.append( self.BF_GET_TEMPLATE % substitutions ) if self.has_setter: answer.append( self.BF_SET_TEMPLATE % substitutions ) @@ -340,7 +339,7 @@ """ def __init__(self, variable, wrapper ): member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper ) - + def _create_impl( self ): assert isinstance( self.wrapper, array_mv_wrapper_t ) doc = '' @@ -355,7 +354,7 @@ answer.append( os.linesep + self.indent( self.PARAM_SEPARATOR ) ) temp = [ algorithm.create_identifier( self, "::boost::python::make_function" ) ] temp.append( '( ' ) - temp.append( '(%s)(&%s)' + temp.append( '(%s)(&%s)' % ( self.wrapper.wrapper_creator_type , self.wrapper.wrapper_creator_full_name ) ) if not self.declaration.type_qualifiers.has_static: @@ -366,16 +365,16 @@ if doc: answer.append( self.PARAM_SEPARATOR ) answer.append( doc ) - answer.append( ' );' ) + answer.append( ' );' ) return ''.join( answer ) - + #TODO: generated fucntion should be static and take instance of the wrapped class #as first argument. class array_mv_wrapper_t( declaration_based.declaration_based_t ): """ Creates C++ code that register array class. """ - + def __init__(self, variable ): declaration_based.declaration_based_t.__init__( self, declaration=variable) @@ -385,16 +384,16 @@ class_name = 'const_array_1_t' else: class_name = 'array_1_t' - - decl_string = declarations.templates.join( + + decl_string = declarations.templates.join( '::'.join( [ns_name, class_name] ) , [ declarations.array_item_type( self.declaration.type ).decl_string , str( declarations.array_size( self.declaration.type ) ) ]) - + return declarations.dummy_type_t( decl_string ) wrapper_type = property( _get_wrapper_type ) - + def _get_wrapper_creator_type(self): return declarations.member_function_type_t.create_decl_string( return_type=self.wrapper_type @@ -402,7 +401,7 @@ , arguments_types=[] , has_const=False ) wrapper_creator_type = property( _get_wrapper_creator_type ) - + def _get_wrapper_creator_name(self): return '_'.join( ['pyplusplus', self.declaration.name, 'wrapper'] ) wrapper_creator_name = property( _get_wrapper_creator_name ) @@ -417,13 +416,13 @@ temp = ''.join([ 'return ' , self.wrapper_type.decl_string , '( ' - , self.declaration.name + , self.declaration.name , ' );']) answer.append( self.indent( temp ) ) answer.append('}') return os.linesep.join( answer ) - + class mem_var_ref_t( member_variable_base_t ): """ Creates C++ code that creates accessor for class member variable, that has type reference. @@ -438,34 +437,36 @@ answer.append( '( ' ) answer.append( '"get_%s"' % self.alias) answer.append( self.param_sep ) - answer.append( '(%s)(&%s)' + answer.append( '(%s)(&%s)' % ( self.wrapper.getter_type.decl_string, self.wrapper.getter_full_name ) ) if self.declaration.getter_call_policies: - answer.append( self.param_sep ) - answer.append( self.declaration.getter_call_policies.create( self ) ) + if not self.declaration.getter_call_policies.is_default(): + answer.append( self.param_sep ) + answer.append( self.declaration.getter_call_policies.create( self ) ) else: - answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) if self.documentation: answer.append( self.param_sep ) answer.append( self.documentation ) answer.append( ' )' ) return ''.join( answer ) - + def _create_setter( self ): answer = ['def'] answer.append( '( ' ) answer.append( '"set_%s"' % self.alias) answer.append( self.param_sep ) - answer.append( '(%s)(&%s)' + answer.append( '(%s)(&%s)' % ( self.wrapper.setter_type.decl_string, self.wrapper.setter_full_name ) ) if self.declaration.setter_call_policies: - answer.append( self.param_sep ) - answer.append( self.declaration.setter_call_policies.create( self ) ) + if not self.declaration.setter_call_policies.is_default(): + answer.append( self.param_sep ) + answer.append( self.declaration.setter_call_policies.create( self ) ) else: - answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) + answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) ) answer.append( ' )' ) return ''.join( answer ) - + def _create_impl( self ): #TODO: fix me, should not force class scope usage answer = [] @@ -475,25 +476,25 @@ answer.append( os.linesep ) answer.append( "%s.%s;" % (class_var_name, self._create_setter() ) ) return ''.join( answer ) - + class mem_var_ref_wrapper_t( declaration_based.declaration_based_t ): """ Creates C++ code that creates accessor for class member variable, that has type reference. """ - + indent = declaration_based.declaration_based_t.indent GET_TEMPLATE = os.linesep.join([ 'static %(type)s get_%(name)s( %(class_type)s& inst ) {' , indent( 'return inst.%(name)s;' ) - , '}' + , '}' , '' ]) - + SET_TEMPLATE = os.linesep.join([ 'static void set_%(name)s( %(class_type)s& inst, %(type)s new_value ){ ' , indent( 'inst.%(name)s = new_value;' ) - , '}' - , '' + , '}' + , '' ]) def __init__(self, variable ): @@ -519,11 +520,11 @@ return_type=self._get_exported_var_type() , arguments_types=[ declarations.reference_t( self._get_class_inst_type() ) ] ) getter_type = property( _get_getter_type ) - + def _get_setter_full_name(self): return self.parent.full_name + '::' + 'set_' + self.declaration.name setter_full_name = property(_get_setter_full_name) - + def _get_setter_type(self): return declarations.free_function_type_t( return_type=declarations.void_t() @@ -531,37 +532,37 @@ , self._get_exported_var_type() ] ) setter_type = property( _get_setter_type ) - def _get_has_setter( self ): + def _get_has_setter( self ): if declarations.is_const( declarations.remove_reference( self.declaration.type ) ): return False elif python_traits.is_immutable( self._get_exported_var_type() ): return True else: pass - + no_ref = declarations.remove_reference( self.declaration.type ) - no_const = declarations.remove_const( no_ref ) + no_const = declarations.remove_const( no_ref ) base_type = declarations.remove_alias( no_const ) if not isinstance( base_type, declarations.declarated_t ): return True #TODO ???? decl = base_type.declaration if decl.is_abstract: return False - if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ): + if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ): return False if not declarations.has_trivial_copy(decl): return False return True has_setter = property( _get_has_setter ) - + def _create_impl(self): answer = [] cls_type = algorithm.create_identifier( self, self.declaration.parent.decl_string ) - + substitutions = dict( type=self._get_exported_var_type().decl_string , class_type=cls_type - , name=self.declaration.name ) + , name=self.declaration.name ) answer.append( self.GET_TEMPLATE % substitutions ) if self.has_setter: answer.append( self.SET_TEMPLATE % substitutions ) - return os.linesep.join( answer ) \ No newline at end of file + return os.linesep.join( answer ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-09-13 09:24:37 UTC (rev 537) +++ pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-09-13 11:08:13 UTC (rev 538) @@ -60,6 +60,7 @@ from pygccxml import declarations from call_policies import call_policy_t +from call_policies import default_call_policies_t from call_policies import default_call_policies from call_policies import compound_policy_t from call_policies import return_argument_t Modified: pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2006-09-13 09:24:37 UTC (rev 537) +++ pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2006-09-13 11:08:13 UTC (rev 538) @@ -5,9 +5,9 @@ """ This modules contains definition of call policies classes. Call policies names -are same, that used in boost.python library. +are same, that used in boost.python library. -For every class that implements code creation of call policies, there is a +For every class that implements code creation of call policies, there is a convinience function. """ @@ -34,27 +34,35 @@ @type creation_policy: L{CREATION_POLICY} """ code = self._create_impl( function_creator ) - if creation_policy == CREATION_POLICY.AS_INSTANCE: + if code and creation_policy == CREATION_POLICY.AS_INSTANCE: code = code + '()' return code + def is_default( self ): + """Returns True is self is instance of L{default_call_policies_t} class""" + #Small hack that allows to write nicer code + return False + def _create_impl( self, function_creator ): raise NotImplementedError() - -class default_t(call_policy_t): + +class default_call_policies_t(call_policy_t): """implementation for ::boost::python::default_call_policies""" def __init__( self ): call_policy_t.__init__( self ) - + def _create_impl(self, function_creator ): return algorithm.create_identifier( function_creator, '::boost::python::default_call_policies' ) - + + def is_default( self ): + return True + def __str__(self): return 'default_call_policies' - + def default_call_policies(): """create ::boost::python::default_call_policies""" - return default_t() + return default_call_policies_t() class compound_policy_t( call_policy_t ): """base class for all call policies, except default one""" @@ -62,24 +70,26 @@ call_policy_t.__init__( self ) self._base = base if not base: - self._base = default_t() - + self._base = default_call_policies_t() + def _get_base_policy( self ): - return self._base + return self._base def _set_base_policy( self, new_policy ): self._base = new_policy base_policy = property( _get_base_policy, _set_base_policy - , doc="base call policy, by default is reference to L{default_t} call policy") + , doc="base call policy, by default is reference to L{default_call_policies_t} call policy") def _get_args(self, function_creator): return [] def _get_name(self, function_creator): raise NotImplementedError() - + def _create_impl( self, function_creator ): args = self._get_args(function_creator) - args.append( self._base.create( function_creator, CREATION_POLICY.AS_TEMPLATE_ARGUMENT ) ) + base_policy_code = self._base.create( function_creator, CREATION_POLICY.AS_TEMPLATE_ARGUMENT ) + if base_policy_code: + args.append( base_policy_code ) name = algorithm.create_identifier( function_creator, self._get_name(function_creator) ) return declarations.templates.join( name, args ) @@ -88,13 +98,13 @@ args = map( lambda text: text.replace( '::boost::python::', '' ) , self._get_args( None ) ) return declarations.templates.join( name, args ) - + class return_argument_t( compound_policy_t ): """implementation for ::boost::python::return_argument call policies""" def __init__( self, position=1, base=None): compound_policy_t.__init__( self, base ) self._position = position - + def _get_position( self ): return self._position def _set_position( self, new_position): @@ -106,7 +116,7 @@ return '::boost::python::return_self' else: return '::boost::python::return_arg' - + def _get_args(self, function_creator): if self.position == 1: return [] @@ -123,7 +133,7 @@ def __init__( self, position=1, base=None): compound_policy_t.__init__( self, base ) self._position = position - + def _get_position( self ): return self._position def _set_position( self, new_position): @@ -132,34 +142,34 @@ def _get_name(self, function_creator): return '::boost::python::return_internal_reference' - + def _get_args(self, function_creator): return [ str( self.position ) ] def return_internal_reference( arg_pos=1, base=None): return return_internal_reference_t( arg_pos, base ) - + class with_custodian_and_ward_t( compound_policy_t ): def __init__( self, custodian, ward, base=None): compound_policy_t.__init__( self, base ) self._custodian = custodian self._ward = ward - + def _get_custodian( self ): return self._custodian def _set_custodian( self, new_custodian): self._custodian = new_custodian custodian = property( _get_custodian, _set_custodian ) - + def _get_ward( self ): return self._ward def _set_ward( self, new_ward): self._ward = new_ward ward = property( _get_ward, _set_ward ) - + def _get_name(self, function_creator): return '::boost::python::with_custodian_and_ward' - + def _get_args(self, function_creator): return [ str( self.custodian ), str( self.ward ) ] @@ -172,7 +182,7 @@ def _get_name(self, function_creator): return '::boost::python::with_custodian_and_ward_postcall' - + def with_custodian_and_ward_postcall( custodian, ward, base=None): return with_custodian_and_ward_postcall_t( custodian, ward, base ) @@ -180,7 +190,7 @@ def __init__( self, result_converter_generator, base=None): compound_policy_t.__init__( self, base ) self._result_converter_generator = result_converter_generator - + def _get_result_converter_generator( self ): return self._result_converter_generator def _set_result_converter_generator( self, new_result_converter_generator): @@ -190,7 +200,7 @@ def _get_name(self, function_creator): return '::boost::python::return_value_policy' - + def _get_args(self, function_creator): if function_creator: rcg = algorithm.create_identifier( function_creator, self.result_converter_generator ) @@ -206,4 +216,4 @@ return_opaque_pointer = '::boost::python::return_opaque_pointer' def return_value_policy( result_converter_generator, base=None): - return return_value_policy_t( result_converter_generator, base ) \ No newline at end of file + return return_value_policy_t( result_converter_generator, base ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-14 12:03:04
|
Revision: 543 http://svn.sourceforge.net/pygccxml/?rev=543&view=rev Author: roman_yakovenko Date: 2006-09-14 05:02:53 -0700 (Thu, 14 Sep 2006) Log Message: ----------- moving guess_mem_fun_creator_classes from code_creators to module_creator package Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/module_creator/creator.py Added Paths: ----------- pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-14 06:19:18 UTC (rev 542) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-14 12:02:53 UTC (rev 543) @@ -118,54 +118,3 @@ from exception_translator import exception_translator_t from exception_translator import exception_translator_register_t - -from pygccxml import declarations - -ACCESS_TYPES = declarations.ACCESS_TYPES -VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES - - -def guess_mem_fun_creator_classes( decl ): - """return tuple of ( registration, declaration ) code creator classes""" - maker_cls = None - fwrapper_cls = None - access_level = decl.parent.find_out_member_access_type( decl ) - if access_level == ACCESS_TYPES.PUBLIC: - if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - maker_cls = mem_fun_t - elif decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: - fwrapper_cls = mem_fun_pv_wrapper_t - maker_cls = mem_fun_pv_t - else: - if decl.function_transformers: - fwrapper_cls = mem_fun_v_transformed_wrapper_t - maker_cls = mem_fun_v_transformed_t - else: - if decl.overridable: - fwrapper_cls = mem_fun_v_wrapper_t - maker_cls = mem_fun_v_t - elif access_level == ACCESS_TYPES.PROTECTED: - if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - if decl.has_static: - fwrapper_cls = mem_fun_protected_s_wrapper_t - maker_cls = mem_fun_protected_s_t - else: - fwrapper_cls = mem_fun_protected_wrapper_t - maker_cls = mem_fun_protected_t - elif decl.virtuality == VIRTUALITY_TYPES.VIRTUAL: - if decl.overridable: - fwrapper_cls = mem_fun_protected_v_wrapper_t - maker_cls = mem_fun_protected_v_t - else: - fwrapper_cls = mem_fun_protected_pv_wrapper_t - maker_cls = mem_fun_protected_pv_t - else: #private - if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - pass#in general we should not come here - elif decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: - fwrapper_cls = mem_fun_private_pv_wrapper_t - else: - if decl.overridable: - fwrapper_cls = mem_fun_v_wrapper_t - maker_cls = mem_fun_v_t - return ( maker_cls, fwrapper_cls ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-14 06:19:18 UTC (rev 542) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-14 12:02:53 UTC (rev 543) @@ -4,6 +4,7 @@ # http://www.boost.org/LICENSE_1_0.txt) import types_database +import creators_wizard import class_organizer import call_policies_resolver from pygccxml import declarations @@ -566,7 +567,7 @@ if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - maker_cls, fwrapper_cls = code_creators.guess_mem_fun_creator_classes( self.curr_decl ) + maker_cls, fwrapper_cls = creators_wizard.find_out_mem_fun_creator_classes( self.curr_decl ) maker = None fwrapper = None Added: pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py (rev 0) +++ pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py 2006-09-14 12:02:53 UTC (rev 543) @@ -0,0 +1,61 @@ +# 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) + +"""this module defines few function that will guess what creator(s) should be +created for exposing a declaration +""" + +from pygccxml import declarations +from pyplusplus import code_creators + + +ACCESS_TYPES = declarations.ACCESS_TYPES +VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES + + +def find_out_mem_fun_creator_classes( decl ): + """return tuple of ( registration, declaration ) code creator classes""" + maker_cls = None + fwrapper_cls = None + access_level = decl.parent.find_out_member_access_type( decl ) + if access_level == ACCESS_TYPES.PUBLIC: + if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + maker_cls = code_creators.mem_fun_t + elif decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: + fwrapper_cls = code_creators.mem_fun_pv_wrapper_t + maker_cls = code_creators.mem_fun_pv_t + else: + if decl.function_transformers: + fwrapper_cls = code_creators.mem_fun_v_transformed_wrapper_t + maker_cls = code_creators.mem_fun_v_transformed_t + else: + if decl.overridable: + fwrapper_cls = code_creators.mem_fun_v_wrapper_t + maker_cls = code_creators.mem_fun_v_t + elif access_level == ACCESS_TYPES.PROTECTED: + if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + if decl.has_static: + fwrapper_cls = code_creators.mem_fun_protected_s_wrapper_t + maker_cls = code_creators.mem_fun_protected_s_t + else: + fwrapper_cls = code_creators.mem_fun_protected_wrapper_t + maker_cls = code_creators.mem_fun_protected_t + elif decl.virtuality == VIRTUALITY_TYPES.VIRTUAL: + if decl.overridable: + fwrapper_cls = code_creators.mem_fun_protected_v_wrapper_t + maker_cls = code_creators.mem_fun_protected_v_t + else: + fwrapper_cls = code_creators.mem_fun_protected_pv_wrapper_t + maker_cls = code_creators.mem_fun_protected_pv_t + else: #private + if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: + pass#in general we should not come here + elif decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: + fwrapper_cls = code_creators.mem_fun_private_pv_wrapper_t + else: + if decl.overridable: + fwrapper_cls = code_creators.mem_fun_v_wrapper_t + maker_cls = code_creators.mem_fun_v_t + return ( maker_cls, fwrapper_cls ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-14 13:02:09
|
Revision: 544 http://svn.sourceforge.net/pygccxml/?rev=544&view=rev Author: roman_yakovenko Date: 2006-09-14 06:01:56 -0700 (Thu, 14 Sep 2006) Log Message: ----------- small refactoring to clean creator_t class. Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-09-14 12:02:53 UTC (rev 543) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-09-14 13:01:56 UTC (rev 544) @@ -90,10 +90,10 @@ if None is self._equality_comparable: self._equality_comparable = declarations.has_public_equal( self ) return self._equality_comparable - + def _set_equality_comparable( self, value ): self._equality_comparable = value - + equality_comparable = property( _get_equality_comparable, _set_equality_comparable , doc="indicates existence of public operator=" \ +"Default value is calculated, based on information presented in the declarations tree" ) @@ -137,7 +137,7 @@ self._null_constructor_body = '' self._copy_constructor_body = '' self._exception_translation_code = None - + def _get_redefine_operators( self ): return self._redefine_operators def _set_redefine_operators( self, new_value ): @@ -211,7 +211,7 @@ @property def exception_argument_name( self ): """exception argument name for translate exception function - + If you don't understand what this argument is, please take a look on Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/exception_translator.html """ @@ -221,7 +221,7 @@ return self._exception_translation_code def _set_exception_translation_code( self, code ): self._exception_translation_code = code - exception_translation_code = property( _get_exception_translation_code, _set_exception_translation_code + exception_translation_code = property( _get_exception_translation_code, _set_exception_translation_code , doc="C++ exception to Python exception translation code" \ +"\nExample: PyErr_SetString(PyExc_RuntimeError, exc.what()); " \ +"\nPy++ will generate the rest of the code." \ @@ -229,29 +229,29 @@ def translate_exception_to_string( self, python_exception_type, to_string ): """registers exception translation to string - + @param python_exception_type: Python exception type, for example PyExc_RuntimeError @type python_exception_type: str - - @param to_string: C++ expression that extracts information from exception. + + @param to_string: C++ expression that extracts information from exception. The type of expression should be char*. @type to_string: str """ - #NICE TO HAVE: + #NICE TO HAVE: #1. exception\assert\warning should be raised if python_exception_type # does not contain valid Python exception #2. Py++ can validate, that member function returns char* code = "PyErr_SetString( %(exception_type)s, %(to_string)s ); " \ % { 'exception_type' : python_exception_type, 'to_string' : to_string } self.exception_translation_code = code - + def add_declaration_code( self, code ): """adds the code to the declaration section""" self.declaration_code.append( user_text.user_text_t( code ) ) def add_registration_code( self, code, works_on_instance=True ): """adds the code to the class registration section - + works_on_instance: If true, the custom code can be applied directly to obj inst. Example: ObjInst."CustomCode" """ @@ -278,3 +278,35 @@ if not self in self.parent.public_members: return 'Py++ can not expose private class.' return '' + + def get_exportable_members( self, sort=None ): + """returns list of internal declarations that should\\could be exported""" + #TODO: obviously this function should be shorter. Almost all logic of this class + # should be spread between decl_wrapper classes + members = filter( lambda mv: mv.ignore == False and mv.exportable, self.public_members ) + #protected and private virtual functions that not overridable and not pure + #virtual should not be exported + for member in self.protected_members: + if not isinstance( member, declarations.calldef_t ): + continue + else: + members.append( member ) + + vfunction_selector = lambda member: isinstance( member, declarations.member_function_t ) \ + and member.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL + members.extend( filter( vfunction_selector, self.private_members ) ) + #now lets filter out none public operators: Py++ does not support them right now + members = filter( lambda decl: not isinstance( decl, declarations.member_operator_t ) + or decl.access_type == declarations.ACCESS_TYPES.PUBLIC + , members ) + #-#if declarations.has_destructor( self ) \ + #-# and not declarations.has_public_destructor( self ): + #remove artificial constructors + members = filter( lambda decl: not isinstance( decl, declarations.constructor_t ) + or not decl.is_artificial + , members ) + members = filter( lambda member: member.ignore == False and member.exportable, members ) + sorted_members = members + if sort: + sorted_members = sort( members ) + return sorted_members Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-09-14 12:02:53 UTC (rev 543) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-09-14 13:01:56 UTC (rev 544) @@ -97,6 +97,9 @@ self._exportable_reason = 'Py++, 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 = 'Py++, by default, does not expose internal declarations (those that gccxml say belong to "<internal>" header).' + elif self.is_artificial \ + and not isinstance( self, ( declarations.class_t, declarations.enumeration_t ) ): + self._exportable_reason = 'Py++, by default, does not expose compiler generated declarations.' else: self._exportable_reason = self._exportable_impl( ) self._exportable = not bool( self._exportable_reason ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-14 12:02:53 UTC (rev 543) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-14 13:01:56 UTC (rev 544) @@ -45,7 +45,13 @@ INDEXING_SUITE_2_MAIN_HEADER = "boost/python/suite/indexing/container_suite.hpp" -DO_NOT_REPORT_MSGS = [ "Py++ does not exports compiler generated constructors" ] +DO_NOT_REPORT_MSGS = [ + "Py++ does not exports compiler generated constructors" + , 'Py++, by default, does not expose internal compilers declarations. Names of those declarations usually start with "__".' + , 'Py++, by default, does not expose internal declarations (those that gccxml say belong to "<internal>" header).' + , 'Py++, by default, does not expose compiler generated declarations.' + , 'Py++ can not expose private class.' +] class creator_t( declarations.decl_visitor_t ): """Creating code creators. @@ -117,7 +123,7 @@ self.__extmodule.adopt_creator( self.__module_body ) prepared_decls = self._prepare_decls( decls, doc_extractor ) - self.__decls = self._filter_decls( self._reorder_decls( prepared_decls ) ) + self.__decls = self._reorder_decls( prepared_decls ) self.curr_code_creator = self.__module_body self.curr_decl = None @@ -163,7 +169,6 @@ for msg in readme: 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 ) \ and isinstance( x.parent, declarations.namespace_t ) @@ -217,48 +222,6 @@ new_ordered.extend( variables ) return new_ordered # - def _exportable_class_members( self, class_decl ): - assert isinstance( class_decl, declarations.class_t ) - members = filter( lambda mv: mv.ignore == False and mv.exportable, class_decl.public_members ) - #protected and private virtual functions that not overridable and not pure - #virtual should not be exported - for member in class_decl.protected_members: - if not isinstance( member, declarations.calldef_t ): - continue - else: - members.append( member ) - - vfunction_selector = lambda member: isinstance( member, declarations.member_function_t ) \ - and member.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL - members.extend( filter( vfunction_selector, class_decl.private_members ) ) - #now lets filter out none public operators: Py++ does not support them right now - members = filter( lambda decl: not isinstance( decl, declarations.member_operator_t ) - or decl.access_type == ACCESS_TYPES.PUBLIC - , members ) - #-#if declarations.has_destructor( class_decl ) \ - #-# and not declarations.has_public_destructor( class_decl ): - #remove artificial constructors - members = filter( lambda decl: not isinstance( decl, declarations.constructor_t ) - or not decl.is_artificial - , members ) - members = filter( lambda member: member.ignore == False and member.exportable, members ) - ordered_members = self._reorder_decls( members ) - return ordered_members - - def _does_class_have_smth_to_export(self, exportable_members ): - return bool( self._filter_decls( exportable_members ) ) - - def _filter_decls( self, decls ): - # Filter out artificial (compiler created) types unless they are classes - # See: http://public.kitware.com/pipermail/gccxml/2004-October/000486.html - decls = filter( lambda x: not (x.is_artificial and - not (isinstance(x, ( declarations.class_t, declarations.enumeration_t)))) - , decls ) - # Filter out type defs - decls = filter( lambda x: not isinstance( x, declarations.typedef_t ), decls ) - - return decls - def __is_same_func( self, f1, f2 ): if not f1.__class__ is f2.__class__: return False @@ -602,7 +565,7 @@ self.__module_body.adopt_creator( maker ) cwrapper = None - exportable_members = self._exportable_class_members(self.curr_code_creator.declaration) + exportable_members = self.curr_code_creator.declaration.get_exportable_members() if self._is_wrapper_needed( self.curr_decl.parent, exportable_members ): class_wrapper = self.curr_code_creator.wrapper cwrapper = code_creators.constructor_wrapper_t( constructor=self.curr_decl ) @@ -710,7 +673,7 @@ assert isinstance( self.curr_decl, declarations.class_t ) cls_decl = self.curr_decl cls_parent_cc = self.curr_code_creator - exportable_members = self._exportable_class_members(self.curr_decl) + exportable_members = self.curr_decl.get_exportable_members(self._reorder_decls) wrapper = None cls_cc = code_creators.class_t( class_inst=self.curr_decl ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-09-14 13:07:11
|
Revision: 545 http://svn.sourceforge.net/pygccxml/?rev=545&view=rev Author: mbaas Date: 2006-09-14 06:06:59 -0700 (Thu, 14 Sep 2006) Log Message: ----------- Committed the current snapshot of the function transformers. This is still work in progress and there are things missing, but it is sort of a milestone (at least for me) because I could use this version successfully for the Maya bindings where it could replace the arg policy feature from pypp_api. In this version, support for function transformers on non-virtual member functions has been implemented. Public (non-pure) virtual methods should now take the transformers into account in all cases (in the previous version it could happen that they were ignored). New policy class for in/out variables. Moved the transformed code creators to calldef_transformed.py (calldef.py is already big enough) so that the chance for conclicts on updates is reduced. Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py pyplusplus_dev/pyplusplus/function_transformers/code_manager.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py Added Paths: ----------- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-14 13:01:56 UTC (rev 544) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-14 13:06:59 UTC (rev 545) @@ -74,8 +74,10 @@ from calldef import copy_constructor_wrapper_t from calldef import null_constructor_wrapper_t -from calldef import mem_fun_v_transformed_t -from calldef import mem_fun_v_transformed_wrapper_t +from calldef_transformed import mem_fun_transformed_t +from calldef_transformed import mem_fun_transformed_wrapper_t +from calldef_transformed import mem_fun_v_transformed_t +from calldef_transformed import mem_fun_v_transformed_wrapper_t from global_variable import global_variable_base_t from global_variable import global_variable_t Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-14 13:01:56 UTC (rev 544) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-14 13:06:59 UTC (rev 545) @@ -10,7 +10,6 @@ import class_declaration from pygccxml import declarations from pyplusplus import decl_wrappers -import pyplusplus.function_transformers as function_transformers #virtual functions that returns const reference to something #could not be overriden by Python. The reason is simple: @@ -234,6 +233,7 @@ else: return '&%s' % declarations.full_name( self.declaration ) + class mem_fun_t( calldef_t ): def __init__( self, function ): calldef_t.__init__( self, function=function ) @@ -446,289 +446,7 @@ answer.append( self.create_default_function() ) return os.linesep.join( answer ) -class mem_fun_v_transformed_t( calldef_t ): - """Creates code for (public) virtual member functions. - """ - def __init__( self, function, wrapper=None ): - calldef_t.__init__( self, function=function, wrapper=wrapper ) - self.default_function_type_alias = 'default_' + self.function_type_alias - - def create_function_type_alias_code( self, exported_class_alias=None ): - result = [] - - ftype = self.declaration.function_type() - result.append( 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) ) - if self.wrapper: - result.append( os.linesep ) - ftype = self.wrapper.function_type() - result.append( 'typedef %s;' % ftype.create_typedef( self.default_function_type_alias ) ) - return ''.join( result ) - - def create_doc(self): - return None - - def create_function_ref_code(self, use_function_alias=False): - result = [] - if use_function_alias: - result.append( '%s(&%s)' - % ( self.function_type_alias, declarations.full_name( self.declaration ) ) ) - if self.wrapper: - result.append( self.param_sep() ) - result.append( '%s(&%s)' - % ( self.default_function_type_alias, self.wrapper.default_full_name() ) ) - elif self.declaration.create_with_signature: - result.append( '(%s)(&%s)' - % ( self.declaration.function_type().decl_string - , declarations.full_name( self.declaration ) ) ) - if self.wrapper: - result.append( self.param_sep() ) - result.append( '(%s)(&%s)' - % ( self.wrapper.function_type().decl_string, self.wrapper.default_full_name() ) ) - else: - if self.wrapper: - result.append( '&%s' % self.wrapper.default_full_name() ) - else: - result.append( '&%s'% declarations.full_name( self.declaration ) ) -# result.append( '&%s'% declarations.full_name( self.declaration ) ) -# if self.wrapper: -# result.append( self.param_sep() ) -# result.append( '&%s' % self.wrapper.default_full_name() ) - return ''.join( result ) - -class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): - """Creates wrapper code for (public) virtual member functions. - - The generated code consists of two functions: the virtual function - and the 'default' function. - """ - - def __init__( self, function ): - """Constructor. - - @param function: Function declaration - @type function: calldef_t - """ - calldef_wrapper_t.__init__( self, function=function ) - - # Stores the name of the variable that holds the override - self._override_var = None - - def default_name(self): - """Return the name of the 'default' function. - - @rtype: str - """ - return "default_" + self.declaration.alias - - def default_full_name(self): - """Return the full name of the 'default' function. - - The returned name also includes the class name. - - @rtype: str - """ - return self.parent.full_name + '::default_' + self.declaration.alias - - def virtual_name(self): - """Return the name of the 'virtual' function. - - @rtype: str - """ - return self.declaration.name - - def base_name(self): - """Return the name of the 'base' function. - - @rtype: str - """ - return "base_" + self.declaration.name - - def function_type(self): - return declarations.member_function_type_t( - return_type=self.declaration.return_type - , class_inst=declarations.dummy_type_t( self.parent.full_name ) - , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) - , has_const=self.declaration.has_const ) - - def create_declaration(self, name, virtual=True): - """Create the function header. - - This method is used for the virtual function (and the base_ function), - but not for the default function. - """ - template = '%(virtual)s$RET_TYPE %(name)s( $ARG_LIST_DEF )%(constness)s %(throw)s' - - # Substitute the $-variables - template = self._subst_manager.subst_virtual(template) - - virtualspec = '' - if virtual: - virtualspec = 'virtual ' - - constness = '' - if self.declaration.has_const: - constness = ' const ' - - return template % { - 'virtual' : virtualspec - , 'name' : name - , 'constness' : constness - , 'throw' : self.throw_specifier_code() - } - - def create_base_body(self): - body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" - - return_ = '' - if not declarations.is_void( self.declaration.return_type ): - return_ = 'return ' - - return body % { - 'name' : self.declaration.name - , 'args' : self.function_call_args() - , 'return_' : return_ - , 'wrapped_class' : self.wrapped_class_identifier() - } - - def create_virtual_body(self): - - body = """ -$DECLARATIONS - -if( %(override_var)s ) -{ - $PRE_CALL - - ${RESULT_VAR_ASSIGNMENT}boost::python::call<$RESULT_TYPE>($INPUT_PARAMS); - - $POST_CALL - - $RETURN_STMT -} -else -{ - %(inherited)s -} -""" - - vf = self._subst_manager.virtual_func - arg0 = "%s.ptr()"%self._override_var - if vf.INPUT_PARAMS=="": - vf.INPUT_PARAMS = arg0 - else: - vf.INPUT_PARAMS = arg0+", "+vf.INPUT_PARAMS - - # Replace the $-variables - body = self._subst_manager.subst_virtual(body) - -# template = [] -# template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' ) -# template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') ) -# template.append( 'else' ) -# template.append( self.indent('%(return_)s%(wrapped_class)s::%(name)s( %(args)s );') ) -# template = os.linesep.join( template ) - - return body % { -# 'override' : self.override_identifier() - 'override_var' : self._override_var - , 'alias' : self.declaration.alias -# , 'func_var' : "func_"+self.declaration.alias - , 'inherited' : self.create_base_body() - } - - def create_default_body(self): - cls_wrapper_type = self.parent.full_name - cls_wrapper = self._subst_manager.wrapper_func.declare_local("cls_wrapper", cls_wrapper_type); - # The name of the 'self' variable (i.e. first argument) - selfname = self._subst_manager.wrapper_func.arg_list[0].name - - body = """$DECLARATIONS - -$PRE_CALL - -%(cls_wrapper_type)s* %(cls_wrapper)s = dynamic_cast<%(cls_wrapper_type)s*>(&%(self)s); -if (%(cls_wrapper)s==0) -{ - // The following call is done on an instance created in C++, - // so it won't invoke Python code. - $RESULT_VAR_ASSIGNMENT$CALL_FUNC_NAME($INPUT_PARAMS); -} -else -{ - // The following call is done on an instance created in Python, - // i.e. a wrapper instance. This call might invoke Python code. - $RESULT_VAR_ASSIGNMENT%(cls_wrapper)s->%(base_name)s($INPUT_PARAMS); -} - -$POST_CALL - -$RETURN_STMT -""" - - # Replace the $-variables - body = self._subst_manager.subst_wrapper(body) - - # Replace the remaining parameters - body = body%{"cls_wrapper_type" : cls_wrapper_type, - "cls_wrapper" : cls_wrapper, - "self" : selfname, - "base_name" : self.base_name() } - -# function_call = declarations.call_invocation.join( self.declaration.name -# , [ self.function_call_args() ] ) -# body = self.wrapped_class_identifier() + '::' + function_call + ';' -# if not declarations.is_void( self.declaration.return_type ): -# body = 'return ' + body - return body - - def create_function(self): - answer = [ self.create_declaration(self.declaration.name) + '{' ] - answer.append( self.indent( self.create_virtual_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) - - def create_base_function( self ): - answer = [ self.create_declaration("base_"+self.declaration.name, False) + '{' ] - body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" - answer.append( self.indent( self.create_base_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) - - def create_default_function( self ): - - header = 'static $RET_TYPE %s( $ARG_LIST_DEF ) {'%self.default_name() - header = self._subst_manager.subst_wrapper(header) - - answer = [ header ] - answer.append( self.indent( self.create_default_body() ) ) - answer.append( '}' ) - return os.linesep.join( answer ) - - - def _create_impl(self): - # Create the substitution manager - decl = self.declaration - sm = function_transformers.substitution_manager_t(decl, transformers=decl.function_transformers) - self._override_var = sm.virtual_func.declare_local(decl.alias+"_callable", "boost::python::override", default='this->get_override( "%s" )'%decl.alias) - self._subst_manager = sm - - answer = [ self.create_function() ] - answer.append( os.linesep ) - answer.append( self.create_base_function() ) - answer.append( os.linesep ) - answer.append( self.create_default_function() ) - answer = os.linesep.join( answer ) - - # Replace the argument list of the declaration so that in the - # case that keywords are created, the correct arguments will be - # picked up (i.e. the modified argument list and not the original - # argument list) - self.declaration.arguments = self._subst_manager.wrapper_func.arg_list - - return answer - - class mem_fun_protected_t( calldef_t ): def __init__( self, function, wrapper ): calldef_t.__init__( self, function=function, wrapper=wrapper ) Added: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py (rev 0) +++ pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-09-14 13:06:59 UTC (rev 545) @@ -0,0 +1,496 @@ +# 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 algorithm +#import code_creator +#import class_declaration +from pygccxml import declarations +from calldef import calldef_t, calldef_wrapper_t +import pyplusplus.function_transformers as function_transformers + +###################################################################### + +class mem_fun_transformed_t( calldef_t ): + """Creates code for public non-virtual member functions. + """ + + def __init__( self, function, wrapper=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper ) + + def create_function_type_alias_code( self, exported_class_alias=None ): + if self.wrapper==None: + ftype = self.declaration.function_type() + else: + ftype = self.wrapper.function_type() + res = 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) + return res + + def create_function_ref_code(self, use_function_alias=False): + if self.wrapper: + full_name = self.wrapper.full_name() + else: + full_name = declarations.full_name( self.declaration ) + + if use_function_alias: + return '%s( &%s )' \ + % ( self.function_type_alias, full_name ) + elif self.declaration.create_with_signature: + if self.wrapper: + func_type = self.wrapper.function_type() + else: + func_type = self.declaration.function_type().decl_string + return '(%s)( &%s )' \ + % ( func_type, full_name ) + else: + return '&%s' % full_name + + +class mem_fun_transformed_wrapper_t( calldef_wrapper_t ): + """Creates wrapper code for (public) non-virtual member functions. + + The generated function is either used as a static member inside the + wrapper class (when self.parent is not None) or as a free function + (when self.parent is None). + """ + + def __init__( self, function ): + """Constructor. + + @param function: Function declaration + @type function: calldef_t + """ + calldef_wrapper_t.__init__( self, function=function ) + +# def is_free_function(self): +# """Return True if the generated function is a free function. +# +# @rtype: bool +# """ +# return self.parent==None + + def function_type(self): + """Return the type of the wrapper function. + + @rtype: type_t + """ + template = '$RET_TYPE' + rettype = self._subst_manager.subst_wrapper(template) + rettype = declarations.dummy_type_t(rettype) + + return declarations.free_function_type_t( + return_type=rettype + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) ) + + + def full_name(self): + """Return the full name of the wrapper function. + + The returned name also includes the class name (if there is any). + + @rtype: str + """ + if self.parent==None: + return '_py_' + self.declaration.alias + else: + return self.parent.full_name + '::_py_' + self.declaration.alias + + def create_sig_id(self): + """Create an ID string that identifies a signature. + + @rtype: str + """ + template = '%s($ARG_LIST_TYPES)'%self.declaration.alias + return self._subst_manager.subst_wrapper(template) + + def create_declaration(self, name): + """Create the function header. + """ + template = 'static $RET_TYPE %(name)s( $ARG_LIST_DEF ) %(throw)s' + + # Substitute the $-variables + template = self._subst_manager.subst_wrapper(template) + + return template % { + 'name' : "_py_"+name + , 'throw' : self.throw_specifier_code() + } + + def create_body(self): + + body = """ +$DECLARATIONS + +$PRE_CALL + +$RESULT_VAR_ASSIGNMENT$CALL_FUNC_NAME($INPUT_PARAMS); + +$POST_CALL + +$RETURN_STMT +""" + + # Replace the $-variables + body = self._subst_manager.subst_wrapper(body) + + return body + + def create_function(self): +# sig_id = self.create_sig_id() + # ...check sig here... + + answer = [70*"/"] + answer.append("// Transformed wrapper function for:") + answer.append("// %s"%self.declaration) + answer.append(70*"/") + answer.append( self.create_declaration(self.declaration.alias) + '{') + answer.append( self.indent( self.create_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def _create_impl(self): + # Create the substitution manager + decl = self.declaration + sm = function_transformers.substitution_manager_t(decl, transformers=decl.function_transformers) + self._subst_manager = sm + + answer = self.create_function() + + # Replace the argument list of the declaration so that in the + # case that keywords are created, the correct arguments will be + # picked up (i.e. the modified argument list and not the original + # argument list) + self.declaration.arguments = self._subst_manager.wrapper_func.arg_list + + return answer + +###################################################################### + +class mem_fun_v_transformed_t( calldef_t ): + """Creates code for (public) virtual member functions. + """ + + def __init__( self, function, wrapper=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper ) + self.default_function_type_alias = 'default_' + self.function_type_alias + + def create_function_type_alias_code( self, exported_class_alias=None ): + if self.wrapper==None: + ftype = self.declaration.function_type() + else: + ftype = self.wrapper.function_type() + + result = [] + result.append( 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) ) + return ''.join( result ) + + def create_doc(self): + return None + + def create_function_ref_code(self, use_function_alias=False): + if self.wrapper: + full_name = self.wrapper.default_full_name() + else: + full_name = declarations.full_name( self.declaration ) + + result = [] + if use_function_alias: + result.append( '%s(&%s)' + % ( self.function_type_alias, full_name ) ) + elif self.declaration.create_with_signature: + if self.wrapper: + func_type = self.wrapper.function_type() + else: + func_type = self.declaration.function_type().decl_string + result.append( '(%s)(&%s)' + % ( func_type, full_name ) ) + else: + result.append( '&%s' % full_name ) + + return ''.join( result ) + + +class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): + """Creates wrapper code for (public) virtual member functions. + + The generated code consists of two functions: the virtual function + and the 'default' function. + """ + + def __init__( self, function ): + """Constructor. + + @param function: Function declaration + @type function: calldef_t + """ + calldef_wrapper_t.__init__( self, function=function ) + + # Stores the name of the variable that holds the override + self._override_var = None + + def default_name(self): + """Return the name of the 'default' function. + + @rtype: str + """ + return "default_" + self.declaration.alias + + def default_full_name(self): + """Return the full name of the 'default' function. + + The returned name also includes the class name. + + @rtype: str + """ + return self.parent.full_name + '::default_' + self.declaration.alias + + def virtual_name(self): + """Return the name of the 'virtual' function. + + @rtype: str + """ + return self.declaration.name + + def base_name(self): + """Return the name of the 'base' function. + + @rtype: str + """ + return "base_" + self.declaration.name + + def function_type(self): + template = '$RET_TYPE' + rettype = self._subst_manager.subst_wrapper(template) + rettype = declarations.dummy_type_t(rettype) + + return declarations.free_function_type_t( + return_type=rettype + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) ) + + return declarations.member_function_type_t( + return_type=self.declaration.return_type + , class_inst=declarations.dummy_type_t( self.parent.full_name ) + , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) + , has_const=self.declaration.has_const ) + + def create_declaration(self, name, virtual=True): + """Create the function header. + + This method is used for the virtual function (and the base_ function), + but not for the default function. + """ + template = '%(virtual)s$RET_TYPE %(name)s( $ARG_LIST_DEF )%(constness)s %(throw)s' + + # Substitute the $-variables + template = self._subst_manager.subst_virtual(template) + + virtualspec = '' + if virtual: + virtualspec = 'virtual ' + + constness = '' + if self.declaration.has_const: + constness = ' const ' + + return template % { + 'virtual' : virtualspec + , 'name' : name + , 'constness' : constness + , 'throw' : self.throw_specifier_code() + } + + def create_base_body(self): + body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" + + return_ = '' + if not declarations.is_void( self.declaration.return_type ): + return_ = 'return ' + + return body % { + 'name' : self.declaration.name + , 'args' : self.function_call_args() + , 'return_' : return_ + , 'wrapped_class' : self.wrapped_class_identifier() + } + + def create_virtual_body(self): + + thread_safe = False + + if thread_safe: + # Todo: Properly allocate "gstate" + body = """ +PyGILState_STATE gstate; +gstate = PyGILState_Ensure(); + +$DECLARATIONS + +PyGILState_Release(gstate); + +if( %(override_var)s ) +{ + gstate = PyGILState_Ensure(); + + try { + $PRE_CALL + + ${RESULT_VAR_ASSIGNMENT}boost::python::call<$RESULT_TYPE>($INPUT_PARAMS); + + $POST_CALL + } + catch(...) + { + if (PyErr_Occurred()) + { + PyErr_Print(); + } + PyGILState_Release(gstate); + throw; + } + PyGILState_Release(gstate); + $RETURN_STMT +} +else +{ + %(inherited)s +} +""" + + if not thread_safe: + body = """ +$DECLARATIONS + +if( %(override_var)s ) +{ + $PRE_CALL + + ${RESULT_VAR_ASSIGNMENT}boost::python::call<$RESULT_TYPE>($INPUT_PARAMS); + + $POST_CALL + + $RETURN_STMT +} +else +{ + %(inherited)s +} +""" + + vf = self._subst_manager.virtual_func + arg0 = "%s.ptr()"%self._override_var + if vf.INPUT_PARAMS=="": + vf.INPUT_PARAMS = arg0 + else: + vf.INPUT_PARAMS = arg0+", "+vf.INPUT_PARAMS + + # Replace the $-variables + body = self._subst_manager.subst_virtual(body) + +# template = [] +# template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' ) +# template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') ) +# template.append( 'else' ) +# template.append( self.indent('%(return_)s%(wrapped_class)s::%(name)s( %(args)s );') ) +# template = os.linesep.join( template ) + + return body % { +# 'override' : self.override_identifier() + 'override_var' : self._override_var + , 'alias' : self.declaration.alias +# , 'func_var' : "func_"+self.declaration.alias + , 'inherited' : self.create_base_body() + } + + def create_default_body(self): + cls_wrapper_type = self.parent.full_name + cls_wrapper = self._subst_manager.wrapper_func.declare_local("cls_wrapper", cls_wrapper_type); + # The name of the 'self' variable (i.e. first argument) + selfname = self._subst_manager.wrapper_func.arg_list[0].name + + body = """$DECLARATIONS + +$PRE_CALL + +%(cls_wrapper_type)s* %(cls_wrapper)s = dynamic_cast<%(cls_wrapper_type)s*>(boost::addressof(%(self)s)); +if (%(cls_wrapper)s==0) +{ + // The following call is done on an instance created in C++, + // so it won't invoke Python code. + $RESULT_VAR_ASSIGNMENT$CALL_FUNC_NAME($INPUT_PARAMS); +} +else +{ + // The following call is done on an instance created in Python, + // i.e. a wrapper instance. This call might invoke Python code. + $RESULT_VAR_ASSIGNMENT%(cls_wrapper)s->%(base_name)s($INPUT_PARAMS); +} + +$POST_CALL + +$RETURN_STMT +""" + + # Replace the $-variables + body = self._subst_manager.subst_wrapper(body) + + # Replace the remaining parameters + body = body%{"cls_wrapper_type" : cls_wrapper_type, + "cls_wrapper" : cls_wrapper, + "self" : selfname, + "base_name" : self.base_name() } + +# function_call = declarations.call_invocation.join( self.declaration.name +# , [ self.function_call_args() ] ) +# body = self.wrapped_class_identifier() + '::' + function_call + ';' +# if not declarations.is_void( self.declaration.return_type ): +# body = 'return ' + body + return body + + def create_function(self): + answer = [ self.create_declaration(self.declaration.name) + '{' ] + answer.append( self.indent( self.create_virtual_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def create_base_function( self ): + answer = [ self.create_declaration("base_"+self.declaration.name, False) + '{' ] + body = "%(return_)s%(wrapped_class)s::%(name)s( %(args)s );" + answer.append( self.indent( self.create_base_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def create_default_function( self ): + + header = 'static $RET_TYPE %s( $ARG_LIST_DEF ) {'%self.default_name() + header = self._subst_manager.subst_wrapper(header) + + answer = [ header ] + answer.append( self.indent( self.create_default_body() ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + + def _create_impl(self): + # Create the substitution manager + decl = self.declaration + sm = function_transformers.substitution_manager_t(decl, transformers=decl.function_transformers) + self._override_var = sm.virtual_func.declare_local(decl.alias+"_callable", "boost::python::override", default='this->get_override( "%s" )'%decl.alias) + self._subst_manager = sm + + answer = [ self.create_function() ] + answer.append( os.linesep ) + answer.append( self.create_base_function() ) + answer.append( os.linesep ) + answer.append( self.create_default_function() ) + answer = os.linesep.join( answer ) + + # Replace the argument list of the declaration so that in the + # case that keywords are created, the correct arguments will be + # picked up (i.e. the modified argument list and not the original + # argument list) + self.declaration.arguments = self._subst_manager.wrapper_func.arg_list + + return answer + Property changes on: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py ___________________________________________________________________ Name: svn:eol-style + native Modified: pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py 2006-09-14 13:01:56 UTC (rev 544) +++ pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py 2006-09-14 13:06:59 UTC (rev 545) @@ -11,6 +11,7 @@ - L{output_t} - L{input_t} + - L{inout_t} - L{input_array_t} - L{output_array_t} """ @@ -105,14 +106,73 @@ reftype = arg.type if not (isinstance(reftype, declarations.reference_t) or isinstance(reftype, declarations.pointer_t)): - raise ValueError, 'Output variable %d ("%s") must be a reference or a pointer (got %s)'%(self.idx, arg.name, arg.type) + raise ValueError, 'Input variable %d ("%s") must be a reference or a pointer (got %s)'%(self.idx, arg.name, arg.type) # Create an equivalent argument that is not a reference type noref_arg = declarations.argument_t(name=arg.name, type=arg.type.base, default_value=arg.default_value) # Insert the noref argument sm.insert_arg(self.idx, noref_arg, arg.name) +# inout_t +class inout_t: + """Handles a single input/output variable. + void foo(int& v) -> v = foo(v) + """ + + def __init__(self, idx): + """Constructor. + + The specified argument must be a reference or a pointer. + + @param idx: Index of the argument that is an in/out value (the first arg has index 1). + @type idx: int + """ + self.idx = idx + self.local_var = "<not initialized>" + + def __str__(self): + return "InOut(%d)"%(self.idx) + + def init_funcs(self, sm): + # Remove the specified input argument from the wrapper function + arg = sm.remove_arg(self.idx) + + # Do some checks (the arg has to be a reference or a pointer) + reftype = arg.type + if not (isinstance(reftype, declarations.reference_t) or + isinstance(reftype, declarations.pointer_t)): + raise ValueError, 'InOut variable %d ("%s") must be a reference or a pointer (got %s)'%(self.idx, arg.name, arg.type) + + # Create an equivalent argument that is not a reference type + noref_arg = declarations.argument_t(name=arg.name, type=arg.type.base, default_value=arg.default_value) + # Insert the noref argument + sm.insert_arg(self.idx, noref_arg, arg.name) + + # Use the input arg to also store the output + self.local_var = noref_arg.name + # Append the output to the result tuple + sm.wrapper_func.result_exprs.append(self.local_var) + + # Replace the expression in the C++ function call + if isinstance(reftype, declarations.pointer_t): + sm.wrapper_func.input_params[self.idx-1] = "&%s"%self.local_var + else: + sm.wrapper_func.input_params[self.idx-1] = self.local_var + + + def virtual_post_call(self, sm): + """Extract the C++ value after the call to the Python function. + """ + arg = sm.virtual_func.arg_list[self.idx-1] + res = "// Extract the C++ value for in/out argument '%s' (index: %d)\n"%(arg.name, self.idx) + if isinstance(arg.type, declarations.pointer_t): + res += "*" + res += "%s = boost::python::extract<%s>(%s);"%(arg.name, arg.type.base, sm.py_result_expr(self.local_var)) + return res + + + # input_array_t class input_array_t: """Handles an input array with fixed size. @@ -160,7 +220,7 @@ self.pylist = sm.virtual_func.declare_local("py_"+arg.name, "boost::python::list") # Replace the removed argument with a Python object. - newarg = declarations.argument_t(arg.name, "boost::python::object") + newarg = declarations.argument_t(arg.name, declarations.dummy_type_t("boost::python::object")) sm.insert_arg(self.idx, newarg, self.pylist) self.argname = arg.name Modified: pyplusplus_dev/pyplusplus/function_transformers/code_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-09-14 13:01:56 UTC (rev 544) +++ pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-09-14 13:06:59 UTC (rev 545) @@ -35,7 +35,7 @@ @ivar ret_type: Return type. The value may be any object where str(obj) is valid C++ code. The value None corresponds to void. This will be the value of the variable RET_TYPE. @type ret_type: str @ivar arg_list: The argument list. The items are pygccxml argument_t objects. This list will appear in the variables ARG_LIST, ARG_LIST_DEF and ARG_LIST_TYPES. - @type arg_list: list of argument_t + @type arg_list: list of L{argument_t<pygccxml.declarations.calldef.argument_t>} @ivar input_params: A list of strings that contain the input parameter for the function call. This list is used for the INPUT_PARAMS variable. @type input_params: list of str @ivar result_var: The name of the variable that will receive the result of the function call. If None, the return value is ignored. This attribute will be used for the variable RESULT_VAR_ASSIGNMENT. @@ -225,8 +225,8 @@ which is a list of individual expressions. Apart from that this class is identical to L{code_manager_t}. - @ivar result_exprs: Similar to result_expr but this list variable can contain more than just one result. The items can be either strings containing the variable names (or expressions) that should be returned or it can be an argument_t object (usually from the argument list of the virtual function) whose name attribute will be used. This attribute only exists on the code manager for the wrapper function (the virtual function cannot return several values, use result_expr instead). - @type result_exprs: list of str or argument_t + @ivar result_exprs: Similar to result_expr but this list variable can contain more than just one result. The items can be either strings containing the variable names (or expressions) that should be returned or it can be an L{argument_t<pygccxml.declarations.calldef.argument_t>} object (usually from the argument list of the virtual function) whose name attribute will be used. This attribute only exists on the code manager for the wrapper function (the virtual function cannot return several values, use result_expr instead). + @type result_exprs: list of str or L{argument_t<pygccxml.declarations.calldef.argument_t>} """ def __init__(self): Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-09-14 13:01:56 UTC (rev 544) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-09-14 13:06:59 UTC (rev 545) @@ -192,29 +192,31 @@ self._wrapper_includes = [] # Initialize the code managers... - - if str(decl.return_type)=="void": - ret_type = None - else: - ret_type = decl.return_type - self.wrapper_func.result_type = str(ret_type) - self.wrapper_func.result_var = self.wrapper_func.declare_local("result", self.wrapper_func.result_type) - self.wrapper_func.result_exprs = [self.wrapper_func.result_var] - self.virtual_func.ret_type = ret_type self.virtual_func.arg_list = decl.arguments[:] self.virtual_func.class_name = wrapper_class self.virtual_func.FUNC_NAME = decl.name self.virtual_func.CALL_FUNC_NAME = decl.name self.virtual_func.input_params = map(lambda a: a.name, decl.arguments) - self.wrapper_func.ret_type = ret_type self.wrapper_func.arg_list = decl.arguments[:] self.wrapper_func.class_name = wrapper_class self.wrapper_func.FUNC_NAME = "%s_wrapper"%decl.alias self.wrapper_func.CALL_FUNC_NAME = decl.name self.wrapper_func.input_params = map(lambda a: a.name, decl.arguments) + if str(decl.return_type)=="void": + ret_type = None + else: + ret_type = decl.return_type + self.wrapper_func.result_type = str(ret_type) + self.wrapper_func.result_var = self.wrapper_func.declare_local("result", self.wrapper_func.result_type) + self.wrapper_func.result_exprs = [self.wrapper_func.result_var] + + self.virtual_func.ret_type = ret_type + + self.wrapper_func.ret_type = ret_type + # The offset that is added to the index in insert_arg() # This index is either 0 for free functions or 1 for member functions # because the "self" argument is not a regular argument. @@ -224,7 +226,7 @@ clsdecl = self._class_decl(decl) if clsdecl!=None: selfname = self.wrapper_func._make_name_unique("self") - selfarg = declarations.argument_t(selfname, "%s&"%clsdecl.name) + selfarg = declarations.argument_t(selfname, declarations.dummy_type_t("%s&"%clsdecl.name)) self.wrapper_func.arg_list.insert(0, selfarg) self.wrapper_func.CALL_FUNC_NAME = "%s.%s"%(selfname, self.wrapper_func.CALL_FUNC_NAME) self._insert_arg_idx_offset = 1 @@ -256,6 +258,8 @@ It is not necessary to call this method manually, it is automatically called at the time a substitution is requested. """ +# print "Transforming:",self.decl +# print " using transformers:", ", ".join(map(lambda x: str(x), self.transformers)) # Append the default return_virtual_result_t code modifier transformers = self.transformers+[return_virtual_result_t()] @@ -335,6 +339,7 @@ if idx==0: if id(self.wrapper_func.ret_type)==id(self.wrapper_func.ret_type): self.wrapper_func.ret_type = None + self.wrapper_func.result_exprs.remove(self.wrapper_func.result_var) else: raise ValueError, 'Argument %d not found on the wrapper function'%(idx) # Remove argument... @@ -345,7 +350,9 @@ try: self.wrapper_func.arg_list.remove(arg) except ValueError: - raise ValueError, 'Argument %d ("%s") not found on the wrapper function'%(idx, arg.name) + msg = str(self.decl)+"\n" + msg += 'Argument %d ("%s") not found on the wrapper function'%(idx, arg.name) + raise ValueError, msg # Remove the input parameter on the Python call in the # virtual function. Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-14 13:01:56 UTC (rev 544) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-14 13:06:59 UTC (rev 545) @@ -546,6 +546,19 @@ maker = maker_cls( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) + # Are we dealing with transformed non-virtual member functions? + if maker_cls==code_creators.mem_fun_transformed_t: + # Create the code creator that generates the function source code + mftw = code_creators.mem_fun_transformed_wrapper_t(self.curr_decl) + # and add it either to the wrapper class or just to the declaration + # area of the cpp file + if self.curr_code_creator.wrapper is None: + self.curr_code_creator.associated_decl_creators.append(mftw) + else: + self.curr_code_creator.wrapper.adopt_creator(mftw) + # Set the wrapper so that the registration code will refer to it + maker.wrapper = mftw + if self.curr_decl.has_static: #static_method should be created only once. found = filter( lambda creator: isinstance( creator, code_creators.static_method_t ) Modified: pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py 2006-09-14 13:01:56 UTC (rev 544) +++ pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py 2006-09-14 13:06:59 UTC (rev 545) @@ -22,7 +22,10 @@ access_level = decl.parent.find_out_member_access_type( decl ) if access_level == ACCESS_TYPES.PUBLIC: if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - maker_cls = code_creators.mem_fun_t + if decl.function_transformers: + maker_cls = code_creators.mem_fun_transformed_t + else: + maker_cls = code_creators.mem_fun_t elif decl.virtuality == VIRTUALITY_TYPES.PURE_VIRTUAL: fwrapper_cls = code_creators.mem_fun_pv_wrapper_t maker_cls = code_creators.mem_fun_pv_t This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-18 20:42:22
|
Revision: 555 http://svn.sourceforge.net/pygccxml/?rev=555&view=rev Author: roman_yakovenko Date: 2006-09-18 13:42:11 -0700 (Mon, 18 Sep 2006) Log Message: ----------- introducing opaque_type_registrator This is a start for next "redesign" session. New base class for code creators should be introduced: regstration_t. It will keep the list of associated creators, that register declarations in global scope Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/code_creators/class_declaration.py pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py pyplusplus_dev/pyplusplus/file_writers/multiple_files.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-18 20:03:06 UTC (rev 554) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-09-18 20:42:11 UTC (rev 555) @@ -30,6 +30,12 @@ def __init__(self, function, wrapper=None ): declaration_based.declaration_based_t.__init__( self, declaration=function ) self._wrapper = wrapper + self._associated_decl_creators = [] + + @property + def associated_decl_creators( self ): + """ references to declaration code creators. """ + return self._associated_decl_creators def _get_wrapper( self ): return self._wrapper Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-09-18 20:03:06 UTC (rev 554) +++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-09-18 20:42:11 UTC (rev 555) @@ -99,18 +99,6 @@ """ references to class declaration code creators. """ return self._associated_decl_creators - def recursive_associated_decl_creators( self ): - """ references to all class declaration code creators. """ - associated_creators = self.associated_decl_creators[:] - - relevant_creators = filter( lambda creator: isinstance( creator, class_t ) - , algorithm.make_flatten( self.creators ) ) - - map( lambda creator: associated_creators.extend( creator.associated_decl_creators ) - , relevant_creators ) - - return associated_creators - def _get_held_type(self): return self.declaration.held_type def _set_held_type(self, held_type): Modified: pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-09-18 20:03:06 UTC (rev 554) +++ pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-09-18 20:42:11 UTC (rev 555) @@ -183,10 +183,11 @@ creators = filter( lambda x: isinstance(x, class_types ), class_creator.creators ) decl_creators = [] - for creator in creators: - if not isinstance( creator, code_creators.class_t ): - continue - decl_creators.extend( creator.recursive_associated_decl_creators() ) + class_creators = filter( lambda creator: isinstance( creator, code_creators.class_t ) + , creators ) + + map( lambda creator: decl_creators.extend( self.associated_decl_creators( creator ) ) + , class_creators ) self.split_internal_creators( class_creator, creators, 'classes', decl_creators ) return 'classes' Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-09-18 20:03:06 UTC (rev 554) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-09-18 20:42:11 UTC (rev 555) @@ -61,6 +61,21 @@ @type: str """ ) + def associated_decl_creators( self, creator ): + """ references to all class declaration code creators. """ + if not isinstance( creator, code_creators.class_t ): + return [] + + associated_creators = creator.associated_decl_creators[:] + + relevant_creators = filter( lambda acreator: isinstance( acreator, code_creators.class_t ) + , code_creators.make_flatten( creator.creators ) ) + + map( lambda acreator: associated_creators.extend( acreator.associated_decl_creators ) + , relevant_creators ) + + return associated_creators + def create_function_code( self, function_name ): return "void %s();" % function_name @@ -199,7 +214,7 @@ class_wrapper = None decl_creators = [] if isinstance( class_creator, code_creators.class_t ): - decl_creators.extend( class_creator.recursive_associated_decl_creators() ) + decl_creators.extend( self.associated_decl_creators( class_creator ) ) if class_creator.wrapper: class_wrapper = class_creator.wrapper decl_creators.append( class_creator.wrapper ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-18 20:03:06 UTC (rev 554) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-18 20:42:11 UTC (rev 555) @@ -131,7 +131,8 @@ self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] self.__exposed_free_fun_overloads = set() - + self.__exposed_opaque_decls = set() + def _prepare_decls( self, decls, doc_extractor ): global DO_NOT_REPORT_MSGS @@ -316,6 +317,18 @@ return True #we already decided that those functions should be exposed, so I need wrapper for them return bool( self.redefined_funcs(class_inst) ) + def register_opaque_type( self, type_, call_policy ): + if not decl_wrappers.is_return_opaque_pointer_policy( call_policy ): + return #not our case + naked_type = declarations.remove_cv( declarations.remove_pointer( type_ ) ) + if decl_wrappers.python_traits.is_immutable( naked_type ): + return #don't register opaque converter for immutable types. + if decl in self.__exposed_opaque_decls: + return #already registered + self.__exposed_opaque_decls.add( decl ) + creator = code_creators.opaque_type_registrator_t( decl ) + self.__extmodule.adopt_declaration_creator( creator ) + def _adopt_free_operator( self, operator ): def adopt_operator_impl( operator, found_creators ): creator = filter( lambda creator: isinstance( creator, code_creators.class_t ) @@ -520,7 +533,8 @@ self.__types_db.update( self.curr_decl ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - + self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) + maker_cls, fwrapper_cls = creators_wizard.find_out_mem_fun_creator_classes( self.curr_decl ) maker = None @@ -598,7 +612,8 @@ if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - + self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) + self.__types_db.update( self.curr_decl ) if not self.curr_decl.parent.is_abstract \ and not declarations.is_reference( self.curr_decl.return_type ): @@ -627,7 +642,7 @@ self.__types_db.update( f ) if None is f.call_policies: f.call_policies = self.__call_policies_resolver( f ) - + self.register_opaque_type( f.return_type, f.call_policies ) overloads_cls_creator = code_creators.free_fun_overloads_class_t( overloads ) self.__extmodule.adopt_declaration_creator( overloads_cls_creator ) @@ -637,6 +652,7 @@ self.__types_db.update( self.curr_decl ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) + self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) maker = code_creators.free_function_t( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) @@ -664,6 +680,7 @@ self.__types_db.update( f ) if None is f.call_policies: f.call_policies = self.__call_policies_resolver( f ) + self.register_opaque_type( f.return_type, f.call_policies ) overloads_cls_creator = code_creators.mem_fun_overloads_class_t( overloads ) self.__extmodule.adopt_declaration_creator( overloads_cls_creator ) @@ -801,6 +818,7 @@ elif declarations.is_reference( self.curr_decl.type ): if None is self.curr_decl.getter_call_policies: self.curr_decl.getter_call_policies = self.__call_policies_resolver( self.curr_decl, 'get' ) + self.register_opaque_type( self.curr_decl.type, self.curr_decl.getter_call_policies ) if None is self.curr_decl.setter_call_policies: self.curr_decl.setter_call_policies = self.__call_policies_resolver( self.curr_decl, 'set' ) wrapper = code_creators.mem_var_ref_wrapper_t( variable=self.curr_decl ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-21 09:51:19
|
Revision: 570 http://svn.sourceforge.net/pygccxml/?rev=570&view=rev Author: roman_yakovenko Date: 2006-09-21 02:51:06 -0700 (Thu, 21 Sep 2006) Log Message: ----------- adding support for associated_decl_creators to file writers Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/class_declaration.py pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py pyplusplus_dev/pyplusplus/file_writers/multiple_files.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-21 09:48:15 UTC (rev 569) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2006-09-21 09:51:06 UTC (rev 570) @@ -27,6 +27,8 @@ from declaration_based import declaration_based_t +from registration_based import registration_based_t + from scoped import scoped_t from module_body import module_body_t @@ -121,4 +123,4 @@ from exception_translator import exception_translator_t from exception_translator import exception_translator_register_t -from opaque_type_registrator import opaque_type_registrator_t \ No newline at end of file +from opaque_type_registrator import opaque_type_registrator_t Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-09-21 09:48:15 UTC (rev 569) +++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-09-21 09:51:06 UTC (rev 570) @@ -90,7 +90,6 @@ registration_based.registration_based_t.__init__( self ) self._wrapper = wrapper self.works_on_instance = False - self._associated_decl_creators = [] def _get_wrapper( self ): return self._wrapper @@ -98,11 +97,6 @@ self._wrapper = new_wrapper wrapper = property( _get_wrapper, _set_wrapper ) - @property - def associated_decl_creators( self ): - """ references to class declaration code creators. """ - return self._associated_decl_creators - def _get_held_type(self): return self.declaration.held_type def _set_held_type(self, held_type): Modified: pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-09-21 09:48:15 UTC (rev 569) +++ pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-09-21 09:51:06 UTC (rev 570) @@ -72,7 +72,7 @@ header_file = os.path.join( self.directory_path, self.wrapper_header(class_creator) ) self.write_file( header_file, wrapper_code ) - def split_internal_creators( self, class_creator, creators, pattern, decl_creators=None): + def split_internal_creators( self, class_creator, creators, pattern ): file_path = os.path.join( self.directory_path , self.create_base_fname( class_creator, pattern ) ) @@ -104,8 +104,8 @@ source_code.append( '' ) source_code.append( self.create_namespaces_code( creators ) ) - if decl_creators: - for decl_creator in decl_creators: + for creator in creators: + for decl_creator in self.associated_decl_creators( creator ): source_code.append( '' ) source_code.append( decl_creator.create() ) decl_creator.create = lambda: '' @@ -174,22 +174,12 @@ , 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 ) - - decl_creators = [] - class_creators = filter( lambda creator: isinstance( creator, code_creators.class_t ) - , creators ) - - map( lambda creator: decl_creators.extend( self.associated_decl_creators( creator ) ) - , class_creators ) - - self.split_internal_creators( class_creator, creators, 'classes', decl_creators ) + self.split_internal_creators( class_creator, creators, 'classes' ) return 'classes' def split_internal_member_variables( self, class_creator ): Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-09-21 09:48:15 UTC (rev 569) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-09-21 09:51:06 UTC (rev 570) @@ -63,17 +63,23 @@ def associated_decl_creators( self, creator ): """ references to all class declaration code creators. """ - if not isinstance( creator, code_creators.class_t ): + if not isinstance( creator, code_creators.registration_based_t ): return [] - + associated_creators = creator.associated_decl_creators[:] - relevant_creators = filter( lambda acreator: isinstance( acreator, code_creators.class_t ) - , code_creators.make_flatten( creator.creators ) ) + internal_creators = [] + if isinstance( creator, code_creators.compound_t ): + internal_creators.extend( + filter( lambda acreator: isinstance( acreator, code_creators.compound_t ) + , code_creators.make_flatten( creator.creators ) ) ) - map( lambda acreator: associated_creators.extend( acreator.associated_decl_creators ) - , relevant_creators ) - + map( lambda internal_creator: associated_creators.extend( internal_creator.associated_decl_creators ) + , internal_creators ) + #now associated_creators contains all code creators associated with the creator + #We should leave only creators, defined in the global namespace + associated_creators = filter( lambda associated_creator: associated_creator.parent is self.extmodule + , associated_creators ) return associated_creators def create_function_code( self, function_name ): @@ -160,7 +166,7 @@ else: return os.linesep.join( map( lambda creator: creator.create(), ns_creators ) ) - def create_source( self, file_name, function_name, registration_creators, declaration_creators=None ): + def create_source( self, file_name, function_name, registration_creators ): """Return the content of a cpp file. @param file_name: The base name of the corresponding include file (without extension) @@ -172,9 +178,10 @@ @returns: The content for a cpp file @rtype: str """ + declaration_creators = [] + for rc in registration_creators: + declaration_creators.extend( self.associated_decl_creators( rc ) ) - if None is declaration_creators: - declaration_creators = [] creators = registration_creators + declaration_creators answer = [] @@ -211,19 +218,10 @@ self.write_file( header_name , self.create_header( class_creator.alias , self.create_function_code( function_name ) ) ) - class_wrapper = None - decl_creators = [] - if isinstance( class_creator, code_creators.class_t ): - decl_creators.extend( self.associated_decl_creators( class_creator ) ) - if class_creator.wrapper: - class_wrapper = class_creator.wrapper - decl_creators.append( class_creator.wrapper ) # Write the .cpp file... - cpp_code = self.create_source( class_creator.alias - , function_name - , [class_creator] - , decl_creators ) + cpp_code = self.create_source( class_creator.alias, function_name, [class_creator] ) + self.write_file( file_path + self.SOURCE_EXT, cpp_code ) # Replace the create() method so that only the register() method is called @@ -286,9 +284,8 @@ self.write_file( header_name , self.create_header( file_pattern, self.create_function_code( function_name ) ) ) self.write_file( file_path + self.SOURCE_EXT - , self.create_source( file_pattern - , function_name - , creators )) + , self.create_source( file_pattern, function_name, creators )) + for creator in creators: creator.create = lambda: '' self.extmodule.body.adopt_creator( Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-21 09:48:15 UTC (rev 569) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-21 09:51:06 UTC (rev 570) @@ -132,7 +132,7 @@ self.__free_operators = [] self.__exposed_free_fun_overloads = set() self.__exposed_opaque_decls = set() - + def _prepare_decls( self, decls, doc_extractor ): global DO_NOT_REPORT_MSGS @@ -534,7 +534,7 @@ if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) - + maker_cls, fwrapper_cls = creators_wizard.find_out_mem_fun_creator_classes( self.curr_decl ) maker = None @@ -569,8 +569,8 @@ self.__extmodule.add_system_header( code_repository.gil_state.file_name ) self.__extmodule.adopt_creator( code_creators.include_t( code_repository.gil_state.file_name ) , self.__extmodule.first_include_index() + 1) - + if self.curr_decl.has_static: #static_method should be created only once. found = filter( lambda creator: isinstance( creator, code_creators.static_method_t ) @@ -620,7 +620,7 @@ if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) - + self.__types_db.update( self.curr_decl ) if not self.curr_decl.parent.is_abstract \ and not declarations.is_reference( self.curr_decl.return_type ): @@ -710,6 +710,7 @@ wrapper = code_creators.class_wrapper_t( declaration=self.curr_decl , class_creator=cls_cc ) cls_cc.wrapper = wrapper + cls_cc.associated_decl_creators.append( wrapper ) #insert wrapper before module body if isinstance( self.curr_decl.parent, declarations.class_t ): #we deal with internal class This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-09-21 09:54:49
|
Revision: 571 http://svn.sourceforge.net/pygccxml/?rev=571&view=rev Author: mbaas Date: 2006-09-21 02:54:39 -0700 (Thu, 21 Sep 2006) Log Message: ----------- 1) Renamed gil_state to gil_guard (and moved the class under pyplusplus::threading). 2) The code creator can tell the module creator what header files it requires. As a result, the header file(s) from the code repository (i.e. __gil_guard.pypp.hpp) only gets created when it is really required. 3) Moved the functionality to add/query required headers from the substitution manager to the code manager. Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev/pyplusplus/function_transformers/code_manager.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-09-21 09:51:06 UTC (rev 570) +++ pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-09-21 09:54:39 UTC (rev 571) @@ -10,6 +10,7 @@ from pygccxml import declarations from calldef import calldef_t, calldef_wrapper_t import pyplusplus.function_transformers as function_transformers +from pyplusplus import code_repository ###################################################################### @@ -64,6 +65,10 @@ """ calldef_wrapper_t.__init__( self, function=function ) + # Create the substitution manager + sm = function_transformers.substitution_manager_t(function, transformers=function.function_transformers) + self._subst_manager = sm + # def is_free_function(self): # """Return True if the generated function is a free function. # @@ -151,10 +156,6 @@ return os.linesep.join( answer ) def _create_impl(self): - # Create the substitution manager - decl = self.declaration - sm = function_transformers.substitution_manager_t(decl, transformers=decl.function_transformers) - self._subst_manager = sm answer = self.create_function() @@ -226,12 +227,17 @@ @type function: calldef_t """ calldef_wrapper_t.__init__( self, function=function ) - + + # Create the substitution manager + sm = function_transformers.substitution_manager_t(function, transformers=function.function_transformers) + self._subst_manager = sm + # Stores the name of the variable that holds the override - self._override_var = None + self._override_var = sm.virtual_func.allocate_local(function.alias+"_callable") # Stores the name of the 'gstate' variable - self._gstate_var = None + self._gstate_var = sm.virtual_func.allocate_local("gstate") + def default_name(self): """Return the name of the 'default' function. @@ -323,7 +329,7 @@ if thread_safe: body = """ -pyplusplus::gil_state_t %(gstate_var)s; +pyplusplus::threading::gil_state_t %(gstate_var)s; %(gstate_var)s.ensure(); boost::python::override %(override_var)s = this->get_override( "%(alias)s" ); @@ -478,15 +484,15 @@ answer.append( self.indent( self.create_default_body() ) ) answer.append( '}' ) return os.linesep.join( answer ) - + def get_required_headers(self): + """Return a list of required header file names.""" + res = [code_repository.gil_guard.file_name] + res += self._subst_manager.virtual_func.get_required_headers() + res += self._subst_manager.wrapper_func.get_required_headers() + return res + def _create_impl(self): - # Create the substitution manager - decl = self.declaration - sm = function_transformers.substitution_manager_t(decl, transformers=decl.function_transformers) - self._override_var = sm.virtual_func.allocate_local(decl.alias+"_callable") - self._gstate_var = sm.virtual_func.allocate_local("gstate") - self._subst_manager = sm answer = [ self.create_function() ] answer.append( os.linesep ) Modified: pyplusplus_dev/pyplusplus/function_transformers/code_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-09-21 09:51:06 UTC (rev 570) +++ pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-09-21 09:54:39 UTC (rev 571) @@ -94,6 +94,39 @@ # A list with variable tuples: (name, type, size, default) self._local_var_list = [] + # Required header file names + self._required_headers = [] + + # require_header + def require_header(self, include): + """Declare an include file that is required for the code to compile. + + include is the name of the include file which may contain <> or "" + characters around the name (which are currently ignored). + If an include file is declared twice it will only be added once. + + @param include: The name of the include file (may contain <> or "") + @type include: str + """ + if include=="": + return + + # Add apostrophes if there aren't any already + if include[0] in '"<': + include = include[1:-1] + + if include not in self._required_headers: + self._required_headers.append(include) + + # get_required_headers + def get_required_headers(self, where=None): + """Return a list of include files required for the function. + + @return: A list of include file names + @rtype: list of str + """ + return self._required_headers + # declare_local def declare_local(self, name, type, size=None, default=None): """Declare a local variable and return its final name. Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-09-21 09:51:06 UTC (rev 570) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-09-21 09:54:39 UTC (rev 571) @@ -160,8 +160,8 @@ @ivar virtual_func: The L{code manager<code_manager_t>} object that manages the virtual function. This is used by the arg policies to modify the virtual function. @type virtual_func: L{code_manager_t} - @group Methods called by the user of the class: append_code_block, subst_wrapper, subst_virtual, get_includes - @group Methods called by the function transformers: remove_arg, insert_arg, py_result_expr, require_include + @group Methods called by the user of the class: append_code_block, subst_wrapper, subst_virtual + @group Methods called by the function transformers: remove_arg, insert_arg, py_result_expr @author: Matthias Baas """ @@ -466,66 +466,6 @@ else: return "%s[%d]"%(pyresult, idx) - # require_include - def require_include(self, include, where=None): - """Declare an include file that is required for the code to compile. - - This function is supposed to be called by function transformer - objects to tell the substitution manager that they create code - that requires a particular header file. - - include is the name of the include file which may contain <> or "" - characters around the name. - - @param include: The name of the include file (may contain <> or "") - @type include: str - @param where: "wrapper", "virtual" or None (for both) - @type where: str - """ - if where not in ["wrapper", "virtual", None]: - raise ValueError, "Invalid 'where' argument: %s"%where - - if include=="": - return - - # Add apostrophes if there aren't any already - if include[0] not in '"<': - include = '"%s"'%include - - if where=="wrapper" or where==None: - if include not in self._wrapper_includes: - self._wrapper_includes.append(include) - - if where=="virtual" or where==None: - if include not in self._virtual_includes: - self._virtual_includes.append(include) - - # get_includes - def get_includes(self, where=None): - """Return a list of include files required for the wrapper and/or the virtual function. - - @param where: "wrapper", "virtual" or None (for a combined list) - @type where: str - @return: A list of include file names (all names contain <> or "") - @rtype: list of str - """ - if where not in ["wrapper", "virtual", None]: - raise ValueError, "Invalid 'where' argument: %s"%where - - if where=="wrapper": - return self._wrapper_includes[:] - - if where=="virtual": - return self._virtual_includes[:] - - # Merge both lists (without duplicating names) - res = self._virtual_includes[:] - for inc in self._wrapper_includes: - if inc not in res: - res.append(inc) - - return res - # subst_virtual def subst_virtual(self, template): """Perform a text substitution using the "virtual" variable set. Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-21 09:51:06 UTC (rev 570) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-21 09:54:39 UTC (rev 571) @@ -554,23 +554,30 @@ # Are we dealing with transformed non-virtual member functions? if maker_cls==code_creators.mem_fun_transformed_t: # Create the code creator that generates the function source code - mftw = code_creators.mem_fun_transformed_wrapper_t(self.curr_decl) + fwrapper = code_creators.mem_fun_transformed_wrapper_t(self.curr_decl) # and add it either to the wrapper class or just to the declaration # area of the cpp file if self.curr_code_creator.wrapper is None: - self.curr_code_creator.associated_decl_creators.append(mftw) + self.curr_code_creator.associated_decl_creators.append(fwrapper) else: - self.curr_code_creator.wrapper.adopt_creator(mftw) + self.curr_code_creator.wrapper.adopt_creator(fwrapper) # Set the wrapper so that the registration code will refer to it - maker.wrapper = mftw + maker.wrapper = fwrapper - # Include the gil_state header from the code repository. - if not self.__extmodule.is_system_header(code_repository.gil_state.file_name): - self.__extmodule.add_system_header( code_repository.gil_state.file_name ) - self.__extmodule.adopt_creator( code_creators.include_t( code_repository.gil_state.file_name ) - , self.__extmodule.first_include_index() + 1) + # Make sure all required headers are included... + required_headers = getattr(fwrapper, "get_required_headers", lambda : [])() + for header in required_headers: + # Check whether the header is already included + included = filter(lambda cc: isinstance(cc, code_creators.include_t) and cc.header==header, self.__extmodule.creators) + if not included: + self.__extmodule.add_include( header ) + # Check if it is a header from the code repository + if header in map(lambda mod: mod.file_name, code_repository.all): + # Make Py++ write the header + self.__extmodule.add_system_header( header ) + if self.curr_decl.has_static: #static_method should be created only once. found = filter( lambda creator: isinstance( creator, code_creators.static_method_t ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-09-23 20:31:12
|
Revision: 577 http://svn.sourceforge.net/pygccxml/?rev=577&view=rev Author: roman_yakovenko Date: 2006-09-23 13:30:56 -0700 (Sat, 23 Sep 2006) Log Message: ----------- adding initial support for automatic registrayion of opaque type Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/opaque_type_registrator.py pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py pyplusplus_dev/pyplusplus/file_writers/multiple_files.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_creators/opaque_type_registrator.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/opaque_type_registrator.py 2006-09-23 07:47:39 UTC (rev 576) +++ pyplusplus_dev/pyplusplus/code_creators/opaque_type_registrator.py 2006-09-23 20:30:56 UTC (rev 577) @@ -4,13 +4,16 @@ # http://www.boost.org/LICENSE_1_0.txt) import os +import code_creator import declaration_based -class opaque_type_registrator_t( declaration_based.declaration_based_t ): +class opaque_type_registrator_t( code_creator.code_creator_t + , declaration_based.declaration_based_t ): """ This class creates code that register static sized array """ def __init__( self, pointee ): + code_creator.code_creator_t.__init__( self ) declaration_based.declaration_based_t.__init__( self, pointee ) self.works_on_instance = False Modified: pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-09-23 07:47:39 UTC (rev 576) +++ pyplusplus_dev/pyplusplus/file_writers/class_multiple_files.py 2006-09-23 20:30:56 UTC (rev 577) @@ -108,7 +108,8 @@ for decl_creator in self.associated_decl_creators( creator ): source_code.append( '' ) source_code.append( decl_creator.create() ) - decl_creator.create = lambda: '' + if not isinstance( decl_creator, self.ref_count_creators ): + decl_creator.create = lambda: '' # Write the register() function... source_code.append( '' ) @@ -228,7 +229,8 @@ for creator in class_creator.associated_decl_creators: source_code.append( '' ) source_code.append( creator.create() ) - creator.create = lambda: '' + if not isinstance( creator, self.ref_count_creators ): + creator.create = lambda: '' # Write the register() function... source_code.append( '' ) Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-09-23 07:47:39 UTC (rev 576) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-09-23 20:30:56 UTC (rev 577) @@ -40,8 +40,8 @@ self.split_method_names = [] # List of methods from the split files self.write_main = write_main self.written_files = [] + self.ref_count_creators = ( code_creators.opaque_type_registrator_t, ) - def write_file( self, fpath, content ): self.written_files.append( fpath ) writer.writer_t.write_file( fpath, content ) @@ -198,7 +198,8 @@ for creator in declaration_creators: answer.append( '' ) answer.append( creator.create() ) - creator.create = lambda: '' + if not isinstance( creator, self.ref_count_creators ): + creator.create = lambda: '' # Write the register() function... answer.append( '' ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-23 07:47:39 UTC (rev 576) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-09-23 20:30:56 UTC (rev 577) @@ -131,7 +131,7 @@ self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] self.__exposed_free_fun_overloads = set() - self.__exposed_opaque_decls = set() + self.__exposed_opaque_decls = {} #decl : creator def _prepare_decls( self, decls, doc_extractor ): global DO_NOT_REPORT_MSGS @@ -319,18 +319,26 @@ return True #function transformers require wrapper return bool( self.redefined_funcs(class_inst) ) - def register_opaque_type( self, type_, call_policy ): + def register_opaque_type( self, creator, type_, call_policy ): if not decl_wrappers.is_return_opaque_pointer_policy( call_policy ): return #not our case naked_type = declarations.remove_cv( declarations.remove_pointer( type_ ) ) if decl_wrappers.python_traits.is_immutable( naked_type ): return #don't register opaque converter for immutable types. - if decl in self.__exposed_opaque_decls: - return #already registered - self.__exposed_opaque_decls.add( decl ) - creator = code_creators.opaque_type_registrator_t( decl ) - self.__extmodule.adopt_declaration_creator( creator ) - + decl = None + if declarations.is_class( naked_type ): + decl = declarations.class_traits.get_declaration( naked_type ) + else:#class declaration: + decl = declarations.class_declaration_traits.get_declaration( naked_type ) + opaque_type_registrator = None + if not id(decl) in self.__exposed_opaque_decls.keys(): + opaque_type_registrator = code_creators.opaque_type_registrator_t( decl ) + self.__exposed_opaque_decls[ id(decl) ] = opaque_type_registrator + self.__extmodule.adopt_declaration_creator( opaque_type_registrator ) + else: + opaque_type_registrator = self.__exposed_opaque_decls[ id(decl) ] + creator.associated_decl_creators.append(opaque_type_registrator) + def _adopt_free_operator( self, operator ): def adopt_operator_impl( operator, found_creators ): creator = filter( lambda creator: isinstance( creator, code_creators.class_t ) @@ -535,7 +543,6 @@ self.__types_db.update( self.curr_decl ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) maker_cls, fwrapper_cls = creators_wizard.find_out_mem_fun_creator_classes( self.curr_decl ) @@ -553,6 +560,8 @@ maker = maker_cls( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) + self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) + # Make sure all required headers are included... required_headers = getattr(fwrapper, "get_required_headers", lambda : [])() for header in required_headers: @@ -566,7 +575,6 @@ # Make Py++ write the header self.__extmodule.add_system_header( header ) - if self.curr_decl.has_static: #static_method should be created only once. found = filter( lambda creator: isinstance( creator, code_creators.static_method_t ) @@ -615,17 +623,18 @@ if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) self.__types_db.update( self.curr_decl ) if not self.curr_decl.parent.is_abstract \ and not declarations.is_reference( self.curr_decl.return_type ): maker = code_creators.casting_operator_t( operator=self.curr_decl ) self.__module_body.adopt_creator( maker ) + self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) #what to do if class is abstract if self.curr_decl.access_type == ACCESS_TYPES.PUBLIC: maker = code_creators.casting_member_operator_t( operator=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) + self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) def visit_free_function( self ): if self.curr_decl in self.__exposed_free_fun_overloads: @@ -645,7 +654,6 @@ self.__types_db.update( f ) if None is f.call_policies: f.call_policies = self.__call_policies_resolver( f ) - self.register_opaque_type( f.return_type, f.call_policies ) overloads_cls_creator = code_creators.free_fun_overloads_class_t( overloads ) self.__extmodule.adopt_declaration_creator( overloads_cls_creator ) @@ -653,13 +661,14 @@ overloads_reg = code_creators.free_fun_overloads_t( overloads_cls_creator ) self.curr_code_creator.adopt_creator( overloads_reg ) overloads_reg.associated_decl_creators.append( overloads_cls_creator ) + self.register_opaque_type( overloads_reg, f.return_type, f.call_policies ) else: self.__types_db.update( self.curr_decl ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - self.register_opaque_type( self.curr_decl.return_type, self.curr_decl.call_policies ) maker = code_creators.free_function_t( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) + self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) def visit_free_operator( self ): self.__types_db.update( self.curr_decl ) @@ -685,15 +694,15 @@ self.__types_db.update( f ) if None is f.call_policies: f.call_policies = self.__call_policies_resolver( f ) - self.register_opaque_type( f.return_type, f.call_policies ) overloads_cls_creator = code_creators.mem_fun_overloads_class_t( overloads ) self.__extmodule.adopt_declaration_creator( overloads_cls_creator ) overloads_reg = code_creators.mem_fun_overloads_t( overloads_cls_creator ) cls_creator.adopt_creator( overloads_reg ) + overloads_reg.associated_decl_creators.append( overloads_cls_creator ) - overloads_reg.associated_decl_creators.append( overloads_cls_creator ) + self.register_opaque_type( overloads_reg, f.return_type, f.call_policies ) return exposed def visit_class(self ): @@ -825,11 +834,11 @@ elif declarations.is_reference( self.curr_decl.type ): if None is self.curr_decl.getter_call_policies: self.curr_decl.getter_call_policies = self.__call_policies_resolver( self.curr_decl, 'get' ) - self.register_opaque_type( self.curr_decl.type, self.curr_decl.getter_call_policies ) if None is self.curr_decl.setter_call_policies: self.curr_decl.setter_call_policies = self.__call_policies_resolver( self.curr_decl, 'set' ) wrapper = code_creators.mem_var_ref_wrapper_t( variable=self.curr_decl ) maker = code_creators.mem_var_ref_t( variable=self.curr_decl, wrapper=wrapper ) + self.register_opaque_type( maker, self.curr_decl.type, self.curr_decl.getter_call_policies ) else: maker = code_creators.member_variable_t( variable=self.curr_decl ) if wrapper: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mb...@us...> - 2006-10-16 17:15:02
|
Revision: 663 http://svn.sourceforge.net/pygccxml/?rev=663&view=rev Author: mbaas Date: 2006-10-16 10:14:55 -0700 (Mon, 16 Oct 2006) Log Message: ----------- Fixed the handling of requested include files and made the function transformers request the convenience header (instead of the code creator). Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-10-16 09:44:27 UTC (rev 662) +++ pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-10-16 17:14:55 UTC (rev 663) @@ -67,6 +67,7 @@ # Create the substitution manager sm = function_transformers.substitution_manager_t(function, transformers=function.function_transformers) + sm.init_funcs() self._subst_manager = sm # def is_free_function(self): @@ -169,6 +170,13 @@ answer.append( '}' ) return os.linesep.join( answer ) + def get_required_headers(self): + """Return a list of required header file names.""" + res = [] + res += self._subst_manager.virtual_func.get_required_headers() + res += self._subst_manager.wrapper_func.get_required_headers() + return res + def _create_impl(self): answer = self.create_function() @@ -244,6 +252,7 @@ # Create the substitution manager sm = function_transformers.substitution_manager_t(function, transformers=function.function_transformers) + sm.init_funcs() self._subst_manager = sm # Stores the name of the variable that holds the override @@ -501,7 +510,7 @@ def get_required_headers(self): """Return a list of required header file names.""" - res = [code_repository.gil_guard.file_name, code_repository.convenience.file_name ] + res = [code_repository.gil_guard.file_name] res += self._subst_manager.virtual_func.get_required_headers() res += self._subst_manager.wrapper_func.get_required_headers() return res Modified: pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py 2006-10-16 09:44:27 UTC (rev 662) +++ pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py 2006-10-16 17:14:55 UTC (rev 663) @@ -17,6 +17,7 @@ """ import os from pygccxml import declarations +from pyplusplus import code_repository # output_t class output_t: @@ -236,6 +237,9 @@ # Replace the input parameter with the C array sm.wrapper_func.input_params[self.idx-1] = self.carray + # Request the convenience header + sm.wrapper_func.require_header(code_repository.convenience.file_name) + def wrapper_pre_call(self, sm): """Wrapper function code. """ @@ -327,6 +331,10 @@ # Declare an int which is used for the loop self.virtual_ivar = sm.virtual_func.declare_local("i", "int", default=0) + # Request the convenience header + sm.virtual_func.require_header(code_repository.convenience.file_name) + + def wrapper_post_call(self, sm): res = "" res += "// Copy the sequence '%s' into '%s'...\n"%(self.wrapper_cval, self.wrapper_pyval) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-10-24 21:02:21
|
Revision: 685 http://svn.sourceforge.net/pygccxml/?rev=685&view=rev Author: roman_yakovenko Date: 2006-10-24 14:02:08 -0700 (Tue, 24 Oct 2006) Log Message: ----------- changing the interface of FT feature Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/function_transformers/__init__.py pyplusplus_dev/pyplusplus/function_transformers/code_manager.py pyplusplus_dev/pyplusplus/function_transformers/subst.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-10-24 19:18:07 UTC (rev 684) +++ pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-10-24 21:02:08 UTC (rev 685) @@ -66,7 +66,8 @@ calldef_wrapper_t.__init__( self, function=function ) # Create the substitution manager - sm = function_transformers.substitution_manager_t(function, transformers=function.function_transformers) + sm = function_transformers.substitution_manager_t( function + , transformers=function.transformations[0].transformers) sm.init_funcs() self._subst_manager = sm @@ -251,7 +252,9 @@ calldef_wrapper_t.__init__( self, function=function ) # Create the substitution manager - sm = function_transformers.substitution_manager_t(function, transformers=function.function_transformers) + sm = function_transformers.substitution_manager_t(function + , transformers=function.transformations[0].transformers ) + sm.init_funcs() self._subst_manager = sm @@ -530,4 +533,4 @@ # argument list) self.declaration.arguments = self._subst_manager.wrapper_func.arg_list - return answer + return answer \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-10-24 19:18:07 UTC (rev 684) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-10-24 21:02:08 UTC (rev 685) @@ -8,6 +8,7 @@ import user_text import decl_wrapper from pygccxml import declarations +from pyplusplus import function_transformers as ft class calldef_t(decl_wrapper.decl_wrapper_t): """base class for all decl_wrappers callable objects classes.""" @@ -28,7 +29,7 @@ self._use_default_arguments = True self._create_with_signature = False self._overridable = None - self._function_transformers = None + self._transformations = None def get_call_policies(self): return self._call_policies @@ -78,16 +79,6 @@ else: return False - #def _finalize_impl( self, error_behavior ): - #if not isinstance( self, declarations.member_calldef_t ): - #pass - #elif self.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL: - #raise RuntimeError( "In order to expose pure virtual function, you should allow to Py++ to create wrapper." ) - #elif self.access_type == declarations.ACCESS_TYPES.PROTECTED: - #self.ignore = True - #else: - #pass - def get_overridable( self ): """Check if the method can be overridden.""" if None is self._overridable: @@ -115,28 +106,25 @@ overridable = property( get_overridable, set_overridable , doc = get_overridable.__doc__ ) - - def _get_function_transformers(self): + @property + def transformations(self): """Get method for property 'function_transformers'. Returns a reference to the internal list (which may be modified). """ - if None is self._function_transformers: + if None is self._transformations: #TODO: for trivial cases get_size( int&, int& ) Py++ should guess #function transformers - self._function_transformers = [] - return self._function_transformers + self._transformations = [] + return self._transformations - def _set_function_transformers(self, function_transformers): - """Set method for property 'function_transformers'.""" - self._function_transformers = function_transformers + def add_transformation(self, *args): + """Set method for property 'function_transformers'. - function_transformers = property( _get_function_transformers, _set_function_transformers, - doc = """A list of function transformer objects that should be applied to the generated C++ code (default: []). - The returned list is the internal list (not a copy) which may be modified. - @type: list""") + args is a list of transformers + """ + self.transformations.append( ft.function_transformation_t( args ) ) - def _exportable_impl_derived( self ): return '' Modified: pyplusplus_dev/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-10-24 19:18:07 UTC (rev 684) +++ pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-10-24 21:02:08 UTC (rev 685) @@ -18,4 +18,20 @@ from substitution_manager import substitution_manager_t from transformer import transformer_t -import transformers \ No newline at end of file +import transformers +from function_transformation import function_transformation_t + +def output( *args, **keywd ): + return transformers.output_t( *args, **keywd ) + +def input( *args, **keywd ): + return transformers.input_t( *args, **keywd ) + +def inout( *args, **keywd ): + return transformers.inout_t( *args, **keywd ) + +def input_array( *args, **keywd ): + return transformers.input_array_t( *args, **keywd ) + +def output_array( *args, **keywd ): + return transformers.output_array_t( *args, **keywd ) Modified: pyplusplus_dev/pyplusplus/function_transformers/code_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-10-24 19:18:07 UTC (rev 684) +++ pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-10-24 21:02:08 UTC (rev 685) @@ -359,4 +359,3 @@ # Invoke the inherited method that sets the actual variables code_manager_t.init_variables(self) - Modified: pyplusplus_dev/pyplusplus/function_transformers/subst.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/subst.py 2006-10-24 19:18:07 UTC (rev 684) +++ pyplusplus_dev/pyplusplus/function_transformers/subst.py 2006-10-24 21:02:08 UTC (rev 685) @@ -140,4 +140,3 @@ return "" return "\n".join(map(lambda s: ((n*" ")+s).rstrip(), code.split("\n"))) - Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-10-24 19:18:07 UTC (rev 684) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-10-24 21:02:08 UTC (rev 685) @@ -11,7 +11,6 @@ from pygccxml import declarations from code_manager import code_manager_t, wrapper_code_manager_t from transformer import transformer_t -from pyplusplus import decl_wrappers # substitution_manager_t class substitution_manager_t: @@ -521,6 +520,8 @@ @rtype: str """ arg_type = declarations.remove_alias( arg.type ) + #prevent recursive import + from pyplusplus import decl_wrappers if decl_wrappers.python_traits.is_immutable( arg_type ): return arg.name elif declarations.is_reference( arg_type ): Modified: pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py 2006-10-24 19:18:07 UTC (rev 684) +++ pyplusplus_dev/pyplusplus/module_creator/creators_wizard.py 2006-10-24 21:02:08 UTC (rev 685) @@ -20,9 +20,11 @@ maker_cls = None fwrapper_cls = None access_level = decl.parent.find_out_member_access_type( decl ) + if len( decl.transformations ) not in ( 0, 1 ): + raise RuntimeError( "Right now Py++ does not support multiple transformation applied on a single function." ) if access_level == ACCESS_TYPES.PUBLIC: if decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: - if decl.function_transformers: + if decl.transformations: maker_cls = code_creators.mem_fun_transformed_t fwrapper_cls = code_creators.mem_fun_transformed_wrapper_t else: @@ -31,7 +33,7 @@ fwrapper_cls = code_creators.mem_fun_pv_wrapper_t maker_cls = code_creators.mem_fun_pv_t else: - if decl.function_transformers: + if decl.transformations: fwrapper_cls = code_creators.mem_fun_v_transformed_wrapper_t maker_cls = code_creators.mem_fun_v_transformed_t else: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-10-27 23:02:23
|
Revision: 690 http://svn.sourceforge.net/pygccxml/?rev=690&view=rev Author: roman_yakovenko Date: 2006-10-27 16:02:12 -0700 (Fri, 27 Oct 2006) Log Message: ----------- adding support for multimap adding few message why function\variable is not exported Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py 2006-10-27 22:58:40 UTC (rev 689) +++ pyplusplus_dev/pyplusplus/code_creators/indexing_suites.py 2006-10-27 23:02:12 UTC (rev 690) @@ -91,7 +91,11 @@ answer.append( '%s.def( ' % self.parent.class_var_name) else: answer.append( 'def( ' ) - answer.append( algorithm.create_identifier(self, "::boost::python::indexing::container_suite" ) ) + bpi = algorithm.create_identifier(self, "::boost::python::indexing" ) + if self.declaration.indexing_suite.use_container_suite: + answer.append( bpi + '::container_suite' ) + else: + answer.append( bpi + '::' + self.declaration.name.split( '<' )[0] + '_suite' ) answer.append( '< ' ) answer.append( self.decl_identifier ) if self.does_user_disable_methods(): Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-10-27 22:58:40 UTC (rev 689) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-10-27 23:02:12 UTC (rev 690) @@ -197,7 +197,11 @@ , doc="boolean, if True, will use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS macro to expose declarations" \ +"Default value is False.") - + def _exportable_impl_derived(self): + if self.access_type == declarations.ACCESS_TYPES.PRIVATE \ + and self.virtuality == declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: + return "Py++ doesn't export private not virtual functions." + return '' class constructor_t( declarations.constructor_t, calldef_t ): """defines a set of properties, that will instruct Py++ how to expose the constructor""" def __init__(self, *arguments, **keywords): @@ -216,6 +220,8 @@ def _exportable_impl_derived( self ): if self.is_artificial: return 'Py++ does not exports compiler generated constructors' + if self.access_type == declarations.ACCESS_TYPES.PRIVATE: + return "Py++ doesn't export private constructor." return '' def does_define_implicit_conversion( self ): @@ -304,6 +310,9 @@ , doc="Gives right alias for operator()( __call__ ) and operator[]( __getitem__ )" ) def _exportable_impl_derived( self ): + if self.access_type == declarations.ACCESS_TYPES.PRIVATE \ + and self.virtuality == declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: + return "Py++ doesn't export private operators." return operators_helper.exportable( self ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py 2006-10-27 22:58:40 UTC (rev 689) +++ pyplusplus_dev/pyplusplus/decl_wrappers/indexing_suite2.py 2006-10-27 23:02:12 UTC (rev 690) @@ -62,7 +62,14 @@ self._disabled_methods = set() self._disabled_groups = set() self._default_applied = False + self._use_container_suite = False + def get_use_container_suite( self ): + return self._use_container_suite + def set_use_container_suite( self, value ): + self._use_container_suite = value + use_container_suite = property( get_use_container_suite, set_use_container_suite ) + def _get_container_class( self ): return self.__container_class container_class = property( _get_container_class Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-10-27 22:58:40 UTC (rev 689) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-10-27 23:02:12 UTC (rev 690) @@ -65,4 +65,7 @@ cls = declarations.class_traits.get_declaration( type_ ) if not cls.name: return "Py++ can not expose variables of with unnamed type." + if isinstance( self.parent, declarations.class_t ): + if self.access_type != declarations.ACCESS_TYPES.PUBLIC: + return "Py++ doesn't expose private or protected member variables." return '' Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-10-27 22:58:40 UTC (rev 689) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-10-27 23:02:12 UTC (rev 690) @@ -37,6 +37,7 @@ , 'deque<' : "boost/python/suite/indexing/deque.hpp" , 'list<' : "boost/python/suite/indexing/list.hpp" , 'map<' : "boost/python/suite/indexing/map.hpp" + , 'multimap<' : "boost/python/suite/indexing/multimap.hpp" , 'hash_map<' : "boost/python/suite/indexing/map.hpp" , 'set<' : "boost/python/suite/indexing/set.hpp" , 'hash_set<' : "boost/python/suite/indexing/set.hpp" @@ -52,6 +53,10 @@ , 'Py++, by default, does not expose compiler generated declarations.' , 'Py++ can not expose private class.' , 'Py++ will generate class wrapper - class contains definition of virtual or pure virtual member function' + , "Py++ doesn't expose private or protected member variables." + , "Py++ doesn't export private not virtual functions." + , "Py++ doesn't export private constructor." + , "Py++ doesn't export private operators." ] class creator_t( declarations.decl_visitor_t ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-10-28 12:38:56
|
Revision: 692 http://svn.sourceforge.net/pygccxml/?rev=692&view=rev Author: roman_yakovenko Date: 2006-10-28 05:38:46 -0700 (Sat, 28 Oct 2006) Log Message: ----------- introducing call_traits( http://boost.org/libs/utility/call_traits.htm ) and making small refactoring to use it Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/decl_wrappers/python_traits.py pyplusplus_dev/pyplusplus/function_transformers/code_manager.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-10-27 23:03:19 UTC (rev 691) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2006-10-28 12:38:46 UTC (rev 692) @@ -198,24 +198,8 @@ def function_call_args( self ): params = [] - for index in range( len( self.declaration.arguments ) ): - arg_type = declarations.remove_alias( self.declaration.arguments[index].type ) - if decl_wrappers.python_traits.is_immutable( arg_type ): - params.append( self.argument_name( index ) ) - elif declarations.is_reference( arg_type ): - no_ref = declarations.remove_reference( arg_type ) - if decl_wrappers.python_traits.is_immutable( no_ref ): - #pass by value - params.append( self.argument_name( index ) ) - else: - #pass by ref - params.append( 'boost::ref(%s)' % self.argument_name( index ) ) - elif declarations.is_pointer( arg_type ) \ - and not declarations.is_pointer( arg_type.base ) \ - and not decl_wrappers.python_traits.is_immutable( arg_type.base ): - params.append( 'boost::python::ptr(%s)' % self.argument_name( index ) ) - else: - params.append( self.argument_name( index ) ) + for index, arg in enumerate( self.declaration.arguments ): + params.append( decl_wrappers.python_traits.call_traits( arg.type ) % self.argument_name( index ) ) return ', '.join( params ) def wrapped_class_identifier( self ): Modified: pyplusplus_dev/pyplusplus/decl_wrappers/python_traits.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/python_traits.py 2006-10-27 23:03:19 UTC (rev 691) +++ pyplusplus_dev/pyplusplus/decl_wrappers/python_traits.py 2006-10-28 12:38:46 UTC (rev 692) @@ -16,4 +16,20 @@ or declarations.smart_pointer_traits.is_smart_pointer( type_ ) #todo is_complex, ... - +def call_traits( type_ ): + """http://boost.org/libs/utility/call_traits.htm""" + type_ = declarations.remove_alias( type_ ) + if is_immutable( type_ ): + return "%s" #pass by value + elif declarations.is_reference( type_ ): + no_ref = declarations.remove_reference( type_ ) + if is_immutable( no_ref ): + return "%s" #pass by value + else: + return "boost::ref(%s)" #pass by ref + elif declarations.is_pointer( type_ ) \ + and not is_immutable( type_.base ) \ + and not declarations.is_pointer( type_.base ): + return "boost::python::ptr(%s)" #pass by ptr + else: + return "%s" #pass by value Modified: pyplusplus_dev/pyplusplus/function_transformers/code_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-10-27 23:03:19 UTC (rev 691) +++ pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-10-28 12:38:46 UTC (rev 692) @@ -358,4 +358,3 @@ # Invoke the inherited method that sets the actual variables code_manager_t.init_variables(self) - Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-10-27 23:03:19 UTC (rev 691) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-10-28 12:38:46 UTC (rev 692) @@ -176,7 +176,8 @@ @param transformers: Function transformer objects @type transformers: list of transformer_t """ - + #prevent recursive import + from pyplusplus import decl_wrappers # Code manager for the virtual function self.virtual_func = code_manager_t() # Code manager for the wrapper function @@ -202,7 +203,9 @@ self.virtual_func.class_name = wrapper_class self.virtual_func.FUNC_NAME = decl.name self.virtual_func.CALL_FUNC_NAME = decl.name - self.virtual_func.input_params = map(lambda a: self._function_call_arg(a), decl.arguments) + self.virtual_func.input_params \ + = map( lambda arg: decl_wrappers.python_traits.call_traits( arg.type ) % arg.name + , decl.arguments ) self.wrapper_func.arg_list = decl.arguments[:] self.wrapper_func.class_name = wrapper_class @@ -488,42 +491,7 @@ decl = parent return None - # _function_call_arg - def _function_call_arg(self, arg): - """Return the C++ expression that represents arg in the actual function call. - This helper method returns a string that contains a C++ expression - that references the argument arg. This expression is supposed to - be used in the function invocation of which this is one input - parameter. The return value is one of three variants: - - - <name> - - boost::ref(<name>) - - boost::python::ptr(<name>) - - @rtype: str - """ - arg_type = declarations.remove_alias( arg.type ) - #prevent recursive import - from pyplusplus import decl_wrappers - if decl_wrappers.python_traits.is_immutable( arg_type ): - return arg.name - elif declarations.is_reference( arg_type ): - no_ref = declarations.remove_reference( arg_type ) - if decl_wrappers.python_traits.is_immutable( no_ref ): - #pass by value - return arg.name - else: - #pass by ref - return 'boost::ref(%s)' % arg.name - elif declarations.is_pointer( arg_type ) \ - and not declarations.is_pointer( arg_type.base ) \ - and not decl_wrappers.python_traits.is_immutable( arg_type.base ): - return 'boost::python::ptr(%s)' % arg.name - else: - return arg.name - - # return_virtual_result_t class return_virtual_result_t(transformer_t): """Extract and return the result value of the virtual function. @@ -609,4 +577,4 @@ print wm.subst_wrapper(template) print wm.get_includes() print wm.get_includes("virtual") - print wm.get_includes("wrapper") + print wm.get_includes("wrapper") \ 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-11-13 19:03:40
|
Revision: 724 http://svn.sourceforge.net/pygccxml/?rev=724&view=rev Author: roman_yakovenko Date: 2006-11-13 11:00:19 -0800 (Mon, 13 Nov 2006) Log Message: ----------- integrating return_pointee_value call policies Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py pyplusplus_dev/pyplusplus/module_builder/call_policies.py pyplusplus_dev/pyplusplus/module_creator/creator.py Modified: pyplusplus_dev/pyplusplus/code_repository/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/__init__.py 2006-11-13 15:43:25 UTC (rev 723) +++ pyplusplus_dev/pyplusplus/code_repository/__init__.py 2006-11-13 19:00:19 UTC (rev 724) @@ -16,8 +16,9 @@ import array_1 import gil_guard import convenience +import call_policies -all = [ array_1, gil_guard, convenience ] +all = [ array_1, gil_guard, convenience, call_policies ] headers = map( lambda f: f.file_name, all ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-11-13 15:43:25 UTC (rev 723) +++ pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-11-13 19:00:19 UTC (rev 724) @@ -80,7 +80,9 @@ from call_policies import return_by_value from call_policies import return_opaque_pointer from call_policies import return_value_policy +from call_policies import return_pointee_value from call_policies import is_return_opaque_pointer_policy +from call_policies import is_return_pointee_value_policy from decl_wrapper_printer import decl_wrapper_printer_t from decl_wrapper_printer import print_declarations Modified: pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2006-11-13 15:43:25 UTC (rev 723) +++ pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2006-11-13 19:00:19 UTC (rev 724) @@ -213,12 +213,18 @@ reference_existing_object = '::boost::python::reference_existing_object' return_by_value = '::boost::python::return_by_value' return_opaque_pointer = '::boost::python::return_opaque_pointer' +return_pointee_value = '::pyplusplus::call_policies::return_pointee_value' def return_value_policy( result_converter_generator, base=None): return return_value_policy_t( result_converter_generator, base ) - def is_return_opaque_pointer_policy( policy ): """returns True is policy represents return_value_policy<return_opaque_pointer>, False otherwise""" return isinstance( policy, return_value_policy_t ) \ and policy.result_converter_generator == return_opaque_pointer + +def is_return_pointee_value_policy( policy ): + """returns True is policy represents return_value_policy<return_pointee_value>, False otherwise""" + return isinstance( policy, return_value_policy_t ) \ + and policy.result_converter_generator == return_pointee_value + \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/module_builder/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2006-11-13 15:43:25 UTC (rev 723) +++ pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2006-11-13 19:00:19 UTC (rev 724) @@ -17,3 +17,4 @@ from pyplusplus.decl_wrappers import return_by_value from pyplusplus.decl_wrappers import return_opaque_pointer from pyplusplus.decl_wrappers import return_value_policy +from pyplusplus.decl_wrappers import return_pointee_value \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-11-13 15:43:25 UTC (rev 723) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-11-13 19:00:19 UTC (rev 724) @@ -139,6 +139,7 @@ self.__free_operators = [] self.__exposed_free_fun_overloads = set() self.__opaque_types_manager = opaque_types_manager.manager_t( self.__extmodule ) + self.__return_pointee_value_exists = False def _prepare_decls( self, decls, doc_extractor ): global DO_NOT_REPORT_MSGS @@ -350,6 +351,14 @@ creators.reverse() self.__module_body.adopt_creators( creators, 0 ) + def __on_demand_include_call_policies( self, call_policy ): + if not self.__return_pointee_value_exists \ + and decl_wrappers.is_return_pointee_value_policy( call_policy ): + self.__return_pointee_value_exists = True + self.__extmodule.add_include( code_repository.call_policies.file_name ) + self.__extmodule.add_system_header( code_repository.call_policies.file_name ) + + def create(self, decl_headers=None): """Create and return the module for the extension. @@ -388,7 +397,8 @@ self.__types_db.update( self.curr_decl ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - + self.__on_demand_include_call_policies( self.curr_decl.call_policies ) + maker_cls, fwrapper_cls = creators_wizard.find_out_mem_fun_creator_classes( self.curr_decl ) maker = None @@ -453,6 +463,7 @@ maker = code_creators.constructor_t( constructor=self.curr_decl, wrapper=cwrapper ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) + self.__on_demand_include_call_policies( self.curr_decl.call_policies ) self.curr_code_creator.adopt_creator( maker ) def visit_destructor( self ): @@ -469,7 +480,8 @@ def visit_casting_operator( self ): if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) - + self.__on_demand_include_call_policies( self.curr_decl.call_policies ) + self.__types_db.update( self.curr_decl ) if not self.curr_decl.parent.is_abstract and not declarations.is_reference( self.curr_decl.return_type ): maker = code_creators.casting_operator_t( operator=self.curr_decl ) @@ -499,6 +511,7 @@ self.__types_db.update( f ) if None is f.call_policies: f.call_policies = self.__call_policies_resolver( f ) + self.__on_demand_include_call_policies( f.call_policies ) overloads_cls_creator = code_creators.free_fun_overloads_class_t( overloads ) self.__extmodule.adopt_declaration_creator( overloads_cls_creator ) @@ -518,6 +531,8 @@ self.__types_db.update( self.curr_decl ) if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) + self.__on_demand_include_call_policies( self.curr_decl.call_policies ) + maker = code_creators.free_function_t( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) @@ -552,6 +567,7 @@ self.__types_db.update( f ) if None is f.call_policies: f.call_policies = self.__call_policies_resolver( f ) + self.__on_demand_include_call_policies( f.call_policies ) overloads_cls_creator = code_creators.mem_fun_overloads_class_t( overloads ) self.__extmodule.adopt_declaration_creator( overloads_cls_creator ) @@ -695,8 +711,10 @@ elif declarations.is_reference( self.curr_decl.type ): if None is self.curr_decl.getter_call_policies: self.curr_decl.getter_call_policies = self.__call_policies_resolver( self.curr_decl, 'get' ) + self.__on_demand_include_call_policies( self.curr_decl.getter_call_policies ) if None is self.curr_decl.setter_call_policies: self.curr_decl.setter_call_policies = self.__call_policies_resolver( self.curr_decl, 'set' ) + self.__on_demand_include_call_policies( self.curr_decl.setter_call_policies ) wrapper = code_creators.mem_var_ref_wrapper_t( variable=self.curr_decl ) maker = code_creators.mem_var_ref_t( variable=self.curr_decl, wrapper=wrapper ) self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:54:37
|
Revision: 698 http://svn.sourceforge.net/pygccxml/?rev=698&view=rev Author: roman_yakovenko Date: 2006-11-08 02:19:28 -0800 (Wed, 08 Nov 2006) Log Message: ----------- fixing treatment of opaque types Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py pyplusplus_dev/pyplusplus/module_creator/creator.py Added Paths: ----------- pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-11-08 10:08:43 UTC (rev 697) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-11-08 10:19:28 UTC (rev 698) @@ -53,6 +53,7 @@ self._equality_comparable = None self._less_than_comparable = None self._isuite_version = 1 + self._opaque = False def _get_indexing_suite_version( self ): return self._isuite_version @@ -112,7 +113,18 @@ less_than_comparable = property( _get_less_than_comparable, _set_less_than_comparable , doc="indicates existence of public operator<. " \ +"Default value is calculated, based on information presented in the declarations tree" ) + + def _get_opaque( self ): + return self._opaque + def _set_opaque( self, value ): + self._opaque = value + + opaque = property( _get_opaque, _set_opaque + , doc="If True, Py++ will treat return types and arguments T* as opaque types." \ + +"Thus it will be able to generate code, that uses " \ + +" BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID macro in a right places." ) + #this will only be exported if indexing suite is not None and only when needed class class_declaration_t( class_common_details_t , decl_wrapper.decl_wrapper_t Modified: pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py 2006-11-08 10:08:43 UTC (rev 697) +++ pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py 2006-11-08 10:19:28 UTC (rev 698) @@ -3,11 +3,14 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +import opaque_types_manager from pygccxml import declarations from pyplusplus import decl_wrappers from pyplusplus import code_creators from pyplusplus.decl_wrappers import python_traits +#TODO: add opaque to documentation + class resolver_t( object ): def __init__( self ): object.__init__( self ) @@ -82,6 +85,9 @@ if declarations.is_same( return_type, self.__const_wchar_pointer ): return decl_wrappers.return_value_policy( decl_wrappers.return_by_value ) + if opaque_types_manager.find_out_opaque_decl( return_type, ensure_opaque_decl=True ): + return decl_wrappers.return_value_policy( decl_wrappers.return_opaque_pointer ) + return None class return_internal_reference_resolver_t( resolver_t ): @@ -167,4 +173,4 @@ resolved = resolver( calldef, hint ) if resolved: return resolved - return None \ No newline at end of file + return None Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-11-08 10:08:43 UTC (rev 697) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-11-08 10:19:28 UTC (rev 698) @@ -6,6 +6,7 @@ import types_database import creators_wizard import class_organizer +import opaque_types_manager import call_policies_resolver from pygccxml import declarations from pyplusplus import decl_wrappers @@ -137,7 +138,7 @@ self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] self.__exposed_free_fun_overloads = set() - self.__exposed_opaque_decls = {} #decl : creator + self.__opaque_types_manager = opaque_types_manager.manager_t( self.__extmodule ) def _prepare_decls( self, decls, doc_extractor ): global DO_NOT_REPORT_MSGS @@ -227,25 +228,6 @@ new_ordered.extend( variables ) return new_ordered # - def register_opaque_type( self, creator, type_, call_policy ): - if not decl_wrappers.is_return_opaque_pointer_policy( call_policy ): - return #not our case - naked_type = declarations.remove_cv( declarations.remove_pointer( type_ ) ) - if decl_wrappers.python_traits.is_immutable( naked_type ): - return #don't register opaque converter for immutable types. - decl = None - if declarations.is_class( naked_type ): - decl = declarations.class_traits.get_declaration( naked_type ) - else:#class declaration: - decl = declarations.class_declaration_traits.get_declaration( naked_type ) - opaque_type_registrator = None - if id(decl) not in self.__exposed_opaque_decls.keys(): - opaque_type_registrator = code_creators.opaque_type_registrator_t( decl ) - self.__exposed_opaque_decls[ id(decl) ] = opaque_type_registrator - self.__extmodule.adopt_declaration_creator( opaque_type_registrator ) - else: - opaque_type_registrator = self.__exposed_opaque_decls[ id(decl) ] - creator.associated_decl_creators.append(opaque_type_registrator) def _adopt_free_operator( self, operator ): def adopt_operator_impl( operator, found_creators ): @@ -475,9 +457,8 @@ else: maker = maker_cls( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) - # Make sure all required headers are included... required_headers = getattr(fwrapper, "get_required_headers", lambda : [])() for header in required_headers: @@ -544,12 +525,12 @@ and not declarations.is_reference( self.curr_decl.return_type ): maker = code_creators.casting_operator_t( operator=self.curr_decl ) self.__module_body.adopt_creator( maker ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) #what to do if class is abstract if self.curr_decl.access_type == ACCESS_TYPES.PUBLIC: maker = code_creators.casting_member_operator_t( operator=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) def visit_free_function( self ): if self.curr_decl in self.__exposed_free_fun_overloads: @@ -576,7 +557,7 @@ overloads_reg = code_creators.free_fun_overloads_t( overloads_cls_creator ) self.curr_code_creator.adopt_creator( overloads_reg ) overloads_reg.associated_decl_creators.append( overloads_cls_creator ) - self.register_opaque_type( overloads_reg, f.return_type, f.call_policies ) + self.__opaque_types_manager.register_opaque( overloads_reg, overloads ) ctext_t = code_creators.custom_text_t for f in overloads: @@ -590,7 +571,7 @@ self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) maker = code_creators.free_function_t( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) ctext_t = code_creators.custom_text_t uc_creators = map( lambda uc: ctext_t( uc.text ), self.curr_decl.declaration_code ) @@ -630,7 +611,7 @@ cls_creator.adopt_creator( overloads_reg ) overloads_reg.associated_decl_creators.append( overloads_cls_creator ) - self.register_opaque_type( overloads_reg, f.return_type, f.call_policies ) + self.__opaque_types_manager.register_opaque( overloads_reg, overloads ) return exposed def visit_class(self ): @@ -769,7 +750,7 @@ self.curr_decl.setter_call_policies = self.__call_policies_resolver( self.curr_decl, 'set' ) wrapper = code_creators.mem_var_ref_wrapper_t( variable=self.curr_decl ) maker = code_creators.mem_var_ref_t( variable=self.curr_decl, wrapper=wrapper ) - self.register_opaque_type( maker, self.curr_decl.type, self.curr_decl.getter_call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) else: maker = code_creators.member_variable_t( variable=self.curr_decl ) if wrapper: Added: pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py (rev 0) +++ pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py 2006-11-08 10:19:28 UTC (rev 698) @@ -0,0 +1,82 @@ +# 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) + +from pygccxml import declarations +from pyplusplus import code_creators +from pyplusplus import decl_wrappers + +def find_out_opaque_decl( type_, ensure_opaque_decl ): + naked_type = declarations.remove_cv( type_ ) + if not declarations.is_pointer( naked_type ): + return None + naked_type = declarations.remove_pointer( declarations.remove_cv( type_ ) ) + if decl_wrappers.python_traits.is_immutable( naked_type ): + return None#immutable types could not be opaque + decl = None + if declarations.is_class( naked_type ): + decl = declarations.class_traits.get_declaration( naked_type ) + elif declarations.is_class_declaration( naked_type ):#class declaration: + decl = declarations.class_declaration_traits.get_declaration( naked_type ) + else: + return None + if ensure_opaque_decl: + if decl.opaque: + return decl + else: + return None + else: + return decl + + +class manager_t( object ): + def __init__( self, extmodule ): + object.__init__( self ) + self.__extmodule = extmodule + self.__exposed_opaque_decls = {} #decl: creator + + def __find_out_opaque_decls( self, decl ): + opaque_types = [] + is_opaque_policy = decl_wrappers.is_return_opaque_pointer_policy + if isinstance( decl, declarations.variable_t ): + opaque_decl = find_out_opaque_decl( decl.type, ensure_opaque_decl=True ) + if opaque_decl: + opaque_types.append( opaque_decl ) + elif is_opaque_policy( decl.getter_call_policies ) or is_opaque_policy( decl.setter_call_policies ): + opaque_decl = find_out_opaque_decl( decl.type, ensure_opaque_decl=False ) + if opaque_decl: + opaque_types.append( opaque_decl ) + else: + pass + elif isinstance( decl, declarations.calldef_t ): + if is_opaque_policy( decl.call_policies ): + opaque_decl = find_out_opaque_decl( decl.return_type, ensure_opaque_decl=False ) + if opaque_decl: + opaque_types.append( opaque_decl ) + all_types = decl.argument_types[:] + if decl.return_type: + all_types.append( decl.return_type ) + for type_ in all_types: + opaque_decl = find_out_opaque_decl( type_, ensure_opaque_decl=True ) + if opaque_decl: + opaque_types.append( opaque_decl ) + else: + pass + return opaque_types + + + def register_opaque( self, creator, decl_or_decls ): + opaque_decls = [] + for decl in declarations.make_flatten( decl_or_decls ): + opaque_decls.extend( self.__find_out_opaque_decls( decl ) ) + + for decl in opaque_decls: + opaque_type_registrator = None + if id(decl) not in self.__exposed_opaque_decls.keys(): + opaque_type_registrator = code_creators.opaque_type_registrator_t( decl ) + self.__exposed_opaque_decls[ id(decl) ] = opaque_type_registrator + self.__extmodule.adopt_declaration_creator( opaque_type_registrator ) + else: + opaque_type_registrator = self.__exposed_opaque_decls[ id(decl) ] + creator.associated_decl_creators.append(opaque_type_registrator) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:55:40
|
Revision: 715 http://svn.sourceforge.net/pygccxml/?rev=715&view=rev Author: roman_yakovenko Date: 2006-11-12 01:53:26 -0800 (Sun, 12 Nov 2006) Log Message: ----------- adding reference to declaration to transformers Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/function_transformers/__init__.py pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/function_transformers/transformer.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-12 09:53:26 UTC (rev 715) @@ -123,7 +123,7 @@ args is a list of transformers """ - self.transformations.append( ft.function_transformation_t( args, **keywd ) ) + self.transformations.append( ft.function_transformation_t( self, args, **keywd ) ) def _exportable_impl_derived( self ): return '' Modified: pyplusplus_dev/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-11-12 09:53:26 UTC (rev 715) @@ -22,16 +22,26 @@ from function_transformation import function_transformation_t def output( *args, **keywd ): - return transformers.output_t( *args, **keywd ) + def creator( function ): + return transformers.output_t( function, *args, **keywd ) + return creator def input( *args, **keywd ): - return transformers.input_t( *args, **keywd ) + def creator( function ): + return transformers.input_t( function, *args, **keywd ) + return creator def inout( *args, **keywd ): - return transformers.inout_t( *args, **keywd ) + def creator( function ): + return transformers.inout_t( function, *args, **keywd ) + return creator def input_array( *args, **keywd ): - return transformers.input_array_t( *args, **keywd ) + def creator( function ): + return transformers.input_array_t( function, *args, **keywd ) + return creator def output_array( *args, **keywd ): - return transformers.output_array_t( *args, **keywd ) + def creator( function ): + return transformers.output_array_t( function, *args, **keywd ) + return creator Modified: pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-12 09:53:26 UTC (rev 715) @@ -9,10 +9,10 @@ class function_transformation_t: - def __init__(self, transformers, **keywd): - """Constructor. - """ - self.__transformers = list(transformers) + def __init__(self, function, transformer_creator, **keywd): + """Constructor. """ + self.__function = function + self.__transformers = map( lambda tr_creator: tr_creator( function ), transformer_creator ) self.__thread_safe = keywd.get( 'thread_safe', False ) @property @@ -27,4 +27,4 @@ @property def thread_safe( self ): - return self.__thread_safe \ No newline at end of file + return self.__thread_safe Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-12 09:53:26 UTC (rev 715) @@ -12,6 +12,7 @@ from pygccxml import declarations from code_manager import code_manager_t, wrapper_code_manager_t from transformer import transformer_t +from transformer import return_ # substitution_manager_t class substitution_manager_t: @@ -262,7 +263,7 @@ """ # Append the default return_virtual_result_t code modifier - transformers = self.transformers+[return_virtual_result_t()] + transformers = self.transformers+[return_virtual_result_t(self.decl)] for cb in transformers: if hasattr(cb, "init_funcs"): @@ -361,6 +362,7 @@ return arg + # insert_arg def insert_arg(self, idx, arg, inputexpr): """Insert a new argument into the argument list of the wrapper function. @@ -475,8 +477,8 @@ to the list of code blocks inside the substitution_manager_t class. """ - def __init__(self): - transformer_t.__init__(self) + def __init__(self, function): + transformer_t.__init__(self, function) self.result_var = "<not initialized>" def __str__(self): Modified: pyplusplus_dev/pyplusplus/function_transformers/transformer.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-12 09:53:26 UTC (rev 715) @@ -11,8 +11,11 @@ import sys, os.path, copy, re, types from pygccxml import declarations, parser +return_ = -1 class transformer_t: + USE_1_BASED_INDEXING = False + """Base class for a function transformer. This class specifies the interface that a user written transformer @@ -23,19 +26,39 @@ @author: Matthias Baas """ - def __init__(self): + def __init__(self, function): """Constructor. """ - pass + self.__function = function + @property + def function( self ): + """reference to the function, for which a wrapper will be generated""" + return self.__function + def required_headers( self ): """Returns list of header files that transformer generated code depends on.""" return [] - def validate( self, function ): - """returns error message or None""" - raise NotImplementedError() + def get_argument( self, reference ): + if isinstance( reference, str ): + found = filter( lambda arg: arg.name == reference, self.function.arguments ) + if len( found ) == 1: + return found[0] + raise RuntimeError( "Argument with %s was not found" % reference ) + else: + assert isinstance( reference, int ) + if transformer_t.USE_1_BASED_INDEXING: + reference += 1 + return self.function.arguments[ reference ] + def get_type( self, reference ): + global return_ + if isinstance( reference, int ) and reference == return_: + return self.function.return_type + else: + return self.get_argument( reference ).type + def init_funcs(self, sm): """Wrapper initialization. @@ -114,4 +137,4 @@ def virtual_cleanup(self, sm): pass - \ No newline at end of file + Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-12 09:53:26 UTC (rev 715) @@ -30,53 +30,52 @@ void getValue(int& v) -> v = getValue() """ - def __init__(self, idx): - transformer.transformer_t.__init__( self ) + def __init__(self, function, arg_ref): + transformer.transformer_t.__init__( self, function ) """Constructor. The specified argument must be a reference or a pointer. - @param idx: Index of the argument that is an output value (the first arg has index 1). - @type idx: int + @param arg_ref: Index of the argument that is an output value (the first arg has index 1). + @type arg_ref: int """ - self.idx = idx + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) self.local_var = "<not initialized>" + if not declarations.is_pointer( self.arg.type ) and not declarations.is_reference( self.arg.type ): + raise ValueError( '%s\nin order to use "output" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) + def __str__(self): - return "output(%d)"%(self.idx) + return "output(%d)"%(self.arg_index) def init_funcs(self, sm): # Remove the specified output argument from the wrapper function - arg = sm.remove_arg(self.idx) + sm.remove_arg(self.arg_index+1) - # Do some sanity checking (whether the argument can actually be - # an output argument, i.e. it has to be a reference or a pointer) - reftype = arg.type - if not declarations.is_pointer( reftype ) and not declarations.is_reference( reftype ): - raise ValueError, '%s\nOutput variable %d ("%s") must be a reference or a pointer (got %s)'%(sm.decl, self.idx, arg.name, arg.type) - # Declare a local variable that will receive the output value - self.local_var = sm.wrapper_func.declare_variable(arg.name, str(reftype.base)) + self.local_var = sm.wrapper_func.declare_variable( self.arg.name, str(self.arg.type.base) ) # Append the output to the result tuple sm.wrapper_func.result_exprs.append(self.local_var) # Replace the expression in the C++ function call - if isinstance(reftype, declarations.pointer_t): - sm.wrapper_func.input_params[self.idx-1] = "&%s"%self.local_var - else: - sm.wrapper_func.input_params[self.idx-1] = self.local_var + input_param = self.local_var + if declarations.is_pointer( self.arg.type ): + input_param = "&%s" % self.local_var + + sm.wrapper_func.input_params[self.arg_index] = input_param def virtual_post_call(self, sm): - """Extract the C++ value after the call to the Python function. - """ - arg = sm.virtual_func.arg_list[self.idx-1] - res = "// Extract the C++ value for output argument '%s' (index: %d)\n"%(arg.name, self.idx) - if isinstance(arg.type, declarations.pointer_t): - res += "*" - res += "%s = boost::python::extract<%s>(%s);"%(arg.name, arg.type.base, sm.py_result_expr(self.local_var)) - return res - + """Extract the C++ value after the call to the Python function.""" + res = [] + if declarations.is_pointer( self.arg.type ): + res.append( "*" ) + res.append( "%s = boost::python::extract<%s>(%s);" \ + % ( self.arg.name, self.arg.type.base, sm.py_result_expr(self.local_var) ) ) + return ''.join( res ) + # input_t class input_t(transformer.transformer_t): """Handles a single input variable. @@ -86,7 +85,7 @@ void setValue(int& v) -> setValue(v) """ - def __init__(self, idx): + def __init__(self, function, idx): """Constructor. The specified argument must be a reference or a pointer. @@ -94,8 +93,8 @@ @param idx: Index of the argument that is an output value (the first arg has index 1). @type idx: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 def __str__(self): return "input(%d)"%(self.idx) @@ -121,7 +120,7 @@ void foo(int& v) -> v = foo(v) """ - def __init__(self, idx): + def __init__(self, function, idx): """Constructor. The specified argument must be a reference or a pointer. @@ -129,8 +128,8 @@ @param idx: Index of the argument that is an in/out value (the first arg has index 1). @type idx: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 self.local_var = "<not initialized>" def __str__(self): @@ -182,7 +181,7 @@ # v must be a sequence of 3 floats """ - def __init__(self, idx, size): + def __init__(self, function, idx, size): """Constructor. @param idx: Index of the argument that is an input array (the first arg has index 1). @@ -190,8 +189,8 @@ @param size: The fixed size of the input array @type size: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 self.size = size self.argname = None @@ -264,7 +263,7 @@ # v will be a list with 3 floats """ - def __init__(self, idx, size): + def __init__(self, function, idx, size): """Constructor. @param idx: Index of the argument that is an output array (the first arg has index 1). @@ -272,8 +271,8 @@ @param size: The fixed size of the output array @type size: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 self.size = size self.argname = None @@ -335,4 +334,4 @@ , 'size' : self.size , 'array_name' : self.argname } - \ 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-11-13 19:55:51
|
Revision: 707 http://svn.sourceforge.net/pygccxml/?rev=707&view=rev Author: roman_yakovenko Date: 2006-11-11 10:12:58 -0800 (Sat, 11 Nov 2006) Log Message: ----------- code_manager_t clean up Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev/pyplusplus/code_repository/gil_guard.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/function_transformers/code_manager.py pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-11-11 18:12:58 UTC (rev 707) @@ -247,11 +247,12 @@ self._subst_manager = sm # Stores the name of the variable that holds the override - self._override_var = sm.virtual_func.allocate_local(function.alias+"_callable") + self._override_var \ + = sm.virtual_func.declare_variable(function.alias + "_callable", 'boost::python::override') # Stores the name of the 'gstate' variable - self._gstate_var = sm.virtual_func.allocate_local("gstate") + self._gstate_var \ + = sm.virtual_func.declare_variable("gstate", 'pyplusplus::threading ::gil_guard_t' ) - def default_name(self): """Return the name of the 'default' function. @@ -339,7 +340,7 @@ def create_virtual_body(self): - thread_safe = getattr(self.declaration, "thread_safe", False) + thread_safe = self.declaration.transformations[0].thread_safe if thread_safe: body = """ @@ -415,25 +416,16 @@ # Replace the $-variables body = self._subst_manager.subst_virtual(body) -# template = [] -# template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' ) -# template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') ) -# template.append( 'else' ) -# template.append( self.indent('%(return_)s%(wrapped_class)s::%(name)s( %(args)s );') ) -# template = os.linesep.join( template ) - return body % { -# 'override' : self.override_identifier() 'override_var' : self._override_var , 'gstate_var' : self._gstate_var , 'alias' : self.declaration.alias -# , 'func_var' : "func_"+self.declaration.alias , 'inherited' : self.create_base_body() } def create_default_body(self): cls_wrapper_type = self.parent.full_name - cls_wrapper = self._subst_manager.wrapper_func.declare_local("cls_wrapper", cls_wrapper_type); + cls_wrapper = self._subst_manager.wrapper_func.declare_variable("cls_wrapper", cls_wrapper_type); # The name of the 'self' variable (i.e. first argument) selfname = self._subst_manager.wrapper_func.arg_list[0].name Modified: pyplusplus_dev/pyplusplus/code_repository/gil_guard.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/gil_guard.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/code_repository/gil_guard.py 2006-11-11 18:12:58 UTC (rev 707) @@ -59,4 +59,4 @@ #endif//__gil_guard_pyplusplus_hpp__ -""" +""" \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-11 18:12:58 UTC (rev 707) @@ -118,12 +118,12 @@ self._transformations = [] return self._transformations - def add_transformation(self, *args): + def add_transformation(self, *args, **keywd): """Set method for property 'function_transformers'. args is a list of transformers """ - self.transformations.append( ft.function_transformation_t( args ) ) + self.transformations.append( ft.function_transformation_t( args, **keywd ) ) def _exportable_impl_derived( self ): return '' Modified: pyplusplus_dev/pyplusplus/function_transformers/code_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-11-11 18:12:58 UTC (rev 707) @@ -19,7 +19,7 @@ manipulate a function and stores the actual substitution variables. Each function has its own code manager instance. - A code block can declare a local variable using L{declare_local()} + A code block can declare a local variable using L{declare_variable()} and it can manipulate one of the attributes that are used to initialize the final variables (see the documentation of the instance variables below). The final variables (such as RET_TYPE, @@ -81,22 +81,15 @@ # exception handler. self.exception_handler_exit = "throw;" - # Key:Variable name / Value:1 - self._allocated_vars = {} # Key:Variable name / Value:(type,size,default) self._declared_vars = {} - # A list with variable tuples: (name, type, size, default) - self._local_var_list = [] - # Required header file names - self._required_headers = [] - def substitute( self, template_code ): tmpl = string.Template(template_code) return tmpl.safe_substitute(self.__dict__) - # declare_local - def declare_local(self, name, type, size=None, default=None): + # declare_variable + def declare_variable(self, name, type, size=None, default=None): """Declare a local variable and return its final name. @param name: The desired variable name @@ -110,64 +103,10 @@ @return: The assigned variable name (which is guaranteed to be unique) @rtype: str """ - name = self.allocate_local(name) + name = self._make_name_unique(name) self._declared_vars[name] = (type,size,default) - self._local_var_list.append((name, type, size, default)) return name - # allocate_local - def allocate_local(self, name): - """Allocate a local variable name and return the final name. - - Allocate a variable name that is unique to the entire - function. The variable will not appear in the DECLARATIONS - block. Instead, the caller has to generate the declaration - code himself at an appropriate place. - - @param name: The desired variable name - @type name: str - @return: The assigned variable name (which is guaranteed to be unique) - @rtype: str - """ - name = self._make_name_unique(name) - self._allocated_vars[name] = 1 - return name - - # is_defined - def is_defined(self, name): - """Check if a variable name is already in use. - - The method returns True if name is the name of an argument or of - a local variable. - - @rtype: bool - """ - if name in self._allocated_vars: - return True - if filter(lambda a: a.name==name, self.arg_list): - return True - return False - - def local_type_str(self, name): - """Return the type of a local variable. - - An exception is raised if a variable called name does not exist. - - @return: Returns the type of the specified local variable. - @rtype: str - """ - if name not in self._allocated_vars: - raise ValueError, 'The type of local variable "%s" is unknown.'%name - if name not in self._declared_vars: - raise ValueError, 'Local variable "%s" not found.'%name - - type,size,default = self._declared_vars[name] - - if size==None: - return type - else: - return "*%s"%type - def init_variables(self): """Initialize the substitution variables. @@ -202,7 +141,8 @@ # Create the declaration block -> DECLARATIONS vardecls = [] - for varname,type,size,default in self._local_var_list: + for varname in self._declared_vars.keys(): + type,size,default = self._declared_vars[ varname ] if default==None: vd = "%s %s"%(type, varname) else: @@ -249,17 +189,14 @@ @return: A unique name based on the input name @rtype: str """ - if not self.is_defined(name): - return name - n = 2 + newname = name while 1: - newname = "%s_%d"%(name, n) - if not self.is_defined(newname): + if not self._declared_vars.has_key( newname ): return newname + newname = "%s_%d"%(name, n) n += 1 - # wrapper_code_manager_t class wrapper_code_manager_t(code_manager_t): """The CodeManager class for the wrapper function. Modified: pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-11 18:12:58 UTC (rev 707) @@ -9,11 +9,12 @@ class function_transformation_t: - def __init__(self, transformers): + def __init__(self, transformers, **keywd): """Constructor. """ self.__transformers = list(transformers) - + self.__thread_safe = keywd.get( 'thread_safe', False ) + @property def transformers( self ): return self.__transformers @@ -23,3 +24,7 @@ map( lambda transformer: headers.extend( transformer.required_headers() ) , self.transformers ) return headers + + @property + def thread_safe( self ): + return self.__thread_safe \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-11 18:12:58 UTC (rev 707) @@ -217,10 +217,8 @@ ret_type = None else: ret_type = decl.return_type -# self.wrapper_func.result_type = str(ret_type) self.wrapper_func.result_type = str(declarations.type_traits.remove_reference(ret_type)) - self.wrapper_func.result_var = self.wrapper_func.declare_local("result", self.wrapper_func.result_type) -# self.wrapper_func.result_var = self.wrapper_func.allocate_local("result") + self.wrapper_func.result_var = self.wrapper_func.declare_variable("result", self.wrapper_func.result_type) self.wrapper_func.result_exprs = [self.wrapper_func.result_var] self.virtual_func.ret_type = ret_type @@ -283,7 +281,7 @@ # inside the virtual function. if len(self.wrapper_func.result_exprs)>0: self.virtual_func.result_type = "boost::python::object" - self.virtual_func.result_var = self.virtual_func.declare_local("pyresult", self.virtual_func.result_type) + self.virtual_func.result_var = self.virtual_func.declare_variable("pyresult", self.virtual_func.result_type) self.wrapper_func.init_variables() self.virtual_func.init_variables() @@ -509,7 +507,7 @@ # Declare the local variable that will hold the return value # for the virtual function - self.result_var = sm.virtual_func.declare_local("result", sm.virtual_func.ret_type) + self.result_var = sm.virtual_func.declare_variable("result", sm.virtual_func.ret_type) # Replace the result expression if there is still the default # result expression (which will not work anyway) if sm.virtual_func.result_expr==sm.virtual_func.result_var: @@ -528,4 +526,3 @@ res = "// Extract the C++ return value\n" res += "%s = boost::python::extract<%s>(%s);"%(self.result_var, sm.virtual_func.ret_type, resexpr) return res - Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-11 18:12:58 UTC (rev 707) @@ -57,7 +57,7 @@ raise ValueError, '%s\nOutput variable %d ("%s") must be a reference or a pointer (got %s)'%(sm.decl, self.idx, arg.name, arg.type) # Declare a local variable that will receive the output value - self.local_var = sm.wrapper_func.declare_local(arg.name, str(reftype.base)) + self.local_var = sm.wrapper_func.declare_variable(arg.name, str(reftype.base)) # Append the output to the result tuple sm.wrapper_func.result_exprs.append(self.local_var) @@ -220,7 +220,7 @@ # Declare a variable that will hold the Python list # (this will be the input of the Python call in the virtual function) - self.pylist = sm.virtual_func.declare_local("py_"+arg.name, "boost::python::list") + self.pylist = sm.virtual_func.declare_variable("py_"+arg.name, "boost::python::list") # Replace the removed argument with a Python object. newarg = declarations.argument_t(arg.name, declarations.dummy_type_t("boost::python::object")) @@ -230,7 +230,7 @@ self.basetype = str(arg.type.base).replace("const", "").strip() # Declare a variable that will hold the C array... - self.carray = sm.wrapper_func.declare_local("c_"+arg.name, self.basetype, size=self.size) + self.carray = sm.wrapper_func.declare_variable("c_"+arg.name, self.basetype, size=self.size) # Replace the input parameter with the C array sm.wrapper_func.input_params[self.idx-1] = self.carray @@ -307,9 +307,9 @@ # Wrapper: # Declare a variable that will hold the C array... - self.wrapper_cval = sm.wrapper_func.declare_local("c_"+self.argname, self.basetype, size=self.size) + self.wrapper_cval = sm.wrapper_func.declare_variable("c_"+self.argname, self.basetype, size=self.size) # Declare a Python list which will receive the output... - self.wrapper_pyval = sm.wrapper_func.declare_local(self.argname, "boost::python::list") + self.wrapper_pyval = sm.wrapper_func.declare_variable(self.argname, "boost::python::list") # ...and add it to the result sm.wrapper_func.result_exprs.append(arg.name) @@ -318,7 +318,7 @@ # Virtual: # Declare a variable that will receive the Python list - self.virtual_pyval = sm.virtual_func.declare_local("py_"+self.argname, "boost::python::object") + self.virtual_pyval = sm.virtual_func.declare_variable("py_"+self.argname, "boost::python::object") def wrapper_post_call(self, sm): tmpl = '%(pypp_con)s::copy_container( %(array)s, %(array)s + %(size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-18 19:20:06
|
Revision: 733 http://svn.sourceforge.net/pygccxml/?rev=733&view=rev Author: roman_yakovenko Date: 2006-11-18 11:20:05 -0800 (Sat, 18 Nov 2006) Log Message: ----------- introducing registration order problem warning Modified Paths: -------------- pyplusplus_dev/pyplusplus/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py Modified: pyplusplus_dev/pyplusplus/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/__init__.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/__init__.py 2006-11-18 19:20:05 UTC (rev 733) @@ -33,7 +33,7 @@ from _logging_ import multi_line_formatter_t -__version__ = '0.7.1' +__version__ = '0.8.3' #Known issues: #3. Modified: pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-11-18 19:20:05 UTC (rev 733) @@ -33,6 +33,8 @@ """ +import algorithm + from decl_wrapper import decl_wrapper_t from calldef_wrapper import calldef_t Modified: pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py 2006-11-18 19:20:05 UTC (rev 733) @@ -9,6 +9,7 @@ """ import re +from pygccxml import declarations def creators_affect_on_me( me ): """This algorithm finds all code creators that can influence on code generated @@ -92,4 +93,45 @@ new_name = nsalias.alias + '::' + full_name[ len(fnsname) : ] return new_name else: - return full_name \ No newline at end of file + return full_name + +class registration_order: + @staticmethod + def is_related( t1, t2 ): + if declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): + return registration_order.is_related( declarations.remove_pointer( t1 ) + , declarations.remove_pointer( t2 ) ) + elif declarations.is_pointer( t1 ) and not declarations.is_pointer( t2 ): + t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) + t2 = declarations.remove_cv( t2 ) + if declarations.is_same( t1, t2 ): + return 1 + elif not declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): + t1 = declarations.remove_cv( t1 ) + t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) + if declarations.is_same( t1, t2 ): + return -1 + else: #not is_pointer( t1 ) and not is_pointer( t2 ): + if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) \ + and declarations.is_bool( t2 ): + return -1 + elif declarations.is_bool( t1 ) \ + and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): + return 1 + else: + pass + return None + + @staticmethod + def select_problematics( calldef ): + if 1 != len( calldef.required_args ): + return [] + problematics = [] + for f in calldef.overloads: + if 1 != len( f.required_args ): + continue + if None != registration_order.is_related( calldef.arguments[0].type, f.arguments[0].type ): + problematics.append( f ) + return problematics + + \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-18 19:20:05 UTC (rev 733) @@ -5,7 +5,9 @@ """defines class that configure "callable" declaration exposing""" +import os import user_text +import algorithm import decl_wrapper from pygccxml import declarations from pyplusplus import function_transformers as ft @@ -163,7 +165,6 @@ #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 - #TODO: add warning to the case described in registration_order.rest document. if len( self.arguments ) > calldef_t.BOOST_PYTHON_MAX_ARITY: tmp = [ "The function has more than %d arguments ( %d ). " ] tmp.append( "You should adjust BOOST_PYTHON_MAX_ARITY macro." ) @@ -183,6 +184,16 @@ if False == self.overridable: msgs.append( self._non_overridable_reason) + + problematics = algorithm.registration_order.select_problematics( self ) + if problematics: + tmp = [ "The function introduces registration order problem. " ] + tmp.append( "For more information read next document: " + + "http://language-binding.net/pyplusplus/documentation/functions/registration_order.html" ) + tmp.append( "Problematic functions: " ) + for f in problematics: + tmp.append( os.linesep + '\t' + str(f) ) + msgs.append( os.linesep.join( tmp ) ) return msgs class member_function_t( declarations.member_function_t, calldef_t ): Modified: pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py 2006-11-18 19:20:05 UTC (rev 733) @@ -4,6 +4,7 @@ # http://www.boost.org/LICENSE_1_0.txt) from pygccxml import declarations +from pyplusplus import decl_wrappers class COLOR: WHITE = 0 @@ -141,27 +142,7 @@ return groups def __cmp_types( self, t1, t2 ): - if declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): - return self.__cmp_types( declarations.remove_pointer( t1 ) - , declarations.remove_pointer( t2 ) ) - elif declarations.is_pointer( t1 ) and not declarations.is_pointer( t2 ): - t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) - t2 = declarations.remove_cv( t2 ) - if declarations.is_same( t1, t2 ): - return 1 - elif not declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): - t1 = declarations.remove_cv( t1 ) - t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) - if declarations.is_same( t1, t2 ): - return -1 - else: #not is_pointer( t1 ) and not is_pointer( t2 ): - if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) and declarations.is_bool( t2 ): - return -1 - elif declarations.is_bool( t1 ) and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): - return 1 - else: - pass - return None + return decl_wrappers.algorithm.registration_order.is_related( t1, t2 ) def __cmp( self, f1, f2 ): result = self.__cmp_types( f1.arguments[0].type, f2.arguments[0].type ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-12-05 21:36:39
|
Revision: 778 http://svn.sourceforge.net/pygccxml/?rev=778&view=rev Author: roman_yakovenko Date: 2006-12-05 13:36:37 -0800 (Tue, 05 Dec 2006) Log Message: ----------- switching to use central repository for all messages. This refactoring will help users to define filter that will ignore selected messages Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py Added Paths: ----------- pyplusplus_dev/pyplusplus/messages/ pyplusplus_dev/pyplusplus/messages/__init__.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-12-05 21:34:41 UTC (rev 777) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-12-05 21:36:37 UTC (rev 778) @@ -9,6 +9,8 @@ import user_text import algorithm import decl_wrapper +import python_traits +from pyplusplus import messages from pygccxml import declarations from pyplusplus import function_transformers as ft @@ -88,15 +90,7 @@ 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." + self._non_overridable_reason = messages.W1003 else: self._overridable = True self._non_overridable_reason = "" @@ -138,20 +132,19 @@ ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) , units ) if ptr2functions: - return "boost.python can not expose function, which takes as argument/returns pointer to function." \ - + " See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information." + return messages.W1004 #Function that take as agrument some instance of non public class #will not be exported. Same to the return variable if isinstance( units[-1], declarations.declarated_t ): dtype = units[-1] if isinstance( dtype.declaration.parent, declarations.class_t ): if dtype.declaration not in dtype.declaration.parent.public_members: - return "Py++ can not expose function that takes as argument/returns instance of non public class. Generated code will not compile." + return messages.W1005 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 "Py++ can not expose function that takes as argument/returns C++ arrays. This will be changed in near future." + return messages.W1006 return self._exportable_impl_derived() def _readme_impl( self ): @@ -160,44 +153,34 @@ return False type_no_ref = declarations.remove_reference( type_ ) return not declarations.is_const( type_no_ref ) \ - and declarations.is_fundamental( type_no_ref ) + and python_traits.is_immutable( type_no_ref ) msgs = [] #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 = [ "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://www.boost.org/libs/python/doc/v2/configuration.html" ) - tmp = ' '.join( tmp ) - msgs.append( tmp % ( calldef_t.BOOST_PYTHON_MAX_ARITY, len( self.arguments ) ) ) + msgs.append( messages.W1007 % ( calldef_t.BOOST_PYTHON_MAX_ARITY, len( self.arguments ) ) ) if self.transformations: #if user defined transformation, than I think it took care of the problems return msgs if suspicious_type( self.return_type ) and None is self.call_policies: - msgs.append( 'The function "%s" returns non-const reference to C++ fundamental type - value can not be modified from Python.' % str( self ) ) + msgs.append( messages.W1008 ) for index, arg in enumerate( self.arguments ): if suspicious_type( arg.type ): - 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 ) ) + msgs.append( messages.W1009 % ( arg.name, index ) ) if False == self.overridable: msgs.append( self._non_overridable_reason) problematics = algorithm.registration_order.select_problematics( self ) if problematics: - tmp = [ "The function introduces registration order problem. " ] - tmp.append( "For more information read next document: " - + "http://language-binding.net/pyplusplus/documentation/functions/registration_order.html" ) - tmp.append( "Problematic functions: " ) + tmp = [] for f in problematics: tmp.append( os.linesep + '\t' + str(f) ) - msgs.append( os.linesep.join( tmp ) ) + msgs.append( messages.W1010 % os.linesep.join( tmp ) ) return msgs class member_function_t( declarations.member_function_t, calldef_t ): @@ -218,7 +201,7 @@ def _exportable_impl_derived(self): if self.access_type == declarations.ACCESS_TYPES.PRIVATE \ and self.virtuality == declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: - return "Py++ doesn't export private not virtual functions." + return messages.W1011 return '' class constructor_t( declarations.constructor_t, calldef_t ): @@ -238,9 +221,9 @@ def _exportable_impl_derived( self ): if self.is_artificial: - return 'Py++ does not exports compiler generated constructors' + return messages.W1012 if self.access_type == declarations.ACCESS_TYPES.PRIVATE: - return "Py++ doesn't export private constructor." + return messages.W1013 return '' def does_define_implicit_conversion( self ): @@ -304,9 +287,7 @@ if isinstance( oper, declarations.member_operator_t ) and oper.symbol in ( '()', '[]' ): return '' if not operators_helper.is_supported( oper ): - msg = [ '"%s" is not supported. ' % oper.name ] - msg.append( 'See Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/operators.html#introduction.' ) - return ' '.join( msg ) + return messages.W1014 % oper.name return '' class member_operator_t( declarations.member_operator_t, calldef_t ): @@ -331,7 +312,7 @@ def _exportable_impl_derived( self ): if self.access_type == declarations.ACCESS_TYPES.PRIVATE \ and self.virtuality == declarations.VIRTUALITY_TYPES.NOT_VIRTUAL: - return "Py++ doesn't export private operators." + return messages.W1015 return operators_helper.exportable( self ) @@ -404,9 +385,9 @@ def _exportable_impl_derived( self ): if not declarations.is_fundamental( self.return_type ) and not self.has_const: - return 'Py++ does not exports non-const casting operators with user defined type as return value. This could be change in future.' + return messages.W1016 if self.access_type != declarations.ACCESS_TYPES.PUBLIC: - return "Py++ doesn't export non-public casting operators." + return messages.W1017 return '' Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-12-05 21:34:41 UTC (rev 777) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-12-05 21:36:37 UTC (rev 778) @@ -10,6 +10,7 @@ import properties import decl_wrapper import scopedef_wrapper +from pyplusplus import messages from pygccxml import declarations import indexing_suite1 as isuite1 import indexing_suite2 as isuite2 @@ -289,12 +290,12 @@ def _exportable_impl( self ): if not self.name: - return 'Py++ can not expose unnamed classes.' + return messages.W1018 #it is possible to do so, but not for unnamed classes defined under namespace. if isinstance( self.parent, declarations.namespace_t ): return '' if not self in self.parent.public_members: - return 'Py++ can not expose private class.' + return messages.W1019 return '' def get_exportable_members( self, sort=None ): @@ -433,40 +434,38 @@ """ explanation = [] if self.wrapper_code: - explanation.append( "Py++ will generate class wrapper - hand written code should be added to the wrapper class" ) + explanation.append( messages.W1020 ) if self.null_constructor_body: - explanation.append( "Py++ will generate class wrapper - hand written code should be added to the wrapper class null constructor body" ) + explanation.append( messages.W1021 ) if self.copy_constructor_body: - explanation.append( "Py++ will generate class wrapper - hand written code should be added to the wrapper class copy constructor body" ) + explanation.append( messages.W1022 ) if self.redefined_funcs(): - explanation.append( "Py++ will generate class wrapper - there are few functions that should be redefined in class wrapper" ) + explanation.append( messages.W1023 ) for member in self.get_exportable_members(): if isinstance( member, declarations.destructor_t ): continue if isinstance( member, declarations.variable_t ): if member.bits: - explanation.append( "Py++ will generate class wrapper - class contains bit field member variable" ) + explanation.append( messages.W1024 ) if declarations.is_pointer( member.type ): - explanation.append( "Py++ will generate class wrapper - class contains T* member variable" ) + explanation.append( messages.W1025 ) if declarations.is_reference( member.type ): - explanation.append( "Py++ will generate class wrapper - class contains T& member variable" ) + explanation.append( messages.W1026 ) if declarations.is_array( member.type ): - explanation.append( "Py++ will generate class wrapper - class contains array member variable" ) + explanation.append( messages.W1027 ) if isinstance( member, declarations.class_t ) and member.is_wrapper_needed(): - explanation.append( "Py++ will generate class wrapper - class contains definition of nested class that requires wrapper class" ) + explanation.append( messages.W1028 ) if isinstance( member, declarations.calldef_t ): if isinstance( member, declarations.constructor_t ) and member.body: - explanation.append( "Py++ will generate class wrapper - hand written code should be added to the wrapper class constructor body" ) + explanation.append( messages.W1029 ) if member.virtuality != VIRTUALITY_TYPES.NOT_VIRTUAL: - explanation.append( "Py++ will generate class wrapper - class contains definition of virtual or pure virtual member function" ) + explanation.append( messages.W1030 ) if member.access_type in ( ACCESS_TYPES.PROTECTED, ACCESS_TYPES.PRIVATE ): - explanation.append( "Py++ will generate class wrapper - user asked to expose non - public member function" ) - #if member.function_transformers: - # return True #function transformers require wrapper + explanation.append( messages.W1031 ) return explanation def _readme_impl( self ): Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-12-05 21:34:41 UTC (rev 777) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-12-05 21:36:37 UTC (rev 778) @@ -9,6 +9,7 @@ import algorithm from pyplusplus import _logging_ from pygccxml import declarations +from pyplusplus import messages class decl_wrapper_t(object): """Declaration interface. @@ -38,7 +39,7 @@ def _set_documentation( self, value ): self._documentation = value documentation = property( _get_documentation, _set_documentation - , doc="Using this property you can set documentatio of exported declaration." ) + , doc="Using this property you can set documentation of the declaration." ) def _generate_valid_name(self, name=None): if name == None: @@ -94,12 +95,12 @@ def get_exportable( self ): if self._exportable is None: if self.name.startswith( '__' ): - self._exportable_reason = 'Py++, by default, does not expose internal compilers declarations. Names of those declarations usually start with "__".' + self._exportable_reason = messages.W1000 elif self.location and self.location.file_name == "<internal>": - self._exportable_reason = 'Py++, by default, does not expose internal declarations (those that gccxml say belong to "<internal>" header).' + self._exportable_reason = messages.W1001 elif self.is_artificial \ and not isinstance( self, ( declarations.class_t, declarations.enumeration_t ) ): - self._exportable_reason = 'Py++, by default, does not expose compiler generated declarations.' + self._exportable_reason = messages.W1002 else: self._exportable_reason = self._exportable_impl( ) self._exportable = not bool( self._exportable_reason ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py 2006-12-05 21:34:41 UTC (rev 777) +++ pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py 2006-12-05 21:36:37 UTC (rev 778) @@ -5,8 +5,9 @@ """defines class that configure enumeration declaration exposing""" -from pygccxml import declarations import decl_wrapper +from pyplusplus import messages +from pygccxml import declarations class enumeration_t(decl_wrapper.decl_wrapper_t, declarations.enumeration_t): """defines a set of properties, that will instruct Py++ how to expose the enumeration @@ -72,7 +73,5 @@ 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. " ) + msgs.append( messages.W1032 ) return msgs Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-12-05 21:34:41 UTC (rev 777) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-12-05 21:36:37 UTC (rev 778) @@ -6,6 +6,7 @@ """defines class that configure global and member variable exposing""" import decl_wrapper +from pyplusplus import messages from pygccxml import declarations from pyplusplus.decl_wrappers import python_traits @@ -43,29 +44,28 @@ def _exportable_impl( self ): if not self.name: - return "Py++ can not expose unnamed variables" + return messages.W1033 if self.bits == 0 and self.name == "": - return "Py++ can not expose alignement bit." + return messages.W1034 type_ = declarations.remove_alias( self.type ) type_ = declarations.remove_const( type_ ) if declarations.is_pointer( type_ ): if self.type_qualifiers.has_static: - return "Py++ can not expose static pointer member variables. This could be changed in future." + return messages.W1035 if python_traits.is_immutable( type_.base ): - return "Py++ can not expose pointer to Python immutable member variables. This could be changed in future." + return messages.W1036 units = declarations.decompose_type( type_ ) ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) , units ) if ptr2functions: - return "boost.python can not expose variables, which are pointer to function." \ - + " See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information." + return messages.W1037 type_ = declarations.remove_pointer( type_ ) if declarations.class_traits.is_my_case( type_ ): cls = declarations.class_traits.get_declaration( type_ ) if not cls.name: - return "Py++ can not expose variables of with unnamed type." + return messages.W1038 if isinstance( self.parent, declarations.class_t ): if self.access_type != declarations.ACCESS_TYPES.PUBLIC: - return "Py++ doesn't expose private or protected member variables." + return messages.W1039 return '' Added: pyplusplus_dev/pyplusplus/messages/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/__init__.py (rev 0) +++ pyplusplus_dev/pyplusplus/messages/__init__.py 2006-12-05 21:36:37 UTC (rev 778) @@ -0,0 +1,127 @@ +# 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) + +"""This package defines all user messages( warnings + errors ), which will be +reported to user. +""" + +W1000 = 'Py++, by default, does not expose internal compilers declarations.'\ + 'Names of those declarations usually start with "__".' + +W1001 = 'Py++, by default, does not expose internal declarations. ' \ + 'GCC-XML reports that these declaration belong to "<internal>" header.' + +W1002 = 'Py++, by default, does not expose compiler generated declarations.' + +W1003 = 'Virtual functions that returns const reference can not be overriden from Python. ' \ + 'Reason: boost::python::override::operator()(...) saves the result of the marshaling ' \ + '(from Python to C++) on the stack. Thus operator() returns reference ' \ + 'to a temporary variable. Consider to use "Function Transformation" functionality ' \ + 'to solve the problem.' + +W1004 = 'Boost.Python library can not expose function, which takes as argument/returns ' \ + 'pointer to function. ' \ + ' See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information.' + +W1005 = 'Py++ can not expose function that takes as argument/returns instance of non public class. ' \ + 'Generated code will not compile.' + +W1006 = 'Py++ need your help to expose function that takes as argument/returns C++ arrays. ' \ + 'Take a look on "Function Transformation" functionality and define the transformation.' + +W1007 = 'The function has more than %d arguments ( %d ). ' \ + 'You should adjust BOOST_PYTHON_MAX_ARITY macro. ' \ + 'For more information see: http://www.boost.org/libs/python/doc/v2/configuration.html' + +W1008 = 'The function returns non-const reference to "Python immutable" type. ' \ + 'The value can not be modified from Python. ' + +W1009 = 'The function takes as argument (name=%s, pos=%d ) non-const reference ' \ + 'to Python immutable type - function could not be called from Python. ' \ + 'Take a look on "Function Transformation" functionality and define the transformation.' + +W1010 = 'The function introduces registration order problem. ' \ + 'For more information about the problem read next document: ' \ + 'http://language-binding.net/pyplusplus/documentation/functions/registration_order.html ' \ + 'Problematic functions list: %s' + +W1011 = "Py++ doesn't export private not virtual functions." + +W1012 = 'Py++ does not exports compiler generated constructors.' + +W1013 = "Py++ doesn't export private constructor." + +W1014 = '"%s" is not supported. ' \ + 'See Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/operators.html#introduction.' + +W1015 = "Py++ doesn't export private operators." + +W1016 = 'Py++ does not exports non-const casting operators with user defined type as return value. ' \ + 'This could be change in future.' + +W1017 = "Py++ doesn't export non-public casting operators." + +W1018 = 'Py++ can not expose unnamed classes.' + +W1019 = 'Py++ can not expose private class.' + +W1020 = "Py++ will generate class wrapper - hand written code should be added to the wrapper class" + +W1021 = "Py++ will generate class wrapper - hand written code should be added to the wrapper class null constructor body" + +W1022 = "Py++ will generate class wrapper - hand written code should be added to the wrapper class copy constructor body" + +W1023 = "Py++ will generate class wrapper - there are few functions that should be redefined in class wrapper" + +W1024 = "Py++ will generate class wrapper - class contains bit field member variable" + +W1025 = "Py++ will generate class wrapper - class contains T* member variable" + +W1026 = "Py++ will generate class wrapper - class contains T& member variable" + +W1027 = "Py++ will generate class wrapper - class contains array member variable" + +W1028 = "Py++ will generate class wrapper - class contains definition of nested class that requires wrapper class" + +W1029 = "Py++ will generate class wrapper - hand written code should be added to the wrapper class constructor body" + +W1030 = "Py++ will generate class wrapper - class contains definition of virtual or pure virtual member function" + +W1031 = "Py++ will generate class wrapper - user asked to expose non - public member function" + +W1032 = "Boost.Python library 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. " + +W1033 = "Py++ can not expose unnamed variables" + +W1034 = "Py++ can not expose alignement bit." + +W1035 = "Py++ can not expose static pointer member variables. This could be changed in future." + +W1036 = "Py++ can not expose pointer to Python immutable member variables. This could be changed in future." + +W1037 = "Boost.Python library can not expose variables, which are pointer to function." \ + " See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information." + +W1038 = "Py++ can not expose variables of with unnamed type." + +W1039 = "Py++ doesn't expose private or protected member variables." + +W1040 = 'The declaration is unexposed, but there are other declarations, which refer to it.' \ + 'This could cause "no to_python converter found" run time error.' \ + 'Declarations: %s' + + + + + + + + + + + Modified: pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2006-12-05 21:34:41 UTC (rev 777) +++ pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2006-12-05 21:36:37 UTC (rev 778) @@ -6,6 +6,7 @@ """defines class, which informs user about used, but unexposed declarations""" import os +from pyplusplus import messages from pygccxml import declarations from pyplusplus import decl_wrappers @@ -84,10 +85,10 @@ def __create_msg( self, dependencies ): depend_on_decl = dependencies[0].find_out_depend_on_declaration() - reason = [ 'There are declarations, which depend on the unexposed one:' ] + decls = [] for dependency in dependencies: - reason.append( ' ' + str( dependency.declaration ) ) - return "%s;%s" % ( depend_on_decl, os.linesep.join( reason ) ) + decls.append( os.linesep + ' ' + str( dependency.declaration ) ) + return "%s;%s" % ( depend_on_decl, messages.W1040 % ''.join( decls ) ) def inform_user( self ): used_not_exported_decls = self.__find_out_used_but_not_exported() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-12-14 08:21:54
|
Revision: 799 http://svn.sourceforge.net/pygccxml/?rev=799&view=rev Author: roman_yakovenko Date: 2006-12-14 00:21:53 -0800 (Thu, 14 Dec 2006) Log Message: ----------- a group of small improvements to the projects, mainly improving error messages Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/calldef.py pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/properties.py pyplusplus_dev/pyplusplus/file_writers/multiple_files.py pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py pyplusplus_dev/pyplusplus/module_creator/types_database.py Modified: pygccxml_dev/pygccxml/declarations/calldef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/calldef.py 2006-12-14 07:04:27 UTC (rev 798) +++ pygccxml_dev/pygccxml/declarations/calldef.py 2006-12-14 08:21:53 UTC (rev 799) @@ -431,6 +431,20 @@ def __init__( self, *args, **keywords ): member_calldef_t.__init__( self, *args, **keywords ) + def __str__(self): + # Get the full name of the calldef... + name = algorithm.full_name(self) + if name[:2]=="::": + name = name[2:] + # Add the arguments... + args = map(lambda a: str(a), self.arguments) + res = "%s(%s)"%(name, ", ".join(args)) + # Append the declaration class + cls = 'constructor' + if self.is_copy_constructor: + cls = 'copy ' + cls + return "%s [%s]"%(res, cls) + def _get_is_copy_constructor(self): args = self.arguments if 1 != len( args ): Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-12-14 07:04:27 UTC (rev 798) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2006-12-14 08:21:53 UTC (rev 799) @@ -128,7 +128,13 @@ msgs = [] if not self.exportable: msgs.append( self.why_not_exportable() ) - msgs.extend( self._readme_impl() ) + + if declarations.templates.is_instantiation( self.name ) \ + and self.alias == self._generate_valid_name(): + msgs.append( messages.W1043 % self.alias ) + + msgs.extend( self._readme_impl() ) + return messages.filter_disabled_msgs( msgs, self.__msgs_to_ignore ) @property Modified: pyplusplus_dev/pyplusplus/decl_wrappers/properties.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/properties.py 2006-12-14 07:04:27 UTC (rev 798) +++ pyplusplus_dev/pyplusplus/decl_wrappers/properties.py 2006-12-14 08:21:53 UTC (rev 799) @@ -6,6 +6,8 @@ "defines property_t helper class" import algorithm +from pyplusplus import messages +from pyplusplus import _logging_ from pygccxml import declarations class property_t( object ): @@ -248,6 +250,12 @@ self.getters, self.setters = recognizer.class_accessors( cls ) self.inherited_getters, self.inherited_setters = recognizer.inherited_accessors( cls ) + def __report_illegal_property( self, property_ ): + logger = _logging_.loggers.declarations + if not messages.filter_disabled_msgs([messages.W1041], property_.fget.parent.disabled_messaged ): + return #user disabled property warning + logger.warn( "%s;%s" % ( property_.fget.parent, messages.W1041 % property_ ) ) + def __is_legal_property( self, property_ ): """property is legal if it does not hide other declarations""" def is_relevant( decl ): @@ -281,11 +289,14 @@ if fset in used_setters: continue property_ = self.recognizer.create_property( fget, fset ) - if property_ and self.__is_legal_property( property_ ): - used_getters.add( fget ) - used_setters.add( fset ) - properties.append( property_ ) - break + if property_: + if self.__is_legal_property( property_ ): + used_getters.add( fget ) + used_setters.add( fset ) + properties.append( property_ ) + break + else: + self.__report_illegal_property( property_ ) return properties def __call__( self ): @@ -306,10 +317,13 @@ if fget in used_getters: continue property_ = self.recognizer.create_read_only_property( fget ) - if property_ and self.__is_legal_property( property_ ): - used_getters.add( fget ) - properties.append( property_ ) - + if property_: + if self.__is_legal_property( property_ ): + used_getters.add( fget ) + properties.append( property_ ) + else: + self.__report_illegal_property( property_ ) + if self.exclude_accessors: map( lambda accessor: accessor.exclude(), used_getters ) map( lambda accessor: accessor.exclude(), used_setters ) Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-12-14 07:04:27 UTC (rev 798) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2006-12-14 08:21:53 UTC (rev 799) @@ -7,6 +7,8 @@ import os import writer +from pyplusplus import messages +from pyplusplus import _logging_ from pygccxml import declarations from pyplusplus import decl_wrappers from pyplusplus import code_creators @@ -133,13 +135,10 @@ value_class = class_traits.get_declaration( element_type ) return self.create_value_traits_header_name( value_class ) except RuntimeError, error: - msg = "%s;%s" \ - % ( str(code_creator.declaration) - , "Py++ 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." ) - self.logger.warn( msg ) + decls_logger = _logging_.loggers.declarations + if not messages.filter_disabled_msgs([messages.W1042], code_creator.declaration.disabled_messaged ): + return #user disabled property warning + decls_logger.warn( "%s;%s" % ( code_creator.declaration, messages.W1042 ) ) def create_include_code( self, creators, head_headers=None, tail_headers=None ): answer = [] Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2006-12-14 07:04:27 UTC (rev 798) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2006-12-14 08:21:53 UTC (rev 799) @@ -3,11 +3,11 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -"""This package defines all user messages( warnings + errors ), which will be +"""This package defines all user messages (warnings + errors), which will be reported to user. """ -W1000 = 'Py++, by default, does not expose internal compilers declarations.'\ +W1000 = 'Py++, by default, does not expose internal compilers declarations. '\ 'Names of those declarations usually start with "__".' W1001 = 'Py++, by default, does not expose internal declarations. ' \ @@ -15,7 +15,7 @@ W1002 = 'Py++, by default, does not expose compiler generated declarations.' -W1003 = 'Virtual functions that returns const reference can not be overriden from Python. ' \ +W1003 = 'Virtual functions that returns const reference cannot be overridden from Python. ' \ 'Reason: boost::python::override::operator()(...) saves the result of the marshaling ' \ '(from Python to C++) on the stack. Thus operator() returns reference ' \ 'to a temporary variable. Consider to use "Function Transformation" functionality ' \ @@ -25,7 +25,7 @@ 'pointer to function. ' \ ' See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information.' -W1005 = 'Py++ can not expose function that takes as argument/returns instance of non public class. ' \ +W1005 = 'Py++ cannot expose function that takes as argument/returns instance of non-public class. ' \ 'Generated code will not compile.' W1006 = 'Py++ need your help to expose function that takes as argument/returns C++ arrays. ' \ @@ -36,9 +36,9 @@ 'For more information see: http://www.boost.org/libs/python/doc/v2/configuration.html' W1008 = 'The function returns non-const reference to "Python immutable" type. ' \ - 'The value can not be modified from Python. ' + 'The value cannot be modified from Python. ' -W1009 = 'The function takes as argument (name=%s, pos=%d ) non-const reference ' \ +W1009 = 'The function takes as argument (name=%s, pos=%d) non-const reference ' \ 'to Python immutable type - function could not be called from Python. ' \ 'Take a look on "Function Transformation" functionality and define the transformation.' @@ -98,7 +98,7 @@ W1033 = "Py++ can not expose unnamed variables" -W1034 = "Py++ can not expose alignement bit." +W1034 = "Py++ can not expose alignment bit." W1035 = "Py++ can not expose static pointer member variables. This could be changed in future." @@ -111,11 +111,21 @@ W1039 = "Py++ doesn't expose private or protected member variables." -W1040 = 'The declaration is unexposed, but there are other declarations, which refer to it.' \ - 'This could cause "no to_python converter found" run time error.' \ +W1040 = 'The declaration is unexposed, but there are other declarations, which refer to it. ' \ + 'This could cause "no to_python converter found" run time error. ' \ 'Declarations: %s' +W1041 = 'Property "%s" could not be created. There is another exposed declaration with the same name( alias )." ' \ + 'The property will make it inaccessible.' +W1042 = 'Py++ 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 possibility, that ' \ + 'generated code will not compile or will lack some functionality. ' \ + 'The solution to the problem is to create a variable of the class.' + +W1043 = 'Py++ created an ugly alias ("%s") for template instantiated class.' + warnings = globals() for identifier, explanation in warnings.items(): Modified: pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2006-12-14 07:04:27 UTC (rev 798) +++ pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2006-12-14 08:21:53 UTC (rev 799) @@ -20,29 +20,13 @@ self.__exported_decls.append( decl ) def __is_std_decl( self, decl ): - if not decl.parent: + #Every class under std should be exported by Boost.Python and\\or Py++ + #Also this is not the case right now, I prefer to hide the warnings + dpath = declarations.declaration_path( decl ) + if len( dpath ) < 3: return False - - if not isinstance( decl.parent, declarations.namespace_t ): + if dpath[1] != 'std': return False - - if 'std' != decl.parent.name: - return False - - ns_std = decl.parent - if not ns_std.parent: - return False - - if not isinstance( ns_std.parent, declarations.namespace_t ): - return False - - if '::' != ns_std.parent.name: - return False - - global_ns = ns_std.parent - if global_ns.parent: - return False - if decl.name.startswith( 'pair<' ): #special case return False Modified: pyplusplus_dev/pyplusplus/module_creator/types_database.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/types_database.py 2006-12-14 07:04:27 UTC (rev 798) +++ pyplusplus_dev/pyplusplus/module_creator/types_database.py 2006-12-14 08:21:53 UTC (rev 799) @@ -3,6 +3,7 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +from pyplusplus import messages from pygccxml import declarations from pyplusplus import code_creators from pyplusplus import _logging_ @@ -73,14 +74,10 @@ #check extraction of element type from container container_cls.indexing_suite.element_type except RuntimeError: - msg = "%s;%s" \ - % ( str(container_cls) - , "Py++ 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 ) - + decls_logger = _logging_.loggers.declarations + if not messages.filter_disabled_msgs([messages.W1042], container_cls.disabled_messaged ): + return #user disabled property warning + decls_logger.warn( "%s;%s" % ( container_cls, messages.W1042 ) ) self.__containers.add( container_cls ) return True @@ -182,4 +179,4 @@ def _get_used_containers( self ): return self.__containers used_containers = property( _get_used_containers) - \ 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-12-21 05:43:07
|
Revision: 807 http://svn.sourceforge.net/pygccxml/?rev=807&view=rev Author: roman_yakovenko Date: 2006-12-20 21:43:08 -0800 (Wed, 20 Dec 2006) Log Message: ----------- adding new warning and making epydoc to be happy Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-12-20 08:47:22 UTC (rev 806) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-12-21 05:43:08 UTC (rev 807) @@ -164,6 +164,9 @@ if self.transformations: #if user defined transformation, than I think it took care of the problems + ft = self.transformations[0] + if ft.alias == ft.unique_name: + msgs.append( messages.W1044 % ft.alias ) return msgs if suspicious_type( self.return_type ) and None is self.call_policies: Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2006-12-20 08:47:22 UTC (rev 806) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2006-12-21 05:43:08 UTC (rev 807) @@ -126,9 +126,20 @@ W1043 = 'Py++ created an ugly alias ("%s") for template instantiated class.' +W1044 = 'Py++ created an ugly alias ("%s") for function wrapper.' + warnings = globals() for identifier, explanation in warnings.items(): + if len( identifier ) != 5: + continue + if identifier[0] != 'W': + continue + try: + int( identifier[1:] ) + except: + continue + globals()[ identifier ] = 'warning %s: %s' % ( identifier, explanation ) del warnings This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2007-01-04 06:47:18
|
Revision: 842 http://svn.sourceforge.net/pygccxml/?rev=842&view=rev Author: roman_yakovenko Date: 2007-01-03 22:46:32 -0800 (Wed, 03 Jan 2007) Log Message: ----------- adding new warning adding auto documentation for properties Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/properties.py pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/properties.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/properties.py 2007-01-03 21:19:39 UTC (rev 841) +++ pyplusplus_dev/pyplusplus/decl_wrappers/properties.py 2007-01-04 06:46:32 UTC (rev 842) @@ -15,7 +15,7 @@ It keeps """ - def __init__( self, name, fget, fset=None, doc='', is_static=False ): + def __init__( self, name, fget, fset=None, doc=None, is_static=False ): self._name = name self._fget = fget self._fset = fset @@ -34,9 +34,19 @@ def fset( self ): return self._fset - @property - def doc( self ): + def _get_doc( self ): + if None is self._doc: + doc = ['get'] + if self.fset: + doc.append( r'\\set' ) + doc.append( r' property, built on top of \"%s\"' % self.fget ) + if self.fset: + doc.append( r' and \"%s\"' % self.fset ) + self._doc = '"%s"' % ''.join( doc ) return self._doc + def _set_doc( self, doc ): + self._doc = doc + doc = property( _get_doc, _set_doc ) @property def is_static( self ): Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2007-01-03 21:19:39 UTC (rev 841) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2007-01-04 06:46:32 UTC (rev 842) @@ -101,6 +101,8 @@ return messages.W1033 if self.bits == 0 and self.name == "": return messages.W1034 + if declarations.is_array( self.type ) and declarations.array_size( self.type ) < 1: + return messages.W1045 type_ = declarations.remove_alias( self.type ) type_ = declarations.remove_const( type_ ) if declarations.is_pointer( type_ ): Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2007-01-03 21:19:39 UTC (rev 841) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2007-01-04 06:46:32 UTC (rev 842) @@ -128,6 +128,10 @@ W1044 = 'Py++ created an ugly alias ("%s") for function wrapper.' +W1045 = 'Py++ does not expose static arrays with unknown size. ' \ + 'You can fix this by setting array size to the actual one.' \ + 'For more information see "array_t" class documentation.' + warnings = globals() for identifier, explanation in warnings.items(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |