summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPearu Peterson <pearu.peterson@gmail.com>2011-03-13 12:54:53 +0200
committerPearu Peterson <pearu.peterson@gmail.com>2011-03-13 12:55:58 +0200
commitb598d9c819113f50488f6995d91dcdbe8e49c3c7 (patch)
treedc3f2a289eef53437768c9c4d21f3561e20587d0
parent30ee1d3526af8892e8e1c22e29f9d7be14881eba (diff)
downloadnumpy-b598d9c819113f50488f6995d91dcdbe8e49c3c7.tar.gz
ENH: f2py: support Fortran size function with two arguments (ticket #1765).
-rwxr-xr-xnumpy/f2py/crackfortran.py11
-rw-r--r--numpy/f2py/tests/src/size/foo.f9014
-rw-r--r--numpy/f2py/tests/test_size.py29
3 files changed, 53 insertions, 1 deletions
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
index c3082bbf7..aa4c3bc0a 100755
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -2037,7 +2037,7 @@ def _eval_length(length,params):
return '(*)'
return _eval_scalar(length,params)
-_is_kind_number = re.compile('\d+_').match
+_is_kind_number = re.compile(r'\d+_').match
def _eval_scalar(value,params):
if _is_kind_number(value):
@@ -2052,6 +2052,13 @@ def _eval_scalar(value,params):
% (msg,value,params.keys()))
return value
+_size_call_sub = re.compile(r'size\s*\((?P<arg1>\w+)\s*[,]').sub
+def two_argument_size_hook(expr):
+ new_expr = _size_call_sub(r'shape(\g<arg1>,-1+', expr)
+ if verbose > 1 and expr!=new_expr:
+ outmess('two_argument_size_hook: mapping %r to %r\n' % (expr, new_expr))
+ return new_expr
+
def analyzevars(block):
global f90modulevars
setmesstext(block)
@@ -2194,6 +2201,7 @@ def analyzevars(block):
if d[:4] == '1 * ': d = d[4:]
if di and di[-4:] == '/(1)': di = di[:-4]
if v: savelindims[d] = v,di
+ d = two_argument_size_hook(d)
vars[n]['dimension'].append(d)
if 'dimension' in vars[n]:
if isintent_c(vars[n]):
@@ -2310,6 +2318,7 @@ def analyzevars(block):
if not vars[n]['depend']: del vars[n]['depend']
if isscalar(vars[n]):
vars[n]['='] = _eval_scalar(vars[n]['='],params)
+ vars[n]['='] = two_argument_size_hook(vars[n]['='])
for n in vars.keys():
if n==block['name']: # n is block name
diff --git a/numpy/f2py/tests/src/size/foo.f90 b/numpy/f2py/tests/src/size/foo.f90
new file mode 100644
index 000000000..9602837fe
--- /dev/null
+++ b/numpy/f2py/tests/src/size/foo.f90
@@ -0,0 +1,14 @@
+
+subroutine foo(a, n, m, b)
+ implicit none
+
+ real, intent(in) :: a(n, m)
+ integer, intent(in) :: n, m
+ real, intent(out) :: b(size(a, 1))
+
+ integer :: i
+
+ do i = 1, size(b)
+ b(i) = sum(a(i,:))
+ enddo
+end subroutine
diff --git a/numpy/f2py/tests/test_size.py b/numpy/f2py/tests/test_size.py
new file mode 100644
index 000000000..c00dd9a31
--- /dev/null
+++ b/numpy/f2py/tests/test_size.py
@@ -0,0 +1,29 @@
+import os
+import math
+
+from numpy.testing import *
+from numpy import array
+
+import util
+
+def _path(*a):
+ return os.path.join(*((os.path.dirname(__file__),) + a))
+
+class TestSizeSumExample(util.F2PyTest):
+ sources = [_path('src', 'size', 'foo.f90'),
+ ]
+
+ @dec.slow
+ def test_all(self):
+ r = self.module.foo([[1,2]])
+ assert_equal(r, [3],`r`)
+
+ r = self.module.foo([[1,2],[3,4]])
+ assert_equal(r, [3,7],`r`)
+
+ r = self.module.foo([[1,2],[3,4],[5,6]])
+ assert_equal(r, [3,7,11],`r`)
+
+if __name__ == "__main__":
+ import nose
+ nose.runmodule()