|
|
|
""" |
|
|
|
Rules for building C/API module with f2py2e. |
|
|
|
Copyright 1999,2000 Pearu Peterson all rights reserved, |
|
Pearu Peterson <[email protected]> |
|
Permission to use, modify, and distribute this software is given under the |
|
terms of the NumPy License. |
|
|
|
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. |
|
$Date: 2004/11/26 11:13:06 $ |
|
Pearu Peterson |
|
|
|
""" |
|
from __future__ import division, absolute_import, print_function |
|
|
|
__version__ = "$Revision: 1.16 $"[10:-1] |
|
|
|
f2py_version='See `f2py -v`' |
|
|
|
import pprint |
|
import copy |
|
import sys |
|
errmess=sys.stderr.write |
|
outmess=sys.stdout.write |
|
show=pprint.pprint |
|
|
|
from .auxfuncs import * |
|
def var2fixfortran(vars,a,fa=None,f90mode=None): |
|
if fa is None: |
|
fa = a |
|
if a not in vars: |
|
show(vars) |
|
outmess('var2fixfortran: No definition for argument "%s".\n'%a) |
|
return '' |
|
if 'typespec' not in vars[a]: |
|
show(vars[a]) |
|
outmess('var2fixfortran: No typespec for argument "%s".\n'%a) |
|
return '' |
|
vardef=vars[a]['typespec'] |
|
if vardef=='type' and 'typename' in vars[a]: |
|
vardef='%s(%s)'%(vardef, vars[a]['typename']) |
|
selector={} |
|
lk = '' |
|
if 'kindselector' in vars[a]: |
|
selector=vars[a]['kindselector'] |
|
lk = 'kind' |
|
elif 'charselector' in vars[a]: |
|
selector=vars[a]['charselector'] |
|
lk = 'len' |
|
if '*' in selector: |
|
if f90mode: |
|
if selector['*'] in ['*', ':', '(*)']: |
|
vardef='%s(len=*)'%(vardef) |
|
else: |
|
vardef='%s(%s=%s)'%(vardef, lk, selector['*']) |
|
else: |
|
if selector['*'] in ['*', ':']: |
|
vardef='%s*(%s)'%(vardef, selector['*']) |
|
else: |
|
vardef='%s*%s'%(vardef, selector['*']) |
|
else: |
|
if 'len' in selector: |
|
vardef='%s(len=%s'%(vardef, selector['len']) |
|
if 'kind' in selector: |
|
vardef='%s,kind=%s)'%(vardef, selector['kind']) |
|
else: |
|
vardef='%s)'%(vardef) |
|
elif 'kind' in selector: |
|
vardef='%s(kind=%s)'%(vardef, selector['kind']) |
|
|
|
vardef='%s %s'%(vardef, fa) |
|
if 'dimension' in vars[a]: |
|
vardef='%s(%s)'%(vardef, ','.join(vars[a]['dimension'])) |
|
return vardef |
|
|
|
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) |
|
name = rout['name'] |
|
fortranname = getfortranname(rout) |
|
f90mode = ismoduleroutine(rout) |
|
newname = '%sf2pywrap'%(name) |
|
|
|
if newname not in vars: |
|
vars[newname] = vars[name] |
|
args = [newname]+rout['args'][1:] |
|
else: |
|
args = [newname]+rout['args'] |
|
|
|
l = var2fixfortran(vars, name, newname, f90mode) |
|
return_char_star = 0 |
|
if l[:13]=='character*(*)': |
|
return_char_star = 1 |
|
if f90mode: l = 'character(len=10)'+l[13:] |
|
else: l = 'character*10'+l[13:] |
|
charselect = vars[name]['charselector'] |
|
if charselect.get('*', '')=='(*)': |
|
charselect['*'] = '10' |
|
sargs = ', '.join(args) |
|
if f90mode: |
|
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, sargs)) |
|
if not need_interface: |
|
add('external %s'%(fortranname)) |
|
l = l + ', '+fortranname |
|
if need_interface: |
|
for line in rout['saved_interface'].split('\n'): |
|
if line.lstrip().startswith('use '): |
|
add(line) |
|
|
|
args = args[1:] |
|
dumped_args = [] |
|
for a in args: |
|
if isexternal(vars[a]): |
|
add('external %s'%(a)) |
|
dumped_args.append(a) |
|
for a in args: |
|
if a in dumped_args: continue |
|
if isscalar(vars[a]): |
|
add(var2fixfortran(vars, a, f90mode=f90mode)) |
|
dumped_args.append(a) |
|
for a in args: |
|
if a in dumped_args: continue |
|
if isintent_in(vars[a]): |
|
add(var2fixfortran(vars, a, f90mode=f90mode)) |
|
dumped_args.append(a) |
|
for a in args: |
|
if a in dumped_args: continue |
|
add(var2fixfortran(vars, a, f90mode=f90mode)) |
|
|
|
add(l) |
|
|
|
if need_interface: |
|
if f90mode: |
|
|
|
pass |
|
else: |
|
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, sargs)) |
|
else: |
|
add('%s = %s(%s)'%(newname, fortranname, sargs)) |
|
if f90mode: |
|
add('end subroutine f2pywrap_%s_%s'%(rout['modulename'], name)) |
|
else: |
|
add('end') |
|
|
|
|
|
|
|
return ret[0] |
|
|
|
def createsubrwrapper(rout,signature=0): |
|
assert issubroutine(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) |
|
name = rout['name'] |
|
fortranname = getfortranname(rout) |
|
f90mode = ismoduleroutine(rout) |
|
|
|
args = rout['args'] |
|
|
|
sargs = ', '.join(args) |
|
if f90mode: |
|
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, sargs)) |
|
if not need_interface: |
|
add('external %s'%(fortranname)) |
|
|
|
if need_interface: |
|
for line in rout['saved_interface'].split('\n'): |
|
if line.lstrip().startswith('use '): |
|
add(line) |
|
|
|
dumped_args = [] |
|
for a in args: |
|
if isexternal(vars[a]): |
|
add('external %s'%(a)) |
|
dumped_args.append(a) |
|
for a in args: |
|
if a in dumped_args: continue |
|
if isscalar(vars[a]): |
|
add(var2fixfortran(vars, a, f90mode=f90mode)) |
|
dumped_args.append(a) |
|
for a in args: |
|
if a in dumped_args: continue |
|
add(var2fixfortran(vars, a, f90mode=f90mode)) |
|
|
|
if need_interface: |
|
if f90mode: |
|
|
|
pass |
|
else: |
|
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: |
|
add('call %s(%s)'%(fortranname, sargs)) |
|
if f90mode: |
|
add('end subroutine f2pywrap_%s_%s'%(rout['modulename'], name)) |
|
else: |
|
add('end') |
|
|
|
|
|
|
|
return ret[0] |
|
|
|
|
|
def assubr(rout): |
|
if isfunction_wrap(rout): |
|
fortranname = getfortranname(rout) |
|
name = rout['name'] |
|
outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n'%(name, fortranname)) |
|
rout = copy.copy(rout) |
|
fname = name |
|
rname = fname |
|
if 'result' in rout: |
|
rname = rout['result'] |
|
rout['vars'][fname]=rout['vars'][rname] |
|
fvar = rout['vars'][fname] |
|
if not isintent_out(fvar): |
|
if 'intent' not in fvar: |
|
fvar['intent']=[] |
|
fvar['intent'].append('out') |
|
flag=1 |
|
for i in fvar['intent']: |
|
if i.startswith('out='): |
|
flag = 0 |
|
break |
|
if flag: |
|
fvar['intent'].append('out=%s' % (rname)) |
|
rout['args'][:] = [fname] + rout['args'] |
|
return rout, createfuncwrapper(rout) |
|
if issubroutine_wrap(rout): |
|
fortranname = getfortranname(rout) |
|
name = rout['name'] |
|
outmess('\t\tCreating wrapper for Fortran subroutine "%s"("%s")...\n'%(name, fortranname)) |
|
rout = copy.copy(rout) |
|
return rout, createsubrwrapper(rout) |
|
return rout, '' |
|
|