pygccxml-commit Mailing List for C++ Python language bindings (Page 20)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(190) |
Apr
(166) |
May
(170) |
Jun
(75) |
Jul
(105) |
Aug
(131) |
Sep
(99) |
Oct
(84) |
Nov
(67) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(66) |
Feb
(49) |
Mar
(25) |
Apr
(62) |
May
(21) |
Jun
(34) |
Jul
(9) |
Aug
(21) |
Sep
(5) |
Oct
|
Nov
(63) |
Dec
(34) |
2008 |
Jan
(10) |
Feb
(42) |
Mar
(26) |
Apr
(25) |
May
(6) |
Jun
(40) |
Jul
(18) |
Aug
(29) |
Sep
(6) |
Oct
(32) |
Nov
(14) |
Dec
(56) |
2009 |
Jan
(127) |
Feb
(52) |
Mar
(2) |
Apr
(10) |
May
(29) |
Jun
(3) |
Jul
|
Aug
(16) |
Sep
(4) |
Oct
(11) |
Nov
(8) |
Dec
(14) |
2010 |
Jan
(31) |
Feb
(1) |
Mar
(7) |
Apr
(9) |
May
(1) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
(8) |
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <rom...@us...> - 2008-08-05 15:40:21
|
Revision: 1382 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1382&view=rev Author: roman_yakovenko Date: 2008-08-05 15:40:28 +0000 (Tue, 05 Aug 2008) Log Message: ----------- updating history Modified Paths: -------------- pygccxml_dev/docs/history/history.rest pyplusplus_dev/docs/history/history.rest Modified: pygccxml_dev/docs/history/history.rest =================================================================== --- pygccxml_dev/docs/history/history.rest 2008-08-05 15:31:48 UTC (rev 1381) +++ pygccxml_dev/docs/history/history.rest 2008-08-05 15:40:28 UTC (rev 1382) @@ -25,7 +25,7 @@ ----------- -Version SVN +Version 1.0 ----------- 1. Support for ellipsis was added. @@ -53,12 +53,15 @@ 4. The recomended `GCC-XML`_ version to use with this release is CVS revision 123. This revision introduces small, but very important feature. `GCC-XML`_ started to dump artificial declarations (constructor, destructor, operator=). - ``pygccxml.declarations.type_traits`` functions were updated to use new + ``pygccxml.declarations.type_traits`` functions were updated to use the new information. 5. ``declarations.decl_printer_t`` class dumps almost all available information about a declaration. +6. ``declarations.is_same_function`` was fixed and now it treats + "covariant returns" right. + ------------- Version 0.9.5 ------------- Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2008-08-05 15:31:48 UTC (rev 1381) +++ pyplusplus_dev/docs/history/history.rest 2008-08-05 15:40:28 UTC (rev 1382) @@ -27,10 +27,10 @@ Version SVN ----------- -1. The algorithm, which calculates what member functions should be redefined in +1. The algorithm, which calculates what member functions should be redefined in derived class wrappers, was improved. Many thanks to Julian Scheid for the bug fix. - + The change explanation. .. code-block:: C++ @@ -41,9 +41,9 @@ class B: public A{ }; - - Previous version of `Py++`_ didn't generate wrapper for class ``B``, even - though ``B`` inherits ``A``'s virtual function. Now if you have the following + + Previous version of `Py++`_ didn't generate wrapper for class ``B``, even + though ``B`` inherits ``A``'s virtual function. Now if you have the following Python code: .. code-block:: Python @@ -54,13 +54,13 @@ def foo(self): print "C.foo" - then when ``foo`` is invoked on this instance on the C++ side of things, the + then when ``foo`` is invoked on this instance on the C++ side of things, the Python code won't be executed as the wrapper was missing. **Warning!** **There is a possibility that your generated code will not work!** **Keep reading.** - If you use "function transformation" functionality, than it is possible the + If you use "function transformation" functionality, than it is possible the generated code will **NOT** work. Consider next example: .. code-block:: C++ @@ -89,31 +89,31 @@ .. code-block:: C++ namespace bp = boost::python; - + struct B_wrapper : B, bp::wrapper< B > { virtual void foo( int & i ) const { ... } - + static boost::python::tuple default_foo( ::B const & inst ) { ... } - - virtual void foo( int & i ) const + + virtual void foo( int & i ) const { ... } - + static boost::python::object default_foo( ::A const & inst ) { ... } }; ... - bp::class_< B_wrapper, bp::bases< A > >( "B" ) + bp::class_< B_wrapper, bp::bases< A > >( "B" ) .def( "foo", (boost::python::tuple (*)( ::B const & ))( &B_wrapper::default_foo ) ) .def( "foo", (boost::python::object (*)( ::A const & ))( &B_wrapper::default_foo ) ); - As you can see, after applying the transformation both functions have same - signature. Do you know what function will be called in some situation? I do - + As you can see, after applying the transformation both functions have same + signature. Do you know what function will be called in some situation? I do - the wrong one :-(. - Unfortunately, there is no easy work around or some trick that you can use, + Unfortunately, there is no easy work around or some trick that you can use, which will not break the existing code. I see few solutions to the problem: - + * change the alias of the functions .. code-block:: Python @@ -129,15 +129,21 @@ * `Py++`_ can introduce a configuration, that will preserve the previous behaviour. I think this is a wrong way to go and doing the API changes is the 'right' longer term solution. - + If you **absolutely need** to preserve API backward compatible, contact me and I will introduce such configuration option. Sorry for inconvenience. -2. Few bugs, related to Indeing Suite 2, were fixed. Many thanks to Oliver Schweitzer +2. Few bugs, related to Indexing Suite 2, were fixed. Many thanks to Oliver Schweitzer for reporting them. +3. New and highly experimental feature was introduced - + `Boost.Python and ctypes integration`_. + ../documentation/ctypes_integration.html + +.. _`Boost.Python and ctypes integration` : ../documentation/ctypes_integration.html + ------------- Version 0.9.5 ------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-05 15:31:40
|
Revision: 1381 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1381&view=rev Author: roman_yakovenko Date: 2008-08-05 15:31:48 +0000 (Tue, 05 Aug 2008) Log Message: ----------- removing gccxml installer Removed Paths: ------------- installers/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-30 18:23:34
|
Revision: 1380 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1380&view=rev Author: roman_yakovenko Date: 2008-07-30 18:23:40 +0000 (Wed, 30 Jul 2008) Log Message: ----------- small bug fix in expose_address Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp pyplusplus_dev/unittests/ft_from_address_tester.py pyplusplus_dev/unittests/member_variables_tester.py Modified: pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-07-27 18:43:00 UTC (rev 1379) +++ pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-07-30 18:23:40 UTC (rev 1380) @@ -33,14 +33,22 @@ template< typename TType, typename TMemVarType > boost::uint32_t -addressof( const TType &inst, const TMemVarType TType::* offset){ +addressof( const TType* inst_ptr, const TMemVarType TType::* offset){ + if( !inst_ptr ){ + throw std::runtime_error( "unable to dereference null pointer" ); + } + const TType& inst = *inst_ptr; return boost::uint32_t( boost::addressof( inst.*offset ) ); } template< typename TType > boost::uint32_t -addressof_inst( const TType &inst){ - return boost::uint32_t( boost::addressof( inst ) ); +addressof_inst( const TType* inst_ptr){ + if( !inst_ptr ){ + throw std::runtime_error( "unable to dereference null pointer" ); + } + + return boost::uint32_t( inst_ptr ); } template< typename TType, typename TMemVarType > @@ -50,7 +58,7 @@ namespace pyppc = pyplusplus::convenience; return bpl::make_function( boost::bind( &pyppc::addressof< TType, TMemVarType >, _1, offset ) , bpl::default_call_policies() - , boost::mpl::vector< boost::uint32_t, const TType& >() ); + , boost::mpl::vector< boost::uint32_t, const TType* >() ); } template< typename TType > @@ -60,7 +68,7 @@ namespace pyppc = pyplusplus::convenience; return bpl::make_function( boost::bind( &pyppc::addressof_inst< TType >, _1 ) , bpl::default_call_policies() - , boost::mpl::vector< boost::uint32_t, const TType& >() ); + , boost::mpl::vector< boost::uint32_t, const TType* >() ); } class register_addressof_static_var : public boost::python::def_visitor<register_addressof_static_var> @@ -72,7 +80,7 @@ template< typename TVarType > register_addressof_static_var( const char* name, const TVarType& var ) : m_name( name ) - , m_address( addressof_inst( var ) ) + , m_address( addressof_inst( boost::addressof( var ) ) ) {} template <class classT> Modified: pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp 2008-07-27 18:43:00 UTC (rev 1379) +++ pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp 2008-07-30 18:23:40 UTC (rev 1380) @@ -23,4 +23,24 @@ return result; } +struct ptr_ptr_t{ + + ptr_ptr_t() + : value( new double( 5.9 ) ) + {} + + ~ptr_ptr_t(){ + delete value; + } + + void get_v_address( double** v ){ + if( !v ){ + throw std::runtime_error( "null pointer" ); + *v = value; + } + } + + double* value; +}; + #endif//__ft_from_address_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-27 18:43:00 UTC (rev 1379) +++ pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-30 18:23:40 UTC (rev 1380) @@ -163,6 +163,17 @@ static int* none_image; }; + + class Andy{ + protected: + Andy() : userData(NULL) {} + + virtual ~Andy() {} + + public: + void * userData; + }; + } } Modified: pyplusplus_dev/unittests/ft_from_address_tester.py =================================================================== --- pyplusplus_dev/unittests/ft_from_address_tester.py 2008-07-27 18:43:00 UTC (rev 1379) +++ pyplusplus_dev/unittests/ft_from_address_tester.py 2008-07-30 18:23:40 UTC (rev 1380) @@ -24,9 +24,11 @@ , *args ) def customize( self, mb ): - mb.global_ns.calldefs().create_with_signature = True mb.calldef( 'sum_matrix' ).add_transformation( ft.from_address(0) ) + ptr_ptr = mb.class_( 'ptr_ptr_t' ) + ptr_ptr.var( 'value' ).expose_address = True + ptr_ptr.mem_fun( 'get_v_address' ).add_transformation( ft.from_address(0 ) ) def run_tests(self, module): rows = 10 @@ -43,6 +45,16 @@ result = module.sum_matrix( ctypes.addressof( matrix ), rows, columns ) self.failUnless( result == sum ) + ptr = module.ptr_ptr_t() + double_ptr_type = ctypes.POINTER( ctypes.c_double ) + value = double_ptr_type.from_address( ptr.value ) + self.failUnless( value.contents.value == 5.9 ) + dd = double_ptr_type(ctypes.c_double(0.0) ) + print dir( ctypes.pointer( dd ).contents ) + ptr.get_v_address( ctypes.pointer( dd ).contents.value ) + print ptr.value + print dd.contents.value + def create_suite(): suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) Modified: pyplusplus_dev/unittests/member_variables_tester.py =================================================================== --- pyplusplus_dev/unittests/member_variables_tester.py 2008-07-27 18:43:00 UTC (rev 1379) +++ pyplusplus_dev/unittests/member_variables_tester.py 2008-07-30 18:23:40 UTC (rev 1380) @@ -25,6 +25,7 @@ image = mb.class_( 'image_t' ) image.var( 'data' ).expose_address = True image.var( 'none_image' ).expose_address = True + mb.class_( 'Andy' ).var('userData').expose_address = True def change_default_color( self, module ): module.point.default_color = module.point.color.blue @@ -95,8 +96,8 @@ data_type = ctypes.POINTER( ctypes.c_int ) data = data_type.from_address( image.data ) for j in range(5): - print '%d : %d' % ( j, data[j] ) - + self.failUnless( j == data[j] ) + data_type = ctypes.POINTER( ctypes.c_int ) data = data_type.from_address( module.image_t.none_image ) self.failUnless( 1997 == data.contents.value ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-27 18:42:51
|
Revision: 1379 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1379&view=rev Author: roman_yakovenko Date: 2008-07-27 18:43:00 +0000 (Sun, 27 Jul 2008) Log Message: ----------- updating from_address FT Modified Paths: -------------- pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp pyplusplus_dev/unittests/ft_from_address_tester.py Modified: pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp 2008-07-23 20:40:56 UTC (rev 1378) +++ pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp 2008-07-27 18:43:00 UTC (rev 1379) @@ -9,14 +9,15 @@ #include <stdexcept> inline unsigned long -sum_matrix( unsigned int** matrix, unsigned int rows, unsigned int columns ){ +sum_matrix( unsigned int* matrix, unsigned int rows, unsigned int columns ){ if( !matrix ){ throw std::runtime_error( "matrix is null" ); } unsigned long result = 0; for( unsigned int r = 0; r < rows; ++r ){ for( unsigned int c = 0; c < columns; ++c ){ - result += matrix[r][c]; + result += *matrix; + ++matrix; } } return result; Modified: pyplusplus_dev/unittests/ft_from_address_tester.py =================================================================== --- pyplusplus_dev/unittests/ft_from_address_tester.py 2008-07-23 20:40:56 UTC (rev 1378) +++ pyplusplus_dev/unittests/ft_from_address_tester.py 2008-07-27 18:43:00 UTC (rev 1379) @@ -29,10 +29,9 @@ mb.calldef( 'sum_matrix' ).add_transformation( ft.from_address(0) ) def run_tests(self, module): - rows = 1 - columns = 1 + rows = 10 + columns = 7 matrix_type = ctypes.c_uint * columns * rows - print matrix_type sum = 0 counter = 0 matrix = matrix_type() @@ -41,10 +40,8 @@ matrix[r][c] = counter sum += counter counter += 1 - print 'matrix filled' result = module.sum_matrix( ctypes.addressof( matrix ), rows, columns ) - print 'result: ', result - print 'sum : ', sum + self.failUnless( result == sum ) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-23 20:40:51
|
Revision: 1378 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1378&view=rev Author: roman_yakovenko Date: 2008-07-23 20:40:56 +0000 (Wed, 23 Jul 2008) Log Message: ----------- adding from_address function transformation Modified Paths: -------------- pyplusplus_dev/pyplusplus/function_transformers/__init__.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py Added Paths: ----------- pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp pyplusplus_dev/unittests/ft_from_address_tester.py Modified: pyplusplus_dev/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2008-07-23 19:17:20 UTC (rev 1377) +++ pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2008-07-23 20:40:56 UTC (rev 1378) @@ -59,3 +59,10 @@ def creator( function ): return transformers.transfer_ownership_t( function, *args, **keywd ) return creator + +def from_address( *args, **keywd ): + def creator( function ): + return transformers.from_address_t( function, *args, **keywd ) + return creator + + Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2008-07-23 19:17:20 UTC (rev 1377) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2008-07-23 20:40:56 UTC (rev 1378) @@ -38,8 +38,8 @@ return declarations.remove_reference( type_ ) else: raise TypeError( 'Type should be reference or pointer, got %s.' % type_ ) - + # output_t class output_t( transformer.transformer_t ): """Handles a single output variable. @@ -61,7 +61,7 @@ """ 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 "output" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ % ( function, self.arg_ref.name, arg.type) @@ -79,13 +79,13 @@ #declaring new variable, which will keep result var_name = controller.declare_variable( remove_ref_or_ptr( self.arg.type ), self.arg.name ) #adding just declared variable to the original function call expression - controller.modify_arg_expression( self.arg_index, var_name ) + controller.modify_arg_expression( self.arg_index, var_name ) #adding the variable to return variables list controller.return_variable( var_name ) def __configure_v_mem_fun_default( self, controller ): self.__configure_sealed( controller ) - + def __configure_v_mem_fun_override( self, controller ): controller.remove_py_arg( self.arg_index ) tmpl = string.Template( @@ -97,10 +97,10 @@ 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_default( controller.default_controller ) self.__configure_v_mem_fun_override( controller.override_controller ) @@ -108,14 +108,14 @@ # input_t class type_modifier_t(transformer.transformer_t): """Change/modify type of the argument. - + Right now compiler should be able to use implicit conversion """ def __init__(self, function, arg_ref, modifier): """Constructor. - modifier is callable, which take the type of the argument and should return + modifier is callable, which take the type of the argument and should return new type """ transformer.transformer_t.__init__( self, function ) @@ -132,23 +132,23 @@ if not declarations.is_convertible( w_arg.type, self.arg.type ): casting_code = 'reinterpret_cast< %s >( %s )' % ( self.arg.type, w_arg.name ) controller.modify_arg_expression(self.arg_index, casting_code) - + def __configure_v_mem_fun_default( self, controller ): self.__configure_sealed( controller ) 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_default( controller.default_controller ) + self.__configure_v_mem_fun_default( controller.default_controller ) def required_headers( self ): """Returns list of header files that transformer generated code depends on.""" return [] - + # input_t class input_t(type_modifier_t): """Handles a single input variable. @@ -175,6 +175,35 @@ def __str__(self): return "input(%s)"%(self.arg.name) +# input_t +class from_address_t(type_modifier_t): + """Handles a single input variable. + + Replaces the actual argument type with some integral type, so you + can use ctypes package. + + void do_smth(int** image) -> do_smth(unsigned int addressof_image) + + """ + + 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 + """ + modifier = lambda type_: declarations.FUNDAMENTAL_TYPES[ 'unsigned int' ] + type_modifier_t.__init__( self, function, arg_ref, modifier ) + + if not is_ptr_or_array( self.arg.type ): + raise ValueError( '%s\nin order to use "from_address_t" transformation, argument %s type must be a pointer or a array (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) + + def __str__(self): + return "from_address(%s)"%(self.arg.name) + # inout_t class inout_t(transformer.transformer_t): """Handles a single input/output variable. @@ -193,7 +222,7 @@ 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) @@ -206,10 +235,10 @@ w_arg.type = remove_ref_or_ptr( self.arg.type ) #adding the variable to return variables list controller.return_variable( w_arg.name ) - + def __configure_v_mem_fun_default( self, controller ): self.__configure_sealed( controller ) - + def __configure_v_mem_fun_override( self, controller ): tmpl = string.Template( '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' ) @@ -220,7 +249,7 @@ def configure_mem_fun( self, controller ): self.__configure_sealed( controller ) - + def configure_free_fun(self, controller ): self.__configure_sealed( controller ) @@ -241,7 +270,7 @@ 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist );' , 'pyplus_conv::copy_sequence( $pylist, std::back_inserter( $native_array), boost::type< $type >() );'])) -_arr2seq = string.Template( +_arr2seq = string.Template( 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) class input_static_array_t(transformer.transformer_t): @@ -258,10 +287,10 @@ @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.name, self.arg.type) @@ -285,41 +314,41 @@ native_array = controller.declare_variable( self.array_item_type , "native_" + self.arg.name , '[%d]' % self.array_size ) - + copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type , pylist=w_arg.name , array_size=self.array_size , native_array=native_array ) - + controller.add_pre_call_code( copy_pylist2arr ) - - controller.modify_arg_expression( self.arg_index, native_array ) + controller.modify_arg_expression( self.arg_index, native_array ) + def __configure_v_mem_fun_default( self, controller ): self.__configure_sealed( controller ) - + def __configure_v_mem_fun_override( self, controller ): 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 ) - + # s - static class output_static_array_t(transformer.transformer_t): """Handles an output array of a fixed size. @@ -365,16 +394,16 @@ , '[%d]' % self.array_size ) #adding just declared variable to the original function call expression - controller.modify_arg_expression( self.arg_index, native_array ) + controller.modify_arg_expression( self.arg_index, native_array ) # Declare a Python list which will receive the output... pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" ) , 'py_' + self.arg.name ) - + copy_arr2pylist = _arr2seq.substitute( native_array=native_array , array_size=self.array_size , pylist=pylist ) - + controller.add_post_call_code( copy_arr2pylist ) #adding the variable to return variables list @@ -393,16 +422,16 @@ , py_result=controller.py_result_variable.name , name=self.arg.name ) controller.add_py_post_call_code( get_ref_to_seq ) - + copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type , pylist=seq , array_size=self.array_size , native_array=self.arg.name ) controller.add_py_post_call_code( copy_pylist2arr ) - + def configure_mem_fun( self, controller ): self.__configure_sealed( controller ) - + def configure_free_fun(self, controller ): self.__configure_sealed( controller ) @@ -420,11 +449,11 @@ 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 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 ) @@ -453,56 +482,56 @@ 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( + 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( + buffer_var = controller.declare_variable( declarations.dummy_type_t( "std::vector< %s >" % self.buffer_item_type.decl_string ) , "native_" + self.buffer_arg.name ) controller.add_pre_call_code( '%s.reserve( %s );' % ( buffer_var, 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 ) + 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 ) - + class transfer_ownership_t(type_modifier_t): """see http://boost.org/libs/python/doc/v2/faq.html#ownership """ @@ -524,13 +553,13 @@ naked_type = declarations.remove_declarated( naked_type ) w_arg.type = declarations.dummy_type_t( 'std::auto_ptr< %s >' % naked_type.decl_string ) controller.modify_arg_expression(self.arg_index, w_arg.name + '.release()' ) - + def __configure_v_mem_fun_default( self, controller ): self.__configure_sealed( controller ) def configure_mem_fun( self, controller ): self.__configure_sealed( controller ) - + def configure_free_fun(self, controller ): self.__configure_sealed( controller ) @@ -540,7 +569,7 @@ #TODO: FT for constructor #~ def configure_constructor( self, controller ): #~ self.__configure_sealed( controller ) - + def required_headers( self ): """Returns list of header files that transformer generated code depends on.""" return [] Added: pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp 2008-07-23 20:40:56 UTC (rev 1378) @@ -0,0 +1,25 @@ +// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __ft_from_address_to_be_exported_hpp__ +#define __ft_from_address_to_be_exported_hpp__ + +#include <stdexcept> + +inline unsigned long +sum_matrix( unsigned int** matrix, unsigned int rows, unsigned int columns ){ + if( !matrix ){ + throw std::runtime_error( "matrix is null" ); + } + unsigned long result = 0; + for( unsigned int r = 0; r < rows; ++r ){ + for( unsigned int c = 0; c < columns; ++c ){ + result += matrix[r][c]; + } + } + return result; +} + +#endif//__ft_from_address_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/ft_from_address_tester.py =================================================================== --- pyplusplus_dev/unittests/ft_from_address_tester.py (rev 0) +++ pyplusplus_dev/unittests/ft_from_address_tester.py 2008-07-23 20:40:56 UTC (rev 1378) @@ -0,0 +1,58 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import sys +import math +import ctypes +import unittest +import fundamental_tester_base +from pygccxml import declarations +from pyplusplus import function_transformers as ft +from pyplusplus.module_builder import call_policies + + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'ft_from_address' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize( self, mb ): + + mb.global_ns.calldefs().create_with_signature = True + mb.calldef( 'sum_matrix' ).add_transformation( ft.from_address(0) ) + + def run_tests(self, module): + rows = 1 + columns = 1 + matrix_type = ctypes.c_uint * columns * rows + print matrix_type + sum = 0 + counter = 0 + matrix = matrix_type() + for r in range( rows ): + for c in range( columns ): + matrix[r][c] = counter + sum += counter + counter += 1 + print 'matrix filled' + result = module.sum_matrix( ctypes.addressof( matrix ), rows, columns ) + print 'result: ', result + print 'sum : ', sum + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-23 19:17:11
|
Revision: 1377 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1377&view=rev Author: roman_yakovenko Date: 2008-07-23 19:17:20 +0000 (Wed, 23 Jul 2008) Log Message: ----------- adding code which will automaticly exclude variables with type "Python immutable* [4]" Modified Paths: -------------- pyplusplus_dev/docs/documentation/www_configuration.py pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py Modified: pyplusplus_dev/docs/documentation/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/www_configuration.py 2008-07-22 18:55:08 UTC (rev 1376) +++ pyplusplus_dev/docs/documentation/www_configuration.py 2008-07-23 19:17:20 UTC (rev 1377) @@ -5,7 +5,8 @@ , 'how_to' : 'how to ... ?' , 'doc_string' : 'documentation string' , 'inserting_code' : 'inserting code' - , 'best_practices' : 'best practices' + , 'best_practices' : 'best practices' , 'multi_module_development' : 'multi-module development' , 'split_module' : 'splitting generated code to files' + , 'ctypes_integration' : 'ctypes integration' } Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-07-22 18:55:08 UTC (rev 1376) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-07-23 19:17:20 UTC (rev 1377) @@ -8,6 +8,7 @@ import decl_wrapper import python_traits import call_policies +import python_traits from pyplusplus import messages from pygccxml import declarations @@ -144,6 +145,8 @@ is_read_only = property( get_is_read_only, set_is_read_only ) def _exportable_impl( self ): + if self.name == 'f': + i = 0 if not self.name: return messages.W1033 if self.bits == 0 and self.name == "": @@ -172,4 +175,10 @@ if isinstance( self.parent, declarations.class_t ): if self.access_type != declarations.ACCESS_TYPES.PUBLIC: return messages.W1039 + if declarations.is_array( type_ ): + item_type = declarations.array_item_type( type_ ) + if declarations.is_pointer( item_type ): + item_type_no_ptr = declarations.remove_pointer( item_type ) + if python_traits.is_immutable( item_type_no_ptr ): + return messages.W1056 return '' Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-22 18:55:08 UTC (rev 1376) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-23 19:17:20 UTC (rev 1377) @@ -220,6 +220,8 @@ W1055 = warning( "Py++ will generate class wrapper - hand written code should be added to the wrapper class destructor body" ) +W1056 = compilation_error( "Py++ can not expose array of pointers of Python immutable types. Take a look on 'ctypes integration' feature." ) + warnings = globals() all_warning_msgs = [] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-22 18:55:03
|
Revision: 1376 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1376&view=rev Author: roman_yakovenko Date: 2008-07-22 18:55:08 +0000 (Tue, 22 Jul 2008) Log Message: ----------- adding "ctypes integration" documentation Added Paths: ----------- pyplusplus_dev/docs/documentation/ctypes_integration.rest Added: pyplusplus_dev/docs/documentation/ctypes_integration.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes_integration.rest (rev 0) +++ pyplusplus_dev/docs/documentation/ctypes_integration.rest 2008-07-22 18:55:08 UTC (rev 1376) @@ -0,0 +1,148 @@ +================== +ctypes integration +================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +`Boost.Python`_ is really a very powerful library, but if you are working +with code written in plain "C" - you've got a problem. You have to create +wrappers for almost every function or variable. + +In general, if you want to work with plain "C" code from `Python`_ +you don't have to create any wrapper - you can use `ctypes`_ package. + +About ctypes +------------ +`ctypes`_ is a foreign function library for Python. It provides C +compatible data types, and allows to call functions in dlls/shared +libraries. It can be used to wrap these libraries in pure Python. + + + +The idea behind "ctypes integration" functionality is simple: you +configure `Py++`_ to expose address of the variables or return +values, as integer and than you can use `ctypes`_ `from_address`_ +functionality to access the data. + +Obviously, this approach has its price: + +* it could be very dangerous - you can corrupt your application memory + +* managing memory is not something a typical `Python`_ user get used to. + It is too "low level". + +In my opinion, the better way to go is to "mix": + +1. expose your native code using `Boost.Python`_ and "ctypes integration" + functionality + +2. use `ctypes`_ module to access your data + +3. create high level API: the wrappers, which will ensure the constraints + and will provide more "natural" interface + +-------------- +Usage examples +-------------- + +Variables +--------- + +Lets say you have the following C++ code: + + .. code-block:: C++ + + struct bytes_t{ + bytes_t(){ + data = new int[5]; + for(int i=0; i<5; i++){ + data[i] = i; + } + } + ... + int* data; + static int* x; + }; + + //somewhere in a cpp file + int* bytes_t::x = new int( 1997 ); + +In order to get access to the ``bytes_t::data`` and ``bytes_t::x`` you +have to turn on ``expose_address`` property to ``True``: + + .. code-block:: Python + + mb = module_builder_t( ... ) + bytes = mb.class_( 'bytes_t' ) + bytes.vars().expose_address = True + +`Py++`_ will generate code, which will expose the address of the variables. + +and now it is a time to show some `ctypes`_ magic: + + .. code-block:: Python + + import ctypes + import your_module as m + + bytes = m.bytes_t() + + data_type = ctypes.POINTER( ctypes.c_int ) + data = data_type.from_address( bytes.data ) + for j in range(5): + print '%d : %d' % ( j, data[j] ) + + data_type = ctypes.POINTER( ctypes.c_int ) + data = data_type.from_address( m.bytes_t.x ) + print x.contents.value + + +"this" pointer +-------------- + +`Py++`_ can expose "this" pointer value to `Python`_: + + .. code-block:: Python + + mb = module_builder_t( ... ) + mb.class_( 'bytes_t' ).expose_this = True + +and the usage example: + + .. code-block:: Python + + import ctypes + import your_module as m + + print m.bytes_t().this + + +Warning: I hope you know what you are doing, otherwise don't blame me :-) + +----------------- +Future directions +----------------- + +The functionality is going to be developed father and I intend to add +next features: + +* to expose the result of "sizeof" applied on a class or variable + +* to add new call policy, which will return value of a pointer as integer + +* to port this functionality to 64bit systems + +* to add support for unions + +.. _`ctypes` : http://docs.python.org/lib/module-ctypes.html +.. _`from_address` : http://docs.python.org/lib/ctypes-data-types.html +.. _`Py++` : ./../pyplusplus.html +.. _`pygccxml` : ./../../pygccxml/pygccxml.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-22 04:34:29
|
Revision: 1375 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1375&view=rev Author: roman_yakovenko Date: 2008-07-22 04:34:35 +0000 (Tue, 22 Jul 2008) Log Message: ----------- adding new test case double*[] Modified Paths: -------------- pyplusplus_dev/unittests/data/arrays_bug_to_be_exported.hpp Modified: pyplusplus_dev/unittests/data/arrays_bug_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/arrays_bug_to_be_exported.hpp 2008-07-21 20:16:53 UTC (rev 1374) +++ pyplusplus_dev/unittests/data/arrays_bug_to_be_exported.hpp 2008-07-22 04:34:35 UTC (rev 1375) @@ -8,6 +8,10 @@ struct arrays_bug{ +struct array_of_arrays{ + double* f[4]; +}; + struct item{ int values[10]; }; struct container{ item items[10]; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-21 20:16:46
|
Revision: 1374 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1374&view=rev Author: roman_yakovenko Date: 2008-07-21 20:16:53 +0000 (Mon, 21 Jul 2008) Log Message: ----------- adding ability to expose address of the static variable Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/member_variable.py pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py pyplusplus_dev/unittests/data/member_variables_to_be_exported.cpp pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp pyplusplus_dev/unittests/member_variables_tester.py Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-17 04:31:02 UTC (rev 1373) +++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-21 20:16:53 UTC (rev 1374) @@ -656,30 +656,30 @@ def __init__(self, variable, wrapper=None ): member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper ) - def _create_impl( self ): - doc = '' #static property does not support documentation - if self.declaration.type_qualifiers.has_static: - add_property = 'add_static_property' - else: - if self.documentation: - doc = self.documentation - add_property = 'add_property' - answer = [ add_property ] + def _create_m_var( self ): + answer = [ 'add_property' ] answer.append( '( ' ) answer.append('"%s"' % self.alias) answer.append( self.PARAM_SEPARATOR ) - - if self.declaration.type_qualifiers.has_static: - answer.append( 'not implemented' ) - else: - answer.append( 'pyplus_conv::make_addressof_getter(&%s)' - % self.decl_identifier ) - if doc: + answer.append( 'pyplus_conv::make_addressof_getter(&%s)' + % self.decl_identifier ) + if self.documentation: answer.append( self.PARAM_SEPARATOR ) - answer.append( doc ) + answer.append( self.documentation ) answer.append( ' ) ' ) - return ''.join( answer ) + def _create_s_var( self ): + return 'def( %(def_visitor)s("%(name)s", %(var)s) )' \ + % { 'def_visitor' : 'pyplus_conv::register_addressof_static_var' + , 'name' : self.alias + , 'var' : self.decl_identifier } + + + def _create_impl( self ): + if self.declaration.type_qualifiers.has_static: + return self._create_s_var() + else: + return self._create_m_var() def _get_system_headers_impl( self ): return [code_repository.ctypes_integration.file_name] Modified: pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-07-17 04:31:02 UTC (rev 1373) +++ pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-07-21 20:16:53 UTC (rev 1374) @@ -32,18 +32,17 @@ namespace pyplusplus{ namespace convenience{ template< typename TType, typename TMemVarType > -boost::uintmax_t +boost::uint32_t addressof( const TType &inst, const TMemVarType TType::* offset){ - return boost::uintmax_t( boost::addressof( inst.*offset ) ); + return boost::uint32_t( boost::addressof( inst.*offset ) ); } template< typename TType > -boost::uintmax_t +boost::uint32_t addressof_inst( const TType &inst){ - return boost::uintmax_t( boost::addressof( inst ) ); + return boost::uint32_t( boost::addressof( inst ) ); } - template< typename TType, typename TMemVarType > boost::python::object make_addressof_getter( const TMemVarType TType::* offset ){ @@ -51,7 +50,7 @@ namespace pyppc = pyplusplus::convenience; return bpl::make_function( boost::bind( &pyppc::addressof< TType, TMemVarType >, _1, offset ) , bpl::default_call_policies() - , boost::mpl::vector< boost::uintmax_t, const TType& >() ); + , boost::mpl::vector< boost::uint32_t, const TType& >() ); } template< typename TType > @@ -61,9 +60,32 @@ namespace pyppc = pyplusplus::convenience; return bpl::make_function( boost::bind( &pyppc::addressof_inst< TType >, _1 ) , bpl::default_call_policies() - , boost::mpl::vector< boost::uintmax_t, const TType& >() ); + , boost::mpl::vector< boost::uint32_t, const TType& >() ); } +class register_addressof_static_var : public boost::python::def_visitor<register_addressof_static_var> +{ + friend class boost::python::def_visitor_access; + +public: + + template< typename TVarType > + register_addressof_static_var( const char* name, const TVarType& var ) + : m_name( name ) + , m_address( addressof_inst( var ) ) + {} + + template <class classT> + void visit(classT& c) const{ + boost::python::scope cls_scope( c ); + cls_scope.attr(m_name) = m_address; + } + +private: + boost::uint32_t m_address; + const char* m_name; +}; + } /*pyplusplus*/ } /*convenience*/ namespace pyplus_conv = pyplusplus::convenience; Modified: pyplusplus_dev/unittests/data/member_variables_to_be_exported.cpp =================================================================== --- pyplusplus_dev/unittests/data/member_variables_to_be_exported.cpp 2008-07-17 04:31:02 UTC (rev 1373) +++ pyplusplus_dev/unittests/data/member_variables_to_be_exported.cpp 2008-07-21 20:16:53 UTC (rev 1374) @@ -5,7 +5,7 @@ #include "member_variables_to_be_exported.hpp" -namespace member_variables{ +namespace member_variables{ int point::instance_count = 0; const point::color point::default_color = point::red; @@ -28,17 +28,24 @@ std::auto_ptr<tree_node_t> root( new tree_node_t() ); root->data = new data_t(); root->data->value = 0; - + root->left = new tree_node_t( root.get() ); root->left->data = new data_t(); root->left->data->value = 1; - - return root; + + return root; } } -namespace statics{ +namespace statics{ std::string mem_var_str_t::class_name( "mem_var_str_t" ); } + + +namespace ctypes{ + int xxx = 1997; + int* image_t::none_image = &xxx; } + +} Modified: pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-17 04:31:02 UTC (rev 1373) +++ pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-21 20:16:53 UTC (rev 1374) @@ -160,6 +160,8 @@ } } int* data; + + static int* none_image; }; } Modified: pyplusplus_dev/unittests/member_variables_tester.py =================================================================== --- pyplusplus_dev/unittests/member_variables_tester.py 2008-07-17 04:31:02 UTC (rev 1373) +++ pyplusplus_dev/unittests/member_variables_tester.py 2008-07-21 20:16:53 UTC (rev 1374) @@ -24,6 +24,7 @@ mb.classes().always_expose_using_scope = True image = mb.class_( 'image_t' ) image.var( 'data' ).expose_address = True + image.var( 'none_image' ).expose_address = True def change_default_color( self, module ): module.point.default_color = module.point.color.blue @@ -96,6 +97,9 @@ for j in range(5): print '%d : %d' % ( j, data[j] ) + data_type = ctypes.POINTER( ctypes.c_int ) + data = data_type.from_address( module.image_t.none_image ) + self.failUnless( 1997 == data.contents.value ) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-17 04:30:55
|
Revision: 1373 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1373&view=rev Author: roman_yakovenko Date: 2008-07-17 04:31:02 +0000 (Thu, 17 Jul 2008) Log Message: ----------- adding ability to expose "this" pointer to python as integer Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/member_variable.py pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/classes_tester.py Added Paths: ----------- pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-14 18:58:40 UTC (rev 1372) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-17 04:31:02 UTC (rev 1373) @@ -135,3 +135,5 @@ from opaque_type_registrator import opaque_type_registrator_t from properties import property_t + +from ctypes_integration_creators import expose_this_t Added: pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py (rev 0) +++ pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py 2008-07-17 04:31:02 UTC (rev 1373) @@ -0,0 +1,39 @@ +# 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 declaration_based +import registration_based +from pygccxml import declarations +from pyplusplus import decl_wrappers +from pyplusplus import code_repository + +class expose_this_t( registration_based.registration_based_t + , declaration_based.declaration_based_t ): + """ + creates code that expose address of the object to Python + """ + + def __init__(self, class_ ): + registration_based.registration_based_t.__init__( self ) + declaration_based.declaration_based_t.__init__( self, declaration=class_) + + def _create_impl(self): + answer = [ 'add_property' ] + answer.append( '( ' ) + answer.append('"this"') + answer.append( self.PARAM_SEPARATOR ) + answer.append( 'pyplus_conv::make_addressof_inst_getter< %s >()' % self.decl_identifier ) + if self.documentation: + answer.append( self.PARAM_SEPARATOR ) + answer.append( self.documentation ) + answer.append( ' ) ' ) + + return ''.join( answer ) + + def _get_system_headers_impl( self ): + return [code_repository.ctypes_integration.file_name] Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-14 18:58:40 UTC (rev 1372) +++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-17 04:31:02 UTC (rev 1373) @@ -669,8 +669,11 @@ answer.append('"%s"' % self.alias) answer.append( self.PARAM_SEPARATOR ) - answer.append( 'pyplus_conv::make_addressof_getter(&%s)' - % self.decl_identifier ) + if self.declaration.type_qualifiers.has_static: + answer.append( 'not implemented' ) + else: + answer.append( 'pyplus_conv::make_addressof_getter(&%s)' + % self.decl_identifier ) if doc: answer.append( self.PARAM_SEPARATOR ) answer.append( doc ) Modified: pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-07-14 18:58:40 UTC (rev 1372) +++ pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-07-17 04:31:02 UTC (rev 1373) @@ -37,6 +37,13 @@ return boost::uintmax_t( boost::addressof( inst.*offset ) ); } +template< typename TType > +boost::uintmax_t +addressof_inst( const TType &inst){ + return boost::uintmax_t( boost::addressof( inst ) ); +} + + template< typename TType, typename TMemVarType > boost::python::object make_addressof_getter( const TMemVarType TType::* offset ){ @@ -47,6 +54,16 @@ , boost::mpl::vector< boost::uintmax_t, const TType& >() ); } +template< typename TType > +boost::python::object +make_addressof_inst_getter(){ + namespace bpl = boost::python; + namespace pyppc = pyplusplus::convenience; + return bpl::make_function( boost::bind( &pyppc::addressof_inst< TType >, _1 ) + , bpl::default_call_policies() + , boost::mpl::vector< boost::uintmax_t, const TType& >() ); +} + } /*pyplusplus*/ } /*convenience*/ namespace pyplus_conv = pyplusplus::convenience; Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-14 18:58:40 UTC (rev 1372) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-17 04:31:02 UTC (rev 1373) @@ -190,6 +190,7 @@ self._redefined_funcs = None self._require_self_reference = False self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED + self._expose_this = None def _get_redefine_operators( self ): return self._redefine_operators @@ -628,3 +629,10 @@ self._require_self_reference = require_self_reference require_self_reference = property( _get_require_self_reference, _set_require_self_reference , doc="boolean, if True the first argument to the constructor will be reference to self object" ) + + def _get_expose_this( self ): + return self._expose_this + def _set_expose_this( self, new_value ): + self._expose_this = new_value + expose_this = property( _get_expose_this, _set_expose_this + , doc="boolean, if True an object address( this pointer ) will be exposed to Python as integer.") Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-14 18:58:40 UTC (rev 1372) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-17 04:31:02 UTC (rev 1373) @@ -593,6 +593,10 @@ cls_parent_cc.adopt_creator( cls_cc ) self.curr_code_creator = cls_cc + + if cls_decl.expose_this: + cls_cc.adopt_creator( code_creators.expose_this_t( cls_decl ) ) + for decl in exportable_members: if decl in exposed: continue Modified: pyplusplus_dev/unittests/classes_tester.py =================================================================== --- pyplusplus_dev/unittests/classes_tester.py 2008-07-14 18:58:40 UTC (rev 1372) +++ pyplusplus_dev/unittests/classes_tester.py 2008-07-17 04:31:02 UTC (rev 1373) @@ -10,14 +10,15 @@ class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'classes' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , tester_t.EXTENSION_NAME , *args ) - + def customize(self, mb ): + mb.classes().expose_this = True mb.class_( 'fundamental2' ).alias = 'FUNDAMENTAL2' apple = mb.class_( 'apple' ) self.failUnless( apple.alias == 'the_tastest_fruit' ) @@ -29,7 +30,7 @@ self.failUnless( 'PROTECTED_STATIC' in protected_static_t.alias) protected_static_t.alias = 'protected_static_t' - def run_tests(self, module): + def run_tests(self, module): self.failIfRaisesAny( module.fundamental1 ) self.failIfRaisesAny( module.FUNDAMENTAL2 ) @@ -39,21 +40,22 @@ self.failIfRaisesAny( module.noncopyable1 ) self.failIfRaisesAny( module.abstract ) - + self.failIfRaisesAny( module.constructor1 ) self.failIfRaisesAny( module.constructor1, 1, 2 ) self.failIfRaisesAny( module.constructor1, 3, module.constructor1() ) - + self.failIfRaisesAny( module.scope_based_exposer ) self.failIfRaisesAny( lambda: module.scope_based_exposer.EColor.red ) - + self.failUnless( 24 == module.protected_static_t.identity(24) ) self.failUnless( 29 == module.protected_static_t.identity(29) ) self.failUnless( -24 == module.protected_static_t().invert_sign(24) ) self.failUnless( 67 == module.protected_static_t().invert_sign(-67) ) - + self.failUnless( module.protected_static_t().this ) + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-14 18:58:35
|
Revision: 1372 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1372&view=rev Author: roman_yakovenko Date: 2008-07-14 11:58:40 -0700 (Mon, 14 Jul 2008) Log Message: ----------- adding ablity to generate class wrapper destructor Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/transfer_ownership_tester.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -68,6 +68,7 @@ from calldef import casting_operator_t from calldef import mem_fun_overloads_t from calldef import free_fun_overloads_t +from calldef import destructor_wrapper_t from calldef import casting_constructor_t from calldef import constructor_wrapper_t from calldef import mem_fun_overloads_class_t Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -1157,7 +1157,25 @@ def _get_system_headers_impl( self ): return [] +class destructor_wrapper_t( code_creator.code_creator_t + , declaration_based.declaration_based_t ): + """ + Creates class wrapper destructor from the code provided by the user + """ + def __init__( self, class_ ): + code_creator.code_creator_t.__init__( self ) + declaration_based.declaration_based_t.__init__( self, declaration=class_ ) + def _create_impl(self): + answer = [ 'virtual ~%s(){' % self.declaration.wrapper_alias ] + answer.append( self.indent( os.linesep.join( self.declaration.destructor_code ) ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def _get_system_headers_impl( self ): + return [] + + class calldef_overloads_class_t( code_creator.code_creator_t ): def __init__( self, functions ): #precondition: all member functions belong to same class and Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -76,8 +76,8 @@ @property def indexing_suite( self ): - """reference to indexing suite configuration class. - + """reference to indexing suite configuration class. + If the class is not STD container, this property will contain None" """ if self._indexing_suite is None: @@ -105,7 +105,7 @@ else: self._always_expose_using_scope = False return self._always_expose_using_scope - + def _set_always_expose_using_scope( self, value ): self._always_expose_using_scope = value always_expose_using_scope = property( _get_always_expose_using_scope, _set_always_expose_using_scope @@ -134,12 +134,12 @@ 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 + self._opaque = value self.ignore = value #don't expose opaque type opaque = property( _get_opaque, _set_opaque @@ -163,12 +163,12 @@ class class_t( class_common_details_t , scopedef_wrapper.scopedef_t , declarations.class_t): - + class EXPOSED_CLASS_TYPE: DECLARED = 'declared' WRAPPER = 'wrapper' ALL = ( DECLARED, WRAPPER ) - + def __init__(self, *arguments, **keywords): class_common_details_t.__init__( self ) declarations.class_t.__init__(self, *arguments, **keywords ) @@ -177,19 +177,20 @@ self._redefine_operators = False self._held_type = None self._noncopyable = None - self._wrapper_alias = None + self._wrapper_alias = None self._registration_code_head = [] self._registration_code_tail = [] self._declaration_code = [] self._wrapper_code = [] self._null_constructor_body = '' self._copy_constructor_body = '' + self._destructor_code = [] self._exception_translation_code = None self._properties = [] self._redefined_funcs = None self._require_self_reference = False self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED - + def _get_redefine_operators( self ): return self._redefine_operators def _set_redefine_operators( self, new_value ): @@ -288,6 +289,15 @@ , doc="copy constructor code, that will be added as is to the copy constructor of class-wrapper") @property + def destructor_code(self): + """list of code to be added to wrapper destructor""" + return self._destructor_code + + def add_destructor_code(self, code): + """adds code to the class-wrapper destructor""" + self._destructor_code.append( code ) + + @property def exception_argument_name( self ): """exception argument name for translate exception function @@ -341,7 +351,7 @@ self.registration_code_tail.append( user_text.class_user_text_t( code, works_on_instance ) ) else: self.registration_code_head.append( user_text.class_user_text_t( code, works_on_instance ) ) - + #preserving backward computability add_code = add_registration_code @@ -385,7 +395,7 @@ 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 ) ) - + def is_exportable( decl ): #filter out non-public member operators - Py++ does not support them right now if isinstance( decl, declarations.member_operator_t ) \ @@ -396,7 +406,7 @@ return False if decl.ignore == True or decl.exportable == False: return False - return True + return True #-#if declarations.has_destructor( self ) \ #-# and not declarations.has_public_destructor( self ): members = filter( is_exportable, members ) @@ -425,7 +435,7 @@ def add_properties( self, recognizer=None, exclude_accessors=False ): props = properties.find_properties( self, recognizer, exclude_accessors ) self.properties.extend( props ) - + def add_static_property( self, name, fget, fset=None, doc='' ): """adds new static property to the class""" self._properties.append( properties.property_t( name, fget, fset, doc, True ) ) @@ -456,14 +466,14 @@ all_included = declarations.custom_matcher_t( lambda decl: decl.ignore == False and decl.exportable ) all_protected = declarations.access_type_matcher_t( 'protected' ) & all_included - all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL ) + all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL ) all_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.VIRTUAL ) \ & ( declarations.access_type_matcher_t( 'public' ) \ - | declarations.access_type_matcher_t( 'protected' )) + | declarations.access_type_matcher_t( 'protected' )) all_not_pure_virtual = ~all_pure_virtual - query = all_protected | all_pure_virtual - mf_query = query | all_virtual + query = all_protected | all_pure_virtual + mf_query = query | all_virtual relevant_opers = declarations.custom_matcher_t( lambda decl: decl.symbol in ('()', '[]') ) funcs = [] defined_funcs = [] @@ -493,7 +503,7 @@ if declarations.is_base_and_derived( f_impl.parent, f.parent ): #add function from the most derived class not_reimplemented_funcs.remove( f_impl ) - not_reimplemented_funcs.add( f ) + not_reimplemented_funcs.add( f ) break else: #should test whether this function is implemented in base class @@ -504,18 +514,18 @@ if is_same_function( f, f_defined ): break else: - not_reimplemented_funcs.add( f ) + not_reimplemented_funcs.add( f ) functions = filter( lambda f: ( False == f.ignore and True == f.exportable ) or all_pure_virtual( f ) , list( not_reimplemented_funcs ) ) - + #Boost.Python is not able to call for non-virtual function, from the base #class if there is a virtual function with the same within base class #See override_bug tester for more information def buggy_bpl_filter( f ): - if f.parent is self: + if f.parent is self: return False if f.access_type != ACCESS_TYPES.PUBLIC: return False @@ -564,6 +574,9 @@ if self.copy_constructor_body: explanation.append( messages.W1022 ) + if self.destructor_code: + explanation.append( messages.W1055 ) + redefined_funcs = self.redefined_funcs() if redefined_funcs: funcs = map( lambda f: f.name, redefined_funcs ) @@ -607,7 +620,7 @@ #MSVC 7.1 has problem with taking reference to operator= if self.member_operators( is_assign, allow_empty=True, recursive=False ): return impl_details.GUESS_VALUES.ALWAYS_TRUE - return super(class_t, self).guess_always_expose_using_scope_value() + return super(class_t, self).guess_always_expose_using_scope_value() def _get_require_self_reference(self): return self._require_self_reference Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -3,7 +3,7 @@ # 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. """ @@ -11,13 +11,13 @@ """implementation details""" def __new__(self, value, identifier=None): return str.__new__(self, value ) - + def __init__(self, value, identifier=None): - self.__identifier = identifier - + self.__identifier = identifier + @property def identifier( self ): - return self.__identifier + return self.__identifier def __mod__( self, values ): str_value = super( message_type, self ).__str__() @@ -34,55 +34,55 @@ W0000 = warning( '%s' ) #general message, usefull in few cases -W1000 = compilation_error( +W1000 = compilation_error( 'Py++, by default, does not expose internal compilers declarations. ' 'Names of those declarations usually start with "__".' ) -W1001 = compilation_error( +W1001 = compilation_error( 'Py++, by default, does not expose internal declarations. ' 'GCC-XML reports that these declaration belong to "<internal>" header.' ) -W1002 = compilation_error( +W1002 = compilation_error( 'Py++, by default, does not expose compiler generated declarations.' ) -W1003 = warning( - '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 ' +W1003 = warning( + '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 ' 'to solve the problem.' ) -W1004 = compilation_error( - 'Boost.Python library can not expose function, which takes as argument/returns ' - 'pointer to function. ' +W1004 = compilation_error( + '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 = compilation_error( - 'Py++ cannot expose function that takes as argument/returns instance of non-public class. ' +W1005 = compilation_error( + 'Py++ cannot expose function that takes as argument/returns instance of non-public class. ' 'Generated code will not compile.' ) -W1006 = compilation_error( +W1006 = compilation_error( '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 = warning( - 'The function has more than %d arguments ( %d ). ' - 'You should adjust BOOST_PYTHON_MAX_ARITY macro. ' +W1007 = warning( + '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 = warning( - 'The function returns non-const reference to "Python immutable" type. ' +W1008 = warning( + 'The function returns non-const reference to "Python immutable" type. ' 'The value cannot be modified from Python. ' ) -W1009 = execution_error( - 'The function takes as argument (name=%s, pos=%d) non-const reference ' - 'to Python immutable type - function could not be called from Python. ' +W1009 = execution_error( + '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 = execution_error( - '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 ' + '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 = warning( "Py++ doesn't export private not virtual functions." ) @@ -91,14 +91,14 @@ W1013 = compilation_error( "Py++ doesn't export private constructor." ) -W1014 = compilation_error( +W1014 = compilation_error( '"%s" is not supported. ' 'See Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/operators.html#introduction.' ) W1015 = compilation_error( "Py++ doesn't export private operators." ) -W1016 = warning( - 'Py++ does not exports non-const casting operators with user defined type as return value. ' +W1016 = warning( + 'Py++ does not exports non-const casting operators with user defined type as return value. ' 'This could be change in future.' ) W1017 = compilation_error( "Py++ doesn't export non-public casting operators." ) @@ -113,7 +113,7 @@ W1022 = warning( "Py++ will generate class wrapper - hand written code should be added to the wrapper class copy constructor body" ) -W1023 = warning( +W1023 = warning( "Py++ will generate class wrapper - there are few functions that should be redefined in class wrapper. " "The functions are: %s." ) @@ -133,10 +133,10 @@ W1031 = warning( 'Py++ will generate class wrapper - user asked to expose non - public member function "%s"' ) -W1032 = execution_error( - "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 . " +W1032 = execution_error( + "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 = compilation_error( "Py++ can not expose unnamed variables" ) @@ -147,21 +147,21 @@ W1036 = compilation_error( "Py++ can not expose pointer to Python immutable member variables. This could be changed in future." ) -W1037 = compilation_error( - "Boost.Python library can not expose variables, which are pointer to function." +W1037 = compilation_error( + "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 = compilation_error( "Py++ can not expose variables of with unnamed type." ) W1039 = compilation_error( "Py++ doesn't expose private or protected member variables." ) -W1040 = execution_error( +W1040 = execution_error( 'The declaration is unexposed, but there are other declarations, which refer to it. ' - 'This could cause "no to_python converter found" run time error. ' + 'This could cause "no to_python converter found" run time error. ' 'Declarations: %s' ) -W1041 = warning( - 'Property "%s" could not be created. There is another exposed declaration with the same name( alias )." ' +W1041 = warning( + 'Property "%s" could not be created. There is another exposed declaration with the same name( alias )." ' 'The property will make it inaccessible.' ) W1042 = warning( @@ -175,15 +175,15 @@ W1044 = warning( 'Py++ created an ugly alias ("%s") for function wrapper.' ) -W1045 = compilation_error( +W1045 = compilation_error( '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.' ) -W1046 = warning( - 'The virtual function was declared with empty throw. ' - 'Adding the ability to override the function from Python breaks the exception specification. ' - 'The function wrapper can throw any exception. ' +W1046 = warning( + 'The virtual function was declared with empty throw. ' + 'Adding the ability to override the function from Python breaks the exception specification. ' + 'The function wrapper can throw any exception. ' 'In case of exception in run-time, the behaviour of the program is undefined! ' ) W1047 = warning( @@ -192,32 +192,34 @@ 'of the classes will not be exposed to Python.' 'Other classes : %s' ) -W1048 = warning( +W1048 = warning( 'There are two or more aliases within "pyplusplus::aliases" namespace for ' 'the class. Py++ selected "%s" as class alias. Other aliases: %s' ) -W1049 = warning( - 'This method could not be overriden in Python - method returns reference ' +W1049 = warning( + 'This method could not be overriden in Python - method returns reference ' 'to local variable!' ) W1050 = compilation_error( - 'The function returns "%s" type. You have to specify a call policies.' - 'Be sure to take a look on Py++ defined call policies: ' + 'The function returns "%s" type. You have to specify a call policies.' + 'Be sure to take a look on Py++ defined call policies: ' 'http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#py-defined-call-policies' ) -W1051 = warning( +W1051 = warning( 'The function takes as argument (name=%s, pos=%d) "%s" type. ' 'You have to specify a call policies or to use "Function Transformation" ' 'functionality.' ) -W1052 = warning( +W1052 = warning( 'Py++ will not expose free operator "%s" - all classes, this operator works on, are excluded.' ) -W1053 = warning( +W1053 = warning( 'Py++ will not expose function "%s" - the function has variable-argument list, spicified by ellipsis (...).' ) W1054 = compilation_error( 'Py++ can not expose unions.' ) +W1055 = warning( "Py++ will generate class wrapper - hand written code should be added to the wrapper class destructor body" ) + warnings = globals() all_warning_msgs = [] @@ -230,13 +232,13 @@ try: int( identifier[1:] ) except: - continue - msg = '%s %s: %s' % ( explanation.__class__.prefix, identifier, str(explanation) ) + continue + msg = '%s %s: %s' % ( explanation.__class__.prefix, identifier, str(explanation) ) msg_inst = explanation.__class__( msg, identifier ) globals()[ identifier ] = msg_inst all_warning_msgs.append( msg_inst ) - + del warnings del identifier del explanation Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -624,6 +624,10 @@ for property_def in cls_decl.properties: cls_cc.adopt_creator( code_creators.property_t(property_def) ) + if wrapper and cls_decl.destructor_code: + destructor = code_creators.destructor_wrapper_t( class_=cls_decl ) + wrapper.adopt_creator( destructor ) + self.curr_decl = cls_decl self.curr_code_creator = cls_parent_cc Modified: pyplusplus_dev/unittests/transfer_ownership_tester.py =================================================================== --- pyplusplus_dev/unittests/transfer_ownership_tester.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/unittests/transfer_ownership_tester.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -12,14 +12,10 @@ from pyplusplus.module_builder import call_policies decref_code = \ -""" - virtual ~%(cls)s(){ - if (this->m_pyobj) { - //Py_DECREF(this->m_pyobj); - this->m_pyobj = 0; - } - } -""" +"""if (this->m_pyobj) { + //Py_DECREF(this->m_pyobj); + this->m_pyobj = 0; +}""" incref_code = \ """ @@ -36,9 +32,9 @@ class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'transfer_ownership' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , tester_t.EXTENSION_NAME , *args ) @@ -46,12 +42,12 @@ def customize( self, mb ): event_clss = mb.classes( lambda cls: cls.name in ( 'event_t', 'do_nothing_t' ) ) for cls in event_clss: - cls.add_wrapper_code( decref_code % { 'cls' : cls.wrapper_alias } ) + cls.add_destructor_code( decref_code ) cls.add_wrapper_code( 'PyObject* m_pyobj;' ) cls.set_constructors_body( 'm_pyobj=0;' ) cls.mem_fun( 'notify' ).add_override_precall_code( incref_code ) cls.mem_fun( 'notify' ).add_default_precall_code( incref_code ) - + cls.held_type = 'std::auto_ptr< %s >' % cls.wrapper_alias cls.add_registration_code( impl_conv_code % { 'from' : cls.wrapper_alias , 'to' : cls.decl_string } @@ -62,7 +58,7 @@ impl_conv_code % { 'from' : cls.decl_string , 'to' : base.related_class.decl_string } , False) - + cls.add_registration_code( #from wrapper to clas base class impl_conv_code % { 'from' : cls.wrapper_alias , 'to' : base.related_class.decl_string } @@ -73,16 +69,16 @@ simulator = mb.class_( 'simulator_t' ) simulator.mem_fun( 'get_event' ).call_policies \ = call_policies.return_internal_reference() - + def run_tests( self, module): class py_event_t( module.event_t ): def __init__( self, container ): module.event_t.__init__( self ) self.container = container - + def notify( self ): self.container.append( 1 ) - + print '1' notify_data = [] simulator = module.simulator_t() @@ -97,9 +93,9 @@ simulator.run() print '6' self.failUnless( notify_data[0] == 1 ) - + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-14 18:14:47
|
Revision: 1371 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1371&view=rev Author: roman_yakovenko Date: 2008-07-14 11:14:53 -0700 (Mon, 14 Jul 2008) Log Message: ----------- adding initial support for ctypes module Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/__init__.py Added Paths: ----------- pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py Modified: pyplusplus_dev/pyplusplus/code_repository/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-14 04:24:28 UTC (rev 1370) +++ pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-14 18:14:53 UTC (rev 1371) @@ -19,15 +19,15 @@ import convenience import return_range import call_policies -#import ctypes_integration +import ctypes_integration all = [ array_1 , gil_guard , convenience , call_policies , named_tuple - , return_range ] - #, ctypes_integration ] + , return_range + , ctypes_integration ] headers = map( lambda f: f.file_name, all ) Added: pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py (rev 0) +++ pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-07-14 18:14:53 UTC (rev 1371) @@ -0,0 +1,57 @@ +# 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 file contains C++ code needed to export one dimensional static arrays. +""" + + +namespace = "pyplusplus::convenience" + +file_name = "__ctypes_integration.pypp.hpp" + +code = \ +"""// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __ctypes_integration_pyplusplus_hpp__ +#define __ctypes_integration_pyplusplus_hpp__ + +#include "boost/python.hpp" +#include "boost/utility/addressof.hpp" +#include "boost/mpl/vector.hpp" +#include "boost/function.hpp" +#include "boost/cstdint.hpp" +#include "boost/bind.hpp" + + +namespace pyplusplus{ namespace convenience{ + +template< typename TType, typename TMemVarType > +boost::uintmax_t +addressof( const TType &inst, const TMemVarType TType::* offset){ + return boost::uintmax_t( boost::addressof( inst.*offset ) ); +} + +template< typename TType, typename TMemVarType > +boost::python::object +make_addressof_getter( const TMemVarType TType::* offset ){ + namespace bpl = boost::python; + namespace pyppc = pyplusplus::convenience; + return bpl::make_function( boost::bind( &pyppc::addressof< TType, TMemVarType >, _1, offset ) + , bpl::default_call_policies() + , boost::mpl::vector< boost::uintmax_t, const TType& >() ); +} + +} /*pyplusplus*/ } /*convenience*/ + +namespace pyplus_conv = pyplusplus::convenience; + +#endif//__ctypes_integration_pyplusplus_hpp__ + +""" + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-14 04:24:18
|
Revision: 1370 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1370&view=rev Author: roman_yakovenko Date: 2008-07-13 21:24:28 -0700 (Sun, 13 Jul 2008) Log Message: ----------- temorary disable ctypes_integration module Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/__init__.py Modified: pyplusplus_dev/pyplusplus/code_repository/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-13 20:50:00 UTC (rev 1369) +++ pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-14 04:24:28 UTC (rev 1370) @@ -19,15 +19,15 @@ import convenience import return_range import call_policies -import ctypes_integration +#import ctypes_integration all = [ array_1 , gil_guard , convenience , call_policies , named_tuple - , return_range - , ctypes_integration ] + , return_range ] + #, ctypes_integration ] headers = map( lambda f: f.file_name, all ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-13 20:49:52
|
Revision: 1369 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1369&view=rev Author: roman_yakovenko Date: 2008-07-13 13:50:00 -0700 (Sun, 13 Jul 2008) Log Message: ----------- adding initial support for ctypes module Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/global_variable.py pyplusplus_dev/pyplusplus/code_creators/member_variable.py pyplusplus_dev/pyplusplus/code_repository/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/bool_by_ref_tester.py pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp pyplusplus_dev/unittests/global_variables_tester.py pyplusplus_dev/unittests/member_variables_tester.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -91,6 +91,7 @@ from global_variable import global_variable_t from global_variable import array_gv_t from global_variable import array_gv_wrapper_t +from global_variable import global_variable_addressof_t from member_variable import member_variable_base_t from member_variable import member_variable_t @@ -101,6 +102,7 @@ from member_variable import array_mv_wrapper_t from member_variable import mem_var_ref_t from member_variable import mem_var_ref_wrapper_t +from member_variable import member_variable_addressof_t from class_declaration import class_t from class_declaration import class_wrapper_t Modified: pyplusplus_dev/pyplusplus/code_creators/global_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -56,7 +56,7 @@ else: obj_identifier = algorithm.create_identifier( self, '::boost::python::object' ) ref_identifier = algorithm.create_identifier( self, '::boost::ref' ) - result.append( ' = %s( %s( %s ) );' % ( obj_identifier, ref_identifier, self.decl_identifier ) ) + result.append( ' = %s( %s( %s ) );' % ( obj_identifier, ref_identifier, self.decl_identifier ) ) return ''.join( result ) class array_gv_t( global_variable_base_t ): @@ -74,7 +74,7 @@ def _create_impl( self ): if self.declaration.already_exposed: return '' - + answer = [] answer.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) answer.append( '().attr("%s")' % self.alias ) @@ -141,7 +141,7 @@ def _create_impl( self ): if self.declaration.already_exposed: return '' - + answer = [self._create_namespaces_name()] answer.append( self.wrapper_type.decl_string ) answer.append( ''.join([ self.wrapper_creator_name, '(){']) ) @@ -157,3 +157,28 @@ def _get_system_headers_impl( self ): return [code_repository.array_1.file_name] + +class global_variable_addressof_t( global_variable_base_t ): + """ + Creates boost.python code that exposes address of global variable. + + This functionality is pretty powerful if you use it with "ctypes" - + standard package. + """ + def __init__(self, variable ): + global_variable_base_t.__init__( self, variable=variable ) + + def _create_impl(self): + if self.declaration.already_exposed: + return '' + + assert isinstance( self.declaration, pygccxml.declarations.variable_t ) + result = [] + #TODO: porting to 64Bit is welcome + result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) + result.append( '().attr("%s")' % self.alias ) + result.append( ' = boost::uint32_t( boost::addressof( %s ) );' % self.decl_identifier ) + return ''.join( result ) + + def _get_system_headers_impl( self ): + return [code_repository.ctypes_integration.file_name] Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -30,7 +30,7 @@ def _set_wrapper( self, new_wrapper ): self._wrapper = new_wrapper wrapper = property( _get_wrapper, _set_wrapper ) - + def _get_system_headers_impl( self ): files = [] if self.declaration.getter_call_policies: @@ -38,7 +38,7 @@ if self.declaration.setter_call_policies: files.append( self.declaration.setter_call_policies.header_file ) return files - + class member_variable_t( member_variable_base_t ): """ Creates boost.python code that exposes member variable. @@ -130,12 +130,12 @@ doc = self.documentation add_property = 'add_property' add_property_args = [ '"%s"' % self.alias ] - getter_code = declarations.call_invocation.join( + getter_code = declarations.call_invocation.join( make_getter , [ '&' + self.decl_identifier , self.declaration.getter_call_policies.create( self ) ] , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) ) - + add_property_args.append( getter_code ) if not self.declaration.is_read_only: setter_code = '' @@ -143,14 +143,14 @@ if self.declaration.setter_call_policies \ and not self.declaration.setter_call_policies.is_default(): setter_args.append( self.declaration.setter_call_policies.create( self ) ) - setter_code = declarations.call_invocation.join( + setter_code = declarations.call_invocation.join( make_setter , setter_args , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) ) add_property_args.append( setter_code) if doc: add_property_args.append( doc ) - return declarations.call_invocation.join( + return declarations.call_invocation.join( add_property , add_property_args , os.linesep + self.indent( self.PARAM_SEPARATOR, 4 ) ) @@ -391,7 +391,7 @@ answer = [] answer.append( 'typedef %s;' % self.wrapper.wrapper_creator_type.create_typedef( 'array_wrapper_creator' ) ) answer.append( os.linesep * 2 ) - + doc = '' if self.declaration.type_qualifiers.has_static: answer.append( self.parent.class_var_name + '.add_static_property' ) @@ -425,7 +425,7 @@ answer.append( os.linesep ) answer.append( '}' ) return ''.join( answer ) - + def _get_system_headers_impl( self ): return [] @@ -445,7 +445,7 @@ @property def wrapper_type( self ): tmpl = "%(namespace)s::%(constness)sarray_1_t< %(item_type)s, %(array_size)d>" - + constness = '' if declarations.is_const( self.declaration.type ): constness = 'const_' @@ -463,14 +463,14 @@ if declarations.is_const( self.declaration.type ): wrapped_cls_type = declarations.const_t( wrapped_cls_type ) return declarations.reference_t( wrapped_cls_type ) - + @property def wrapper_creator_type(self): return declarations.free_function_type_t( return_type=self.wrapper_type , arguments_types=[self.wrapped_class_type] ) - - @property + + @property def wrapper_creator_name(self): return '_'.join( ['pyplusplus', self.declaration.name, 'wrapper'] ) @@ -494,8 +494,8 @@ def _get_system_headers_impl( self ): return [code_repository.array_1.file_name] - + class mem_var_ref_t( member_variable_base_t ): """ Creates C++ code that creates accessor for class member variable, that has type reference. @@ -644,3 +644,39 @@ def _get_system_headers_impl( self ): return [] + +class member_variable_addressof_t( member_variable_base_t ): + """ + Creates boost.python code that exposes address of member variable. + + This functionality is pretty powerful if you use it with "ctypes" - + standard package. + + """ + def __init__(self, variable, wrapper=None ): + member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper ) + + def _create_impl( self ): + doc = '' #static property does not support documentation + if self.declaration.type_qualifiers.has_static: + add_property = 'add_static_property' + else: + if self.documentation: + doc = self.documentation + add_property = 'add_property' + answer = [ add_property ] + answer.append( '( ' ) + answer.append('"%s"' % self.alias) + answer.append( self.PARAM_SEPARATOR ) + + answer.append( 'pyplus_conv::make_addressof_getter(&%s)' + % self.decl_identifier ) + if doc: + answer.append( self.PARAM_SEPARATOR ) + answer.append( doc ) + answer.append( ' ) ' ) + + return ''.join( answer ) + + def _get_system_headers_impl( self ): + return [code_repository.ctypes_integration.file_name] Modified: pyplusplus_dev/pyplusplus/code_repository/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -19,8 +19,15 @@ import convenience import return_range import call_policies +import ctypes_integration -all = [ array_1, gil_guard, convenience, call_policies, named_tuple, return_range ] +all = [ array_1 + , gil_guard + , convenience + , call_policies + , named_tuple + , return_range + , ctypes_integration ] headers = map( lambda f: f.file_name, all ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -21,6 +21,7 @@ self._apply_smart_ptr_wa = False self._is_read_only = None self._use_make_functions = None + self._expose_address = None __call_policies_doc__ = \ """There are usecase, when exporting member variable forces Py++ to @@ -89,7 +90,27 @@ self._use_make_functions = value use_make_functions = property( get_use_make_functions, set_use_make_functions , doc=__use_make_functions_doc__) + + __expose_address_doc__ = \ + """There are some cases when Boost.Python doesn't provide a convenient way + to expose the variable to Python. For example: + double* x[10]; + //or + char* buffer; //in case you want to modify the buffer in place + + In this cases Py++ doesn't help too. In these cases it is possible to expose + the actual address of the variable. After that, you can use built-in "ctypes" + package to edit the content of the variable. + """ + def get_expose_address( self ): + return self._expose_address + def set_expose_address( self, value ): + self._expose_address = value + expose_address = property( get_expose_address, set_expose_address + , doc= __expose_address_doc__ ) + + def __find_out_is_read_only(self): type_ = declarations.remove_alias( self.type ) @@ -127,14 +148,15 @@ 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 + if not self.expose_address: + 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_ ): - if self.type_qualifiers.has_static: + if not self.expose_address and self.type_qualifiers.has_static: return messages.W1035 - if python_traits.is_immutable( type_.base ): + if not self.expose_address and python_traits.is_immutable( type_.base ): return messages.W1036 units = declarations.decompose_type( type_ ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -309,7 +309,7 @@ if not ( None is element_type ) and class_traits.is_my_case( element_type ): value_cls = class_traits.get_declaration( element_type ) has_prerequisits = value_cls.less_than_comparable \ - and value_cls.equality_comparable + and value_cls.equality_comparable if ( not has_prerequisits ) and ( value_cls not in created_value_traits ): created_value_traits.add( value_cls ) element_type_cc = code_creators.value_traits_t( value_cls ) @@ -576,19 +576,19 @@ self.__extmodule.adopt_declaration_creator( wrapper ) #next constructors are not present in code, but compiler generated - #Boost.Python requiers them to be declared in the wrapper class + #Boost.Python requiers them to be declared in the wrapper class noncopyable_vars = self.curr_decl.find_noncopyable_vars() - + copy_constr = self.curr_decl.find_copy_constructor() if not self.curr_decl.noncopyable and copy_constr and copy_constr.is_artificial: cccc = code_creators.copy_constructor_wrapper_t( class_=self.curr_decl) wrapper.adopt_creator( cccc ) - trivial_constr = self.curr_decl.find_trivial_constructor() + trivial_constr = self.curr_decl.find_trivial_constructor() if trivial_constr and trivial_constr.is_artificial and not noncopyable_vars: tcons = code_creators.null_constructor_wrapper_t( class_=self.curr_decl ) wrapper.adopt_creator( tcons ) - + exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc ) cls_parent_cc.adopt_creator( cls_cc ) @@ -655,6 +655,15 @@ self.__types_db.update( self.curr_decl ) self.__dependencies_manager.add_exported( self.curr_decl ) + if self.curr_decl.expose_address: + creator_type = None + if isinstance( self.curr_decl.parent, declarations.namespace_t ): + creator_type = code_creators.global_variable_addressof_t + else: + creator_type = code_creators.member_variable_addressof_t + self.curr_code_creator.adopt_creator( creator_type(self.curr_decl) ) + return + if declarations.is_array( self.curr_decl.type ): if self._register_array_1( self.curr_decl.type ): array_1_registrator = code_creators.array_1_registrator_t( array_type=self.curr_decl.type ) Modified: pyplusplus_dev/unittests/bool_by_ref_tester.py =================================================================== --- pyplusplus_dev/unittests/bool_by_ref_tester.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/bool_by_ref_tester.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -33,7 +33,7 @@ module.listener.__init__(self) def listen( self, id, name, skip): print "Python: listen called with", id, name, skip - return True ## Test always returns True... + return 11## Test always returns True... c = list1() ret = module.callListener( c ) Modified: pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,13 +5,13 @@ class listener { public: - virtual void listen(int id, const std::string& name, bool& skip) { + virtual void listen(int id, const std::string& name, int& skip) { throw std::runtime_error ( std::string ("Virtual function listener::listen called!") ); } }; bool callListener ( listener* myListener) { - bool skip = false; + int skip = 10; std::cout << "C++: Calling myListener->listen\n"; myListener->listen(100, "test", skip); std::cout << "C++: Called OK " << skip <<"\n"; Modified: pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp =================================================================== --- pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,20 +5,25 @@ #include "global_variables_to_be_exported.hpp" -namespace global_variables{ +namespace global_variables{ const color const_var = red; color non_const_var = blue; data garray[10]; double arr_of_doubles[100]; - + void init_garray(){ for( int i =0; i < 10; ++i ){ garray[i].value = -i; } } +int some_value = -7; +int get_some_value(){ return some_value; } +unsigned int get_some_value_address(){ return (unsigned int)( &some_value ); } + } -const char someSin[3] = "AB"; \ No newline at end of file + +const char someSin[3] = "AB"; Modified: pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -6,7 +6,7 @@ #ifndef __global_variables_to_be_exported_hpp__ #define __global_variables_to_be_exported_hpp__ -namespace global_variables{ +namespace global_variables{ enum color{ red, green, blue }; @@ -19,6 +19,12 @@ extern double arr_of_doubles[100]; void init_garray(); +extern int some_value; + +int get_some_value(); + +unsigned int get_some_value_address(); + } Modified: pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -9,12 +9,12 @@ #include <string> #include <iostream> -namespace member_variables{ +namespace member_variables{ struct point{ enum color{ red, green, blue }; - - point() + + point() : prefered_color( blue ) , x( -1 ) , y( 2 ) @@ -42,7 +42,7 @@ unsigned int a : 1; unsigned int : 0; const unsigned int b : 11; -}; +}; unsigned int get_a(const bit_fields_t& inst); void set_a( bit_fields_t& inst, unsigned int new_value ); @@ -55,17 +55,17 @@ } } - struct variable_t{ + struct variable_t{ variable_t() : value(-9){} - int value; + int value; }; int get_ivars_item( int index ){ return ivars[index]; } - + const variable_t vars[3]; - int ivars[10]; + int ivars[10]; int ivars2[10]; }; @@ -78,10 +78,10 @@ }; struct tree_node_t{ - + data_t *data; tree_node_t *left; - tree_node_t *right; + tree_node_t *right; const tree_node_t *parent; tree_node_t(const tree_node_t* parent=0) @@ -90,7 +90,7 @@ , right( 0 ) , parent( parent ) {} - + ~tree_node_t(){ std::cout << "\n~tree_node_t"; } @@ -108,7 +108,7 @@ fundamental_t( EFruit& fruit, const int& i ) : m_fruit( fruit ), m_i( i ) {} - + EFruit& m_fruit; const int& m_i; }; @@ -151,5 +151,17 @@ } +namespace ctypes{ + struct image_t{ + image_t(){ + data = new int[5]; + for(int i=0; i<5; i++){ + data[i] = i; + } + } + int* data; + }; } + +} #endif//__member_variables_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/global_variables_tester.py =================================================================== --- pyplusplus_dev/unittests/global_variables_tester.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/global_variables_tester.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,22 +5,24 @@ import os import sys +import ctypes import unittest import fundamental_tester_base class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'global_variables' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , tester_t.EXTENSION_NAME , *args ) - - def customize(self, mb ): + + def customize(self, mb ): mb.variable('non_const_var').alias = 'NonConstVar' + mb.variable( 'some_value' ).expose_address = True - def run_tests(self, module): + def run_tests(self, module): self.failUnless( module.NonConstVar == module.color.blue ) self.failUnless( module.const_var == module.color.red ) module.init_garray() @@ -28,11 +30,19 @@ for index in range( 10 ): self.failUnless( -index == module.garray[index].value ) self.failUnless( 3 == len( module.someSin ) - and module.someSin[0] == 'A' + and module.someSin[0] == 'A' and module.someSin[1] == 'B' and module.someSin[2] == '\0' ) + + self.failUnless( module.some_value == module.get_some_value_address() ) + self.failUnless( -7 == module.get_some_value() ) + x = ctypes.c_int.from_address( module.some_value ) + self.failUnless( x.value == module.get_some_value() ) + x.value = 9 + self.failUnless( x.value == module.get_some_value() == 9) + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite Modified: pyplusplus_dev/unittests/member_variables_tester.py =================================================================== --- pyplusplus_dev/unittests/member_variables_tester.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/member_variables_tester.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,35 +5,39 @@ import os import sys +import ctypes import unittest import fundamental_tester_base +import pdb class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'member_variables' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , tester_t.EXTENSION_NAME , *args ) - - def customize(self, mb ): + + def customize(self, mb ): mb.variable( 'prefered_color' ).alias = 'PreferedColor' mb.classes().always_expose_using_scope = True + image = mb.class_( 'image_t' ) + image.var( 'data' ).expose_address = True def change_default_color( self, module ): module.point.default_color = module.point.color.blue - + def change_prefered_color( self, module ): - xypoint = module.point() + xypoint = module.point() xypoint.PreferedColor = module.point.color.blue - + def set_b( self, bf, value ): bf.b = value - - def run_tests(self, module): + + def run_tests(self, module): self.failIfRaisesAny( module.point ) - xypoint = module.point() + xypoint = module.point() self.failUnless( module.point.instance_count == 1) self.failUnless( xypoint.instance_count == 1) self.failUnless( module.point.default_color == module.point.color.red) @@ -49,43 +53,52 @@ self.failUnless( 1 == bf.a ) self.failUnless( bf.b == module.get_b( bf ) ) self.failIfNotRaisesAny( lambda: self.set_b( bf, 23 ) ) - + array = module.array_t() self.failUnless( len( array.vars ) == 3 ) for i in range( len( array.vars ) ): self.failUnless( array.vars[i].value == -9 ) self.failUnless( len( array.ivars ) == 10 ) - + ivars = array.ivars del array #testing call policies for i in range(20): for index in range(10): self.failUnless( ivars[index] == -index ) - + array = module.array_t() for index in range( len(array.ivars) ): array.ivars[index] = index * index self.failUnless( array.get_ivars_item( index ) == index * index ) - + tree = module.create_tree() self.failUnless( tree.parent is None ) self.failUnless( tree.data.value == 0 ) self.failUnless( tree.right is None ) self.failUnless( tree.left ) self.failUnless( tree.left.data.value == 1 ) - + tree.right = module.create_tree() self.failUnless( tree.right.parent is None ) self.failUnless( tree.right.data.value == 0 ) self.failUnless( tree.right.right is None ) self.failUnless( tree.right.left ) self.failUnless( tree.right.left.data.value == 1 ) - + mem_var_str = module.mem_var_str_t() mem_var_str.identity( module.mem_var_str_t.class_name ) - + + image = module.image_t() + + #pdb.set_trace() + data_type = ctypes.POINTER( ctypes.c_int ) + data = data_type.from_address( image.data ) + for j in range(5): + print '%d : %d' % ( j, data[j] ) + + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite @@ -93,4 +106,4 @@ unittest.TextTestRunner(verbosity=2).run( create_suite() ) if __name__ == "__main__": - run_suite() \ No newline at end of file + run_suite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-13 20:48:11
|
Revision: 1368 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1368&view=rev Author: roman_yakovenko Date: 2008-07-13 13:48:20 -0700 (Sun, 13 Jul 2008) Log Message: ----------- updating documentation Modified Paths: -------------- pygccxml_dev/docs/history/history.rest Modified: pygccxml_dev/docs/history/history.rest =================================================================== --- pygccxml_dev/docs/history/history.rest 2008-07-10 06:06:24 UTC (rev 1367) +++ pygccxml_dev/docs/history/history.rest 2008-07-13 20:48:20 UTC (rev 1368) @@ -30,58 +30,71 @@ 1. Support for ellipsis was added. - Warning: this feature introduce backward compatibility problem! + Warning: this feature introduce backward compatibility problem! - Description: + Description: .. code-block:: C++ void do_smth( int, ... ) - - Before this change, pygccxml would report that the function ``do_smth`` has + + Before this change, pygccxml would report that the function ``do_smth`` has only one argument. - - After this change, pygccxml will report that the function has two arguments. - The second argument type will be ``declarations.ellipsis_t``. All classes, - which describe callables, have new property ``has_ellipsis``. It the value of + + After this change, pygccxml will report that the function has two arguments. + The second argument type will be ``declarations.ellipsis_t``. All classes, + which describe callables, have new property ``has_ellipsis``. It the value of the property is ``True``, than the function has ellipsis in its definition. +2. New expiremental back-end, based on ``.pdb`` (progam database file), was added. + +3. New high-level API wrapper for ``.bsc`` (browse source code file) was added. + +4. The recomended `GCC-XML`_ version to use with this release is CVS revision 123. + This revision introduces small, but very important feature. `GCC-XML`_ + started to dump artificial declarations (constructor, destructor, operator=). + ``pygccxml.declarations.type_traits`` functions were updated to use new + information. + +5. ``declarations.decl_printer_t`` class dumps almost all available information + about a declaration. + ------------- Version 0.9.5 ------------- 1. Class ``free_operator_t`` is now able to provide references to the class declarations instances it works on. - -2. Support for `GCC-XML attributes`_ was added. Many thanks to Miguel Lobo for + +2. Support for `GCC-XML attributes`_ was added. Many thanks to Miguel Lobo for the implementation. .. _`GCC-XML attributes`: http://www.gccxml.org/HTML/Running.html -3. A bug in parsing a function exception specification was fixed. Many thanks to +3. A bug in parsing a function exception specification was fixed. Many thanks to Jeremy Sanders. - -4. Support for a type/class "align", "offset" and "size" was added. Many thanks to + +4. Support for a type/class "align", "offset" and "size" was added. Many thanks to Ben Schleimer for the implementation. - + 5. Support for GCC-XML 0.9 was added. 6. Support for ``__restrict__`` was added. -7. ``declarations.has_trivial_copy`` was renamed to ``declarations.has_copy_constructor``. +7. ``declarations.has_trivial_copy`` was renamed to ``declarations.has_copy_constructor``. The old name is still available, but will be removed soon. - + 8. ``declarations.priority_queue`` was renamed to ``declarations.priority_queue_traits``. 9. ``declarations.find_container_traits`` function was added. 10. Support for "partial name" was added. "Partial name" is the class name, without - template default arguments. The functionality was added to std containers + template default arguments. The functionality was added to std containers classes. - -11. ``declarations.class_t`` and ``declarations.class_declaration_t`` has new property - + +11. ``declarations.class_t`` and ``declarations.class_declaration_t`` has new property - ``container_traits``. This property describes std container element class. - + 12. All logging is now done to ``stderr`` instead of ``stdout``. ------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-10 06:06:16
|
Revision: 1367 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1367&view=rev Author: roman_yakovenko Date: 2008-07-09 23:06:24 -0700 (Wed, 09 Jul 2008) Log Message: ----------- small documentation fix Modified Paths: -------------- pyplusplus_dev/docs/documentation/how_to/how_to.rest Modified: pyplusplus_dev/docs/documentation/how_to/how_to.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to/how_to.rest 2008-07-06 19:29:39 UTC (rev 1366) +++ pyplusplus_dev/docs/documentation/how_to/how_to.rest 2008-07-10 06:06:24 UTC (rev 1367) @@ -68,14 +68,11 @@ .. code-block:: Python - registration_code = 'def( "get_size", &%s::get_size )' % window.wrapper_alias - -.. code-block:: Python - mb = module_builder_t( ... ) window = mb.class_( "window_t" ) window.member_function( "get_size" ).exclude() window.add_wrapper_code( wrapper_code ) + registration_code = 'def( "get_size", &%s::get_size )' % window.wrapper_alias window.registration_code( registration_code ) That's all. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-06 19:29:31
|
Revision: 1366 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1366&view=rev Author: roman_yakovenko Date: 2008-07-06 12:29:39 -0700 (Sun, 06 Jul 2008) Log Message: ----------- add new unit test Added Paths: ----------- pyplusplus_dev/unittests/bool_by_ref_tester.py pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp Added: pyplusplus_dev/unittests/bool_by_ref_tester.py =================================================================== --- pyplusplus_dev/unittests/bool_by_ref_tester.py (rev 0) +++ pyplusplus_dev/unittests/bool_by_ref_tester.py 2008-07-06 19:29:39 UTC (rev 1366) @@ -0,0 +1,51 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import sys +import math +import unittest +import fundamental_tester_base +from pygccxml import declarations +from pyplusplus import function_transformers as ft +from pyplusplus.module_builder import call_policies + + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'bool_by_ref' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize( self, mb ): + set_flag = mb.mem_fun( '::tests::listener::listen' ) + set_flag.add_transformation( ft.inout(2) ) + + + def run_tests(self, module): + class list1 ( module.listener ): + def __init__ ( self ): + module.listener.__init__(self) + def listen( self, id, name, skip): + print "Python: listen called with", id, name, skip + return True ## Test always returns True... + + c = list1() + ret = module.callListener( c ) + print ret + +def create_suite(): + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(tester_t)) + return suite + +def run_suite(): + unittest.TextTestRunner(verbosity=2).run( create_suite() ) + +if __name__ == "__main__": + run_suite() Added: pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp 2008-07-06 19:29:39 UTC (rev 1366) @@ -0,0 +1,21 @@ +#include <stdexcept> +#include <iostream> + +namespace tests{ + +class listener { + public: + virtual void listen(int id, const std::string& name, bool& skip) { + throw std::runtime_error ( std::string ("Virtual function listener::listen called!") ); + } +}; + +bool callListener ( listener* myListener) { + bool skip = false; + std::cout << "C++: Calling myListener->listen\n"; + myListener->listen(100, "test", skip); + std::cout << "C++: Called OK " << skip <<"\n"; + return skip; +} + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-02 11:28:41
|
Revision: 1365 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1365&view=rev Author: roman_yakovenko Date: 2008-07-02 04:28:47 -0700 (Wed, 02 Jul 2008) Log Message: ----------- update docs Modified Paths: -------------- pygccxml_dev/docs/msvc/msvc.rest website/site_creator/main.py Modified: pygccxml_dev/docs/msvc/msvc.rest =================================================================== --- pygccxml_dev/docs/msvc/msvc.rest 2008-07-01 16:55:48 UTC (rev 1364) +++ pygccxml_dev/docs/msvc/msvc.rest 2008-07-02 11:28:47 UTC (rev 1365) @@ -1,12 +1,12 @@ -========================= -MS Visual Studio backends -========================= +========================== +MS Visual Studio back-ends +========================== .. contents:: Table of contents ----------------------------------------- -Why we need other than GCC-XML backends? ----------------------------------------- +----------------------------------------- +Why we need other than GCC-XML back-ends? +----------------------------------------- It is not a secret, that Windows is not a native environment for GCC. There are cases, that it cant compile the code, "produced" for other compilers. On Windows, @@ -14,75 +14,97 @@ your source code. Sometimes, changing the source code is not an option and different solution is needed. -Recently, I started to work on another back-end for `pygccxml`_, based on free tools, -available and freely redistributable with MS Visual Studio: +-------- +The idea +-------- -* PDB - program database. A .pdb files hold debugging information about your - program. In other words, it contains information about every type and function - you use. -* BSC - browse source code. A .bsc file is a comprehensive database that contains - information about a program's symbols, including symbol references, - function calltrees, and definition tables. +The idea is the same as with `GCC-XML`_ - don't write custom C++ parser, but use +the compiler to extract the information. -Both .pdb and .bsc files contain valuable information about your source code. -I guess, you will be surprised how much information it is possible to extract -from them. +During the build process, MS Visual Studio generates few files, which contain +source code "description": ----------------------------- -How it works? ----------------------------- +* .pdb file. A "program database" file holds debugging information about your + program. It is generated automaticly during "Debug" builds. -Microsoft provides API for extracting information from the files: +* .bsc file. A "browse source code" file is a comprehensive database that contains + information about a program's symbols, including symbol references, function + calltrees, and definition tables. .bsc file is not generated by default, so + you will have to turn-on this option. -* `DIA SDK`_ - Debug Interface Access Software Development Kit is able to read and - provide more-or-less convenient access to the information stored in .pdb files. - DIA SDK exposes it functionality via "COM" technology. `pygccxml`_ uses "comtypes" - project to work with the API. +I guess, you will be surprised how much information it is possible to extract. -* `BSC Toolkit`_ comes with C API. `pygccxml`_ uses "ctypes" module, from the Python - standard library. +Microsoft provides API for working with the files: -Both toolkits comes with their own terminolgy. Unless you want to help me, to -develop this backend, you can fully ignore this fact. `pygccxml`_ bridges the -domains and provide clear and consistent API. +* `DIA SDK`_ - Debug Interface Access Software Development Kit reads and gives + more or less convenient access to the information stored in the .pdb files. + `DIA SDK`_ is an integral part of MS Visual Studio. -Both files, .pdb and .bsc, contain valuable information, but some pieces are -presented in one file and not in other one. In near future `pygccxml`_ will be able -to combine the information, extracted from the files. Hint: you can send me the -patch :-). + `DIA SDK`_ exposes its functionality via "COM" technology. `pygccxml`_ uses + `comtypes package`_ to work with the API. ------------------- -The backend status ------------------- +* `Browse Source Code Toolkit`_ comes with C API. In order to read .bsc files you + have to `install the toolkit`_. + `pygccxml`_ uses "ctypes" module, from the Python standard library. + +Both API's comes with documentation and examples. + +`pygccxml`_ is going to introduce another back-end based on these tools. Each of +these tools doesn't tell the "whole story" about your source code, but if we +merge the information, extracted from the files, you can get almost the complete +picture. + + +------------------- +The back-end status +------------------- + The short version ----------------- -I feel like this backend has "beta" state. +The back-end has "alpha" state. The long version ---------------- -`pygccxml`_ pdb backend is able to extract almost all declarations from the .pdb -file. There are few exceptions and problems, that should be solved, before I will -consider this backend as "production" ready: +`pygccxml`_ MSVC back-end will consist from few packages: -* add support for bit fields - should not be a problem -* function exception specification - this information is missing in the file -* a declaration location within source code - from the DIA API I understand the - information is there and should be available, but for some reason I can access - it. -* there is some problem with extracting the exact integral type, used in the - source code - for example I have a problem to decide whether "long long int" - or "long int" is used within the code. I believe, it should be possible to - partially solve this problem. -* unit test - `pygccxml`_ comes with impressive amount of unit tests. Today only - small amount of them supports pdb backend. This should be fixed. -* performance - the backend is very slow right now, but this is "by design" and - I believe it is possible to improve it. +* ``pdb`` package reads the declaration tree from the .pdb file. This package is + almost complete. I still have to resolve few problems and your help is welcome: + * add support for bit fields - should not be a problem + * function exception specification - this information is missing in the file + + * a declaration location within source code - from the DIA API I understand the + information is there and should be available, but for some reason I can access + it. + + * there is some problem with extracting the exact integral type, used in the + source code - for example I have a problem to decide whether "long long int" + or "long int" is used within the code. I believe, it should be possible to + partially solve this problem. + + * unit tests - `pygccxml`_ comes with impressive amount of unit tests. Today + only some of them support pdb backend. + + * performance - the backend is very slow right now, but this is "by design" and + I believe it is possible to improve it. + +* ``bsc`` package is a Python wrapper for `BSC Toolkit`_. I am almost sure, it is + not possible to create "declarations tree" from the .bsc file. So this package + will be used to complete the information, extracted from the .pdb files. + +* ``msvc`` package will be the top level package that will provide a convinient + access to the both sub-packages and provide "merge" functionality. As you can + guess this package doesn't exist. + + .. _`DIA SDK`: http://msdn.microsoft.com/en-us/library/x93ctkx8.aspx +.. _`Browse Source Code Toolkit` : http://www.microsoft.com/downloads/details.aspx?FamilyId=621AE185-1C2A-4D6B-8146-183D66FE709D&displaylang=en .. _`BSC Toolkit`: http://www.microsoft.com/downloads/details.aspx?FamilyId=621AE185-1C2A-4D6B-8146-183D66FE709D&displaylang=en .. _`pygccxml`: ./../pygccxml.html .. _`GCC-XML`: http://www.gccxml.org +.. _`comtypes package` : http://starship.python.net/crew/theller/comtypes/ +.. _`install the toolkit` : http://www.microsoft.com/downloads/details.aspx?FamilyId=621AE185-1C2A-4D6B-8146-183D66FE709D&displaylang=en Modified: website/site_creator/main.py =================================================================== --- website/site_creator/main.py 2008-07-01 16:55:48 UTC (rev 1364) +++ website/site_creator/main.py 2008-07-02 11:28:47 UTC (rev 1365) @@ -82,7 +82,7 @@ curr_work_dir = os.path.abspath( os.curdir ) try: - print 'file: ', destrination_file_name + print 'file:///' + destrination_file_name.replace( '\\', '/' ) os.chdir( dir_ ) tmpl = page_creator.Template( rest_file ) tmpl.write( destrination_file_name, encoding='utf-8', output='xhtml' ) @@ -105,4 +105,4 @@ c.copy_css() c.create_html_files() c.clean_www_dir() - print 'done' \ No newline at end of file + print 'done' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-01 16:55:40
|
Revision: 1364 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1364&view=rev Author: roman_yakovenko Date: 2008-07-01 09:55:48 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Added Paths: ----------- pygccxml_dev/docs/msvc/www_configuration.py Added: pygccxml_dev/docs/msvc/www_configuration.py =================================================================== --- pygccxml_dev/docs/msvc/www_configuration.py (rev 0) +++ pygccxml_dev/docs/msvc/www_configuration.py 2008-07-01 16:55:48 UTC (rev 1364) @@ -0,0 +1,2 @@ +name = 'MS Visual Studio back-end' +#main_html_file = 'index.html' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-01 12:38:44
|
Revision: 1363 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1363&view=rev Author: roman_yakovenko Date: 2008-07-01 05:38:49 -0700 (Tue, 01 Jul 2008) Log Message: ----------- adding msvc backend documentation Added Paths: ----------- pygccxml_dev/docs/msvc/ pygccxml_dev/docs/msvc/msvc.rest Added: pygccxml_dev/docs/msvc/msvc.rest =================================================================== --- pygccxml_dev/docs/msvc/msvc.rest (rev 0) +++ pygccxml_dev/docs/msvc/msvc.rest 2008-07-01 12:38:49 UTC (rev 1363) @@ -0,0 +1,88 @@ +========================= +MS Visual Studio backends +========================= + +.. contents:: Table of contents + +---------------------------------------- +Why we need other than GCC-XML backends? +---------------------------------------- + +It is not a secret, that Windows is not a native environment for GCC. There are +cases, that it cant compile the code, "produced" for other compilers. On Windows, +if you want to use `GCC-XML`_, you should treat it as another compiler and adopt +your source code. Sometimes, changing the source code is not an option and different +solution is needed. + +Recently, I started to work on another back-end for `pygccxml`_, based on free tools, +available and freely redistributable with MS Visual Studio: + +* PDB - program database. A .pdb files hold debugging information about your + program. In other words, it contains information about every type and function + you use. +* BSC - browse source code. A .bsc file is a comprehensive database that contains + information about a program's symbols, including symbol references, + function calltrees, and definition tables. + +Both .pdb and .bsc files contain valuable information about your source code. +I guess, you will be surprised how much information it is possible to extract +from them. + +---------------------------- +How it works? +---------------------------- + +Microsoft provides API for extracting information from the files: + +* `DIA SDK`_ - Debug Interface Access Software Development Kit is able to read and + provide more-or-less convenient access to the information stored in .pdb files. + DIA SDK exposes it functionality via "COM" technology. `pygccxml`_ uses "comtypes" + project to work with the API. + +* `BSC Toolkit`_ comes with C API. `pygccxml`_ uses "ctypes" module, from the Python + standard library. + +Both toolkits comes with their own terminolgy. Unless you want to help me, to +develop this backend, you can fully ignore this fact. `pygccxml`_ bridges the +domains and provide clear and consistent API. + +Both files, .pdb and .bsc, contain valuable information, but some pieces are +presented in one file and not in other one. In near future `pygccxml`_ will be able +to combine the information, extracted from the files. Hint: you can send me the +patch :-). + +------------------ +The backend status +------------------ + +The short version +----------------- + +I feel like this backend has "beta" state. + +The long version +---------------- + +`pygccxml`_ pdb backend is able to extract almost all declarations from the .pdb +file. There are few exceptions and problems, that should be solved, before I will +consider this backend as "production" ready: + +* add support for bit fields - should not be a problem +* function exception specification - this information is missing in the file +* a declaration location within source code - from the DIA API I understand the + information is there and should be available, but for some reason I can access + it. +* there is some problem with extracting the exact integral type, used in the + source code - for example I have a problem to decide whether "long long int" + or "long int" is used within the code. I believe, it should be possible to + partially solve this problem. +* unit test - `pygccxml`_ comes with impressive amount of unit tests. Today only + small amount of them supports pdb backend. This should be fixed. +* performance - the backend is very slow right now, but this is "by design" and + I believe it is possible to improve it. + + +.. _`DIA SDK`: http://msdn.microsoft.com/en-us/library/x93ctkx8.aspx +.. _`BSC Toolkit`: http://www.microsoft.com/downloads/details.aspx?FamilyId=621AE185-1C2A-4D6B-8146-183D66FE709D&displaylang=en +.. _`pygccxml`: ./../pygccxml.html +.. _`GCC-XML`: http://www.gccxml.org This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-27 19:24:28
|
Revision: 1362 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1362&view=rev Author: roman_yakovenko Date: 2008-06-27 12:24:37 -0700 (Fri, 27 Jun 2008) Log Message: ----------- fixing small bug. for the following class struct map_iterator_t{ map_iterator_t( int i ){} map_iterator_t( const map_iterator_t& ){} private: map_iterator_t(){}; }; py++ generated wrong code Modified Paths: -------------- pygccxml_dev/unittests/copy_constructor_tester.py pyplusplus_dev/pyplusplus/code_creators/class_declaration.py pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp pyplusplus_dev/unittests/ogre_generate_tester.py pyplusplus_dev/unittests/test_all.py Modified: pygccxml_dev/unittests/copy_constructor_tester.py =================================================================== --- pygccxml_dev/unittests/copy_constructor_tester.py 2008-06-27 15:22:04 UTC (rev 1361) +++ pygccxml_dev/unittests/copy_constructor_tester.py 2008-06-27 19:24:37 UTC (rev 1362) @@ -19,7 +19,7 @@ def setUp(self): if not self.global_ns: - xml_file = os.path.join( autoconfig.data_directory, 'ogre1.4.xml' ) + xml_file = os.path.join( autoconfig.data_directory, 'ogre.1.7.xml' ) reader = parser.source_reader_t( autoconfig.cxx_parsers_cfg.gccxml ) self.global_ns = declarations.get_global_namespace( reader.read_xml_file(xml_file) ) self.global_ns.init_optimizer() Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2008-06-27 15:22:04 UTC (rev 1361) +++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2008-06-27 19:24:37 UTC (rev 1362) @@ -228,12 +228,14 @@ if cs and len(cs) == 1 and cs[0].is_trivial_constructor and self.declaration.find_noncopyable_vars(): has_suitable_constructor = False + trivial_constructor = self.declaration.find_trivial_constructor() + if has_nonpublic_destructor \ or ( self.declaration.is_abstract and not self.wrapper ) \ or not has_suitable_constructor: result.append( ", " ) result.append( algorithm.create_identifier( self, '::boost::python::no_init' ) ) - elif not self.declaration.find_trivial_constructor(): + elif not trivial_constructor or trivial_constructor.access_type != 'public': if inits: used_init = inits[0] result.append( ", " ) Modified: pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp 2008-06-27 15:22:04 UTC (rev 1361) +++ pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp 2008-06-27 19:24:37 UTC (rev 1362) @@ -48,6 +48,13 @@ event_t( TData& ){}; }; +struct map_iterator_t{ + map_iterator_t( int i ){} + map_iterator_t( const map_iterator_t& ){} +private: + map_iterator_t(){}; +}; + } #endif//__no_init_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/ogre_generate_tester.py =================================================================== --- pyplusplus_dev/unittests/ogre_generate_tester.py 2008-06-27 15:22:04 UTC (rev 1361) +++ pyplusplus_dev/unittests/ogre_generate_tester.py 2008-06-27 19:24:37 UTC (rev 1362) @@ -24,7 +24,7 @@ messages.disable( *messages.all_warning_msgs ) ogre_file = autoconfig.data_directory.replace( 'pyplusplus_dev', 'pygccxml_dev' ) - ogre_file = parser.create_gccxml_fc( os.path.join( ogre_file, 'ogre1.4.xml' ) ) + ogre_file = parser.create_gccxml_fc( os.path.join( ogre_file, 'ogre.1.7.xml' ) ) mb = module_builder.module_builder_t( [ ogre_file ] Modified: pyplusplus_dev/unittests/test_all.py =================================================================== --- pyplusplus_dev/unittests/test_all.py 2008-06-27 15:22:04 UTC (rev 1361) +++ pyplusplus_dev/unittests/test_all.py 2008-06-27 19:24:37 UTC (rev 1362) @@ -105,6 +105,7 @@ import inner_tmpl_class_tester import bug_covariant_returns_tester import embeded_tester +#import ogre_generate_tester testers = [ algorithms_tester @@ -197,6 +198,7 @@ , inner_tmpl_class_tester , bug_covariant_returns_tester , embeded_tester +# , ogre_generate_tester too much time ] class module_runner_t( object ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-27 15:22:00
|
Revision: 1361 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1361&view=rev Author: roman_yakovenko Date: 2008-06-27 08:22:04 -0700 (Fri, 27 Jun 2008) Log Message: ----------- updating ogre version Added Paths: ----------- pygccxml_dev/unittests/data/ogre.1.7.xml.bz2 Added: pygccxml_dev/unittests/data/ogre.1.7.xml.bz2 =================================================================== (Binary files differ) Property changes on: pygccxml_dev/unittests/data/ogre.1.7.xml.bz2 ___________________________________________________________________ Name: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-27 14:54:33
|
Revision: 1360 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1360&view=rev Author: roman_yakovenko Date: 2008-06-27 07:54:42 -0700 (Fri, 27 Jun 2008) Log Message: ----------- remove old ogre xml file Removed Paths: ------------- pygccxml_dev/unittests/data/ogre1.4.xml.bz2 Deleted: pygccxml_dev/unittests/data/ogre1.4.xml.bz2 =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-26 10:53:48
|
Revision: 1359 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1359&view=rev Author: roman_yakovenko Date: 2008-06-26 03:53:58 -0700 (Thu, 26 Jun 2008) Log Message: ----------- verify that 1983915 bug was fixed Modified Paths: -------------- pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp Modified: pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp 2008-06-26 10:49:15 UTC (rev 1358) +++ pyplusplus_dev/unittests/data/no_init_to_be_exported.hpp 2008-06-26 10:53:58 UTC (rev 1359) @@ -43,6 +43,11 @@ } } +struct event_t{ + template< class TData > + event_t( TData& ){}; +}; + } #endif//__no_init_to_be_exported_hpp__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-26 10:49:06
|
Revision: 1358 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1358&view=rev Author: roman_yakovenko Date: 2008-06-26 03:49:15 -0700 (Thu, 26 Jun 2008) Log Message: ----------- updating to latest GCCXML version struct X{ const int items[10]; } will generate no_init in class_<...> constructor Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2008-06-26 09:36:26 UTC (rev 1357) +++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2008-06-26 10:49:15 UTC (rev 1358) @@ -220,9 +220,17 @@ inits = filter( lambda x: isinstance( x, calldef.constructor_t ), self.creators ) has_nonpublic_destructor = declarations.has_destructor( self.declaration ) \ and not declarations.has_public_destructor( self.declaration ) + + #select all public constructors and exclude copy constructor + cs = self.declaration.constructors( lambda c: not c.is_copy_constructor and c.access_type == 'public' + , recursive=False, allow_empty=True ) + has_suitable_constructor = bool( cs ) + if cs and len(cs) == 1 and cs[0].is_trivial_constructor and self.declaration.find_noncopyable_vars(): + has_suitable_constructor = False + if has_nonpublic_destructor \ or ( self.declaration.is_abstract and not self.wrapper ) \ - or not declarations.has_any_non_copyconstructor(self.declaration): + or not has_suitable_constructor: result.append( ", " ) result.append( algorithm.create_identifier( self, '::boost::python::no_init' ) ) elif not self.declaration.find_trivial_constructor(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |