diff options
Diffstat (limited to 'numpy/f2py/f90mod_rules.py')
-rw-r--r-- | numpy/f2py/f90mod_rules.py | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/numpy/f2py/f90mod_rules.py b/numpy/f2py/f90mod_rules.py new file mode 100644 index 000000000..ffd432b1d --- /dev/null +++ b/numpy/f2py/f90mod_rules.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python +""" + +Build F90 module support for f2py2e. + +Copyright 2000 Pearu Peterson all rights reserved, +Pearu Peterson <pearu@ioc.ee> +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: 2005/02/03 19:30:23 $ +Pearu Peterson +""" + +__version__ = "$Revision: 1.27 $"[10:-1] + +f2py_version='See `f2py -v`' + +import pprint +import sys,string,time,types,copy +errmess=sys.stderr.write +outmess=sys.stdout.write +show=pprint.pprint + +from auxfuncs import * +import numpy as N +import capi_maps +import cfuncs +import rules +import func2subr +from crackfortran import undo_rmbadname, undo_rmbadname1 + +options={} + +def findf90modules(m): + if ismodule(m): return [m] + if not hasbody(m): return [] + ret = [] + for b in m['body']: + if ismodule(b): ret.append(b) + else: ret=ret+findf90modules(b) + return ret + +fgetdims1 = """\ + external f2pysetdata + logical ns + integer r,i,j + integer(%d) s(*) + ns = .FALSE. + if (allocated(d)) then + do i=1,r + if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then + ns = .TRUE. + end if + end do + if (ns) then + deallocate(d) + end if + end if + if ((.not.allocated(d)).and.(s(1).ge.1)) then""" % N.intp().itemsize + +fgetdims2="""\ + end if + if (allocated(d)) then + do i=1,r + s(i) = size(d,i) + end do + end if + flag = 1 + call f2pysetdata(d,allocated(d))""" + +fgetdims2_sa="""\ + end if + if (allocated(d)) then + do i=1,r + s(i) = size(d,i) + end do + !s(r) must be equal to len(d(1)) + end if + flag = 2 + call f2pysetdata(d,allocated(d))""" + + +def buildhooks(pymod): + global fgetdims1,fgetdims2 + ret = {'f90modhooks':[],'initf90modhooks':[],'body':[], + 'need':['F_FUNC','arrayobject.h'], + 'separatorsfor':{'includes0':'\n','includes':'\n'}, + 'docs':['"Fortran 90/95 modules:\\n"'], + 'latexdoc':[]} + fhooks=[''] + def fadd(line,s=fhooks): s[0] = '%s\n %s'%(s[0],line) + doc = [''] + def dadd(line,s=doc): s[0] = '%s\n%s'%(s[0],line) + for m in findf90modules(pymod): + sargs,fargs,efargs,modobjs,notvars,onlyvars=[],[],[],[],[m['name']],[] + sargsp = [] + ifargs = [] + mfargs = [] + if hasbody(m): + for b in m['body']: notvars.append(b['name']) + for n in m['vars'].keys(): + var = m['vars'][n] + if (n not in notvars) and (not l_or(isintent_hide,isprivate)(var)): + onlyvars.append(n) + mfargs.append(n) + outmess('\t\tConstructing F90 module support for "%s"...\n'%(m['name'])) + if onlyvars: + outmess('\t\t Variables: %s\n'%(string.join(onlyvars))) + chooks=[''] + def cadd(line,s=chooks): s[0] = '%s\n%s'%(s[0],line) + ihooks=[''] + def iadd(line,s=ihooks): s[0] = '%s\n%s'%(s[0],line) + + vrd=capi_maps.modsign2map(m) + cadd('static FortranDataDef f2py_%s_def[] = {'%(m['name'])) + dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n'%(m['name'])) + if hasnote(m): + note = m['note'] + if type(note) is type([]): note=string.join(note,'\n') + dadd(note) + if onlyvars: + dadd('\\begin{description}') + for n in onlyvars: + var = m['vars'][n] + modobjs.append(n) + ct = capi_maps.getctype(var) + at = capi_maps.c2capi_map[ct] + dm = capi_maps.getarrdims(n,var) + dms = string.strip(string.replace(dm['dims'],'*','-1')) + dms = string.strip(string.replace(dms,':','-1')) + if not dms: dms='-1' + use_fgetdims2 = fgetdims2 + if isstringarray(var): + if var.has_key('charselector') and var['charselector'].has_key('len'): + cadd('\t{"%s",%s,{{%s,%s}},%s},'\ + %(undo_rmbadname1(n),dm['rank'],dms,var['charselector']['len'],at)) + use_fgetdims2 = fgetdims2_sa + else: + cadd('\t{"%s",%s,{{%s}},%s},'%(undo_rmbadname1(n),dm['rank'],dms,at)) + else: + cadd('\t{"%s",%s,{{%s}},%s},'%(undo_rmbadname1(n),dm['rank'],dms,at)) + dadd('\\item[]{{}\\verb@%s@{}}'%(capi_maps.getarrdocsign(n,var))) + if hasnote(var): + note = var['note'] + if type(note) is type([]): note=string.join(note,'\n') + dadd('--- %s'%(note)) + if isallocatable(var): + fargs.append('f2py_%s_getdims_%s'%(m['name'],n)) + efargs.append(fargs[-1]) + sargs.append('void (*%s)(int*,int*,void(*)(char*,int*),int*)'%(n)) + sargsp.append('void (*)(int*,int*,void(*)(char*,int*),int*)') + iadd('\tf2py_%s_def[i_f2py++].func = %s;'%(m['name'],n)) + fadd('subroutine %s(r,s,f2pysetdata,flag)'%(fargs[-1])) + fadd('use %s, only: d => %s\n'%(m['name'],undo_rmbadname1(n))) + fadd('integer flag\n') + fhooks[0]=fhooks[0]+fgetdims1 + dms = eval('range(1,%s+1)'%(dm['rank'])) + fadd(' allocate(d(%s))\n'%(string.join(map(lambda i:'s(%s)'%i,dms),','))) + fhooks[0]=fhooks[0]+use_fgetdims2 + fadd('end subroutine %s'%(fargs[-1])) + else: + fargs.append(n) + sargs.append('char *%s'%(n)) + sargsp.append('char*') + iadd('\tf2py_%s_def[i_f2py++].data = %s;'%(m['name'],n)) + if onlyvars: + dadd('\\end{description}') + if hasbody(m): + for b in m['body']: + if not isroutine(b): + print 'Skipping',b['block'],b['name'] + continue + modobjs.append('%s()'%(b['name'])) + b['modulename'] = m['name'] + api,wrap=rules.buildapi(b) + if isfunction(b): + fhooks[0]=fhooks[0]+wrap + fargs.append('f2pywrap_%s_%s'%(m['name'],b['name'])) + #efargs.append(fargs[-1]) + ifargs.append(func2subr.createfuncwrapper(b,signature=1)) + else: + fargs.append(b['name']) + mfargs.append(fargs[-1]) + #if options.has_key('--external-modroutines') and options['--external-modroutines']: + # outmess('\t\t\tapplying --external-modroutines for %s\n'%(b['name'])) + # efargs.append(fargs[-1]) + api['externroutines']=[] + ar=applyrules(api,vrd) + ar['docs']=[] + ar['docshort']=[] + ret=dictappend(ret,ar) + cadd('\t{"%s",-1,{{-1}},0,NULL,(void *)f2py_rout_#modulename#_%s_%s,doc_f2py_rout_#modulename#_%s_%s},'%(b['name'],m['name'],b['name'],m['name'],b['name'])) + sargs.append('char *%s'%(b['name'])) + sargsp.append('char *') + iadd('\tf2py_%s_def[i_f2py++].data = %s;'%(m['name'],b['name'])) + cadd('\t{NULL}\n};\n') + iadd('}') + ihooks[0]='static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s'%(m['name'],string.join(sargs,','),ihooks[0]) + if '_' in m['name']: + F_FUNC='F_FUNC_US' + else: + F_FUNC='F_FUNC' + iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));'\ + %(F_FUNC,m['name'],string.upper(m['name']),string.join(sargsp,','))) + iadd('static void f2py_init_%s(void) {'%(m['name'])) + iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'\ + %(F_FUNC,m['name'],string.upper(m['name']),m['name'])) + iadd('}\n') + ret['f90modhooks']=ret['f90modhooks']+chooks+ihooks + ret['initf90modhooks']=['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));'%(m['name'],m['name'],m['name'])]+ret['initf90modhooks'] + fadd('') + fadd('subroutine f2pyinit%s(f2pysetupfunc)'%(m['name'])) + #fadd('use %s'%(m['name'])) + if mfargs: + for a in undo_rmbadname(mfargs): + fadd('use %s, only : %s'%(m['name'],a)) + if ifargs: + fadd(string.join(['interface']+ifargs)) + fadd('end interface') + fadd('external f2pysetupfunc') + if efargs: + for a in undo_rmbadname(efargs): + fadd('external %s'%(a)) + fadd('call f2pysetupfunc(%s)'%(string.join(undo_rmbadname(fargs),','))) + fadd('end subroutine f2pyinit%s\n'%(m['name'])) + + dadd(string.replace(string.join(ret['latexdoc'],'\n'),r'\subsection{',r'\subsubsection{')) + + ret['latexdoc']=[] + ret['docs'].append('"\t%s --- %s"'%(m['name'], + string.join(undo_rmbadname(modobjs),','))) + + ret['routine_defs']='' + ret['doc']=[] + ret['docshort']=[] + ret['latexdoc']=doc[0] + if len(ret['docs'])<=1: ret['docs']='' + return ret,fhooks[0] |