[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.
|