[pygccxml-commit] SF.net SVN: pygccxml: [683] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-10-24 19:11:20
|
Revision: 683 http://svn.sourceforge.net/pygccxml/?rev=683&view=rev Author: roman_yakovenko Date: 2006-10-24 12:10:52 -0700 (Tue, 24 Oct 2006) Log Message: ----------- renaming function_transformation.py => transformer.py function_transformer_t => transformer_t arg_policies.py => transformers.py Modified Paths: -------------- pyplusplus_dev/contrib/pypp_api/pypp_api/__init__.py pyplusplus_dev/pyplusplus/function_transformers/__init__.py pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py pyplusplus_dev/unittests/function_transformations_tester.py Added Paths: ----------- pyplusplus_dev/pyplusplus/function_transformers/transformer.py pyplusplus_dev/pyplusplus/function_transformers/transformers.py Removed Paths: ------------- pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py pyplusplus_dev/pyplusplus/function_transformers/function_transformer.py Modified: pyplusplus_dev/contrib/pypp_api/pypp_api/__init__.py =================================================================== --- pyplusplus_dev/contrib/pypp_api/pypp_api/__init__.py 2006-10-24 12:10:40 UTC (rev 682) +++ pyplusplus_dev/contrib/pypp_api/pypp_api/__init__.py 2006-10-24 19:10:52 UTC (rev 683) @@ -69,11 +69,11 @@ from decltypes import * #from argpolicy import * -from pyplusplus.function_transformers.arg_policies import output_t as Output -from pyplusplus.function_transformers.arg_policies import input_t as Input -from pyplusplus.function_transformers.arg_policies import inout_t as InOut -from pyplusplus.function_transformers.arg_policies import input_array_t as InputArray -from pyplusplus.function_transformers.arg_policies import output_array_t as OutputArray +from pyplusplus.function_transformers.transformers import output_t as Output +from pyplusplus.function_transformers.transformers import input_t as Input +from pyplusplus.function_transformers.transformers import inout_t as InOut +from pyplusplus.function_transformers.transformers import input_array_t as InputArray +from pyplusplus.function_transformers.transformers import output_array_t as OutputArray from modulebuilder import ModuleBuilder Modified: pyplusplus_dev/pyplusplus/function_transformers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-10-24 12:10:40 UTC (rev 682) +++ pyplusplus_dev/pyplusplus/function_transformers/__init__.py 2006-10-24 19:10:52 UTC (rev 683) @@ -17,6 +17,5 @@ """ from substitution_manager import substitution_manager_t -from function_transformer import function_transformer_t - -import arg_policies +from transformer import transformer_t +import transformers \ No newline at end of file Deleted: pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py 2006-10-24 12:10:40 UTC (rev 682) +++ pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py 2006-10-24 19:10:52 UTC (rev 683) @@ -1,357 +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 standard argument policy objects. - -The following policies are available: - - - L{output_t} - - L{input_t} - - L{inout_t} - - L{input_array_t} - - L{output_array_t} -""" -import os -from pygccxml import declarations -from pyplusplus import code_repository - -# output_t -class output_t: - """Handles a single output variable. - - The specified variable is removed from the argument list and is turned - into a return value. - - void getValue(int& v) -> v = getValue() - """ - - def __init__(self, idx): - """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 - """ - self.idx = idx - self.local_var = "<not initialized>" - - def __str__(self): - return "Output(%d)"%(self.idx) - - def init_funcs(self, sm): - # Remove the specified output argument from the wrapper function - arg = sm.remove_arg(self.idx) - - # 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)): - 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)) - # 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 - - - 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 - - -# input_t -class input_t: - """Handles a single input variable. - - The reference on the specified variable is removed. - - void setValue(int& v) -> setValue(v) - """ - - def __init__(self, idx): - """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 - """ - self.idx = idx - - def __str__(self): - return "Input(%d)"%(self.idx) - - def init_funcs(self, sm): - # Remove the specified input argument from the wrapper function - arg = sm.remove_arg(self.idx) - - # 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)): - 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 - noref_arg = declarations.argument_t(name=arg.name, type=arg.type.base, default_value=arg.default_value) - # Insert the noref argument - sm.insert_arg(self.idx, noref_arg, arg.name) - -# inout_t -class inout_t: - """Handles a single input/output variable. - - void foo(int& v) -> v = foo(v) - """ - - def __init__(self, idx): - """Constructor. - - The specified argument must be a reference or a pointer. - - @param idx: Index of the argument that is an in/out value (the first arg has index 1). - @type idx: int - """ - self.idx = idx - self.local_var = "<not initialized>" - - def __str__(self): - return "InOut(%d)"%(self.idx) - - def init_funcs(self, sm): - # Remove the specified input argument from the wrapper function - arg = sm.remove_arg(self.idx) - - # 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)): - 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 - noref_arg = declarations.argument_t(name=arg.name, type=arg.type.base, default_value=arg.default_value) - # Insert the noref argument - sm.insert_arg(self.idx, noref_arg, arg.name) - - # Use the input arg to also store the output - self.local_var = noref_arg.name - # 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 - - - 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 in/out 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 - - - -# input_array_t -class input_array_t: - """Handles an input array with fixed size. - - void setVec3(double* v) -> setVec3(object v) - # v must be a sequence of 3 floats - - - TODO: Error handling (in the wrapper function)! - - """ - - def __init__(self, idx, size): - """Constructor. - - @param idx: Index of the argument that is an input array (the first arg has index 1). - @type idx: int - @param size: The fixed size of the input array - @type size: int - """ - self.idx = idx - self.size = size - - self.argname = None - self.basetype = None - self.carray = None - self.wrapper_ivar = None - self.virtual_ivar = None - self.pylist = None - - def __str__(self): - return "InputArray(%d,%d)"%(self.idx, self.size) - - def init_funcs(self, sm): - - # 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)): - 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 - # (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") - - # Replace the removed argument with a Python object. - newarg = declarations.argument_t(arg.name, declarations.dummy_type_t("boost::python::object")) - sm.insert_arg(self.idx, newarg, self.pylist) - - self.argname = arg.name - 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) - # 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 - - # Request the convenience header - sm.wrapper_func.require_header(code_repository.convenience.file_name) - - def wrapper_pre_call(self, sm): - """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( '}' ) - return os.linesep.join( tmpl ) % { - 'type' : self.basetype - , '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 - - -# output_array_t -class output_array_t: - """Handles an output array of a fixed size. - - void getVec3(double* v) -> v = getVec3() - # v will be a list with 3 floats - - TODO: Error handling (in the virtual function)! - - """ - - def __init__(self, idx, size): - """Constructor. - - @param idx: Index of the argument that is an output array (the first arg has index 1). - @type idx: int - @param size: The fixed size of the output array - @type size: int - """ - - self.idx = idx - self.size = size - - self.argname = None - self.basetype = None - self.pyval = None - self.cval = None - self.ivar = None - - def __str__(self): - return "OutputArray(%d,%d)"%(self.idx, self.size) - - def init_funcs(self, sm): - # 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)): - raise ValueError, "%s\nArgument %d (%s) must be a pointer."%(sm.decl, self.idx, arg.name) - - self.argname = arg.name - self.basetype = str(arg.type.base).replace("const", "").strip() - - # 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) - # Declare a Python list which will receive the output... - self.wrapper_pyval = sm.wrapper_func.declare_local(self.argname, "boost::python::list") - # ...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: - - # 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 - - 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( '}' ) - return os.linesep.join( tmpl ) % { - 'type' : self.basetype - , 'argname' : sm.py_result_expr(self.argname) - , 'size' : self.size - , 'ivar' : self.virtual_ivar - , 'array_name' : self.argname - } Deleted: pyplusplus_dev/pyplusplus/function_transformers/function_transformer.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/function_transformer.py 2006-10-24 12:10:40 UTC (rev 682) +++ pyplusplus_dev/pyplusplus/function_transformers/function_transformer.py 2006-10-24 19:10:52 UTC (rev 683) @@ -1,109 +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 class L{function_transformer_t}. -""" - -import sys, os.path, copy, re, types -from pygccxml import declarations, parser - - -# function_transformer_t -class function_transformer_t: - """Base class for a function transformer. - - This class specifies the interface that a user written transformer - has to implement. It doesn't contain any actual functionality so - a user doesn't have to derive from this class. Methods that are not - implemented are treated as if they would do nothing and return None. - - @author: Matthias Baas - """ - - def __init__(self): - """Constructor. - """ - pass - - def init_funcs(self, sm): - """Wrapper initialization. - - This method is called before the actual wrapper source code is - generated. This is the place where you can modify the signature - of the C++ wrapper function or allocate local variables. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - """ - pass - - def wrapper_pre_call(self, sm): - """Generate the C++ code that should be executed before the actual function call. - - The code from this method will be put into the wrapper function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def wrapper_post_call(self, sm): - """Generate the C++ code that should be executed after the actual function call. - - The code from this method will be put into the wrapper function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def wrapper_cleanup(self, sm): - """Generate code that should be executed in the case of an error. - - This method has to assume that the preCall code was executed but - the postCall code won't be executed because something went wrong. - - <not used yet> - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def virtual_pre_call(self, sm): - """Generate the C++ code that should be executed before the actual function call. - - The code from this method will be put into the virtual function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def virtual_post_call(self, sm): - """Generate the C++ code that should be executed after the actual function call. - - The code from this method will be put into the virtual function. - - @param sm: Substitution manager instance - @type sm: L{substitution_manager_t} - @return: C++ code or None - @rtype: str - """ - pass - - def virtual_cleanup(self, sm): - pass - Modified: pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-10-24 12:10:40 UTC (rev 682) +++ pyplusplus_dev/pyplusplus/function_transformers/substitution_manager.py 2006-10-24 19:10:52 UTC (rev 683) @@ -10,7 +10,7 @@ from pygccxml import declarations from code_manager import code_manager_t, wrapper_code_manager_t -from function_transformer import function_transformer_t +from transformer import transformer_t from pyplusplus import decl_wrappers # substitution_manager_t @@ -174,7 +174,7 @@ @param wrapper_class: The name of the class the generated function should belong to (or None if the generated function should be a free function) @type wrapper_class: str @param transformers: Function transformer objects - @type transformers: list of function_transformer_t + @type transformers: list of transformer_t """ # Code manager for the virtual function @@ -540,7 +540,7 @@ # return_virtual_result_t -class return_virtual_result_t(function_transformer_t): +class return_virtual_result_t(transformer_t): """Extract and return the result value of the virtual function. This is an internal code block object that is automatically appended @@ -548,7 +548,7 @@ """ def __init__(self): - function_transformer_t.__init__(self) + transformer_t.__init__(self) self.result_var = "<not initialized>" def __str__(self): @@ -591,7 +591,7 @@ if __name__=="__main__": import pyplusplus from pygccxml import parser - from arg_policies import Output + from transformers import Output cpp = """ class Spam { @@ -624,4 +624,4 @@ print wm.subst_wrapper(template) print wm.get_includes() print wm.get_includes("virtual") - print wm.get_includes("wrapper") + print wm.get_includes("wrapper") \ No newline at end of file Copied: pyplusplus_dev/pyplusplus/function_transformers/transformer.py (from rev 682, pyplusplus_dev/pyplusplus/function_transformers/function_transformer.py) =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformer.py (rev 0) +++ pyplusplus_dev/pyplusplus/function_transformers/transformer.py 2006-10-24 19:10:52 UTC (rev 683) @@ -0,0 +1,107 @@ +# 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 class L{transformer_t}. +""" + +import sys, os.path, copy, re, types +from pygccxml import declarations, parser + + +class transformer_t: + """Base class for a function transformer. + + This class specifies the interface that a user written transformer + has to implement. It doesn't contain any actual functionality so + a user doesn't have to derive from this class. Methods that are not + implemented are treated as if they would do nothing and return None. + + @author: Matthias Baas + """ + + def __init__(self): + """Constructor. + """ + pass + + def init_funcs(self, sm): + """Wrapper initialization. + + This method is called before the actual wrapper source code is + generated. This is the place where you can modify the signature + of the C++ wrapper function or allocate local variables. + + @param sm: Substitution manager instance + @type sm: L{substitution_manager_t} + """ + pass + + def wrapper_pre_call(self, sm): + """Generate the C++ code that should be executed before the actual function call. + + The code from this method will be put into the wrapper function. + + @param sm: Substitution manager instance + @type sm: L{substitution_manager_t} + @return: C++ code or None + @rtype: str + """ + pass + + def wrapper_post_call(self, sm): + """Generate the C++ code that should be executed after the actual function call. + + The code from this method will be put into the wrapper function. + + @param sm: Substitution manager instance + @type sm: L{substitution_manager_t} + @return: C++ code or None + @rtype: str + """ + pass + + def wrapper_cleanup(self, sm): + """Generate code that should be executed in the case of an error. + + This method has to assume that the preCall code was executed but + the postCall code won't be executed because something went wrong. + + <not used yet> + + @param sm: Substitution manager instance + @type sm: L{substitution_manager_t} + @return: C++ code or None + @rtype: str + """ + pass + + def virtual_pre_call(self, sm): + """Generate the C++ code that should be executed before the actual function call. + + The code from this method will be put into the virtual function. + + @param sm: Substitution manager instance + @type sm: L{substitution_manager_t} + @return: C++ code or None + @rtype: str + """ + pass + + def virtual_post_call(self, sm): + """Generate the C++ code that should be executed after the actual function call. + + The code from this method will be put into the virtual function. + + @param sm: Substitution manager instance + @type sm: L{substitution_manager_t} + @return: C++ code or None + @rtype: str + """ + pass + + def virtual_cleanup(self, sm): + pass Copied: pyplusplus_dev/pyplusplus/function_transformers/transformers.py (from rev 682, pyplusplus_dev/pyplusplus/function_transformers/arg_policies.py) =================================================================== --- pyplusplus_dev/pyplusplus/function_transformers/transformers.py (rev 0) +++ pyplusplus_dev/pyplusplus/function_transformers/transformers.py 2006-10-24 19:10:52 UTC (rev 683) @@ -0,0 +1,357 @@ +# 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 standard argument policy objects. + +The following policies are available: + + - L{output_t} + - L{input_t} + - L{inout_t} + - L{input_array_t} + - L{output_array_t} +""" +import os +from pygccxml import declarations +from pyplusplus import code_repository + +# output_t +class output_t: + """Handles a single output variable. + + The specified variable is removed from the argument list and is turned + into a return value. + + void getValue(int& v) -> v = getValue() + """ + + def __init__(self, idx): + """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 + """ + self.idx = idx + self.local_var = "<not initialized>" + + def __str__(self): + return "Output(%d)"%(self.idx) + + def init_funcs(self, sm): + # Remove the specified output argument from the wrapper function + arg = sm.remove_arg(self.idx) + + # 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)): + 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)) + # 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 + + + 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 + + +# input_t +class input_t: + """Handles a single input variable. + + The reference on the specified variable is removed. + + void setValue(int& v) -> setValue(v) + """ + + def __init__(self, idx): + """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 + """ + self.idx = idx + + def __str__(self): + return "Input(%d)"%(self.idx) + + def init_funcs(self, sm): + # Remove the specified input argument from the wrapper function + arg = sm.remove_arg(self.idx) + + # 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)): + 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 + noref_arg = declarations.argument_t(name=arg.name, type=arg.type.base, default_value=arg.default_value) + # Insert the noref argument + sm.insert_arg(self.idx, noref_arg, arg.name) + +# inout_t +class inout_t: + """Handles a single input/output variable. + + void foo(int& v) -> v = foo(v) + """ + + def __init__(self, idx): + """Constructor. + + The specified argument must be a reference or a pointer. + + @param idx: Index of the argument that is an in/out value (the first arg has index 1). + @type idx: int + """ + self.idx = idx + self.local_var = "<not initialized>" + + def __str__(self): + return "InOut(%d)"%(self.idx) + + def init_funcs(self, sm): + # Remove the specified input argument from the wrapper function + arg = sm.remove_arg(self.idx) + + # 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)): + 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 + noref_arg = declarations.argument_t(name=arg.name, type=arg.type.base, default_value=arg.default_value) + # Insert the noref argument + sm.insert_arg(self.idx, noref_arg, arg.name) + + # Use the input arg to also store the output + self.local_var = noref_arg.name + # 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 + + + 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 in/out 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 + + + +# input_array_t +class input_array_t: + """Handles an input array with fixed size. + + void setVec3(double* v) -> setVec3(object v) + # v must be a sequence of 3 floats + + + TODO: Error handling (in the wrapper function)! + + """ + + def __init__(self, idx, size): + """Constructor. + + @param idx: Index of the argument that is an input array (the first arg has index 1). + @type idx: int + @param size: The fixed size of the input array + @type size: int + """ + self.idx = idx + self.size = size + + self.argname = None + self.basetype = None + self.carray = None + self.wrapper_ivar = None + self.virtual_ivar = None + self.pylist = None + + def __str__(self): + return "InputArray(%d,%d)"%(self.idx, self.size) + + def init_funcs(self, sm): + + # 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)): + 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 + # (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") + + # Replace the removed argument with a Python object. + newarg = declarations.argument_t(arg.name, declarations.dummy_type_t("boost::python::object")) + sm.insert_arg(self.idx, newarg, self.pylist) + + self.argname = arg.name + 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) + # 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 + + # Request the convenience header + sm.wrapper_func.require_header(code_repository.convenience.file_name) + + def wrapper_pre_call(self, sm): + """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( '}' ) + return os.linesep.join( tmpl ) % { + 'type' : self.basetype + , '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 + + +# output_array_t +class output_array_t: + """Handles an output array of a fixed size. + + void getVec3(double* v) -> v = getVec3() + # v will be a list with 3 floats + + TODO: Error handling (in the virtual function)! + + """ + + def __init__(self, idx, size): + """Constructor. + + @param idx: Index of the argument that is an output array (the first arg has index 1). + @type idx: int + @param size: The fixed size of the output array + @type size: int + """ + + self.idx = idx + self.size = size + + self.argname = None + self.basetype = None + self.pyval = None + self.cval = None + self.ivar = None + + def __str__(self): + return "OutputArray(%d,%d)"%(self.idx, self.size) + + def init_funcs(self, sm): + # 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)): + raise ValueError, "%s\nArgument %d (%s) must be a pointer."%(sm.decl, self.idx, arg.name) + + self.argname = arg.name + self.basetype = str(arg.type.base).replace("const", "").strip() + + # 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) + # Declare a Python list which will receive the output... + self.wrapper_pyval = sm.wrapper_func.declare_local(self.argname, "boost::python::list") + # ...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: + + # 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 + + 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( '}' ) + return os.linesep.join( tmpl ) % { + 'type' : self.basetype + , 'argname' : sm.py_result_expr(self.argname) + , 'size' : self.size + , 'ivar' : self.virtual_ivar + , 'array_name' : self.argname + } Modified: pyplusplus_dev/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev/unittests/function_transformations_tester.py 2006-10-24 12:10:40 UTC (rev 682) +++ pyplusplus_dev/unittests/function_transformations_tester.py 2006-10-24 19:10:52 UTC (rev 683) @@ -7,7 +7,7 @@ import sys import unittest import fundamental_tester_base -from pyplusplus.function_transformers.arg_policies import * +from pyplusplus.function_transformers.transformers import * from pyplusplus.decl_wrappers import * class tester_t(fundamental_tester_base.fundamental_tester_base_t): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |