[pygccxml-commit] SF.net SVN: pygccxml: [891] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2007-01-31 22:12:43
|
Revision: 891 http://svn.sourceforge.net/pygccxml/?rev=891&view=rev Author: roman_yakovenko Date: 2007-01-31 14:12:43 -0800 (Wed, 31 Jan 2007) Log Message: ----------- adding initial support for input_c_buffer transformer Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/include.py pyplusplus_dev/pyplusplus/code_creators/module.py pyplusplus_dev/pyplusplus/code_repository/convenience.py pyplusplus_dev/pyplusplus/function_transformers/__init__.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp pyplusplus_dev/unittests/function_transformations_tester.py Modified: pyplusplus_dev/pyplusplus/code_creators/include.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/include.py 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/pyplusplus/code_creators/include.py 2007-01-31 22:12:43 UTC (rev 891) @@ -12,10 +12,15 @@ """ Creates C++ code for include directive """ - def __init__( self, header ): + def __init__( self, header, user_defined=False ): code_creator.code_creator_t.__init__(self) self._header = include_directories.include_directories_t.normalize( header ) self._include_dirs_optimization = None #This parameter will be set from module_t.create function + self._user_defined = user_defined + + @property + def is_user_defined(self): + return self._user_defined def _get_header(self): return self._header @@ -30,6 +35,10 @@ include_dirs_optimization = property( _get_include_dirs_optimization, _set_include_dirs_optimization ) def _create_impl(self): + header = self.header.strip() + if header.startswith( '"' ) or header.startswith( '<' ): + return '#include %s' % self.header + if not self.include_dirs_optimization: return '#include "%s"' % self.header else: Modified: pyplusplus_dev/pyplusplus/code_creators/module.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/module.py 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/pyplusplus/code_creators/module.py 2007-01-31 22:12:43 UTC (rev 891) @@ -133,6 +133,8 @@ if creator.header in self.__system_headers: if not leave_system_headers: self.remove_creator( creator ) + if creator.is_user_defined: + pass else: self.remove_creator( creator ) map( lambda header: self.adopt_include( include.include_t( header=header ) ) @@ -169,8 +171,8 @@ code = self.unindent(code) return os.linesep.join( includes ) + 2 * os.linesep + code + os.linesep - def add_include( self, header ): - self.adopt_include( include.include_t( header=header ) ) + def add_include( self, header, user_defined ): + self.adopt_include( include.include_t( header=header, user_defined=user_defined ) ) def add_namespace_usage( self, namespace_name ): self.adopt_creator( namespace.namespace_using_t( namespace_name ) Modified: pyplusplus_dev/pyplusplus/code_repository/convenience.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/convenience.py 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/pyplusplus/code_repository/convenience.py 2007-01-31 22:12:43 UTC (rev 891) @@ -88,10 +88,19 @@ void copy_sequence( boost::python::object const& seq, Inserter inserter ){ index_type length = boost::python::len( seq ); for( index_type index = 0; index < length; ++index ){ - inserter( seq[index] ); + inserter = seq[index]; } } +template< class Inserter, class TItemType > +void copy_sequence( boost::python::object const& seq, Inserter inserter, boost::type< TItemType > ){ + index_type length = boost::python::len( seq ); + for( index_type index = 0; index < length; ++index ){ + boost::python::object item = seq[index]; + inserter = boost::python::extract< TItemType >( item ); + } +} + struct list_inserter{ list_inserter( boost::python::list& py_list ) : m_py_list( py_list ) @@ -112,17 +121,23 @@ , m_curr_pos( 0 ) , m_size( size ) {} - - void operator()( boost::python::object const & item ){ + + void insert( const T& item ){ if( m_size <= m_curr_pos ){ std::stringstream err; err << "Index out of range. Array size is" << m_size << ", " << "current position is" << m_curr_pos << "."; raise_error( PyExc_ValueError, err.str().c_str() ); } - m_array[ m_curr_pos ] = boost::python::extract< T >( item ); + m_array[ m_curr_pos ] = item; m_curr_pos += 1; } + + array_inserter_t<T>& + operator=( boost::python::object const & item ){ + insert( boost::python::extract< T >( item ) ); + return *this; + } private: T* m_array; Modified: pyplusplus_dev/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2007-01-31 22:12:43 UTC (rev 891) @@ -49,3 +49,8 @@ def creator( function ): return transformers.type_modifier_t( function, *args, **keywd ) return creator + +def input_c_buffer( *args, **keywd ): + def creator( function ): + return transformers.input_c_buffer_t( function, *args, **keywd ) + return creator Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2007-01-31 22:12:43 UTC (rev 891) @@ -224,9 +224,13 @@ _seq2arr = string.Template( os.linesep.join([ - 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist, $array_size );' + 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist, $array_size );' , 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );'])) +_seq2vector = string.Template( os.linesep.join([ + 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist );' + , 'pyplus_conv::copy_sequence( $pylist, std::back_inserter( $native_array), boost::type< $type >() );'])) + _arr2seq = string.Template( 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) @@ -395,3 +399,95 @@ def configure_virtual_mem_fun( self, controller ): self.__configure_v_mem_fun_override( controller.override_controller ) self.__configure_v_mem_fun_default( controller.default_controller ) + + +class input_c_buffer_t(transformer.transformer_t): + """Handles an input of C buffere: + + void write( byte *buffer, int size ) -> void write( python sequence ) + """ + + def __init__(self, function, buffer_arg_ref, size_arg_ref): + """Constructor. + + @param buffer_arg_ref: "reference" to the buffer argument + @param buffer_arg_ref: "reference" to argument, which holds buffer size + """ + transformer.transformer_t.__init__( self, function ) + + self.buffer_arg = self.get_argument( buffer_arg_ref ) + self.buffer_arg_index = self.function.arguments.index( self.buffer_arg ) + + self.size_arg = self.get_argument( size_arg_ref ) + self.size_arg_index = self.function.arguments.index( self.size_arg ) + + if not is_ptr_or_array( self.buffer_arg.type ): + raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "buffer" argument %s type must be a array or a pointer (got %s).' ) \ + % ( function, self.buffer_arg.name, self.buffer_arg.type) + + if not declarations.is_integral( self.size_arg.type ): + raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "size" argument %s type must be an integral type (got %s).' ) \ + % ( function, self.size_arg.name, self.size_arg.type) + + self.buffer_item_type = declarations.array_item_type( self.buffer_arg.type ) + + def __str__(self): + return "input_c_buffer(buffer arg=%s, size arg=%s)" \ + % ( self.buffer_arg.name, self.size_arg.name) + + def required_headers( self ): + """Returns list of header files that transformer generated code depends on.""" + return [ code_repository.convenience.file_name, '<vector>', '<iterator>' ] + + def __configure_sealed(self, controller): + global _seq2arr + w_buffer_arg = controller.find_wrapper_arg( self.buffer_arg.name ) + w_buffer_arg.type = declarations.dummy_type_t( "boost::python::object" ) + + controller.remove_wrapper_arg( self.size_arg.name ) + + size_var = controller.declare_variable( + declarations.remove_const( self.size_arg.type ) + , self.size_arg.name + , ' = boost::python::len(%s)' % w_buffer_arg.name ) + + # Declare a variable that will hold the C array... + buffer_var = controller.declare_variable( + declarations.dummy_type_t( "std::vector< %s >" % self.buffer_item_type.decl_string ) + , "native_" + self.buffer_arg.name + , '(%s)' % size_var ) + + copy_pylist2arr = _seq2vector.substitute( type=self.buffer_item_type + , pylist=w_buffer_arg.name + , native_array=buffer_var ) + + controller.add_pre_call_code( copy_pylist2arr ) + + controller.modify_arg_expression( self.buffer_arg_index, '&%s[0]' % buffer_var ) + controller.modify_arg_expression( self.size_arg_index, '%s' % size_var ) + + def __configure_v_mem_fun_default( self, controller ): + self.__configure_sealed( controller ) + + def __configure_v_mem_fun_override( self, controller ): + raise NotImplementedError() + #global _arr2seq + #pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' ) + #, 'py_' + self.arg.name ) + + #copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name + #, array_size=self.array_size + #, pylist=pylist ) + + #controller.add_py_pre_call_code( copy_arr2pylist ) + + def configure_mem_fun( self, controller ): + self.__configure_sealed( controller ) + + def configure_free_fun(self, controller ): + self.__configure_sealed( controller ) + + def configure_virtual_mem_fun( self, controller ): + self.__configure_v_mem_fun_override( controller.override_controller ) + self.__configure_v_mem_fun_default( controller.default_controller ) + Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-01-31 22:12:43 UTC (rev 891) @@ -429,7 +429,7 @@ 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 ) + self.__extmodule.add_include( header, user_defined=True ) # Check if it is a header from the code repository if header in code_repository.headers: Modified: pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp 2007-01-31 22:12:43 UTC (rev 891) @@ -8,6 +8,7 @@ #include <cmath> #include <string> +#include <iostream> namespace ft2{ @@ -219,6 +220,18 @@ }; +struct input_c_buffer_tester_t{ + std::string write( char* buffer, int dummy, int size ) const { + std::cout << "wwwwwwwwwww> " << std::string( buffer, size ); + return std::string( buffer, size ); + } + + static std::string write_s( int dummy, char* buffer, int size ){ + return std::string( buffer, size ); + } + +}; + } #endif//__function_transformations_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev/unittests/function_transformations_tester.py 2007-01-31 18:53:51 UTC (rev 890) +++ pyplusplus_dev/unittests/function_transformations_tester.py 2007-01-31 22:12:43 UTC (rev 891) @@ -79,6 +79,12 @@ clone.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) clone.add_transformation( ft.modify_type(0, declarations.remove_reference ) ) + cls = mb.class_( 'input_c_buffer_tester_t') + write_mf = cls.mem_fun( 'write' ) + write_mf.add_transformation( ft.input_c_buffer( 'buffer', 'size' ) ) + write_s = cls.mem_fun( 'write_s' ) + write_s.add_transformation( ft.input_c_buffer( 'buffer', 'size' ) ) + def run_tests(self, module): """Run the actual unit tests. """ @@ -226,6 +232,13 @@ tmp = module.modify_type_tester_t() self.failUnless( 123 == tmp.do_nothing(123) ) self.failUnless( tmp != tmp.clone(123) ) + + tmp = module.input_c_buffer_tester_t() + hw = 'hello world' + dummy = 11 + print 'xxxxxxxxxxx> ', tmp.write( list( hw ), dummy ) + self.failUnless( 'hello world' == tmp.write( list( hw ), dummy ) ) + self.failUnless( 'hello world' == tmp.write_s( dummy, tuple( list( hw ) ) ) ) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |