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