[pygccxml-commit] SF.net SVN: pygccxml: [748] pyplusplus_dev_ft
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-11-22 15:20:50
|
Revision: 748 http://svn.sourceforge.net/pygccxml/?rev=748&view=rev Author: roman_yakovenko Date: 2006-11-22 07:20:49 -0800 (Wed, 22 Nov 2006) Log Message: ----------- adding transformers and improving generated code Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp pyplusplus_dev_ft/unittests/function_transformations_tester.py Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-22 15:20:49 UTC (rev 748) @@ -3,6 +3,7 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +import re import os import algorithm import code_creator @@ -13,8 +14,10 @@ import pyplusplus.function_transformers as function_transformers from pyplusplus import code_repository -###################################################################### - +__REMOVE_DUPLICAET_LINESEP = re.compile( '(%s){2,}' % os.linesep ) +def remove_duplicate_linesep( code ): + return __REMOVE_DUPLICAET_LINESEP.sub( os.linesep, code ) + class mem_fun_transformed_t( calldef_t ): """Creates code for public non-virtual member functions. """ @@ -133,10 +136,13 @@ , declarations.call_invocation.join( declarations.templates.join( make_object, [c_p_alias] ) , [cntrl.result_variable.name] ) ) - return_stmt = declarations.call_invocation.join( - make_tuple - , return_vars - , os.linesep + self.indent( self.PARAM_SEPARATOR, 6 ) ) + + return_stmt = declarations.call_invocation.join( make_tuple, return_vars ) + if self.LINE_LENGTH < len( return_stmt ): + return_stmt = declarations.call_invocation.join( + make_tuple + , return_vars + , os.linesep + self.indent( self.PARAM_SEPARATOR, 6 ) ) elif not declarations.is_void( self.declaration.return_type ): return_stmt = cntrl.result_variable.name else: @@ -157,7 +163,9 @@ def _create_impl(self): answer = ['// Transformed wrapper function for "%s"' % self.declaration ] answer.append( self.create_declaration(self.declaration.alias) + '{') - answer.append( self.indent( self.create_body() ) ) + body = self.create_body() + body = remove_duplicate_linesep( body ) + answer.append( self.indent( body ) ) answer.append( '}' ) return os.linesep.join( answer ) Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/__init__.py 2006-11-22 15:20:49 UTC (rev 748) @@ -26,15 +26,15 @@ return transformers.output_t( function, *args, **keywd ) return creator -#def input( *args, **keywd ): - #def creator( function ): - #return transformers.input_t( function, *args, **keywd ) - #return creator +def input( *args, **keywd ): + def creator( function ): + return transformers.input_t( function, *args, **keywd ) + return creator -#def inout( *args, **keywd ): - #def creator( function ): - #return transformers.inout_t( function, *args, **keywd ) - #return creator +def inout( *args, **keywd ): + def creator( function ): + return transformers.inout_t( function, *args, **keywd ) + return creator #def input_array( *args, **keywd ): #def creator( function ): @@ -44,4 +44,4 @@ #def output_array( *args, **keywd ): #def creator( function ): #return transformers.output_array_t( function, *args, **keywd ) - #return creator \ No newline at end of file + #return creator Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-22 15:20:49 UTC (rev 748) @@ -67,9 +67,9 @@ def __init__( self, function ): controller_base_t.__init__( self, function ) - self.__wrapper_args = function.arguments[:] + self.__wrapper_args = [ arg.clone() for arg in function.arguments ] self.__result_var = variable_t( self.function.return_type - , self.register_variable_name( 'result' ) ) + , self.register_variable_name( 'result' ) ) self.__return_variables = [] self.__pre_call = [] self.__post_call = [] @@ -91,13 +91,17 @@ def wrapper_args( self ): return self.__wrapper_args + def find_wrapper_arg( self, name ): + for arg in self.wrapper_args: + if arg.name == name: + return arg + return None + def remove_wrapper_arg( self, name ): - for index, arg in enumerate( self.wrapper_args ): - if arg.name == name: - del self.wrapper_args[ index ] - return - else: + arg = self.find_wrapper_arg( name ) + if not arg: raise LookupError( "Unable to remove '%s' argument - not found!" % name ) + del self.wrapper_args[ self.wrapper_args.index(arg) ] @property def arg_expressions( self ): Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-22 15:20:49 UTC (rev 748) @@ -77,3 +77,229 @@ controller.modify_argument_expression( self.arg_index, var_name ) #adding the variable to return variables list controller.return_variable( var_name ) + +# input_t +class input_t(transformer.transformer_t): + """Handles a single input variable. + + The reference on the specified variable is removed. + + void setValue(int& v) -> setValue(v) + """ + + def __init__(self, function, arg_ref): + """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 + """ + transformer.transformer_t.__init__( self, function ) + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) + + if not is_ref_or_ptr( self.arg.type ): + raise ValueError( '%s\nin order to use "input" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) + + def __str__(self): + return "input(%d)"%(self.idx) + + def configure_mem_fun( self, controller ): + assert isinstance( controller, controllers.mem_fun_controller_t ) + w_arg = controller.find_wrapper_arg( self.arg.name ) + w_arg.type = remove_ref_or_ptr( self.arg.type ) + +# inout_t +class inout_t(transformer.transformer_t): + """Handles a single input/output variable. + + void foo(int& v) -> v = foo(v) + """ + + def __init__(self, function, arg_ref): + """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 + """ + transformer.transformer_t.__init__( self, function ) + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) + + if not is_ref_or_ptr( self.arg.type ): + raise ValueError( '%s\nin order to use "inout" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) + + def __str__(self): + return "inout(%d)"%(self.arg_index) + + def init_funcs(self, sm): + assert isinstance( controller, controllers.mem_fun_controller_t ) + w_arg = controller.find_wrapper_arg( self.arg.name ) + w_arg.type = remove_ref_or_ptr( self.arg.type ) + #adding the variable to return variables list + controller.return_variable( w_arg ) + + +#~ # input_array_t +#~ class input_array_t(transformer.transformer_t): + #~ """Handles an input array with fixed size. + + #~ void setVec3(double* v) -> setVec3(object v) + #~ # v must be a sequence of 3 floats + #~ """ + + #~ def __init__(self, function, arg_ref, array_size): + #~ """Constructor. + + #~ @param size: The fixed size of the input array + #~ @type size: int + #~ """ + #~ transformer.transformer_t.__init__( self, function ) + + #~ self.arg = self.get_argument( arg_ref ) + #~ self.arg_index = self.function.arguments.index( self.arg ) + + #~ if not is_ptr_or_array( self.arg.type ): + #~ raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ + #~ % ( function, self.arg_ref.name, arg.type) + + #~ self.array_size = array_size + #~ self.native_array = None + #~ self.pylist = None + + #~ def __str__(self): + #~ return "input_array(%s,%d)"%( self.arg.name, self.array_size) + + #~ def required_headers( self ): + #~ """Returns list of header files that transformer generated code depends on.""" + #~ return [ code_repository.convenience.file_name ] + + #~ def init_funcs(self, sm): + #~ # Remove the original argument... + #~ sm.remove_arg(self.arg_index + 1) + + #~ # 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_variable("py_" + self.arg.name, "boost::python::list") + + #~ # Replace the removed argument with a Python object. + #~ newarg = self.arg.clone( type=declarations.dummy_type_t("boost::python::object") ) + #~ sm.insert_arg(self.arg_index+1, newarg, self.pylist) + + #~ # Declare a variable that will hold the C array... + #~ self.native_array = sm.wrapper_func.declare_variable( + #~ "native_" + self.arg.name + #~ , declarations.array_item_type( self.arg.type ) + #~ , '[%d]' % self.array_size) + + #~ # Replace the input parameter with the C array + #~ sm.wrapper_func.input_params[self.arg_index] = self.native_array + + #~ def wrapper_pre_call(self, sm): + #~ """Wrapper function code. + #~ """ + #~ tmpl = [] + #~ tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) + #~ tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) + #~ return os.linesep.join( tmpl ) % { + #~ 'type' : declarations.array_item_type( self.arg.type ) + #~ , 'pypp_con' : 'pyplusplus::convenience' + #~ , 'pylist' : self.arg.name + #~ , 'array_size' : self.array_size + #~ , 'native_array' : self.native_array + #~ } + + #~ def virtual_pre_call(self, sm): + #~ """Virtual function code.""" + #~ tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' + #~ return tmpl % { + #~ 'pypp_con' : 'pyplusplus::convenience' + #~ , 'native_array' : self.arg.name + #~ , 'array_size' : self.array_size + #~ , 'pylist' : self.pylist + #~ } + + +#~ # output_array_t +#~ class output_array_t(transformer.transformer_t): + #~ """Handles an output array of a fixed size. + + #~ void getVec3(double* v) -> v = getVec3() + #~ # v will be a list with 3 floats + #~ """ + + #~ def __init__(self, function, arg_ref, size): + #~ """Constructor. + + #~ @param idx: Index of the argument that is an output array (the first arg has index 1). + #~ @type idx: int + #~ @param size: The fixed size of the output array + #~ @type size: int + #~ """ + #~ transformer.transformer_t.__init__( self, function ) + #~ self.arg = self.get_argument( arg_ref ) + #~ self.arg_index = self.function.arguments.index( self.arg ) + + #~ if not is_ptr_or_array( self.arg.type ): + #~ raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ + #~ % ( function, self.arg_ref.name, arg.type) + + #~ self.array_size = size + #~ self.native_array = None + #~ self.pylist = None + + #~ def __str__(self): + #~ return "output_array(%s,%d)"%( self.arg.name, self.array_size) + + #~ def required_headers( self ): + #~ """Returns list of header files that transformer generated code depends on.""" + #~ return [ code_repository.convenience.file_name ] + + #~ def init_funcs(self, sm): + #~ # Remove the original argument... + #~ sm.remove_arg(self.arg_index + 1) + + #~ # Declare a variable that will hold the C array... + #~ self.native_array = sm.wrapper_func.declare_variable( + #~ "native_" + self.arg.name + #~ , declarations.array_item_type( self.arg.type ) + #~ , '[%d]' % self.array_size) + + #~ # Declare a Python list which will receive the output... + #~ self.pylist = sm.wrapper_func.declare_variable( + #~ 'py_' + self.arg.name + #~ , "boost::python::list" ) + + #~ # ...and add it to the result + #~ sm.wrapper_func.result_exprs.append(self.pylist) + + #~ sm.wrapper_func.input_params[ self.arg_index ] = self.native_array + + #~ self.virtual_pylist = sm.virtual_func.declare_variable("py_"+self.arg.name, "boost::python::object") + + #~ def wrapper_post_call(self, sm): + #~ tmpl = '%(pypp_con)s::copy_container( %(native_array)s, %(native_array)s + %(array_size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' + #~ return tmpl % { + #~ 'pypp_con' : 'pyplusplus::convenience' + #~ , 'native_array' : self.native_array + #~ , 'array_size' : self.array_size + #~ , 'pylist' : self.pylist + #~ } + + #~ def virtual_post_call(self, sm): + #~ tmpl = [] + #~ tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(pylist)s, %(array_size)d );' ) + #~ tmpl.append( '%(pypp_con)s::copy_sequence( %(pylist)s, %(pypp_con)s::array_inserter( %(native_array)s, %(array_size)d ) );' ) + #~ return os.linesep.join( tmpl ) % { + #~ 'type' : declarations.array_item_type( self.arg.type ) + #~ , 'pypp_con' : 'pyplusplus::convenience' + #~ , 'pylist' : sm.py_result_expr(self.pylist) + #~ , 'array_size' : self.array_size + #~ , 'native_array' : self.arg.name + #~ } + Modified: pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp =================================================================== --- pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/unittests/data/function_transformations_to_be_exported.hpp 2006-11-22 15:20:49 UTC (rev 748) @@ -10,6 +10,7 @@ namespace ft2{ +//used to check output transformer struct calculator_t{ calculator_t(){ std::cout << std::endl << "=> calculator_t created"; @@ -35,6 +36,23 @@ } }; +//used to check input transformer +struct window_t{ + window_t() + : height( 0 ) + , width( 0 ) + {} + + void resize( int& h, int& w ){ + height = h; + width = w; + } + + int height; + int width; +}; + + } //~ namespace ft{ Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-22 09:26:21 UTC (rev 747) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-22 15:20:49 UTC (rev 748) @@ -30,6 +30,11 @@ clone_and_assign_5.add_transformation( ft.output(0) ) clone_and_assign_5.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) + window = mb.class_( 'window_t' ) + window.add_wrapper_code( '' ) + window.mem_fun( 'resize' ).add_transformation( ft.input(0), ft.input(1) ) + + #~ image = mb.class_( "image_t" ) #~ image.include() #~ image.add_wrapper_code( '' ) @@ -67,6 +72,11 @@ #test make_object function self.failUnless( sys.getrefcount( calc ) == sys.getrefcount( calc2 ) ) + window = module.window_t() + window.height = 0 + window.width = 0 + window.resize( h=1, w=2 ) + self.failUnless( window.height==1 and window.width==2 ) #~ img = module.image_t( 2, 6) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |