pygccxml-commit Mailing List for C++ Python language bindings (Page 46)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(190) |
Apr
(166) |
May
(170) |
Jun
(75) |
Jul
(105) |
Aug
(131) |
Sep
(99) |
Oct
(84) |
Nov
(67) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(66) |
Feb
(49) |
Mar
(25) |
Apr
(62) |
May
(21) |
Jun
(34) |
Jul
(9) |
Aug
(21) |
Sep
(5) |
Oct
|
Nov
(63) |
Dec
(34) |
2008 |
Jan
(10) |
Feb
(42) |
Mar
(26) |
Apr
(25) |
May
(6) |
Jun
(40) |
Jul
(18) |
Aug
(29) |
Sep
(6) |
Oct
(32) |
Nov
(14) |
Dec
(56) |
2009 |
Jan
(127) |
Feb
(52) |
Mar
(2) |
Apr
(10) |
May
(29) |
Jun
(3) |
Jul
|
Aug
(16) |
Sep
(4) |
Oct
(11) |
Nov
(8) |
Dec
(14) |
2010 |
Jan
(31) |
Feb
(1) |
Mar
(7) |
Apr
(9) |
May
(1) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
(8) |
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <rom...@us...> - 2006-11-18 19:20:06
|
Revision: 733 http://svn.sourceforge.net/pygccxml/?rev=733&view=rev Author: roman_yakovenko Date: 2006-11-18 11:20:05 -0800 (Sat, 18 Nov 2006) Log Message: ----------- introducing registration order problem warning Modified Paths: -------------- pyplusplus_dev/pyplusplus/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py Modified: pyplusplus_dev/pyplusplus/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/__init__.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/__init__.py 2006-11-18 19:20:05 UTC (rev 733) @@ -33,7 +33,7 @@ from _logging_ import multi_line_formatter_t -__version__ = '0.7.1' +__version__ = '0.8.3' #Known issues: #3. Modified: pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2006-11-18 19:20:05 UTC (rev 733) @@ -33,6 +33,8 @@ """ +import algorithm + from decl_wrapper import decl_wrapper_t from calldef_wrapper import calldef_t Modified: pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/decl_wrappers/algorithm.py 2006-11-18 19:20:05 UTC (rev 733) @@ -9,6 +9,7 @@ """ import re +from pygccxml import declarations def creators_affect_on_me( me ): """This algorithm finds all code creators that can influence on code generated @@ -92,4 +93,45 @@ new_name = nsalias.alias + '::' + full_name[ len(fnsname) : ] return new_name else: - return full_name \ No newline at end of file + return full_name + +class registration_order: + @staticmethod + def is_related( t1, t2 ): + if declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): + return registration_order.is_related( declarations.remove_pointer( t1 ) + , declarations.remove_pointer( t2 ) ) + elif declarations.is_pointer( t1 ) and not declarations.is_pointer( t2 ): + t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) + t2 = declarations.remove_cv( t2 ) + if declarations.is_same( t1, t2 ): + return 1 + elif not declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): + t1 = declarations.remove_cv( t1 ) + t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) + if declarations.is_same( t1, t2 ): + return -1 + else: #not is_pointer( t1 ) and not is_pointer( t2 ): + if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) \ + and declarations.is_bool( t2 ): + return -1 + elif declarations.is_bool( t1 ) \ + and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): + return 1 + else: + pass + return None + + @staticmethod + def select_problematics( calldef ): + if 1 != len( calldef.required_args ): + return [] + problematics = [] + for f in calldef.overloads: + if 1 != len( f.required_args ): + continue + if None != registration_order.is_related( calldef.arguments[0].type, f.arguments[0].type ): + problematics.append( f ) + return problematics + + \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-18 19:20:05 UTC (rev 733) @@ -5,7 +5,9 @@ """defines class that configure "callable" declaration exposing""" +import os import user_text +import algorithm import decl_wrapper from pygccxml import declarations from pyplusplus import function_transformers as ft @@ -163,7 +165,6 @@ #TODO: functions that takes as argument pointer to pointer to smth, could not be exported #see http://www.boost.org/libs/python/doc/v2/faq.html#funcptr - #TODO: add warning to the case described in registration_order.rest document. if len( self.arguments ) > calldef_t.BOOST_PYTHON_MAX_ARITY: tmp = [ "The function has more than %d arguments ( %d ). " ] tmp.append( "You should adjust BOOST_PYTHON_MAX_ARITY macro." ) @@ -183,6 +184,16 @@ if False == self.overridable: msgs.append( self._non_overridable_reason) + + problematics = algorithm.registration_order.select_problematics( self ) + if problematics: + tmp = [ "The function introduces registration order problem. " ] + tmp.append( "For more information read next document: " + + "http://language-binding.net/pyplusplus/documentation/functions/registration_order.html" ) + tmp.append( "Problematic functions: " ) + for f in problematics: + tmp.append( os.linesep + '\t' + str(f) ) + msgs.append( os.linesep.join( tmp ) ) return msgs class member_function_t( declarations.member_function_t, calldef_t ): Modified: pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py 2006-11-18 19:18:32 UTC (rev 732) +++ pyplusplus_dev/pyplusplus/module_creator/sort_algorithms.py 2006-11-18 19:20:05 UTC (rev 733) @@ -4,6 +4,7 @@ # http://www.boost.org/LICENSE_1_0.txt) from pygccxml import declarations +from pyplusplus import decl_wrappers class COLOR: WHITE = 0 @@ -141,27 +142,7 @@ return groups def __cmp_types( self, t1, t2 ): - if declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): - return self.__cmp_types( declarations.remove_pointer( t1 ) - , declarations.remove_pointer( t2 ) ) - elif declarations.is_pointer( t1 ) and not declarations.is_pointer( t2 ): - t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) - t2 = declarations.remove_cv( t2 ) - if declarations.is_same( t1, t2 ): - return 1 - elif not declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): - t1 = declarations.remove_cv( t1 ) - t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) - if declarations.is_same( t1, t2 ): - return -1 - else: #not is_pointer( t1 ) and not is_pointer( t2 ): - if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) and declarations.is_bool( t2 ): - return -1 - elif declarations.is_bool( t1 ) and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): - return 1 - else: - pass - return None + return decl_wrappers.algorithm.registration_order.is_related( t1, t2 ) def __cmp( self, f1, f2 ): result = self.__cmp_types( f1.arguments[0].type, f2.arguments[0].type ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-18 19:18:36
|
Revision: 732 http://svn.sourceforge.net/pygccxml/?rev=732&view=rev Author: roman_yakovenko Date: 2006-11-18 11:18:32 -0800 (Sat, 18 Nov 2006) Log Message: ----------- updating doc Modified Paths: -------------- pyplusplus_dev/docs/documentation/functions/registration_order.rest Modified: pyplusplus_dev/docs/documentation/functions/registration_order.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/registration_order.rest 2006-11-18 19:16:48 UTC (rev 731) +++ pyplusplus_dev/docs/documentation/functions/registration_order.rest 2006-11-18 19:18:32 UTC (rev 732) @@ -113,10 +113,12 @@ from pyplusplus.module_creator import sort_algorithms sort_algorithms.USE_CALLDEF_ORGANIZER = True - + # The functionality is available from version 0.8.3 + 4. The last and the perfect solution. `Py++`_ will let you know, when your code - has such problem. After this you can change the aliases of the functions. - The third step is to create small "dispatch" function in Python: + has such problem. The functionality is available from version 0.8.3. After + this you can change the aliases of the functions. The third step is to create + small "dispatch" function in Python: .. code-block:: Python This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-18 19:16:48
|
Revision: 731 http://svn.sourceforge.net/pygccxml/?rev=731&view=rev Author: roman_yakovenko Date: 2006-11-18 11:16:48 -0800 (Sat, 18 Nov 2006) Log Message: ----------- adding source code to generated documentation Modified Paths: -------------- pyplusplus_dev/setup.py Modified: pyplusplus_dev/setup.py =================================================================== --- pyplusplus_dev/setup.py 2006-11-18 19:15:50 UTC (rev 730) +++ pyplusplus_dev/setup.py 2006-11-18 19:16:48 UTC (rev 731) @@ -58,7 +58,6 @@ html_writer = HTMLWriter( docindex , prj_name='Py++' , prj_url='http://www.language-binding.net' - , include_source_code=False #This will decrease the size of generated documentation , show_private=False , show_frames=False ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-18 19:15:50
|
Revision: 730 http://svn.sourceforge.net/pygccxml/?rev=730&view=rev Author: roman_yakovenko Date: 2006-11-18 11:15:50 -0800 (Sat, 18 Nov 2006) Log Message: ----------- adding source code to generated documentation Modified Paths: -------------- pygccxml_dev/setup.py Modified: pygccxml_dev/setup.py =================================================================== --- pygccxml_dev/setup.py 2006-11-16 22:20:02 UTC (rev 729) +++ pygccxml_dev/setup.py 2006-11-18 19:15:50 UTC (rev 730) @@ -21,7 +21,6 @@ html_writer = HTMLWriter( docindex , prj_name='pygccxml' , prj_url='http://www.language-binding.net' - , include_source_code=False #This will decrease the size of generated documentation , show_private=False , show_frames=False) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-16 22:20:04
|
Revision: 729 http://svn.sourceforge.net/pygccxml/?rev=729&view=rev Author: roman_yakovenko Date: 2006-11-16 14:20:02 -0800 (Thu, 16 Nov 2006) Log Message: ----------- adding todo item Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-16 22:19:32 UTC (rev 728) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-16 22:20:02 UTC (rev 729) @@ -162,6 +162,8 @@ msgs = [] #TODO: functions that takes as argument pointer to pointer to smth, could not be exported #see http://www.boost.org/libs/python/doc/v2/faq.html#funcptr + + #TODO: add warning to the case described in registration_order.rest document. if len( self.arguments ) > calldef_t.BOOST_PYTHON_MAX_ARITY: tmp = [ "The function has more than %d arguments ( %d ). " ] tmp.append( "You should adjust BOOST_PYTHON_MAX_ARITY macro." ) @@ -171,6 +173,7 @@ if suspicious_type( self.return_type ) and None is self.call_policies: msgs.append( 'The function "%s" returns non-const reference to C++ fundamental type - value can not be modified from Python.' % str( self ) ) + for index, arg in enumerate( self.arguments ): if suspicious_type( arg.type ): tmpl = [ 'The function takes as argument (name=%s, pos=%d ) ' ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-16 22:19:33
|
Revision: 728 http://svn.sourceforge.net/pygccxml/?rev=728&view=rev Author: roman_yakovenko Date: 2006-11-16 14:19:32 -0800 (Thu, 16 Nov 2006) Log Message: ----------- adding registration order document Modified Paths: -------------- pyplusplus_dev/docs/documentation/functions/www_configuration.py Added Paths: ----------- pyplusplus_dev/docs/documentation/functions/registration_order.rest Added: pyplusplus_dev/docs/documentation/functions/registration_order.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/registration_order.rest (rev 0) +++ pyplusplus_dev/docs/documentation/functions/registration_order.rest 2006-11-16 22:19:32 UTC (rev 728) @@ -0,0 +1,156 @@ +================== +Registration order +================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +"... I would very much like to pass bools from Python to C++ and have them +accepted as bools. However I cannot seem to do this. ..." + +"... My class has 2 "append" functions. The first one, has single argument with +type "const char*", the second one also has single argument with type "char". +It seems, that I am not able to call the first function. ..." + +If you have problem similar to described ones, than I am almost sure you have +registration order problem. + +------- +Example +------- + +.. code-block:: C++ + + struct tester_t{ + tester_t() {} + + const char* append(const char*) + { return "append(const char *)"; } + + const char* append(const char) + { return "append(const char)"; } + + const char* do_smth( bool ) + { return "do_smth( bool )"; } + + const char* do_smth( int ) + { return "do_smth( int )"; } + }; + +`Py++`_ generates code, that register functions in the order they apper in the +source code: + +.. code-block:: C++ + + namespace bp = boost::python; + + BOOST_PYTHON_MODULE(my_module){ + bp::class_< tester_t >( "tester_t" ) + .def( bp::init< >() ) + .def( "append" + , (char const * ( ::tester_t::* )( char const * ) )( &::tester_t::append ) ) + .def( "append" + , (char const * ( ::tester_t::* )( char const ) )( &::tester_t::append ) ) + .def( "do_smth" + , (char const * ( ::tester_t::* )( bool ) )( &::tester_t::do_smth ) ) + .def( "do_smth" + , (char const * ( ::tester_t::* )( int ) )( &::tester_t::do_smth ) ); + } + +--------------------------- +Registration order pitfalls +--------------------------- + +Do you want to guess what is the output of the next program: + +.. code-block:: Python + + import my_module + tester = my_module.tester_t() + print tester.do_smth( True ) + print tester.do_smth( 10 ) + print tester.append( "Hello world!" ) + +? + +The output is: + + do_smth( int ) + + do_smth( int ) + + append(const char) + +Unexpected, right? The registration order of exposed overloaded functions is +important. `Boost.Python`_ tries overloads in reverse order of definition. + +If I understand right, `Boost.Python`_ tries to match in reverse order the +overloaded functions, if it can convert `Python`_ arguments to C++ ones, it does +this and calls the function. + +Now, when you understand the behaviour, it should be pretty simple to provide +a correct functionality: + +1. You can change alias of the function, by mangling the type of the argument + into it: + + .. code-block:: Python + + mb = module_builder_t( ... ) + for f in mb.class_( 'tester_t' ).member_functions(): + f.alias = f.alias + f.arguments[0].type.decl_string + +2. You can reorder the declarations within the source file. + +3. You can ask `Py++`_ to generate code, which takes into account the order of + declarations: + + .. code-block:: Python + + from pyplusplus.module_creator import sort_algorithms + + sort_algorithms.USE_CALLDEF_ORGANIZER = True + +4. The last and the perfect solution. `Py++`_ will let you know, when your code + has such problem. After this you can change the aliases of the functions. + The third step is to create small "dispatch" function in Python: + + .. code-block:: Python + + import my_module + + def tester_t_do_smth( self, value ): + if isinstance( value, bool ): + self.do_smth_bool( value ): + else: + self.do_smth_int( value ) + + tester_t.do_smth = tester_t_do_smth + + The tehnique showen here described pretty good in `Boost.Python`_ + `Extending Wrapped Objects in Python tutorials`_ . + + May be in future, `Py++`_ will generate this code for you. Anyway, if you have + a lot of use cases like this consider to generate `Python`_ code and not to + write it manually. + +.. _`Extending Wrapped Objects in Python tutorials` : http://boost.org/libs/python/doc/tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python + + + + +.. _`Py++` : ./../pyplusplus.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: Modified: pyplusplus_dev/docs/documentation/functions/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/functions/www_configuration.py 2006-11-16 14:00:26 UTC (rev 727) +++ pyplusplus_dev/docs/documentation/functions/www_configuration.py 2006-11-16 22:19:32 UTC (rev 728) @@ -3,4 +3,5 @@ names = { 'call_policies' : 'call policies' , 'default_args' : 'default arguments' + , 'registration_order' : 'registration order' } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-16 14:00:27
|
Revision: 727 http://svn.sourceforge.net/pygccxml/?rev=727&view=rev Author: roman_yakovenko Date: 2006-11-16 06:00:26 -0800 (Thu, 16 Nov 2006) Log Message: ----------- adding documentation that describes opaque functionality, A class that marked as "opaque" will not be exposed Modified Paths: -------------- pyplusplus_dev/docs/documentation/functions/call_policies.rest pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/unittests/call_policies_tester.py Modified: pyplusplus_dev/docs/documentation/functions/call_policies.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/call_policies.rest 2006-11-15 14:46:17 UTC (rev 726) +++ pyplusplus_dev/docs/documentation/functions/call_policies.rest 2006-11-16 14:00:26 UTC (rev 727) @@ -90,6 +90,12 @@ * return type is ``void*`` * return type is ``const void*`` + + * return type is ``T*`` and ``T`` is a user defined opaque type + + ``class_t`` and ``class_declaration_t`` classes have ``opaque`` property. + You have to set it to ``True``, if you want `Py++`_ to create this call + policy automaticly for all functions, that use ``T*`` as return type. * ``copy_const_reference`` @@ -133,16 +139,44 @@ Special case ------------ +Before you read this paragraph consider to read `Boost.Python`_ `return_opaque_pointer documentation`_. + ``return_value_policy( return_opaque_pointer )`` is a special policy for `Boost.Python`_. In this case, it requieres from you to define specialization for the ``boost::python::type_id`` function on the type pointed to by returned pointer. `Py++`_ will generate the required code. -For more information about the call policy please refer to `Boost.Python`_ -`documentation`_. -.. _`documentation` : http://boost.org/libs/python/doc/v2/return_opaque_pointer.html +Actually you should define ``boost::python::type_id`` specialization also in case +a function takes the opaque type as an argument. `Py++`_ can do it for you, all +you need is to say to mark a declaration as opaque. +Example: + +.. code-block:: C++ + + struct identity_impl_t{}; + typedef identity_impl_t* identity; + + struct world_t{ + + world_t( identity id ); + + identity get_id() const; + + ... + }; + +`Py++`_ code: + +.. code-block:: Python + + mb = module_builder_t(...) + mb.class_( 'identity_impl_t' ).opaque = True + + +.. _`return_opaque_pointer documentation` : http://boost.org/libs/python/doc/v2/return_opaque_pointer.html + -------------------------- Py++ defined call policies -------------------------- @@ -177,9 +211,26 @@ , bpl::return_value_policy< pyplusplus::call_policies::return_pointee_value<> >() ); } -`Py++`_ code is pretty simple and similar to what you already know: +The `Py++`_ code is not that different from what you already know: +.. code-block:: Python + from pyplusplus import module_builder + from pyplusplus.module_builder import call_policies + + mb = module_builder.module_builder_t( ... ) + mb.free_function( return_type='float *' ).call_policies \ + = call_policies.return_value_policy( call_policies.return_pointee_value ) + +Python code: + +.. code-block:: Python + + import my_module + + assert 0.5 == my_module.get_value() + assert None is my_module.get_null_value() + .. _`ResultConverterGenerator` : http://boost.org/libs/python/doc/v2/ResultConverter.html#ResultConverterGenerator-concept .. _`Py++` : ./../pyplusplus.html Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-11-15 14:46:17 UTC (rev 726) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-11-16 14:00:26 UTC (rev 727) @@ -118,7 +118,8 @@ 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 , doc="If True, Py++ will treat return types and arguments T* as opaque types." \ Modified: pyplusplus_dev/unittests/call_policies_tester.py =================================================================== --- pyplusplus_dev/unittests/call_policies_tester.py 2006-11-15 14:46:17 UTC (rev 726) +++ pyplusplus_dev/unittests/call_policies_tester.py 2006-11-16 14:00:26 UTC (rev 727) @@ -22,9 +22,7 @@ mb.calldef( 'return_second_arg' ).call_policies = call_policies.return_arg( 2 ) mb.calldef( 'return_self' ).call_policies = call_policies.return_self() - mb.class_( 'impl_details_t' ).exclude() - mb.calldef( 'get_impl_details' ).call_policies \ - = call_policies.return_value_policy( call_policies.return_opaque_pointer ) + mb.class_( 'impl_details_t' ).opaque = True mb.calldef( 'get_opaque' ).call_policies \ = call_policies.return_value_policy( call_policies.return_opaque_pointer ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-15 14:46:21
|
Revision: 726 http://svn.sourceforge.net/pygccxml/?rev=726&view=rev Author: roman_yakovenko Date: 2006-11-15 06:46:17 -0800 (Wed, 15 Nov 2006) Log Message: ----------- Added Paths: ----------- pyplusplus_dev/pyplusplus/function_transformers/controllers.py pyplusplus_dev/pyplusplus/function_transformers/templates.py Added: pyplusplus_dev/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/controllers.py (rev 0) +++ pyplusplus_dev/pyplusplus/function_transformers/controllers.py 2006-11-15 14:46:17 UTC (rev 726) @@ -0,0 +1,108 @@ +import string +import templates +from pygccxml import declarations + +class variable_t( object ): + def __init__( self, name, type, initialize_expr='' ): + self.__name = name + self.__type = type + self.__initialize_expr = initialize_expr + + @property + def name( self ): + return self.__name + + @property + def type( self ): + return self.__type + + @property + def initialize_expr( self ): + return self.__initialize_expr + + def declare_var_string( self ): + return templates.substitute( "$type $name$initialize_expr;" + , name=self.name + , type=self.type + , initialize_expr=self.initialize_expr ) + +class controller_base_t( object ): + def __init__( self, function ): + object.__init__( self ) + self.__function = function + self.__variables = {} #name : variable + self.__names_in_use = set( map( lambda arg: arg.name, self.function.arguments ) ) + + def declare_variable( self, type, name, initialize_expr='' ): + unique_name = self.__create_unique_var_name( name ) + self.__variables[ unique_name ] = variable_t( type, unique_name, initialize_expr ) + + def register_variable_name( self, name ): + return self.__create_unique_var_name( name ) + + def __create_unique_var_name( self, name ): + n = 2 + unique_name = name + while 1: + if unique_name in self.__names_in_use: + unique_name = "%s_%d" % ( name, n ) + n += 1 + else: + self.__names_in_use.add( unique_name ) + return unique_name + +class mem_fun_controller_t( controller_base_t ): + def __init__( self, function ): + controller_base_t.__init__( self, function ) + self.__transformed_args = function.arguments[:] + self.__transformed_return_type = function.return_type + + self.__return_variables = [] + self.__pre_call = [] + self.__post_call = [] + self.__save_return_value_stmt = None + self.__input_params = [ arg.name for arg in function.arguments ] + self.__return_stmt = None + + @property + def transformed_args( self ): + return self.__transformed_args + + def __get_transformed_return_type( self ): + return self.__transformed_return_type + def __set_transformed_return_type( self, type_ ): + if isinstane( type, types.StringTypes ): + type_ = declarations.dummy_type_t( type_ ) + self.__transformed_return_type = type_ + transformed_return_type = property( __get_transformed_return_type, __set_transformed_return_type ) + + def add_return_variable( self, variable_name ): + self.__return_variables.append( name ) + + @property + def pre_call( self ): + return self.__pre_call + + def add_pre_call_code( self, code ): + self.__pre_call.append( code ) + + @property + def pos_call( self ): + return self.__post_call + + def add_post_call_code( self, code ): + self.__post_call.append( code ) + + def __get_save_return_value_stmt( self ): + return self.__save_return_value_stmt + def __set_save_return_value_stmt( self, expr ): + self.__save_return_value_stmt = expr + save_return_value_stmt = property( __get_save_return_value_stmt, __set_save_return_value_stmt ) + + def set_input_param( self, index, var_name_or_expr ): + self.__input_params[ index ] = var_name_or_expr + + @property + def return_stmt + + Added: pyplusplus_dev/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/templates.py (rev 0) +++ pyplusplus_dev/pyplusplus/function_transformers/templates.py 2006-11-15 14:46:17 UTC (rev 726) @@ -0,0 +1,82 @@ +# Copyright 2006 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) + +# Matthias Baas is an initial author of the templates. + +import os +from string import Template + +# function_name - C++ function name +# function_alias - function name that Python user will see + +class mem_fun: + body = Template( os.linesep.join([ + '$declare_variables' + , '$pre_call' + , '$save_return_value_stmt$function_name($input_params);' + , '$post_call' + , '$return_stmt' + ])) + +class mem_fun_v: + + original_function_call = Template( "$return_$wrapped_class::%function_name( $args );" ) + + override_body = Template( os.linesep.join([ + '$declare_variables' + , '$declare_override_function = this->get_override( "$function_alias" );' + , 'if( $override_function_var_name ){' + , ' $declare_override_variables' + , ' $override_pre_call' + , ' ${save_override_return_value}boost::python::call<$override_return_type>( $override_function_var_name$override_input_params;' + , ' $override_post_call' + , ' $override_return_stmt' + , '}' + , 'else{' + , ' ' + original_function_call.template + , '}' + ])) + + override_body_safe = Template( os.linesep.join([ + '$declare_gil_guard' + , '$declare_variables' + , '$lock_gil_guard' + , '$declare_override_function = this->get_override( "$function_alias" );' + , '$unlock_gil_guard' + , 'if( $override_function_var_name ){' + , ' $lock_gil_guard //release() will be called from destructor' + , ' $declare_override_variables' + , ' $override_pre_call' + , ' ${save_override_return_value}boost::python::call<$override_return_type>( $override_function_var_name$override_input_params;' + , ' $override_post_call' + , ' $override_return_stmt' + , '}' + , 'else{' + , ' ' + original_function_call.template + , '}' + ])) + + default_body = Template( os.linesep.join([ + '$declare_variables' + , '$pre_call' + , '$declare_wrapped_class_inst' + , 'if( dynamic_cast< $wrapped_class* >( boost::addressof( $wrapped_class_inst_var_name ) ) ){' + # The following call is done on an instance created in Python i.e. a + # wrapper instance. this call might invoke python code. + , ' $save_return_value_stmt$wrapped_class_inst_var_name->$wrapped_class::$function_name($input_params);' + , '}' + , 'else{' + # The following call is done on an instance created in C++, so it won't + # invoke python code. + , ' $save_return_value_stmt$function_name($input_params);' + , '}' + , '$post_call' + , '$return_stmt' + ])) + + +def substitute( text, **keywd ): + return Template( text ).substitute( **keywd ) + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:58:10
|
Revision: 714 http://svn.sourceforge.net/pygccxml/?rev=714&view=rev Author: roman_yakovenko Date: 2006-11-11 23:23:32 -0800 (Sat, 11 Nov 2006) Log Message: ----------- integrating return_pointee_value with Py++ Added Paths: ----------- pyplusplus_dev/pyplusplus/code_repository/call_policies.py Added: pyplusplus_dev/pyplusplus/code_repository/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/call_policies.py (rev 0) +++ pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2006-11-12 07:23:32 UTC (rev 714) @@ -0,0 +1,78 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +""" +This file contains C++ code - custom call policies +""" + + +namespace = "pyplusplus::call_policies" + +file_name = "__call_policies.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 call_policies_pyplusplus_hpp__ +#define call_policies_pyplusplus_hpp__ + +#include "boost/python.hpp" + +namespace pyplusplus{ namespace call_policies{ + +namespace bpl = boost::python; + +namespace detail{ + +struct make_value_holder{ + + template <class T> + static PyObject* execute(T* p){ + if (p == 0){ + return bpl::detail::none(); + } + else{ + bpl::object p_value( *p ); + return bpl::incref( p_value.ptr() ); + } + } + +}; + +template <class R> +struct return_pointee_value_requires_a_pointer_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) +{} +# endif +; + +} //detail + +struct return_pointee_value{ + + template <class T> + struct apply{ + + BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value ); + + typedef typename boost::mpl::if_c< + ok + , bpl::to_python_indirect<T, detail::make_value_holder> + , detail::return_pointee_value_requires_a_pointer_return_type<T> + >::type type; + + }; + +}; + +} /*pyplusplus*/ } /*call_policies*/ + + +#endif//call_policies_pyplusplus_hpp__ + +""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:57:39
|
Revision: 711 http://svn.sourceforge.net/pygccxml/?rev=711&view=rev Author: roman_yakovenko Date: 2006-11-11 11:12:12 -0800 (Sat, 11 Nov 2006) Log Message: ----------- removing dead code Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-11-11 19:04:40 UTC (rev 710) +++ pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-11-11 19:12:12 UTC (rev 711) @@ -71,13 +71,6 @@ sm.init_funcs() self._subst_manager = sm -# def is_free_function(self): -# """Return True if the generated function is a free function. -# -# @rtype: bool -# """ -# return self.parent==None - def function_type(self): """Return the type of the wrapper function. @@ -95,7 +88,6 @@ """Return the name of the wrapper function. This is just the local name without any scope information. - """ # A list with the individual components of the name components = ["_py"] @@ -118,14 +110,6 @@ else: return self.wrapper_name() - def create_sig_id(self): - """Create an ID string that identifies a signature. - - @rtype: str - """ - template = '%s($ARG_LIST_TYPES)'%self.declaration.alias - return self._subst_manager.subst_wrapper(template) - def create_declaration(self, name): """Create the function header. """ @@ -154,9 +138,6 @@ return body def create_function(self): -# sig_id = self.create_sig_id() - # ...check sig here... - answer = [70*"/"] answer.append("// Transformed wrapper function for:") answer.append("// %s"%self.declaration) @@ -460,12 +441,6 @@ "cls_wrapper" : cls_wrapper, "self" : selfname, "base_name" : self.base_name() } - -# function_call = declarations.call_invocation.join( self.declaration.name -# , [ self.function_call_args() ] ) -# body = self.wrapped_class_identifier() + '::' + function_call + ';' -# if not declarations.is_void( self.declaration.return_type ): -# body = 'return ' + body return body def create_function(self): @@ -506,4 +481,5 @@ # argument list) self.declaration.arguments = self._subst_manager.wrapper_func.arg_list - return answer \ No newline at end of file + return answer + \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:56:41
|
Revision: 713 http://svn.sourceforge.net/pygccxml/?rev=713&view=rev Author: roman_yakovenko Date: 2006-11-11 22:44:46 -0800 (Sat, 11 Nov 2006) Log Message: ----------- improving unit test Modified Paths: -------------- pyplusplus_dev/unittests/inner_class_bug_tester.py Modified: pyplusplus_dev/unittests/inner_class_bug_tester.py =================================================================== --- pyplusplus_dev/unittests/inner_class_bug_tester.py 2006-11-12 06:38:55 UTC (rev 712) +++ pyplusplus_dev/unittests/inner_class_bug_tester.py 2006-11-12 06:44:46 UTC (rev 713) @@ -20,7 +20,11 @@ def run_tests( self, module): main = module.main_t() + main.main_method() + main.main_method2() inner = module.main_t.inner_t( 12 ) + inner.inner_method() + inner.inner_method2() 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...> - 2006-11-13 19:55:51
|
Revision: 707 http://svn.sourceforge.net/pygccxml/?rev=707&view=rev Author: roman_yakovenko Date: 2006-11-11 10:12:58 -0800 (Sat, 11 Nov 2006) Log Message: ----------- code_manager_t clean up Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev/pyplusplus/code_repository/gil_guard.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/function_transformers/code_manager.py pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/code_creators/calldef_transformed.py 2006-11-11 18:12:58 UTC (rev 707) @@ -247,11 +247,12 @@ self._subst_manager = sm # Stores the name of the variable that holds the override - self._override_var = sm.virtual_func.allocate_local(function.alias+"_callable") + self._override_var \ + = sm.virtual_func.declare_variable(function.alias + "_callable", 'boost::python::override') # Stores the name of the 'gstate' variable - self._gstate_var = sm.virtual_func.allocate_local("gstate") + self._gstate_var \ + = sm.virtual_func.declare_variable("gstate", 'pyplusplus::threading ::gil_guard_t' ) - def default_name(self): """Return the name of the 'default' function. @@ -339,7 +340,7 @@ def create_virtual_body(self): - thread_safe = getattr(self.declaration, "thread_safe", False) + thread_safe = self.declaration.transformations[0].thread_safe if thread_safe: body = """ @@ -415,25 +416,16 @@ # Replace the $-variables body = self._subst_manager.subst_virtual(body) -# template = [] -# template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' ) -# template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') ) -# template.append( 'else' ) -# template.append( self.indent('%(return_)s%(wrapped_class)s::%(name)s( %(args)s );') ) -# template = os.linesep.join( template ) - return body % { -# 'override' : self.override_identifier() 'override_var' : self._override_var , 'gstate_var' : self._gstate_var , 'alias' : self.declaration.alias -# , 'func_var' : "func_"+self.declaration.alias , 'inherited' : self.create_base_body() } def create_default_body(self): cls_wrapper_type = self.parent.full_name - cls_wrapper = self._subst_manager.wrapper_func.declare_local("cls_wrapper", cls_wrapper_type); + cls_wrapper = self._subst_manager.wrapper_func.declare_variable("cls_wrapper", cls_wrapper_type); # The name of the 'self' variable (i.e. first argument) selfname = self._subst_manager.wrapper_func.arg_list[0].name Modified: pyplusplus_dev/pyplusplus/code_repository/gil_guard.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/gil_guard.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/code_repository/gil_guard.py 2006-11-11 18:12:58 UTC (rev 707) @@ -59,4 +59,4 @@ #endif//__gil_guard_pyplusplus_hpp__ -""" +""" \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-11 18:12:58 UTC (rev 707) @@ -118,12 +118,12 @@ self._transformations = [] return self._transformations - def add_transformation(self, *args): + def add_transformation(self, *args, **keywd): """Set method for property 'function_transformers'. args is a list of transformers """ - self.transformations.append( ft.function_transformation_t( args ) ) + self.transformations.append( ft.function_transformation_t( args, **keywd ) ) def _exportable_impl_derived( self ): return '' Modified: pyplusplus_dev/pyplusplus/function_transformers/code_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-11-11 18:12:58 UTC (rev 707) @@ -19,7 +19,7 @@ manipulate a function and stores the actual substitution variables. Each function has its own code manager instance. - A code block can declare a local variable using L{declare_local()} + A code block can declare a local variable using L{declare_variable()} and it can manipulate one of the attributes that are used to initialize the final variables (see the documentation of the instance variables below). The final variables (such as RET_TYPE, @@ -81,22 +81,15 @@ # exception handler. self.exception_handler_exit = "throw;" - # Key:Variable name / Value:1 - self._allocated_vars = {} # Key:Variable name / Value:(type,size,default) self._declared_vars = {} - # A list with variable tuples: (name, type, size, default) - self._local_var_list = [] - # Required header file names - self._required_headers = [] - def substitute( self, template_code ): tmpl = string.Template(template_code) return tmpl.safe_substitute(self.__dict__) - # declare_local - def declare_local(self, name, type, size=None, default=None): + # declare_variable + def declare_variable(self, name, type, size=None, default=None): """Declare a local variable and return its final name. @param name: The desired variable name @@ -110,64 +103,10 @@ @return: The assigned variable name (which is guaranteed to be unique) @rtype: str """ - name = self.allocate_local(name) + name = self._make_name_unique(name) self._declared_vars[name] = (type,size,default) - self._local_var_list.append((name, type, size, default)) return name - # allocate_local - def allocate_local(self, name): - """Allocate a local variable name and return the final name. - - Allocate a variable name that is unique to the entire - function. The variable will not appear in the DECLARATIONS - block. Instead, the caller has to generate the declaration - code himself at an appropriate place. - - @param name: The desired variable name - @type name: str - @return: The assigned variable name (which is guaranteed to be unique) - @rtype: str - """ - name = self._make_name_unique(name) - self._allocated_vars[name] = 1 - return name - - # is_defined - def is_defined(self, name): - """Check if a variable name is already in use. - - The method returns True if name is the name of an argument or of - a local variable. - - @rtype: bool - """ - if name in self._allocated_vars: - return True - if filter(lambda a: a.name==name, self.arg_list): - return True - return False - - def local_type_str(self, name): - """Return the type of a local variable. - - An exception is raised if a variable called name does not exist. - - @return: Returns the type of the specified local variable. - @rtype: str - """ - if name not in self._allocated_vars: - raise ValueError, 'The type of local variable "%s" is unknown.'%name - if name not in self._declared_vars: - raise ValueError, 'Local variable "%s" not found.'%name - - type,size,default = self._declared_vars[name] - - if size==None: - return type - else: - return "*%s"%type - def init_variables(self): """Initialize the substitution variables. @@ -202,7 +141,8 @@ # Create the declaration block -> DECLARATIONS vardecls = [] - for varname,type,size,default in self._local_var_list: + for varname in self._declared_vars.keys(): + type,size,default = self._declared_vars[ varname ] if default==None: vd = "%s %s"%(type, varname) else: @@ -249,17 +189,14 @@ @return: A unique name based on the input name @rtype: str """ - if not self.is_defined(name): - return name - n = 2 + newname = name while 1: - newname = "%s_%d"%(name, n) - if not self.is_defined(newname): + if not self._declared_vars.has_key( newname ): return newname + newname = "%s_%d"%(name, n) n += 1 - # wrapper_code_manager_t class wrapper_code_manager_t(code_manager_t): """The CodeManager class for the wrapper function. Modified: pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-11 18:12:58 UTC (rev 707) @@ -9,11 +9,12 @@ class function_transformation_t: - def __init__(self, transformers): + def __init__(self, transformers, **keywd): """Constructor. """ self.__transformers = list(transformers) - + self.__thread_safe = keywd.get( 'thread_safe', False ) + @property def transformers( self ): return self.__transformers @@ -23,3 +24,7 @@ map( lambda transformer: headers.extend( transformer.required_headers() ) , self.transformers ) return headers + + @property + def thread_safe( self ): + return self.__thread_safe \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-11 18:12:58 UTC (rev 707) @@ -217,10 +217,8 @@ ret_type = None else: ret_type = decl.return_type -# self.wrapper_func.result_type = str(ret_type) self.wrapper_func.result_type = str(declarations.type_traits.remove_reference(ret_type)) - self.wrapper_func.result_var = self.wrapper_func.declare_local("result", self.wrapper_func.result_type) -# self.wrapper_func.result_var = self.wrapper_func.allocate_local("result") + self.wrapper_func.result_var = self.wrapper_func.declare_variable("result", self.wrapper_func.result_type) self.wrapper_func.result_exprs = [self.wrapper_func.result_var] self.virtual_func.ret_type = ret_type @@ -283,7 +281,7 @@ # inside the virtual function. if len(self.wrapper_func.result_exprs)>0: self.virtual_func.result_type = "boost::python::object" - self.virtual_func.result_var = self.virtual_func.declare_local("pyresult", self.virtual_func.result_type) + self.virtual_func.result_var = self.virtual_func.declare_variable("pyresult", self.virtual_func.result_type) self.wrapper_func.init_variables() self.virtual_func.init_variables() @@ -509,7 +507,7 @@ # Declare the local variable that will hold the return value # for the virtual function - self.result_var = sm.virtual_func.declare_local("result", sm.virtual_func.ret_type) + self.result_var = sm.virtual_func.declare_variable("result", sm.virtual_func.ret_type) # Replace the result expression if there is still the default # result expression (which will not work anyway) if sm.virtual_func.result_expr==sm.virtual_func.result_var: @@ -528,4 +526,3 @@ res = "// Extract the C++ return value\n" res += "%s = boost::python::extract<%s>(%s);"%(self.result_var, sm.virtual_func.ret_type, resexpr) return res - Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-11 07:14:29 UTC (rev 706) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-11 18:12:58 UTC (rev 707) @@ -57,7 +57,7 @@ raise ValueError, '%s\nOutput variable %d ("%s") must be a reference or a pointer (got %s)'%(sm.decl, self.idx, arg.name, arg.type) # Declare a local variable that will receive the output value - self.local_var = sm.wrapper_func.declare_local(arg.name, str(reftype.base)) + self.local_var = sm.wrapper_func.declare_variable(arg.name, str(reftype.base)) # Append the output to the result tuple sm.wrapper_func.result_exprs.append(self.local_var) @@ -220,7 +220,7 @@ # Declare a variable that will hold the Python list # (this will be the input of the Python call in the virtual function) - self.pylist = sm.virtual_func.declare_local("py_"+arg.name, "boost::python::list") + self.pylist = sm.virtual_func.declare_variable("py_"+arg.name, "boost::python::list") # Replace the removed argument with a Python object. newarg = declarations.argument_t(arg.name, declarations.dummy_type_t("boost::python::object")) @@ -230,7 +230,7 @@ self.basetype = str(arg.type.base).replace("const", "").strip() # Declare a variable that will hold the C array... - self.carray = sm.wrapper_func.declare_local("c_"+arg.name, self.basetype, size=self.size) + self.carray = sm.wrapper_func.declare_variable("c_"+arg.name, self.basetype, size=self.size) # Replace the input parameter with the C array sm.wrapper_func.input_params[self.idx-1] = self.carray @@ -307,9 +307,9 @@ # Wrapper: # Declare a variable that will hold the C array... - self.wrapper_cval = sm.wrapper_func.declare_local("c_"+self.argname, self.basetype, size=self.size) + self.wrapper_cval = sm.wrapper_func.declare_variable("c_"+self.argname, self.basetype, size=self.size) # Declare a Python list which will receive the output... - self.wrapper_pyval = sm.wrapper_func.declare_local(self.argname, "boost::python::list") + self.wrapper_pyval = sm.wrapper_func.declare_variable(self.argname, "boost::python::list") # ...and add it to the result sm.wrapper_func.result_exprs.append(arg.name) @@ -318,7 +318,7 @@ # Virtual: # Declare a variable that will receive the Python list - self.virtual_pyval = sm.virtual_func.declare_local("py_"+self.argname, "boost::python::object") + self.virtual_pyval = sm.virtual_func.declare_variable("py_"+self.argname, "boost::python::object") def wrapper_post_call(self, sm): tmpl = '%(pypp_con)s::copy_container( %(array)s, %(array)s + %(size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:55:40
|
Revision: 715 http://svn.sourceforge.net/pygccxml/?rev=715&view=rev Author: roman_yakovenko Date: 2006-11-12 01:53:26 -0800 (Sun, 12 Nov 2006) Log Message: ----------- adding reference to declaration to transformers Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/function_transformers/__init__.py pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/function_transformers/transformer.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2006-11-12 09:53:26 UTC (rev 715) @@ -123,7 +123,7 @@ args is a list of transformers """ - self.transformations.append( ft.function_transformation_t( args, **keywd ) ) + self.transformations.append( ft.function_transformation_t( self, args, **keywd ) ) def _exportable_impl_derived( self ): return '' Modified: pyplusplus_dev/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-11-12 09:53:26 UTC (rev 715) @@ -22,16 +22,26 @@ from function_transformation import function_transformation_t def output( *args, **keywd ): - return transformers.output_t( *args, **keywd ) + def creator( function ): + return transformers.output_t( function, *args, **keywd ) + return creator def input( *args, **keywd ): - return transformers.input_t( *args, **keywd ) + def creator( function ): + return transformers.input_t( function, *args, **keywd ) + return creator def inout( *args, **keywd ): - return transformers.inout_t( *args, **keywd ) + def creator( function ): + return transformers.inout_t( function, *args, **keywd ) + return creator def input_array( *args, **keywd ): - return transformers.input_array_t( *args, **keywd ) + def creator( function ): + return transformers.input_array_t( function, *args, **keywd ) + return creator def output_array( *args, **keywd ): - return transformers.output_array_t( *args, **keywd ) + def creator( function ): + return transformers.output_array_t( function, *args, **keywd ) + return creator Modified: pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/function_transformation.py 2006-11-12 09:53:26 UTC (rev 715) @@ -9,10 +9,10 @@ class function_transformation_t: - def __init__(self, transformers, **keywd): - """Constructor. - """ - self.__transformers = list(transformers) + def __init__(self, function, transformer_creator, **keywd): + """Constructor. """ + self.__function = function + self.__transformers = map( lambda tr_creator: tr_creator( function ), transformer_creator ) self.__thread_safe = keywd.get( 'thread_safe', False ) @property @@ -27,4 +27,4 @@ @property def thread_safe( self ): - return self.__thread_safe \ No newline at end of file + return self.__thread_safe Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-12 09:53:26 UTC (rev 715) @@ -12,6 +12,7 @@ from pygccxml import declarations from code_manager import code_manager_t, wrapper_code_manager_t from transformer import transformer_t +from transformer import return_ # substitution_manager_t class substitution_manager_t: @@ -262,7 +263,7 @@ """ # Append the default return_virtual_result_t code modifier - transformers = self.transformers+[return_virtual_result_t()] + transformers = self.transformers+[return_virtual_result_t(self.decl)] for cb in transformers: if hasattr(cb, "init_funcs"): @@ -361,6 +362,7 @@ return arg + # insert_arg def insert_arg(self, idx, arg, inputexpr): """Insert a new argument into the argument list of the wrapper function. @@ -475,8 +477,8 @@ to the list of code blocks inside the substitution_manager_t class. """ - def __init__(self): - transformer_t.__init__(self) + def __init__(self, function): + transformer_t.__init__(self, function) self.result_var = "<not initialized>" def __str__(self): Modified: pyplusplus_dev/pyplusplus/function_transformers/transformer.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-12 09:53:26 UTC (rev 715) @@ -11,8 +11,11 @@ import sys, os.path, copy, re, types from pygccxml import declarations, parser +return_ = -1 class transformer_t: + USE_1_BASED_INDEXING = False + """Base class for a function transformer. This class specifies the interface that a user written transformer @@ -23,19 +26,39 @@ @author: Matthias Baas """ - def __init__(self): + def __init__(self, function): """Constructor. """ - pass + self.__function = function + @property + def function( self ): + """reference to the function, for which a wrapper will be generated""" + return self.__function + def required_headers( self ): """Returns list of header files that transformer generated code depends on.""" return [] - def validate( self, function ): - """returns error message or None""" - raise NotImplementedError() + def get_argument( self, reference ): + if isinstance( reference, str ): + found = filter( lambda arg: arg.name == reference, self.function.arguments ) + if len( found ) == 1: + return found[0] + raise RuntimeError( "Argument with %s was not found" % reference ) + else: + assert isinstance( reference, int ) + if transformer_t.USE_1_BASED_INDEXING: + reference += 1 + return self.function.arguments[ reference ] + def get_type( self, reference ): + global return_ + if isinstance( reference, int ) and reference == return_: + return self.function.return_type + else: + return self.get_argument( reference ).type + def init_funcs(self, sm): """Wrapper initialization. @@ -114,4 +137,4 @@ def virtual_cleanup(self, sm): pass - \ No newline at end of file + Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-12 07:23:32 UTC (rev 714) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-12 09:53:26 UTC (rev 715) @@ -30,53 +30,52 @@ void getValue(int& v) -> v = getValue() """ - def __init__(self, idx): - transformer.transformer_t.__init__( self ) + def __init__(self, function, arg_ref): + transformer.transformer_t.__init__( self, function ) """Constructor. The specified argument must be a reference or a pointer. - @param idx: Index of the argument that is an output value (the first arg has index 1). - @type idx: int + @param arg_ref: Index of the argument that is an output value (the first arg has index 1). + @type arg_ref: int """ - self.idx = idx + self.arg = self.get_argument( arg_ref ) + self.arg_index = self.function.arguments.index( self.arg ) self.local_var = "<not initialized>" + if not declarations.is_pointer( self.arg.type ) and not declarations.is_reference( self.arg.type ): + raise ValueError( '%s\nin order to use "output" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ + % ( function, self.arg_ref.name, arg.type) + def __str__(self): - return "output(%d)"%(self.idx) + return "output(%d)"%(self.arg_index) def init_funcs(self, sm): # Remove the specified output argument from the wrapper function - arg = sm.remove_arg(self.idx) + sm.remove_arg(self.arg_index+1) - # Do some sanity checking (whether the argument can actually be - # an output argument, i.e. it has to be a reference or a pointer) - reftype = arg.type - if not declarations.is_pointer( reftype ) and not declarations.is_reference( reftype ): - raise ValueError, '%s\nOutput variable %d ("%s") must be a reference or a pointer (got %s)'%(sm.decl, self.idx, arg.name, arg.type) - # Declare a local variable that will receive the output value - self.local_var = sm.wrapper_func.declare_variable(arg.name, str(reftype.base)) + self.local_var = sm.wrapper_func.declare_variable( self.arg.name, str(self.arg.type.base) ) # Append the output to the result tuple sm.wrapper_func.result_exprs.append(self.local_var) # Replace the expression in the C++ function call - if isinstance(reftype, declarations.pointer_t): - sm.wrapper_func.input_params[self.idx-1] = "&%s"%self.local_var - else: - sm.wrapper_func.input_params[self.idx-1] = self.local_var + input_param = self.local_var + if declarations.is_pointer( self.arg.type ): + input_param = "&%s" % self.local_var + + sm.wrapper_func.input_params[self.arg_index] = input_param def virtual_post_call(self, sm): - """Extract the C++ value after the call to the Python function. - """ - arg = sm.virtual_func.arg_list[self.idx-1] - res = "// Extract the C++ value for output argument '%s' (index: %d)\n"%(arg.name, self.idx) - if isinstance(arg.type, declarations.pointer_t): - res += "*" - res += "%s = boost::python::extract<%s>(%s);"%(arg.name, arg.type.base, sm.py_result_expr(self.local_var)) - return res - + """Extract the C++ value after the call to the Python function.""" + res = [] + if declarations.is_pointer( self.arg.type ): + res.append( "*" ) + res.append( "%s = boost::python::extract<%s>(%s);" \ + % ( self.arg.name, self.arg.type.base, sm.py_result_expr(self.local_var) ) ) + return ''.join( res ) + # input_t class input_t(transformer.transformer_t): """Handles a single input variable. @@ -86,7 +85,7 @@ void setValue(int& v) -> setValue(v) """ - def __init__(self, idx): + def __init__(self, function, idx): """Constructor. The specified argument must be a reference or a pointer. @@ -94,8 +93,8 @@ @param idx: Index of the argument that is an output value (the first arg has index 1). @type idx: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 def __str__(self): return "input(%d)"%(self.idx) @@ -121,7 +120,7 @@ void foo(int& v) -> v = foo(v) """ - def __init__(self, idx): + def __init__(self, function, idx): """Constructor. The specified argument must be a reference or a pointer. @@ -129,8 +128,8 @@ @param idx: Index of the argument that is an in/out value (the first arg has index 1). @type idx: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 self.local_var = "<not initialized>" def __str__(self): @@ -182,7 +181,7 @@ # v must be a sequence of 3 floats """ - def __init__(self, idx, size): + def __init__(self, function, idx, size): """Constructor. @param idx: Index of the argument that is an input array (the first arg has index 1). @@ -190,8 +189,8 @@ @param size: The fixed size of the input array @type size: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 self.size = size self.argname = None @@ -264,7 +263,7 @@ # v will be a list with 3 floats """ - def __init__(self, idx, size): + def __init__(self, function, idx, size): """Constructor. @param idx: Index of the argument that is an output array (the first arg has index 1). @@ -272,8 +271,8 @@ @param size: The fixed size of the output array @type size: int """ - transformer.transformer_t.__init__( self ) - self.idx = idx + transformer.transformer_t.__init__( self, function ) + self.idx = idx + 1 self.size = size self.argname = None @@ -335,4 +334,4 @@ , 'size' : self.size , 'array_name' : self.argname } - \ No newline at end of file + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:54:47
|
Revision: 701 http://svn.sourceforge.net/pygccxml/?rev=701&view=rev Author: roman_yakovenko Date: 2006-11-08 11:00:37 -0800 (Wed, 08 Nov 2006) Log Message: ----------- porting indexiing suite to gcc Modified Paths: -------------- pyplusplus_dev/indexing_suite_v2/indexing/map.hpp pyplusplus_dev/indexing_suite_v2/indexing/multimap.hpp Modified: pyplusplus_dev/indexing_suite_v2/indexing/map.hpp =================================================================== --- pyplusplus_dev/indexing_suite_v2/indexing/map.hpp 2006-11-08 18:58:43 UTC (rev 700) +++ pyplusplus_dev/indexing_suite_v2/indexing/map.hpp 2006-11-08 19:00:37 UTC (rev 701) @@ -177,7 +177,8 @@ boost::python::list _keys; //For some reason code with set could not be compiled //std::set< key_param > unique_keys; - for( iterator index = most_derived::begin(c); index != most_derived::end(c); ++index ){ + typedef BOOST_DEDUCED_TYPENAME container::iterator iter_type; + for( iter_type index = most_derived::begin(c); index != most_derived::end(c); ++index ){ //if( unique_keys.end() == unique_keys.find( index->first ) ){ // unique_keys.insert( index->first ); if( !_keys.count( index->first ) ){ Modified: pyplusplus_dev/indexing_suite_v2/indexing/multimap.hpp =================================================================== --- pyplusplus_dev/indexing_suite_v2/indexing/multimap.hpp 2006-11-08 18:58:43 UTC (rev 700) +++ pyplusplus_dev/indexing_suite_v2/indexing/multimap.hpp 2006-11-08 19:00:37 UTC (rev 701) @@ -141,7 +141,8 @@ boost::python::list _keys; //For some reason code with set could not be compiled //std::set< key_param > unique_keys; - for( iterator index = most_derived::begin(c); index != most_derived::end(c); ++index ){ + typedef BOOST_DEDUCED_TYPENAME container::iterator iter_type; + for( iter_type index = most_derived::begin(c); index != most_derived::end(c); ++index ){ //if( unique_keys.end() == unique_keys.find( index->first ) ){ // unique_keys.insert( index->first ); if( !_keys.count( index->first ) ){ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:54:46
|
Revision: 700 http://svn.sourceforge.net/pygccxml/?rev=700&view=rev Author: roman_yakovenko Date: 2006-11-08 10:58:43 -0800 (Wed, 08 Nov 2006) Log Message: ----------- adding fix for signed char, char bug Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/cpptypes.py pygccxml_dev/pygccxml/declarations/type_traits.py pygccxml_dev/pygccxml/declarations/type_visitor.py pygccxml_dev/pygccxml/parser/linker.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2006-11-08 18:47:53 UTC (rev 699) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2006-11-08 18:58:43 UTC (rev 700) @@ -27,6 +27,7 @@ from cpptypes import fundamental_t from cpptypes import void_t from cpptypes import char_t +from cpptypes import signed_char_t from cpptypes import unsigned_char_t from cpptypes import wchar_t from cpptypes import short_int_t Modified: pygccxml_dev/pygccxml/declarations/cpptypes.py =================================================================== --- pygccxml_dev/pygccxml/declarations/cpptypes.py 2006-11-08 18:47:53 UTC (rev 699) +++ pygccxml_dev/pygccxml/declarations/cpptypes.py 2006-11-08 18:58:43 UTC (rev 700) @@ -112,6 +112,12 @@ def __init__( self ): fundamental_t.__init__( self, char_t.CPPNAME ) +class signed_char_t( fundamental_t ): + """represents signed char type""" + CPPNAME = 'signed char' + def __init__( self ): + fundamental_t.__init__( self, signed_char_t.CPPNAME ) + class unsigned_char_t( fundamental_t ): """represents unsigned char type""" CPPNAME = 'unsigned char' @@ -265,7 +271,7 @@ FUNDAMENTAL_TYPES = { void_t.CPPNAME : void_t() , char_t.CPPNAME : char_t() - , 'signed ' + char_t.CPPNAME : char_t() + , signed_char_t.CPPNAME : signed_char_t() , unsigned_char_t.CPPNAME : unsigned_char_t() , wchar_t.CPPNAME : wchar_t() , short_int_t.CPPNAME : short_int_t() Modified: pygccxml_dev/pygccxml/declarations/type_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/type_traits.py 2006-11-08 18:47:53 UTC (rev 699) +++ pygccxml_dev/pygccxml/declarations/type_traits.py 2006-11-08 18:58:43 UTC (rev 700) @@ -118,6 +118,7 @@ """returns True, if type represents C++ integral type, False otherwise""" integral_def = create_cv_types( cpptypes.char_t() ) \ + create_cv_types( cpptypes.unsigned_char_t() ) \ + + create_cv_types( cpptypes.signed_char_t() ) \ + create_cv_types( cpptypes.wchar_t() ) \ + create_cv_types( cpptypes.short_int_t() ) \ + create_cv_types( cpptypes.short_unsigned_int_t() ) \ Modified: pygccxml_dev/pygccxml/declarations/type_visitor.py =================================================================== --- pygccxml_dev/pygccxml/declarations/type_visitor.py 2006-11-08 18:47:53 UTC (rev 699) +++ pygccxml_dev/pygccxml/declarations/type_visitor.py 2006-11-08 18:58:43 UTC (rev 700) @@ -24,7 +24,10 @@ def visit_unsigned_char( self ): raise NotImplementedError() - + + def visit_signed_char( self ): + raise NotImplementedError() + def visit_wchar( self ): raise NotImplementedError() Modified: pygccxml_dev/pygccxml/parser/linker.py =================================================================== --- pygccxml_dev/pygccxml/parser/linker.py 2006-11-08 18:47:53 UTC (rev 699) +++ pygccxml_dev/pygccxml/parser/linker.py 2006-11-08 18:58:43 UTC (rev 700) @@ -141,6 +141,9 @@ def visit_char( self ): pass + def visit_signed_char( self ): + pass + def visit_unsigned_char( self ): pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:54:37
|
Revision: 698 http://svn.sourceforge.net/pygccxml/?rev=698&view=rev Author: roman_yakovenko Date: 2006-11-08 02:19:28 -0800 (Wed, 08 Nov 2006) Log Message: ----------- fixing treatment of opaque types Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py pyplusplus_dev/pyplusplus/module_creator/creator.py Added Paths: ----------- pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-11-08 10:08:43 UTC (rev 697) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2006-11-08 10:19:28 UTC (rev 698) @@ -53,6 +53,7 @@ self._equality_comparable = None self._less_than_comparable = None self._isuite_version = 1 + self._opaque = False def _get_indexing_suite_version( self ): return self._isuite_version @@ -112,7 +113,18 @@ less_than_comparable = property( _get_less_than_comparable, _set_less_than_comparable , doc="indicates existence of public operator<. " \ +"Default value is calculated, based on information presented in the declarations tree" ) + + def _get_opaque( self ): + return self._opaque + def _set_opaque( self, value ): + self._opaque = value + + opaque = property( _get_opaque, _set_opaque + , doc="If True, Py++ will treat return types and arguments T* as opaque types." \ + +"Thus it will be able to generate code, that uses " \ + +" BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID macro in a right places." ) + #this will only be exported if indexing suite is not None and only when needed class class_declaration_t( class_common_details_t , decl_wrapper.decl_wrapper_t Modified: pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py 2006-11-08 10:08:43 UTC (rev 697) +++ pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py 2006-11-08 10:19:28 UTC (rev 698) @@ -3,11 +3,14 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +import opaque_types_manager from pygccxml import declarations from pyplusplus import decl_wrappers from pyplusplus import code_creators from pyplusplus.decl_wrappers import python_traits +#TODO: add opaque to documentation + class resolver_t( object ): def __init__( self ): object.__init__( self ) @@ -82,6 +85,9 @@ if declarations.is_same( return_type, self.__const_wchar_pointer ): return decl_wrappers.return_value_policy( decl_wrappers.return_by_value ) + if opaque_types_manager.find_out_opaque_decl( return_type, ensure_opaque_decl=True ): + return decl_wrappers.return_value_policy( decl_wrappers.return_opaque_pointer ) + return None class return_internal_reference_resolver_t( resolver_t ): @@ -167,4 +173,4 @@ resolved = resolver( calldef, hint ) if resolved: return resolved - return None \ No newline at end of file + return None Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-11-08 10:08:43 UTC (rev 697) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-11-08 10:19:28 UTC (rev 698) @@ -6,6 +6,7 @@ import types_database import creators_wizard import class_organizer +import opaque_types_manager import call_policies_resolver from pygccxml import declarations from pyplusplus import decl_wrappers @@ -137,7 +138,7 @@ self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] self.__exposed_free_fun_overloads = set() - self.__exposed_opaque_decls = {} #decl : creator + self.__opaque_types_manager = opaque_types_manager.manager_t( self.__extmodule ) def _prepare_decls( self, decls, doc_extractor ): global DO_NOT_REPORT_MSGS @@ -227,25 +228,6 @@ new_ordered.extend( variables ) return new_ordered # - def register_opaque_type( self, creator, type_, call_policy ): - if not decl_wrappers.is_return_opaque_pointer_policy( call_policy ): - return #not our case - naked_type = declarations.remove_cv( declarations.remove_pointer( type_ ) ) - if decl_wrappers.python_traits.is_immutable( naked_type ): - return #don't register opaque converter for immutable types. - decl = None - if declarations.is_class( naked_type ): - decl = declarations.class_traits.get_declaration( naked_type ) - else:#class declaration: - decl = declarations.class_declaration_traits.get_declaration( naked_type ) - opaque_type_registrator = None - if id(decl) not in self.__exposed_opaque_decls.keys(): - opaque_type_registrator = code_creators.opaque_type_registrator_t( decl ) - self.__exposed_opaque_decls[ id(decl) ] = opaque_type_registrator - self.__extmodule.adopt_declaration_creator( opaque_type_registrator ) - else: - opaque_type_registrator = self.__exposed_opaque_decls[ id(decl) ] - creator.associated_decl_creators.append(opaque_type_registrator) def _adopt_free_operator( self, operator ): def adopt_operator_impl( operator, found_creators ): @@ -475,9 +457,8 @@ else: maker = maker_cls( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) - # Make sure all required headers are included... required_headers = getattr(fwrapper, "get_required_headers", lambda : [])() for header in required_headers: @@ -544,12 +525,12 @@ and not declarations.is_reference( self.curr_decl.return_type ): maker = code_creators.casting_operator_t( operator=self.curr_decl ) self.__module_body.adopt_creator( maker ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) #what to do if class is abstract if self.curr_decl.access_type == ACCESS_TYPES.PUBLIC: maker = code_creators.casting_member_operator_t( operator=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) def visit_free_function( self ): if self.curr_decl in self.__exposed_free_fun_overloads: @@ -576,7 +557,7 @@ overloads_reg = code_creators.free_fun_overloads_t( overloads_cls_creator ) self.curr_code_creator.adopt_creator( overloads_reg ) overloads_reg.associated_decl_creators.append( overloads_cls_creator ) - self.register_opaque_type( overloads_reg, f.return_type, f.call_policies ) + self.__opaque_types_manager.register_opaque( overloads_reg, overloads ) ctext_t = code_creators.custom_text_t for f in overloads: @@ -590,7 +571,7 @@ self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) maker = code_creators.free_function_t( function=self.curr_decl ) self.curr_code_creator.adopt_creator( maker ) - self.register_opaque_type( maker, self.curr_decl.return_type, self.curr_decl.call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) ctext_t = code_creators.custom_text_t uc_creators = map( lambda uc: ctext_t( uc.text ), self.curr_decl.declaration_code ) @@ -630,7 +611,7 @@ cls_creator.adopt_creator( overloads_reg ) overloads_reg.associated_decl_creators.append( overloads_cls_creator ) - self.register_opaque_type( overloads_reg, f.return_type, f.call_policies ) + self.__opaque_types_manager.register_opaque( overloads_reg, overloads ) return exposed def visit_class(self ): @@ -769,7 +750,7 @@ self.curr_decl.setter_call_policies = self.__call_policies_resolver( self.curr_decl, 'set' ) wrapper = code_creators.mem_var_ref_wrapper_t( variable=self.curr_decl ) maker = code_creators.mem_var_ref_t( variable=self.curr_decl, wrapper=wrapper ) - self.register_opaque_type( maker, self.curr_decl.type, self.curr_decl.getter_call_policies ) + self.__opaque_types_manager.register_opaque( maker, self.curr_decl ) else: maker = code_creators.member_variable_t( variable=self.curr_decl ) if wrapper: Added: pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py (rev 0) +++ pyplusplus_dev/pyplusplus/module_creator/opaque_types_manager.py 2006-11-08 10:19:28 UTC (rev 698) @@ -0,0 +1,82 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from pygccxml import declarations +from pyplusplus import code_creators +from pyplusplus import decl_wrappers + +def find_out_opaque_decl( type_, ensure_opaque_decl ): + naked_type = declarations.remove_cv( type_ ) + if not declarations.is_pointer( naked_type ): + return None + naked_type = declarations.remove_pointer( declarations.remove_cv( type_ ) ) + if decl_wrappers.python_traits.is_immutable( naked_type ): + return None#immutable types could not be opaque + decl = None + if declarations.is_class( naked_type ): + decl = declarations.class_traits.get_declaration( naked_type ) + elif declarations.is_class_declaration( naked_type ):#class declaration: + decl = declarations.class_declaration_traits.get_declaration( naked_type ) + else: + return None + if ensure_opaque_decl: + if decl.opaque: + return decl + else: + return None + else: + return decl + + +class manager_t( object ): + def __init__( self, extmodule ): + object.__init__( self ) + self.__extmodule = extmodule + self.__exposed_opaque_decls = {} #decl: creator + + def __find_out_opaque_decls( self, decl ): + opaque_types = [] + is_opaque_policy = decl_wrappers.is_return_opaque_pointer_policy + if isinstance( decl, declarations.variable_t ): + opaque_decl = find_out_opaque_decl( decl.type, ensure_opaque_decl=True ) + if opaque_decl: + opaque_types.append( opaque_decl ) + elif is_opaque_policy( decl.getter_call_policies ) or is_opaque_policy( decl.setter_call_policies ): + opaque_decl = find_out_opaque_decl( decl.type, ensure_opaque_decl=False ) + if opaque_decl: + opaque_types.append( opaque_decl ) + else: + pass + elif isinstance( decl, declarations.calldef_t ): + if is_opaque_policy( decl.call_policies ): + opaque_decl = find_out_opaque_decl( decl.return_type, ensure_opaque_decl=False ) + if opaque_decl: + opaque_types.append( opaque_decl ) + all_types = decl.argument_types[:] + if decl.return_type: + all_types.append( decl.return_type ) + for type_ in all_types: + opaque_decl = find_out_opaque_decl( type_, ensure_opaque_decl=True ) + if opaque_decl: + opaque_types.append( opaque_decl ) + else: + pass + return opaque_types + + + def register_opaque( self, creator, decl_or_decls ): + opaque_decls = [] + for decl in declarations.make_flatten( decl_or_decls ): + opaque_decls.extend( self.__find_out_opaque_decls( decl ) ) + + for decl in opaque_decls: + opaque_type_registrator = None + if id(decl) not in self.__exposed_opaque_decls.keys(): + opaque_type_registrator = code_creators.opaque_type_registrator_t( decl ) + self.__exposed_opaque_decls[ id(decl) ] = opaque_type_registrator + self.__extmodule.adopt_declaration_creator( opaque_type_registrator ) + else: + opaque_type_registrator = self.__exposed_opaque_decls[ id(decl) ] + creator.associated_decl_creators.append(opaque_type_registrator) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:54:19
|
Revision: 704 http://svn.sourceforge.net/pygccxml/?rev=704&view=rev Author: roman_yakovenko Date: 2006-11-09 13:21:32 -0800 (Thu, 09 Nov 2006) Log Message: ----------- adding few classes and functions for array <=> list copy removing subst.py file Modified Paths: -------------- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/pyplusplus/function_transformers/transformer.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py Removed Paths: ------------- pyplusplus_dev/pyplusplus/function_transformers/subst.py Modified: pyplusplus_dev/pyplusplus/function_transformers/code_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-11-09 21:20:11 UTC (rev 703) +++ pyplusplus_dev/pyplusplus/function_transformers/code_manager.py 2006-11-09 21:21:32 UTC (rev 704) @@ -9,10 +9,10 @@ """ import types -from subst import subst_t +import string # code_manager_t -class code_manager_t(subst_t): +class code_manager_t: """This class manages pieces of source code for a C++ function. The class mainly provides the interface for the code blocks to @@ -51,13 +51,7 @@ """ def __init__(self): - """Constructor. - """ - subst_t.__init__(self, blockvars=["DECLARATIONS", - "PRE_CALL", - "POST_CALL", - "EXCEPTION_HANDLER_EXIT"]) - + """Constructor.""" # The name of the class of which the generated function is a member # (pass None or an empty string if the function is a free function) self.class_name = None @@ -97,6 +91,10 @@ # Required header file names self._required_headers = [] + def substitute( self, template_code ): + tmpl = string.Template(template_code) + return tmpl.safe_substitute(self.__dict__) + # require_header def require_header(self, include): """Declare an include file that is required for the code to compile. @@ -342,15 +340,6 @@ elif len(result_exprs)==1: self.ret_type = "boost::python::object" self.result_expr = "boost::python::object(%s)"%result_exprs[0] -## self.result_expr = self.result_exprs[0] -## try: -## # Try to determine the type of the result expression -## # (assuming it's just a local variable) -## self.ret_type = self.local_type_str(self.result_expr) -## except: -## # if the above fails, return a generic Python object -## self.ret_type = "boost::python::object" -## self.result_expr = "boost::python::object(%s)"%result_exprs[0] # More than one output value... else: self.ret_type = "boost::python::object" @@ -358,3 +347,5 @@ # Invoke the inherited method that sets the actual variables code_manager_t.init_variables(self) + + \ No newline at end of file Deleted: pyplusplus_dev/pyplusplus/function_transformers/subst.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/subst.py 2006-11-09 21:20:11 UTC (rev 703) +++ pyplusplus_dev/pyplusplus/function_transformers/subst.py 2006-11-09 21:21:32 UTC (rev 704) @@ -1,142 +0,0 @@ -# Copyright 2006 Roman Yakovenko. -# Distributed under the Boost Software License, Version 1.0. (See -# accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -# -# Initial author: Matthias Baas - -"""This module contains the base class L{subst_t}. -""" - -import re -import string - -# subst_t -class subst_t: - """Perform text substitutions. - - This class performs text substitutions on a template string. The - variables are simply stored as attributes inside the class and may - be of any type that can be converted to a string. - If a template string references a variable that does not exist, - the reference is not substituted. - - Example:: - - sm = subst_t(blockvars=['BODY']) - sm.RETURNTYPE = 'int' - sm.FUNCNAME = 'foo' - sm.ARGLIST = 'int n' - sm.BODY = '''int res=0; - for(int i=0; i<n; i++) - { - res += n; - } - return res;''' - - template = ''' - $RETURNTYPE $FUNCNAME($ARGLIST) - { - $BODY - } - ''' - - print sm.substitute(template) - - The result of the substitution will be:: - - int foo(int n) - { - int res=0; - for(int i=0; i<n; i++) - { - res += n; - } - return res; - } - - The variable BODY is a block variable which means it may contain - an entire block of text where each line should be indented with - the same depth as the variable in the template string. The value - of BODY should not contain an already indented block. - - @author: Matthias Baas - """ - - def __init__(self, blockvars): - """Constructor. - - The argument blockvars is used to declare the names of those - variables that may contain a block of code (i.e. multiple lines). - - @param blockvars: A list of block variable names. - @type blockvars: list of str - """ - self._blockvars = dict(map(lambda x: (x,0), blockvars)) - - def substitute(self, template): - """Substitute the variables in template and return the result. - - All variables of the form "$<varname>" or "${varname}" are - replaced with the corresponding attribute <varname>. Block - variables must appear in one single line. The indendation of - the variable determines the indendation of the entire block. - References to unknown variables won't get substituted. - - @param template: The template string - @type template: str - @return: Returns the input string where all variables have been substituted. - @rtype: str - """ - - lines = [] - # Replace the block variables... - for line in template.split("\n"): - s = line.lstrip() - # Determine the indendation depth - depth = len(line)-len(s) - key = s.rstrip() - if key!="" and key[0]=="$" and key[1:] in self._blockvars: - block = getattr(self, key[1:], None) - if block==None or block=="": - line = None - else: - line = self._indent(depth, block) - else: - line = line.rstrip() - if line!=None and (line!="" or (lines!=[] and lines[-1]!="")): - lines.append(line) - code = "\n".join(lines) - - # Replace the non-block variables... - tmpl = string.Template(code) - code = tmpl.safe_substitute(self.__dict__) - - # Replace trailing blanks on each line... - expr = re.compile("[ ]+$", re.MULTILINE) - code = expr.sub("", code) - - # Replace two subsequent empty lines with one single line... - expr = re.compile("^\n^\n", re.MULTILINE) - n1 = len(code) - while 1: - code = expr.sub("\n", code) - n2 = len(code) - if n2==n1: - break - n1 = n2 - - # Remove blank lines right after '{' or before '}' - code = code.replace("{\n\n", "{\n") - code = code.replace("\n\n}", "\n}") - - return code - - # _indent - def _indent(self, n, code): - """Indent source code. - """ - if code=="": - return "" - return "\n".join(map(lambda s: ((n*" ")+s).rstrip(), code.split("\n"))) - Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-09 21:20:11 UTC (rev 703) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-11-09 21:21:32 UTC (rev 704) @@ -271,8 +271,6 @@ It is not necessary to call this method manually, it is automatically called at the time a substitution is requested. """ -# print "Transforming:",self.decl -# print " using transformers:", ", ".join(map(lambda x: str(x), self.transformers)) # Append the default return_virtual_result_t code modifier transformers = self.transformers+[return_virtual_result_t()] @@ -285,9 +283,7 @@ # inside the virtual function. if len(self.wrapper_func.result_exprs)>0: self.virtual_func.result_type = "boost::python::object" -# self.virtual_func.result_var = self.virtual_func.allocate_local("pyresult") self.virtual_func.result_var = self.virtual_func.declare_local("pyresult", self.virtual_func.result_type) -# self.virtual_func.result_expr = self.virtual_func.result_var self.wrapper_func.init_variables() self.virtual_func.init_variables() @@ -296,7 +292,7 @@ block_sep = os.linesep * 2 # Create the wrapper function pre-call block... - tmp = filter(None, map(lambda cb: cb.wrapper_pre_call(self), transformers) ) + tmp = filter(None, map(lambda cb: cb.wrapper_pre_call(self), transformers) ) self.wrapper_func.PRE_CALL = block_sep.join( tmp ) # Create the wrapper function post-call block... @@ -524,11 +520,6 @@ # value of the C++ function call. If the value exists it is extracted # from the Python result tuple, converted to C++ and returned from # the virtual function. If it does not exist, do nothing. -# try: -# resultidx = sm.wrapper_func.result_exprs.index(sm.wrapper_func.result_var) -# except ValueError: -# return - try: resexpr = sm.py_result_expr(self.result_var) except ValueError: @@ -536,45 +527,6 @@ res = "// Extract the C++ return value\n" res += "%s = boost::python::extract<%s>(%s);"%(self.result_var, sm.virtual_func.ret_type, resexpr) -# res += "%s = boost::python::extract<%s>(%s[%d]);"%(self.result_var, sm.virtual_func.ret_type, sm.virtual_func.result_var, resultidx) return res -###################################################################### -if __name__=="__main__": - import pyplusplus - from pygccxml import parser - from transformers import Output - cpp = """ - class Spam - { - public: - int foo(int& w, int* h, int mode=0); - }; - """ - parser = parser.project_reader_t(parser.config.config_t(), - decl_factory=pyplusplus.decl_wrappers.dwfactory_t()) - root = parser.read_string(cpp) - spam = root[0].class_("Spam") - foo = spam.member_function("foo") - - wm = substitution_manager_t(foo, transformers=[Output(1), Output(2)], wrapper_class="Spam_wrapper") - - template = '''$RET_TYPE $CLASS_SPEC$FUNC_NAME($ARG_LIST) -{ - $DECLARATIONS - - $PRE_CALL - - $RESULT_VAR_ASSIGNMENT$CALL_FUNC_NAME($INPUT_PARAMS); - - $POST_CALL - - $RETURN_STMT -} -''' - print wm.subst_virtual(template) - print wm.subst_wrapper(template) - print wm.get_includes() - print wm.get_includes("virtual") - print wm.get_includes("wrapper") \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/function_transformers/transformer.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-09 21:20:11 UTC (rev 703) +++ pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-09 21:21:32 UTC (rev 704) @@ -105,3 +105,5 @@ def virtual_cleanup(self, sm): pass + + \ No newline at end of file Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-09 21:20:11 UTC (rev 703) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-09 21:21:32 UTC (rev 704) @@ -205,8 +205,6 @@ self.argname = None self.basetype = None self.carray = None - self.wrapper_ivar = None - self.virtual_ivar = None self.pylist = None def __str__(self): @@ -234,10 +232,6 @@ # Declare a variable that will hold the C array... self.carray = sm.wrapper_func.declare_local("c_"+arg.name, self.basetype, size=self.size) - # and an int which is used for the loop - self.wrapper_ivar = sm.wrapper_func.declare_local("i", "int", default=0) - # and another one in the virtual function - self.virtual_ivar = sm.virtual_func.declare_local("i", "int", default=0) # Replace the input parameter with the C array sm.wrapper_func.input_params[self.idx-1] = self.carray @@ -249,26 +243,25 @@ """Wrapper function code. """ tmpl = [] - tmpl.append( 'pyplusplus::convenience::ensure_uniform_sequence< %(type)s >( %(argname)s, %(size)d );' ) - tmpl.append( 'for(%(ivar)s=0; %(ivar)s<%(size)d; ++%(ivar)s){' ) - tmpl.append( ' %(array_name)s[ %(ivar)s ] = boost::python::extract< %(type)s >( %(argname)s[%(ivar)s] );' ) - tmpl.append( '}' ) + tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(argname)s, %(size)d );' ) + tmpl.append( '%(pypp_con)s::copy_sequence( %(argname)s, %(pypp_con)s::array_inserter( %(array_name)s, %(size)d ) );' ) return os.linesep.join( tmpl ) % { 'type' : self.basetype + , 'pypp_con' : 'pyplusplus::convenience' , 'argname' : self.argname , 'size' : self.size - , 'ivar' : self.wrapper_ivar , 'array_name' : self.carray } def virtual_pre_call(self, sm): - """Virtual function code. - """ - res = "" - res += "// Copy the array '%s' into list '%s'...\n"%(self.argname, self.pylist) - res += "for(%s=0; %s<%d; %s++)\n"%(self.virtual_ivar, self.virtual_ivar, self.size, self.virtual_ivar) - res += " %s.append(%s[%s]);"%(self.pylist, self.argname, self.virtual_ivar) - return res + """Virtual function code.""" + tmpl = '%(pypp_con)s::copy_container( %(array)s, %(array)s + %(size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' + return tmpl % { + 'pypp_con' : 'pyplusplus::convenience' + , 'array' : self.argname + , 'size' : self.size + , 'pylist' : self.pylist + } # output_array_t @@ -323,9 +316,6 @@ # ...and add it to the result sm.wrapper_func.result_exprs.append(arg.name) - # Declare an int which is used for the loop - self.wrapper_ivar = sm.wrapper_func.declare_local("i", "int", default=0) - sm.wrapper_func.input_params[self.idx-1] = self.wrapper_cval # Virtual: @@ -333,31 +323,28 @@ # Declare a variable that will receive the Python list self.virtual_pyval = sm.virtual_func.declare_local("py_"+self.argname, "boost::python::object") - # Declare an int which is used for the loop - self.virtual_ivar = sm.virtual_func.declare_local("i", "int", default=0) - # Request the convenience header sm.virtual_func.require_header(code_repository.convenience.file_name) def wrapper_post_call(self, sm): - res = "" - res += "// Copy the sequence '%s' into '%s'...\n"%(self.wrapper_cval, self.wrapper_pyval) - res += "for(%s=0; %s<%d; %s++)\n"%(self.wrapper_ivar, self.wrapper_ivar, self.size, self.wrapper_ivar) - res += " %s.append(%s[%s]);"%(self.wrapper_pyval, self.wrapper_cval , self.wrapper_ivar) - return res + tmpl = '%(pypp_con)s::copy_container( %(array)s, %(array)s + %(size)d, %(pypp_con)s::list_inserter( %(pylist)s ) );' + return tmpl % { + 'pypp_con' : 'pyplusplus::convenience' + , 'array' : self.wrapper_cval + , 'size' : self.size + , 'pylist' : self.wrapper_pyval + } def virtual_post_call(self, sm): tmpl = [] - tmpl.append( 'pyplusplus::convenience::ensure_uniform_sequence< %(type)s >( %(argname)s, %(size)d );' ) - tmpl.append( 'for(%(ivar)s=0; %(ivar)s<%(size)d; ++%(ivar)s){' ) - tmpl.append( ' %(array_name)s[ %(ivar)s ] = boost::python::extract< %(type)s >( %(argname)s[%(ivar)s] );' ) - tmpl.append( '}' ) + tmpl.append( '%(pypp_con)s::ensure_uniform_sequence< %(type)s >( %(argname)s, %(size)d );' ) + tmpl.append( '%(pypp_con)s::copy_sequence( %(argname)s, %(pypp_con)s::array_inserter( %(array_name)s, %(size)d ) );' ) return os.linesep.join( tmpl ) % { 'type' : self.basetype + , 'pypp_con' : 'pyplusplus::convenience' , 'argname' : sm.py_result_expr(self.argname) , 'size' : self.size - , 'ivar' : self.virtual_ivar , 'array_name' : self.argname } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:54:11
|
Revision: 703 http://svn.sourceforge.net/pygccxml/?rev=703&view=rev Author: roman_yakovenko Date: 2006-11-09 13:20:11 -0800 (Thu, 09 Nov 2006) Log Message: ----------- adding few classes and functions for array <=> list copy Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/convenience.py Modified: pyplusplus_dev/pyplusplus/code_repository/convenience.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/convenience.py 2006-11-09 11:40:41 UTC (rev 702) +++ pyplusplus_dev/pyplusplus/code_repository/convenience.py 2006-11-09 21:20:11 UTC (rev 703) @@ -78,6 +78,63 @@ } } +template< class Iterator, class Inserter > +void copy_container( Iterator begin, Iterator end, Inserter inserter ){ + for( Iterator index = begin; index != end; ++index ) + inserter( *index ); +} + +template< class Inserter > +void copy_sequence( boost::python::object const& seq, Inserter inserter ){ + index_type length = boost::python::len( seq ); + for( index_type index = 0; index < length; ++index ){ + inserter( seq[index] ); + } +} + +struct list_inserter{ + list_inserter( boost::python::list& py_list ) + : m_py_list( py_list ) + {} + + template< class T > + void operator()( T const & value ){ + m_py_list.append( value ); + } +private: + boost::python::list& m_py_list; +}; + +template < class T > +struct array_inserter_t{ + array_inserter_t( T* array, index_type size ) + : m_array( array ) + , m_curr_pos( 0 ) + , m_size( size ) + {} + + void operator()( boost::python::object const & item ){ + if( m_size <= m_curr_pos ){ + std::stringstream err; + err << "Index out of range. Array size is" << m_size << ", " + << "current position is" << m_curr_pos << "."; + raise_error( PyExc_ValueError, err.str().c_str() ); + } + m_array[ m_curr_pos ] = boost::python::extract< T >( item ); + m_curr_pos += 1; + } + +private: + T* m_array; + index_type m_curr_pos; + const index_type m_size; +}; + +template< class T> +array_inserter_t<T> array_inserter( T* array, index_type size ){ + return array_inserter_t<T>( array, size ); +} + } /*pyplusplus*/ } /*convenience*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:46:25
|
Revision: 725 http://svn.sourceforge.net/pygccxml/?rev=725&view=rev Author: roman_yakovenko Date: 2006-11-13 11:23:28 -0800 (Mon, 13 Nov 2006) Log Message: ----------- integrating return_pointee_value call policies - unit tests Modified Paths: -------------- pyplusplus_dev/unittests/call_policies_tester.py pyplusplus_dev/unittests/data/call_policies_to_be_exported.cpp pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp Modified: pyplusplus_dev/unittests/call_policies_tester.py =================================================================== --- pyplusplus_dev/unittests/call_policies_tester.py 2006-11-13 19:00:19 UTC (rev 724) +++ pyplusplus_dev/unittests/call_policies_tester.py 2006-11-13 19:23:28 UTC (rev 725) @@ -29,6 +29,12 @@ mb.calldef( 'get_opaque' ).call_policies \ = call_policies.return_value_policy( call_policies.return_opaque_pointer ) + mb.calldef( 'get_fundamental_ptr_value' ).call_policies \ + = call_policies.return_value_policy( call_policies.return_pointee_value ) + + mb.calldef( 'get_fundamental_ptr_value_null' ).call_policies \ + = call_policies.return_value_policy( call_policies.return_pointee_value ) + def run_tests(self, module): self.failUnless( module.compare( module.my_address() ) ) @@ -45,6 +51,10 @@ cont = module.container() self.failUnless( 1977 == cont[1977] ) + self.failUnless( 0.5 == module.get_fundamental_ptr_value() ) + + self.failUnless( None is module.get_fundamental_ptr_value_null() ) + module.get_impl_details() module.get_opaque() Modified: pyplusplus_dev/unittests/data/call_policies_to_be_exported.cpp =================================================================== --- pyplusplus_dev/unittests/data/call_policies_to_be_exported.cpp 2006-11-13 19:00:19 UTC (rev 724) +++ pyplusplus_dev/unittests/data/call_policies_to_be_exported.cpp 2006-11-13 19:23:28 UTC (rev 725) @@ -1,5 +1,4 @@ -// 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) - +// 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) Modified: pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp 2006-11-13 19:00:19 UTC (rev 724) +++ pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp 2006-11-13 19:23:28 UTC (rev 725) @@ -61,6 +61,20 @@ } +namespace fundamental_ptr{ + +inline float* get_fundamental_ptr_value(){ + static float x = 0.5; + return &x; } +inline float* get_fundamental_ptr_value_null(){ + return (float*)(0); +} + + +} + +} + #endif//__call_policies_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...> - 2006-11-13 19:40:36
|
Revision: 697 http://svn.sourceforge.net/pygccxml/?rev=697&view=rev Author: roman_yakovenko Date: 2006-11-08 02:08:43 -0800 (Wed, 08 Nov 2006) Log Message: ----------- adding small convenient method, that returns all argument types Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/calldef.py Modified: pygccxml_dev/pygccxml/declarations/calldef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/calldef.py 2006-11-07 18:16:09 UTC (rev 696) +++ pygccxml_dev/pygccxml/declarations/calldef.py 2006-11-08 10:08:43 UTC (rev 697) @@ -136,6 +136,11 @@ @type: list of L{argument_t}""") @property + def argument_types( self ): + """list of all argument types""" + return [ arg.type for arg in self.arguments ] + + @property def required_args(self): """list of all required arguments""" r_args = [] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:40:19
|
Revision: 699 http://svn.sourceforge.net/pygccxml/?rev=699&view=rev Author: roman_yakovenko Date: 2006-11-08 10:47:53 -0800 (Wed, 08 Nov 2006) Log Message: ----------- adding fix for signed char, char bug Modified Paths: -------------- pygccxml_dev/docs/history/history.rest Modified: pygccxml_dev/docs/history/history.rest =================================================================== --- pygccxml_dev/docs/history/history.rest 2006-11-08 10:19:28 UTC (rev 698) +++ pygccxml_dev/docs/history/history.rest 2006-11-08 18:47:53 UTC (rev 699) @@ -17,7 +17,16 @@ * Georgiy Dernovoy * Darren Garnier * Gottfried Ganssauge + * Gaetan Lehmann + +------------- +Version 0.8.* +------------- +1. ``signed char`` and ``char`` are two different types. This bug was fixed and + now `pygccxml`_ treats them right. Many thanks to Gaetan Lehmann for reporting + the bug. + ------------- Version 0.8.2 ------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:40:17
|
Revision: 702 http://svn.sourceforge.net/pygccxml/?rev=702&view=rev Author: roman_yakovenko Date: 2006-11-09 03:40:41 -0800 (Thu, 09 Nov 2006) Log Message: ----------- adding new call policy - temporal Added Paths: ----------- pyplusplus_dev/pyplusplus/code_repository/return_pointee_value.hpp Added: pyplusplus_dev/pyplusplus/code_repository/return_pointee_value.hpp =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/return_pointee_value.hpp (rev 0) +++ pyplusplus_dev/pyplusplus/code_repository/return_pointee_value.hpp 2006-11-09 11:40:41 UTC (rev 702) @@ -0,0 +1,60 @@ +// 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 RETURN_POINTEE_VALUE_9_11_2006 +#define RETURN_POINTEE_VALUE_9_11_2006 + +#include <boost/python.hpp> + +namespace boost{ namespace python{ + +namespace detail{ + + struct make_value_holder + { + template <class T> + static PyObject* execute(T* p) + { + if (p == 0) + { + return python::detail::none(); + } + else + { + object p_value( *p ); + return incref( p_value.ptr() ); + } + } + }; + + template <class R> + struct return_pointee_value_requires_a_pointer_return_type + # if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} + # endif + ; + +} //detail + + +struct return_pointee_value +{ + template <class T> + struct apply + { + BOOST_STATIC_CONSTANT( bool, ok = is_pointer<T>::value ); + + typedef typename mpl::if_c< + ok + , to_python_indirect<T, detail::make_value_holder> + , detail::return_pointee_value_requires_a_pointer_return_type<T> + >::type type; + }; +}; + + +} } //boost::python + +#endif//RETURN_POINTEE_VALUE_9_11_2006 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:39:56
|
Revision: 709 http://svn.sourceforge.net/pygccxml/?rev=709&view=rev Author: roman_yakovenko Date: 2006-11-11 11:01:31 -0800 (Sat, 11 Nov 2006) Log Message: ----------- adding new function to the interface, derived classes implementation will come soon Modified Paths: -------------- pyplusplus_dev/pyplusplus/function_transformers/transformer.py Modified: pyplusplus_dev/pyplusplus/function_transformers/transformer.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-11 18:59:16 UTC (rev 708) +++ pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-11-11 19:01:31 UTC (rev 709) @@ -32,6 +32,10 @@ """Returns list of header files that transformer generated code depends on.""" return [] + def validate( self, function ): + """returns error message or None""" + raise NotImplementedError() + def init_funcs(self, sm): """Wrapper initialization. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:39:10
|
Revision: 710 http://svn.sourceforge.net/pygccxml/?rev=710&view=rev Author: roman_yakovenko Date: 2006-11-11 11:04:40 -0800 (Sat, 11 Nov 2006) Log Message: ----------- fixing the implementation to use type_traits functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/function_transformers/transformers.py Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-11 19:01:31 UTC (rev 709) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-11-11 19:04:40 UTC (rev 710) @@ -52,8 +52,7 @@ # Do some sanity checking (whether the argument can actually be # an output argument, i.e. it has to be a reference or a pointer) reftype = arg.type - if not (isinstance(reftype, declarations.reference_t) or - isinstance(reftype, declarations.pointer_t)): + if not declarations.is_pointer( reftype ) and not declarations.is_reference( reftype ): raise ValueError, '%s\nOutput variable %d ("%s") must be a reference or a pointer (got %s)'%(sm.decl, self.idx, arg.name, arg.type) # Declare a local variable that will receive the output value @@ -107,8 +106,7 @@ # Do some checks (the arg has to be a reference or a pointer) reftype = arg.type - if not (isinstance(reftype, declarations.reference_t) or - isinstance(reftype, declarations.pointer_t)): + if not declarations.is_pointer( reftype ) and not declarations.is_reference( reftype ): raise ValueError, '%s\nInput variable %d ("%s") must be a reference or a pointer (got %s)'%(sm.decl, self.idx, arg.name, arg.type) # Create an equivalent argument that is not a reference type @@ -144,8 +142,7 @@ # Do some checks (the arg has to be a reference or a pointer) reftype = arg.type - if not (isinstance(reftype, declarations.reference_t) or - isinstance(reftype, declarations.pointer_t)): + if not declarations.is_pointer( reftype ) and not declarations.is_reference( reftype ): raise ValueError, '%s\nInOut variable %d ("%s") must be a reference or a pointer (got %s)'%(sm.decl, self.idx, arg.name, arg.type) # Create an equivalent argument that is not a reference type @@ -214,8 +211,7 @@ # Remove the original argument... arg = sm.remove_arg(self.idx) - if not (isinstance(arg.type, declarations.pointer_t) or - isinstance(arg.type, declarations.array_t)): + if not declarations.is_pointer( arg.type ) and not declarations.is_array( arg.type ): raise ValueError, "%s\nArgument %d (%s) must be a pointer."%(sm.decl, self.idx, arg.name) # Declare a variable that will hold the Python list @@ -297,8 +293,7 @@ # Remove the original argument... arg = sm.remove_arg(self.idx) - if not (isinstance(arg.type, declarations.pointer_t) or - isinstance(arg.type, declarations.array_t)): + if not declarations.is_pointer( arg.type ) and not declarations.is_array( arg.type ): raise ValueError, "%s\nArgument %d (%s) must be a pointer."%(sm.decl, self.idx, arg.name) self.argname = arg.name This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2006-11-13 19:37:58
|
Revision: 712 http://svn.sourceforge.net/pygccxml/?rev=712&view=rev Author: roman_yakovenko Date: 2006-11-11 22:38:55 -0800 (Sat, 11 Nov 2006) Log Message: ----------- adding test case for inner class bug Modified Paths: -------------- pyplusplus_dev/unittests/test_all.py Added Paths: ----------- pyplusplus_dev/unittests/data/inner_class_bug_to_be_exported.hpp pyplusplus_dev/unittests/inner_class_bug_tester.py Added: pyplusplus_dev/unittests/data/inner_class_bug_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/inner_class_bug_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/inner_class_bug_to_be_exported.hpp 2006-11-12 06:38:55 UTC (rev 712) @@ -0,0 +1,27 @@ +// 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 __inner_class_bug_to_be_exported_hpp__ +#define __inner_class_bug_to_be_exported_hpp__ + +namespace inner_classes { + +struct main_t{ + + void main_method(){} + virtual void main_method2(){} + virtual void main_method3() = 0; + + struct inner_t{ + inner_t( int ){} + void inner_method(){} + virtual void inner_method2(){} + virtual void inner_method3() = 0; + }; +}; + +} + +#endif//__inner_class_bug_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/inner_class_bug_tester.py =================================================================== --- pyplusplus_dev/unittests/inner_class_bug_tester.py (rev 0) +++ pyplusplus_dev/unittests/inner_class_bug_tester.py 2006-11-12 06:38:55 UTC (rev 712) @@ -0,0 +1,34 @@ +# Copyright 2004 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import sys +import unittest +import fundamental_tester_base + + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'inner_class_bug' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def run_tests( self, module): + main = module.main_t() + inner = module.main_t.inner_t( 12 ) + +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() Modified: pyplusplus_dev/unittests/test_all.py =================================================================== --- pyplusplus_dev/unittests/test_all.py 2006-11-11 19:12:12 UTC (rev 711) +++ pyplusplus_dev/unittests/test_all.py 2006-11-12 06:38:55 UTC (rev 712) @@ -65,6 +65,7 @@ import properties_tester import arrays_bug_tester import convenience_tester +import inner_class_bug_tester def create_suite(times): testers = [ @@ -126,6 +127,7 @@ , properties_tester , arrays_bug_tester , convenience_tester + , inner_class_bug_tester ] main_suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |