Chris@87
|
1 #!/usr/bin/env python
|
Chris@87
|
2 """
|
Chris@87
|
3
|
Chris@87
|
4 Build F90 module support for f2py2e.
|
Chris@87
|
5
|
Chris@87
|
6 Copyright 2000 Pearu Peterson all rights reserved,
|
Chris@87
|
7 Pearu Peterson <pearu@ioc.ee>
|
Chris@87
|
8 Permission to use, modify, and distribute this software is given under the
|
Chris@87
|
9 terms of the NumPy License.
|
Chris@87
|
10
|
Chris@87
|
11 NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
Chris@87
|
12 $Date: 2005/02/03 19:30:23 $
|
Chris@87
|
13 Pearu Peterson
|
Chris@87
|
14
|
Chris@87
|
15 """
|
Chris@87
|
16 from __future__ import division, absolute_import, print_function
|
Chris@87
|
17
|
Chris@87
|
18 __version__ = "$Revision: 1.27 $"[10:-1]
|
Chris@87
|
19
|
Chris@87
|
20 f2py_version='See `f2py -v`'
|
Chris@87
|
21
|
Chris@87
|
22 import pprint
|
Chris@87
|
23 import sys
|
Chris@87
|
24 errmess=sys.stderr.write
|
Chris@87
|
25 outmess=sys.stdout.write
|
Chris@87
|
26 show=pprint.pprint
|
Chris@87
|
27
|
Chris@87
|
28 from .auxfuncs import *
|
Chris@87
|
29 import numpy as np
|
Chris@87
|
30 from . import capi_maps
|
Chris@87
|
31 from . import func2subr
|
Chris@87
|
32 from .crackfortran import undo_rmbadname, undo_rmbadname1
|
Chris@87
|
33
|
Chris@87
|
34 options={}
|
Chris@87
|
35
|
Chris@87
|
36 def findf90modules(m):
|
Chris@87
|
37 if ismodule(m): return [m]
|
Chris@87
|
38 if not hasbody(m): return []
|
Chris@87
|
39 ret = []
|
Chris@87
|
40 for b in m['body']:
|
Chris@87
|
41 if ismodule(b): ret.append(b)
|
Chris@87
|
42 else: ret=ret+findf90modules(b)
|
Chris@87
|
43 return ret
|
Chris@87
|
44
|
Chris@87
|
45 fgetdims1 = """\
|
Chris@87
|
46 external f2pysetdata
|
Chris@87
|
47 logical ns
|
Chris@87
|
48 integer r,i,j
|
Chris@87
|
49 integer(%d) s(*)
|
Chris@87
|
50 ns = .FALSE.
|
Chris@87
|
51 if (allocated(d)) then
|
Chris@87
|
52 do i=1,r
|
Chris@87
|
53 if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then
|
Chris@87
|
54 ns = .TRUE.
|
Chris@87
|
55 end if
|
Chris@87
|
56 end do
|
Chris@87
|
57 if (ns) then
|
Chris@87
|
58 deallocate(d)
|
Chris@87
|
59 end if
|
Chris@87
|
60 end if
|
Chris@87
|
61 if ((.not.allocated(d)).and.(s(1).ge.1)) then""" % np.intp().itemsize
|
Chris@87
|
62
|
Chris@87
|
63 fgetdims2="""\
|
Chris@87
|
64 end if
|
Chris@87
|
65 if (allocated(d)) then
|
Chris@87
|
66 do i=1,r
|
Chris@87
|
67 s(i) = size(d,i)
|
Chris@87
|
68 end do
|
Chris@87
|
69 end if
|
Chris@87
|
70 flag = 1
|
Chris@87
|
71 call f2pysetdata(d,allocated(d))"""
|
Chris@87
|
72
|
Chris@87
|
73 fgetdims2_sa="""\
|
Chris@87
|
74 end if
|
Chris@87
|
75 if (allocated(d)) then
|
Chris@87
|
76 do i=1,r
|
Chris@87
|
77 s(i) = size(d,i)
|
Chris@87
|
78 end do
|
Chris@87
|
79 !s(r) must be equal to len(d(1))
|
Chris@87
|
80 end if
|
Chris@87
|
81 flag = 2
|
Chris@87
|
82 call f2pysetdata(d,allocated(d))"""
|
Chris@87
|
83
|
Chris@87
|
84
|
Chris@87
|
85 def buildhooks(pymod):
|
Chris@87
|
86 global fgetdims1, fgetdims2
|
Chris@87
|
87 from . import rules
|
Chris@87
|
88 ret = {'f90modhooks':[],'initf90modhooks':[],'body':[],
|
Chris@87
|
89 'need':['F_FUNC', 'arrayobject.h'],
|
Chris@87
|
90 'separatorsfor':{'includes0':'\n','includes':'\n'},
|
Chris@87
|
91 'docs':['"Fortran 90/95 modules:\\n"'],
|
Chris@87
|
92 'latexdoc':[]}
|
Chris@87
|
93 fhooks=['']
|
Chris@87
|
94 def fadd(line,s=fhooks): s[0] = '%s\n %s'%(s[0], line)
|
Chris@87
|
95 doc = ['']
|
Chris@87
|
96 def dadd(line,s=doc): s[0] = '%s\n%s'%(s[0], line)
|
Chris@87
|
97 for m in findf90modules(pymod):
|
Chris@87
|
98 sargs, fargs, efargs, modobjs, notvars, onlyvars=[], [], [], [], [m['name']], []
|
Chris@87
|
99 sargsp = []
|
Chris@87
|
100 ifargs = []
|
Chris@87
|
101 mfargs = []
|
Chris@87
|
102 if hasbody(m):
|
Chris@87
|
103 for b in m['body']: notvars.append(b['name'])
|
Chris@87
|
104 for n in m['vars'].keys():
|
Chris@87
|
105 var = m['vars'][n]
|
Chris@87
|
106 if (n not in notvars) and (not l_or(isintent_hide, isprivate)(var)):
|
Chris@87
|
107 onlyvars.append(n)
|
Chris@87
|
108 mfargs.append(n)
|
Chris@87
|
109 outmess('\t\tConstructing F90 module support for "%s"...\n'%(m['name']))
|
Chris@87
|
110 if onlyvars:
|
Chris@87
|
111 outmess('\t\t Variables: %s\n'%(' '.join(onlyvars)))
|
Chris@87
|
112 chooks=['']
|
Chris@87
|
113 def cadd(line,s=chooks): s[0] = '%s\n%s'%(s[0], line)
|
Chris@87
|
114 ihooks=['']
|
Chris@87
|
115 def iadd(line,s=ihooks): s[0] = '%s\n%s'%(s[0], line)
|
Chris@87
|
116
|
Chris@87
|
117 vrd=capi_maps.modsign2map(m)
|
Chris@87
|
118 cadd('static FortranDataDef f2py_%s_def[] = {'%(m['name']))
|
Chris@87
|
119 dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n'%(m['name']))
|
Chris@87
|
120 if hasnote(m):
|
Chris@87
|
121 note = m['note']
|
Chris@87
|
122 if isinstance(note, list): note='\n'.join(note)
|
Chris@87
|
123 dadd(note)
|
Chris@87
|
124 if onlyvars:
|
Chris@87
|
125 dadd('\\begin{description}')
|
Chris@87
|
126 for n in onlyvars:
|
Chris@87
|
127 var = m['vars'][n]
|
Chris@87
|
128 modobjs.append(n)
|
Chris@87
|
129 ct = capi_maps.getctype(var)
|
Chris@87
|
130 at = capi_maps.c2capi_map[ct]
|
Chris@87
|
131 dm = capi_maps.getarrdims(n, var)
|
Chris@87
|
132 dms = dm['dims'].replace('*', '-1').strip()
|
Chris@87
|
133 dms = dms.replace(':', '-1').strip()
|
Chris@87
|
134 if not dms: dms='-1'
|
Chris@87
|
135 use_fgetdims2 = fgetdims2
|
Chris@87
|
136 if isstringarray(var):
|
Chris@87
|
137 if 'charselector' in var and 'len' in var['charselector']:
|
Chris@87
|
138 cadd('\t{"%s",%s,{{%s,%s}},%s},'\
|
Chris@87
|
139 %(undo_rmbadname1(n), dm['rank'], dms, var['charselector']['len'], at))
|
Chris@87
|
140 use_fgetdims2 = fgetdims2_sa
|
Chris@87
|
141 else:
|
Chris@87
|
142 cadd('\t{"%s",%s,{{%s}},%s},'%(undo_rmbadname1(n), dm['rank'], dms, at))
|
Chris@87
|
143 else:
|
Chris@87
|
144 cadd('\t{"%s",%s,{{%s}},%s},'%(undo_rmbadname1(n), dm['rank'], dms, at))
|
Chris@87
|
145 dadd('\\item[]{{}\\verb@%s@{}}'%(capi_maps.getarrdocsign(n, var)))
|
Chris@87
|
146 if hasnote(var):
|
Chris@87
|
147 note = var['note']
|
Chris@87
|
148 if isinstance(note, list): note='\n'.join(note)
|
Chris@87
|
149 dadd('--- %s'%(note))
|
Chris@87
|
150 if isallocatable(var):
|
Chris@87
|
151 fargs.append('f2py_%s_getdims_%s'%(m['name'], n))
|
Chris@87
|
152 efargs.append(fargs[-1])
|
Chris@87
|
153 sargs.append('void (*%s)(int*,int*,void(*)(char*,int*),int*)'%(n))
|
Chris@87
|
154 sargsp.append('void (*)(int*,int*,void(*)(char*,int*),int*)')
|
Chris@87
|
155 iadd('\tf2py_%s_def[i_f2py++].func = %s;'%(m['name'], n))
|
Chris@87
|
156 fadd('subroutine %s(r,s,f2pysetdata,flag)'%(fargs[-1]))
|
Chris@87
|
157 fadd('use %s, only: d => %s\n'%(m['name'], undo_rmbadname1(n)))
|
Chris@87
|
158 fadd('integer flag\n')
|
Chris@87
|
159 fhooks[0]=fhooks[0]+fgetdims1
|
Chris@87
|
160 dms = eval('range(1,%s+1)'%(dm['rank']))
|
Chris@87
|
161 fadd(' allocate(d(%s))\n'%(','.join(['s(%s)'%i for i in dms])))
|
Chris@87
|
162 fhooks[0]=fhooks[0]+use_fgetdims2
|
Chris@87
|
163 fadd('end subroutine %s'%(fargs[-1]))
|
Chris@87
|
164 else:
|
Chris@87
|
165 fargs.append(n)
|
Chris@87
|
166 sargs.append('char *%s'%(n))
|
Chris@87
|
167 sargsp.append('char*')
|
Chris@87
|
168 iadd('\tf2py_%s_def[i_f2py++].data = %s;'%(m['name'], n))
|
Chris@87
|
169 if onlyvars:
|
Chris@87
|
170 dadd('\\end{description}')
|
Chris@87
|
171 if hasbody(m):
|
Chris@87
|
172 for b in m['body']:
|
Chris@87
|
173 if not isroutine(b):
|
Chris@87
|
174 print('Skipping', b['block'], b['name'])
|
Chris@87
|
175 continue
|
Chris@87
|
176 modobjs.append('%s()'%(b['name']))
|
Chris@87
|
177 b['modulename'] = m['name']
|
Chris@87
|
178 api, wrap=rules.buildapi(b)
|
Chris@87
|
179 if isfunction(b):
|
Chris@87
|
180 fhooks[0]=fhooks[0]+wrap
|
Chris@87
|
181 fargs.append('f2pywrap_%s_%s'%(m['name'], b['name']))
|
Chris@87
|
182 #efargs.append(fargs[-1])
|
Chris@87
|
183 ifargs.append(func2subr.createfuncwrapper(b, signature=1))
|
Chris@87
|
184 else:
|
Chris@87
|
185 if wrap:
|
Chris@87
|
186 fhooks[0]=fhooks[0]+wrap
|
Chris@87
|
187 fargs.append('f2pywrap_%s_%s'%(m['name'], b['name']))
|
Chris@87
|
188 ifargs.append(func2subr.createsubrwrapper(b, signature=1))
|
Chris@87
|
189 else:
|
Chris@87
|
190 fargs.append(b['name'])
|
Chris@87
|
191 mfargs.append(fargs[-1])
|
Chris@87
|
192 #if '--external-modroutines' in options and options['--external-modroutines']:
|
Chris@87
|
193 # outmess('\t\t\tapplying --external-modroutines for %s\n'%(b['name']))
|
Chris@87
|
194 # efargs.append(fargs[-1])
|
Chris@87
|
195 api['externroutines']=[]
|
Chris@87
|
196 ar=applyrules(api, vrd)
|
Chris@87
|
197 ar['docs']=[]
|
Chris@87
|
198 ar['docshort']=[]
|
Chris@87
|
199 ret=dictappend(ret, ar)
|
Chris@87
|
200 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']))
|
Chris@87
|
201 sargs.append('char *%s'%(b['name']))
|
Chris@87
|
202 sargsp.append('char *')
|
Chris@87
|
203 iadd('\tf2py_%s_def[i_f2py++].data = %s;'%(m['name'], b['name']))
|
Chris@87
|
204 cadd('\t{NULL}\n};\n')
|
Chris@87
|
205 iadd('}')
|
Chris@87
|
206 ihooks[0]='static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s'%(m['name'], ','.join(sargs), ihooks[0])
|
Chris@87
|
207 if '_' in m['name']:
|
Chris@87
|
208 F_FUNC='F_FUNC_US'
|
Chris@87
|
209 else:
|
Chris@87
|
210 F_FUNC='F_FUNC'
|
Chris@87
|
211 iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));'\
|
Chris@87
|
212 %(F_FUNC, m['name'], m['name'].upper(), ','.join(sargsp)))
|
Chris@87
|
213 iadd('static void f2py_init_%s(void) {'%(m['name']))
|
Chris@87
|
214 iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'\
|
Chris@87
|
215 %(F_FUNC, m['name'], m['name'].upper(), m['name']))
|
Chris@87
|
216 iadd('}\n')
|
Chris@87
|
217 ret['f90modhooks']=ret['f90modhooks']+chooks+ihooks
|
Chris@87
|
218 ret['initf90modhooks']=['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));'%(m['name'], m['name'], m['name'])]+ret['initf90modhooks']
|
Chris@87
|
219 fadd('')
|
Chris@87
|
220 fadd('subroutine f2pyinit%s(f2pysetupfunc)'%(m['name']))
|
Chris@87
|
221 #fadd('use %s'%(m['name']))
|
Chris@87
|
222 if mfargs:
|
Chris@87
|
223 for a in undo_rmbadname(mfargs):
|
Chris@87
|
224 fadd('use %s, only : %s'%(m['name'], a))
|
Chris@87
|
225 if ifargs:
|
Chris@87
|
226 fadd(' '.join(['interface']+ifargs))
|
Chris@87
|
227 fadd('end interface')
|
Chris@87
|
228 fadd('external f2pysetupfunc')
|
Chris@87
|
229 if efargs:
|
Chris@87
|
230 for a in undo_rmbadname(efargs):
|
Chris@87
|
231 fadd('external %s'%(a))
|
Chris@87
|
232 fadd('call f2pysetupfunc(%s)'%(','.join(undo_rmbadname(fargs))))
|
Chris@87
|
233 fadd('end subroutine f2pyinit%s\n'%(m['name']))
|
Chris@87
|
234
|
Chris@87
|
235 dadd('\n'.join(ret['latexdoc']).replace(r'\subsection{', r'\subsubsection{'))
|
Chris@87
|
236
|
Chris@87
|
237 ret['latexdoc']=[]
|
Chris@87
|
238 ret['docs'].append('"\t%s --- %s"'%(m['name'],
|
Chris@87
|
239 ','.join(undo_rmbadname(modobjs))))
|
Chris@87
|
240
|
Chris@87
|
241 ret['routine_defs']=''
|
Chris@87
|
242 ret['doc']=[]
|
Chris@87
|
243 ret['docshort']=[]
|
Chris@87
|
244 ret['latexdoc']=doc[0]
|
Chris@87
|
245 if len(ret['docs'])<=1: ret['docs']=''
|
Chris@87
|
246 return ret, fhooks[0]
|