summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rwxr-xr-xnumpy/f2py/crackfortran.py20
-rw-r--r--numpy/f2py/func2subr.py42
-rw-r--r--numpy/f2py/tests/src/assumed_shape/foo_free.f9034
-rw-r--r--numpy/f2py/tests/test_assumed_shape.py25
4 files changed, 106 insertions, 15 deletions
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
index 032901af9..43bcfa259 100755
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -78,6 +78,7 @@ f2py_version = __version__.version
B['entry'] --- dictionary {entryname:argslist,..}
B['varnames'] --- list of variable names given in the order of reading the
Fortran code, useful for derived types.
+ B['saved_interface'] --- a string of scanned routine signature, defines explicit interface
*** Variable definition is a dictionary
D = B['vars'][<variable name>] =
{'typespec'[,'attrspec','kindselector','charselector','=','typename']}
@@ -1707,6 +1708,8 @@ def analyzebody(block,args,tab=''):
continue
if onlyfuncs and b['name'] not in onlyfuncs:
continue
+ b['saved_interface'] = crack2fortrangen(b, '\n'+' '*6, as_interface=True)
+
else: as_=args
b=postcrack(b,as_,tab=tab+'\t')
if b['block']=='interface' and not b['body']:
@@ -2451,7 +2454,7 @@ def determineexprtype(expr,vars,rules={}):
return t
######
-def crack2fortrangen(block,tab='\n'):
+def crack2fortrangen(block,tab='\n', as_interface=False):
global skipfuncs, onlyfuncs
setmesstext(block)
ret=''
@@ -2462,7 +2465,7 @@ def crack2fortrangen(block,tab='\n'):
continue
if onlyfuncs and g['name'] not in onlyfuncs:
continue
- ret=ret+crack2fortrangen(g,tab)
+ ret=ret+crack2fortrangen(g,tab,as_interface=as_interface)
return ret
prefix=''
name=''
@@ -2503,9 +2506,9 @@ def crack2fortrangen(block,tab='\n'):
#if 'prefix' in block:
# prefix=block['prefix']+' '
body=crack2fortrangen(block['body'],tab+tabchar)
- vars=vars2fortran(block,block['vars'],al,tab+tabchar)
+ vars=vars2fortran(block,block['vars'],al,tab+tabchar, as_interface=as_interface)
mess=''
- if 'from' in block:
+ if 'from' in block and not as_interface:
mess='! in %s'%block['from']
if 'entry' in block:
entry_stmts = ''
@@ -2558,7 +2561,7 @@ def true_intent_list(var):
ret.append(intent)
return ret
-def vars2fortran(block,vars,args,tab=''):
+def vars2fortran(block,vars,args,tab='', as_interface=False):
"""
TODO:
public sub
@@ -2579,9 +2582,10 @@ def vars2fortran(block,vars,args,tab=''):
errmess('vars2fortran: Confused?!: "%s" is not defined in vars.\n'%a)
if 'varnames' in block:
nout.extend(block['varnames'])
- for a in vars.keys():
- if a not in nout:
- nout.append(a)
+ if not as_interface:
+ for a in vars.keys():
+ if a not in nout:
+ nout.append(a)
for a in nout:
if 'depend' in vars[a]:
for d in vars[a]['depend']:
diff --git a/numpy/f2py/func2subr.py b/numpy/f2py/func2subr.py
index 7ce30bc70..6ef8da3cb 100644
--- a/numpy/f2py/func2subr.py
+++ b/numpy/f2py/func2subr.py
@@ -75,6 +75,23 @@ def var2fixfortran(vars,a,fa=None,f90mode=None):
def createfuncwrapper(rout,signature=0):
assert isfunction(rout)
+
+ extra_args = []
+ vars = rout['vars']
+ for a in rout['args']:
+ v = rout['vars'][a]
+ for i,d in enumerate(v.get('dimension',[])):
+ if d==':':
+ dn = 'f2py_%s_d%s' % (a, i)
+ dv = dict(typespec='integer', intent=['hide'])
+ dv['='] = 'shape(%s, %s)' % (a, i)
+ extra_args.append(dn)
+ vars[dn] = dv
+ v['dimension'][i] = dn
+ rout['args'].extend(extra_args)
+ need_interface = bool(extra_args)
+
+
ret = ['']
def add(line,ret=ret):
ret[0] = '%s\n %s'%(ret[0],line)
@@ -82,7 +99,7 @@ def createfuncwrapper(rout,signature=0):
fortranname = getfortranname(rout)
f90mode = ismoduleroutine(rout)
newname = '%sf2pywrap'%(name)
- vars = rout['vars']
+
if newname not in vars:
vars[newname] = vars[name]
args = [newname]+rout['args'][1:]
@@ -98,14 +115,15 @@ def createfuncwrapper(rout,signature=0):
charselect = vars[name]['charselector']
if charselect.get('*','')=='(*)':
charselect['*'] = '10'
+ sargs = ', '.join(args)
if f90mode:
- sargs = ', '.join(args)
add('subroutine f2pywrap_%s_%s (%s)'%(rout['modulename'],name,sargs))
if not signature:
add('use %s, only : %s'%(rout['modulename'],fortranname))
else:
- add('subroutine f2pywrap%s (%s)'%(name,', '.join(args)))
- add('external %s'%(fortranname))
+ add('subroutine f2pywrap%s (%s)'%(name,sargs))
+ if not need_interface:
+ add('external %s'%(fortranname))
#if not return_char_star:
l = l + ', '+fortranname
args = args[1:]
@@ -125,11 +143,18 @@ def createfuncwrapper(rout,signature=0):
add(l)
+ if need_interface:
+ add('interface')
+ add(rout['saved_interface'].lstrip())
+ add('end interface')
+
+ sargs = ', '.join([a for a in args if a not in extra_args])
+
if not signature:
if islogicalfunction(rout):
- add('%s = .not.(.not.%s(%s))'%(newname,fortranname,', '.join(args)))
+ add('%s = .not.(.not.%s(%s))'%(newname,fortranname,sargs))
else:
- add('%s = %s(%s)'%(newname,fortranname,', '.join(args)))
+ add('%s = %s(%s)'%(newname,fortranname,sargs))
if f90mode:
add('end subroutine f2pywrap_%s_%s'%(rout['modulename'],name))
else:
@@ -140,7 +165,8 @@ def createfuncwrapper(rout,signature=0):
return ret[0]
def assubr(rout):
- if not isfunction_wrap(rout): return rout,''
+ if not isfunction_wrap(rout):
+ return rout,''
fortranname = getfortranname(rout)
name = rout['name']
outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n'%(name,fortranname))
@@ -165,3 +191,5 @@ def assubr(rout):
rout['args'] = [fname] + rout['args']
return rout,createfuncwrapper(rout)
+
+
diff --git a/numpy/f2py/tests/src/assumed_shape/foo_free.f90 b/numpy/f2py/tests/src/assumed_shape/foo_free.f90
new file mode 100644
index 000000000..43c076f15
--- /dev/null
+++ b/numpy/f2py/tests/src/assumed_shape/foo_free.f90
@@ -0,0 +1,34 @@
+
+subroutine sum(x, res)
+ implicit none
+ real, intent(in) :: x(:)
+ real, intent(out) :: res
+
+ integer :: i
+
+ print *, "sum: size(x) = ", size(x)
+
+ res = 0.0
+
+ do i = 1, size(x)
+ res = x(i)
+ enddo
+
+end subroutine sum
+
+function fsum(x) result (res)
+ implicit none
+ real, intent(in) :: x(:)
+ real :: res
+
+ integer :: i
+
+ print *, "fsum: size(x) = ", size(x)
+
+ res = 0.0
+
+ do i = 1, size(x)
+ res = res + x(i)
+ enddo
+
+end function fsum
diff --git a/numpy/f2py/tests/test_assumed_shape.py b/numpy/f2py/tests/test_assumed_shape.py
new file mode 100644
index 000000000..5784c54f9
--- /dev/null
+++ b/numpy/f2py/tests/test_assumed_shape.py
@@ -0,0 +1,25 @@
+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 TestMixed(util.F2PyTest):
+ sources = [_path('src', 'assumed_shape', 'foo_free.f90')]
+
+ @dec.slow
+ def test_all(self):
+ print self.module.__doc__
+ r = self.module.fsum([1,2])
+ assert r==3,`r`
+ #r = self.module.sum([1,2])
+ #assert r==3,`r`
+
+if __name__ == "__main__":
+ import nose
+ nose.runmodule()