[pygccxml-commit] SF.net SVN: pygccxml:[1378] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
|
From: <rom...@us...> - 2008-07-23 20:40:51
|
Revision: 1378
http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1378&view=rev
Author: roman_yakovenko
Date: 2008-07-23 20:40:56 +0000 (Wed, 23 Jul 2008)
Log Message:
-----------
adding from_address function transformation
Modified Paths:
--------------
pyplusplus_dev/pyplusplus/function_transformers/__init__.py
pyplusplus_dev/pyplusplus/function_transformers/transformers.py
Added Paths:
-----------
pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp
pyplusplus_dev/unittests/ft_from_address_tester.py
Modified: pyplusplus_dev/pyplusplus/function_transformers/__init__.py
===================================================================
--- pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2008-07-23 19:17:20 UTC (rev 1377)
+++ pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2008-07-23 20:40:56 UTC (rev 1378)
@@ -59,3 +59,10 @@
def creator( function ):
return transformers.transfer_ownership_t( function, *args, **keywd )
return creator
+
+def from_address( *args, **keywd ):
+ def creator( function ):
+ return transformers.from_address_t( function, *args, **keywd )
+ return creator
+
+
Modified: pyplusplus_dev/pyplusplus/function_transformers/transformers.py
===================================================================
--- pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2008-07-23 19:17:20 UTC (rev 1377)
+++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2008-07-23 20:40:56 UTC (rev 1378)
@@ -38,8 +38,8 @@
return declarations.remove_reference( type_ )
else:
raise TypeError( 'Type should be reference or pointer, got %s.' % type_ )
-
+
# output_t
class output_t( transformer.transformer_t ):
"""Handles a single output variable.
@@ -61,7 +61,7 @@
"""
self.arg = self.get_argument( arg_ref )
self.arg_index = self.function.arguments.index( self.arg )
-
+
if not is_ref_or_ptr( self.arg.type ):
raise ValueError( '%s\nin order to use "output" transformation, argument %s type must be a reference or a pointer (got %s).' ) \
% ( function, self.arg_ref.name, arg.type)
@@ -79,13 +79,13 @@
#declaring new variable, which will keep result
var_name = controller.declare_variable( remove_ref_or_ptr( self.arg.type ), self.arg.name )
#adding just declared variable to the original function call expression
- controller.modify_arg_expression( self.arg_index, var_name )
+ controller.modify_arg_expression( self.arg_index, var_name )
#adding the variable to return variables list
controller.return_variable( var_name )
def __configure_v_mem_fun_default( self, controller ):
self.__configure_sealed( controller )
-
+
def __configure_v_mem_fun_override( self, controller ):
controller.remove_py_arg( self.arg_index )
tmpl = string.Template(
@@ -97,10 +97,10 @@
def configure_mem_fun( self, controller ):
self.__configure_sealed( controller )
-
+
def configure_free_fun(self, controller ):
self.__configure_sealed( controller )
-
+
def configure_virtual_mem_fun( self, controller ):
self.__configure_v_mem_fun_default( controller.default_controller )
self.__configure_v_mem_fun_override( controller.override_controller )
@@ -108,14 +108,14 @@
# input_t
class type_modifier_t(transformer.transformer_t):
"""Change/modify type of the argument.
-
+
Right now compiler should be able to use implicit conversion
"""
def __init__(self, function, arg_ref, modifier):
"""Constructor.
- modifier is callable, which take the type of the argument and should return
+ modifier is callable, which take the type of the argument and should return
new type
"""
transformer.transformer_t.__init__( self, function )
@@ -132,23 +132,23 @@
if not declarations.is_convertible( w_arg.type, self.arg.type ):
casting_code = 'reinterpret_cast< %s >( %s )' % ( self.arg.type, w_arg.name )
controller.modify_arg_expression(self.arg_index, casting_code)
-
+
def __configure_v_mem_fun_default( self, controller ):
self.__configure_sealed( controller )
def configure_mem_fun( self, controller ):
self.__configure_sealed( controller )
-
+
def configure_free_fun(self, controller ):
self.__configure_sealed( controller )
def configure_virtual_mem_fun( self, controller ):
- self.__configure_v_mem_fun_default( controller.default_controller )
+ self.__configure_v_mem_fun_default( controller.default_controller )
def required_headers( self ):
"""Returns list of header files that transformer generated code depends on."""
return []
-
+
# input_t
class input_t(type_modifier_t):
"""Handles a single input variable.
@@ -175,6 +175,35 @@
def __str__(self):
return "input(%s)"%(self.arg.name)
+# input_t
+class from_address_t(type_modifier_t):
+ """Handles a single input variable.
+
+ Replaces the actual argument type with some integral type, so you
+ can use ctypes package.
+
+ void do_smth(int** image) -> do_smth(unsigned int addressof_image)
+
+ """
+
+ def __init__(self, function, arg_ref):
+ """Constructor.
+
+ The specified argument must be a reference or a pointer.
+
+ @param idx: Index of the argument that is an output value (the first arg has index 1).
+ @type idx: int
+ """
+ modifier = lambda type_: declarations.FUNDAMENTAL_TYPES[ 'unsigned int' ]
+ type_modifier_t.__init__( self, function, arg_ref, modifier )
+
+ if not is_ptr_or_array( self.arg.type ):
+ raise ValueError( '%s\nin order to use "from_address_t" transformation, argument %s type must be a pointer or a array (got %s).' ) \
+ % ( function, self.arg_ref.name, arg.type)
+
+ def __str__(self):
+ return "from_address(%s)"%(self.arg.name)
+
# inout_t
class inout_t(transformer.transformer_t):
"""Handles a single input/output variable.
@@ -193,7 +222,7 @@
transformer.transformer_t.__init__( self, function )
self.arg = self.get_argument( arg_ref )
self.arg_index = self.function.arguments.index( self.arg )
-
+
if not is_ref_or_ptr( self.arg.type ):
raise ValueError( '%s\nin order to use "inout" transformation, argument %s type must be a reference or a pointer (got %s).' ) \
% ( function, self.arg_ref.name, arg.type)
@@ -206,10 +235,10 @@
w_arg.type = remove_ref_or_ptr( self.arg.type )
#adding the variable to return variables list
controller.return_variable( w_arg.name )
-
+
def __configure_v_mem_fun_default( self, controller ):
self.__configure_sealed( controller )
-
+
def __configure_v_mem_fun_override( self, controller ):
tmpl = string.Template(
'$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' )
@@ -220,7 +249,7 @@
def configure_mem_fun( self, controller ):
self.__configure_sealed( controller )
-
+
def configure_free_fun(self, controller ):
self.__configure_sealed( controller )
@@ -241,7 +270,7 @@
'pyplus_conv::ensure_uniform_sequence< $type >( $pylist );'
, 'pyplus_conv::copy_sequence( $pylist, std::back_inserter( $native_array), boost::type< $type >() );']))
-_arr2seq = string.Template(
+_arr2seq = string.Template(
'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' )
class input_static_array_t(transformer.transformer_t):
@@ -258,10 +287,10 @@
@type size: int
"""
transformer.transformer_t.__init__( self, function )
-
+
self.arg = self.get_argument( arg_ref )
self.arg_index = self.function.arguments.index( self.arg )
-
+
if not is_ptr_or_array( self.arg.type ):
raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \
% ( function, self.arg.name, self.arg.type)
@@ -285,41 +314,41 @@
native_array = controller.declare_variable( self.array_item_type
, "native_" + self.arg.name
, '[%d]' % self.array_size )
-
+
copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type
, pylist=w_arg.name
, array_size=self.array_size
, native_array=native_array )
-
+
controller.add_pre_call_code( copy_pylist2arr )
-
- controller.modify_arg_expression( self.arg_index, native_array )
+ controller.modify_arg_expression( self.arg_index, native_array )
+
def __configure_v_mem_fun_default( self, controller ):
self.__configure_sealed( controller )
-
+
def __configure_v_mem_fun_override( self, controller ):
global _arr2seq
pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' )
, 'py_' + self.arg.name )
-
+
copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name
, array_size=self.array_size
, pylist=pylist )
-
+
controller.add_py_pre_call_code( copy_arr2pylist )
def configure_mem_fun( self, controller ):
self.__configure_sealed( controller )
-
+
def configure_free_fun(self, controller ):
self.__configure_sealed( controller )
def configure_virtual_mem_fun( self, controller ):
self.__configure_v_mem_fun_override( controller.override_controller )
self.__configure_v_mem_fun_default( controller.default_controller )
-
+
# s - static
class output_static_array_t(transformer.transformer_t):
"""Handles an output array of a fixed size.
@@ -365,16 +394,16 @@
, '[%d]' % self.array_size )
#adding just declared variable to the original function call expression
- controller.modify_arg_expression( self.arg_index, native_array )
+ controller.modify_arg_expression( self.arg_index, native_array )
# Declare a Python list which will receive the output...
pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" )
, 'py_' + self.arg.name )
-
+
copy_arr2pylist = _arr2seq.substitute( native_array=native_array
, array_size=self.array_size
, pylist=pylist )
-
+
controller.add_post_call_code( copy_arr2pylist )
#adding the variable to return variables list
@@ -393,16 +422,16 @@
, py_result=controller.py_result_variable.name
, name=self.arg.name )
controller.add_py_post_call_code( get_ref_to_seq )
-
+
copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type
, pylist=seq
, array_size=self.array_size
, native_array=self.arg.name )
controller.add_py_post_call_code( copy_pylist2arr )
-
+
def configure_mem_fun( self, controller ):
self.__configure_sealed( controller )
-
+
def configure_free_fun(self, controller ):
self.__configure_sealed( controller )
@@ -420,11 +449,11 @@
def __init__(self, function, buffer_arg_ref, size_arg_ref):
"""Constructor.
- @param buffer_arg_ref: "reference" to the buffer argument
+ @param buffer_arg_ref: "reference" to the buffer argument
@param buffer_arg_ref: "reference" to argument, which holds buffer size
"""
transformer.transformer_t.__init__( self, function )
-
+
self.buffer_arg = self.get_argument( buffer_arg_ref )
self.buffer_arg_index = self.function.arguments.index( self.buffer_arg )
@@ -453,56 +482,56 @@
global _seq2arr
w_buffer_arg = controller.find_wrapper_arg( self.buffer_arg.name )
w_buffer_arg.type = declarations.dummy_type_t( "boost::python::object" )
-
+
controller.remove_wrapper_arg( self.size_arg.name )
- size_var = controller.declare_variable(
+ size_var = controller.declare_variable(
declarations.remove_const( self.size_arg.type )
, self.size_arg.name
, ' = boost::python::len(%s)' % w_buffer_arg.name )
-
+
# Declare a variable that will hold the C array...
- buffer_var = controller.declare_variable(
+ buffer_var = controller.declare_variable(
declarations.dummy_type_t( "std::vector< %s >" % self.buffer_item_type.decl_string )
, "native_" + self.buffer_arg.name )
controller.add_pre_call_code( '%s.reserve( %s );' % ( buffer_var, size_var ) )
-
+
copy_pylist2arr = _seq2vector.substitute( type=self.buffer_item_type
, pylist=w_buffer_arg.name
, native_array=buffer_var )
-
+
controller.add_pre_call_code( copy_pylist2arr )
-
- controller.modify_arg_expression( self.buffer_arg_index, '&%s[0]' % buffer_var )
- controller.modify_arg_expression( self.size_arg_index, '%s' % size_var )
+ controller.modify_arg_expression( self.buffer_arg_index, '&%s[0]' % buffer_var )
+ controller.modify_arg_expression( self.size_arg_index, '%s' % size_var )
+
def __configure_v_mem_fun_default( self, controller ):
self.__configure_sealed( controller )
-
+
def __configure_v_mem_fun_override( self, controller ):
raise NotImplementedError()
#global _arr2seq
#pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' )
#, 'py_' + self.arg.name )
-
+
#copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name
#, array_size=self.array_size
#, pylist=pylist )
-
+
#controller.add_py_pre_call_code( copy_arr2pylist )
def configure_mem_fun( self, controller ):
self.__configure_sealed( controller )
-
+
def configure_free_fun(self, controller ):
self.__configure_sealed( controller )
def configure_virtual_mem_fun( self, controller ):
self.__configure_v_mem_fun_override( controller.override_controller )
self.__configure_v_mem_fun_default( controller.default_controller )
-
+
class transfer_ownership_t(type_modifier_t):
"""see http://boost.org/libs/python/doc/v2/faq.html#ownership
"""
@@ -524,13 +553,13 @@
naked_type = declarations.remove_declarated( naked_type )
w_arg.type = declarations.dummy_type_t( 'std::auto_ptr< %s >' % naked_type.decl_string )
controller.modify_arg_expression(self.arg_index, w_arg.name + '.release()' )
-
+
def __configure_v_mem_fun_default( self, controller ):
self.__configure_sealed( controller )
def configure_mem_fun( self, controller ):
self.__configure_sealed( controller )
-
+
def configure_free_fun(self, controller ):
self.__configure_sealed( controller )
@@ -540,7 +569,7 @@
#TODO: FT for constructor
#~ def configure_constructor( self, controller ):
#~ self.__configure_sealed( controller )
-
+
def required_headers( self ):
"""Returns list of header files that transformer generated code depends on."""
return []
Added: pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp
===================================================================
--- pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp (rev 0)
+++ pyplusplus_dev/unittests/data/ft_from_address_to_be_exported.hpp 2008-07-23 20:40:56 UTC (rev 1378)
@@ -0,0 +1,25 @@
+// Copyright 2004 Roman Yakovenko.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef __ft_from_address_to_be_exported_hpp__
+#define __ft_from_address_to_be_exported_hpp__
+
+#include <stdexcept>
+
+inline unsigned long
+sum_matrix( unsigned int** matrix, unsigned int rows, unsigned int columns ){
+ if( !matrix ){
+ throw std::runtime_error( "matrix is null" );
+ }
+ unsigned long result = 0;
+ for( unsigned int r = 0; r < rows; ++r ){
+ for( unsigned int c = 0; c < columns; ++c ){
+ result += matrix[r][c];
+ }
+ }
+ return result;
+}
+
+#endif//__ft_from_address_to_be_exported_hpp__
Added: pyplusplus_dev/unittests/ft_from_address_tester.py
===================================================================
--- pyplusplus_dev/unittests/ft_from_address_tester.py (rev 0)
+++ pyplusplus_dev/unittests/ft_from_address_tester.py 2008-07-23 20:40:56 UTC (rev 1378)
@@ -0,0 +1,58 @@
+# Copyright 2004 Roman Yakovenko.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import os
+import sys
+import math
+import ctypes
+import unittest
+import fundamental_tester_base
+from pygccxml import declarations
+from pyplusplus import function_transformers as ft
+from pyplusplus.module_builder import call_policies
+
+
+class tester_t(fundamental_tester_base.fundamental_tester_base_t):
+ EXTENSION_NAME = 'ft_from_address'
+
+ def __init__( self, *args ):
+ fundamental_tester_base.fundamental_tester_base_t.__init__(
+ self
+ , tester_t.EXTENSION_NAME
+ , *args )
+
+ def customize( self, mb ):
+
+ mb.global_ns.calldefs().create_with_signature = True
+ mb.calldef( 'sum_matrix' ).add_transformation( ft.from_address(0) )
+
+ def run_tests(self, module):
+ rows = 1
+ columns = 1
+ matrix_type = ctypes.c_uint * columns * rows
+ print matrix_type
+ sum = 0
+ counter = 0
+ matrix = matrix_type()
+ for r in range( rows ):
+ for c in range( columns ):
+ matrix[r][c] = counter
+ sum += counter
+ counter += 1
+ print 'matrix filled'
+ result = module.sum_matrix( ctypes.addressof( matrix ), rows, columns )
+ print 'result: ', result
+ print 'sum : ', sum
+
+def create_suite():
+ suite = unittest.TestSuite()
+ suite.addTest( unittest.makeSuite(tester_t))
+ return suite
+
+def run_suite():
+ unittest.TextTestRunner(verbosity=2).run( create_suite() )
+
+if __name__ == "__main__":
+ run_suite()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|