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