Chris@87
|
1 #!/usr/bin/env python
|
Chris@87
|
2 """
|
Chris@87
|
3
|
Chris@87
|
4 Rules for building C/API module with f2py2e.
|
Chris@87
|
5
|
Chris@87
|
6 Copyright 1999,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: 2004/11/26 11:13:06 $
|
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.16 $"[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 copy
|
Chris@87
|
24 import sys
|
Chris@87
|
25 errmess=sys.stderr.write
|
Chris@87
|
26 outmess=sys.stdout.write
|
Chris@87
|
27 show=pprint.pprint
|
Chris@87
|
28
|
Chris@87
|
29 from .auxfuncs import *
|
Chris@87
|
30 def var2fixfortran(vars,a,fa=None,f90mode=None):
|
Chris@87
|
31 if fa is None:
|
Chris@87
|
32 fa = a
|
Chris@87
|
33 if a not in vars:
|
Chris@87
|
34 show(vars)
|
Chris@87
|
35 outmess('var2fixfortran: No definition for argument "%s".\n'%a)
|
Chris@87
|
36 return ''
|
Chris@87
|
37 if 'typespec' not in vars[a]:
|
Chris@87
|
38 show(vars[a])
|
Chris@87
|
39 outmess('var2fixfortran: No typespec for argument "%s".\n'%a)
|
Chris@87
|
40 return ''
|
Chris@87
|
41 vardef=vars[a]['typespec']
|
Chris@87
|
42 if vardef=='type' and 'typename' in vars[a]:
|
Chris@87
|
43 vardef='%s(%s)'%(vardef, vars[a]['typename'])
|
Chris@87
|
44 selector={}
|
Chris@87
|
45 lk = ''
|
Chris@87
|
46 if 'kindselector' in vars[a]:
|
Chris@87
|
47 selector=vars[a]['kindselector']
|
Chris@87
|
48 lk = 'kind'
|
Chris@87
|
49 elif 'charselector' in vars[a]:
|
Chris@87
|
50 selector=vars[a]['charselector']
|
Chris@87
|
51 lk = 'len'
|
Chris@87
|
52 if '*' in selector:
|
Chris@87
|
53 if f90mode:
|
Chris@87
|
54 if selector['*'] in ['*', ':', '(*)']:
|
Chris@87
|
55 vardef='%s(len=*)'%(vardef)
|
Chris@87
|
56 else:
|
Chris@87
|
57 vardef='%s(%s=%s)'%(vardef, lk, selector['*'])
|
Chris@87
|
58 else:
|
Chris@87
|
59 if selector['*'] in ['*', ':']:
|
Chris@87
|
60 vardef='%s*(%s)'%(vardef, selector['*'])
|
Chris@87
|
61 else:
|
Chris@87
|
62 vardef='%s*%s'%(vardef, selector['*'])
|
Chris@87
|
63 else:
|
Chris@87
|
64 if 'len' in selector:
|
Chris@87
|
65 vardef='%s(len=%s'%(vardef, selector['len'])
|
Chris@87
|
66 if 'kind' in selector:
|
Chris@87
|
67 vardef='%s,kind=%s)'%(vardef, selector['kind'])
|
Chris@87
|
68 else:
|
Chris@87
|
69 vardef='%s)'%(vardef)
|
Chris@87
|
70 elif 'kind' in selector:
|
Chris@87
|
71 vardef='%s(kind=%s)'%(vardef, selector['kind'])
|
Chris@87
|
72
|
Chris@87
|
73 vardef='%s %s'%(vardef, fa)
|
Chris@87
|
74 if 'dimension' in vars[a]:
|
Chris@87
|
75 vardef='%s(%s)'%(vardef, ','.join(vars[a]['dimension']))
|
Chris@87
|
76 return vardef
|
Chris@87
|
77
|
Chris@87
|
78 def createfuncwrapper(rout,signature=0):
|
Chris@87
|
79 assert isfunction(rout)
|
Chris@87
|
80
|
Chris@87
|
81 extra_args = []
|
Chris@87
|
82 vars = rout['vars']
|
Chris@87
|
83 for a in rout['args']:
|
Chris@87
|
84 v = rout['vars'][a]
|
Chris@87
|
85 for i, d in enumerate(v.get('dimension', [])):
|
Chris@87
|
86 if d==':':
|
Chris@87
|
87 dn = 'f2py_%s_d%s' % (a, i)
|
Chris@87
|
88 dv = dict(typespec='integer', intent=['hide'])
|
Chris@87
|
89 dv['='] = 'shape(%s, %s)' % (a, i)
|
Chris@87
|
90 extra_args.append(dn)
|
Chris@87
|
91 vars[dn] = dv
|
Chris@87
|
92 v['dimension'][i] = dn
|
Chris@87
|
93 rout['args'].extend(extra_args)
|
Chris@87
|
94 need_interface = bool(extra_args)
|
Chris@87
|
95
|
Chris@87
|
96 ret = ['']
|
Chris@87
|
97 def add(line,ret=ret):
|
Chris@87
|
98 ret[0] = '%s\n %s'%(ret[0], line)
|
Chris@87
|
99 name = rout['name']
|
Chris@87
|
100 fortranname = getfortranname(rout)
|
Chris@87
|
101 f90mode = ismoduleroutine(rout)
|
Chris@87
|
102 newname = '%sf2pywrap'%(name)
|
Chris@87
|
103
|
Chris@87
|
104 if newname not in vars:
|
Chris@87
|
105 vars[newname] = vars[name]
|
Chris@87
|
106 args = [newname]+rout['args'][1:]
|
Chris@87
|
107 else:
|
Chris@87
|
108 args = [newname]+rout['args']
|
Chris@87
|
109
|
Chris@87
|
110 l = var2fixfortran(vars, name, newname, f90mode)
|
Chris@87
|
111 return_char_star = 0
|
Chris@87
|
112 if l[:13]=='character*(*)':
|
Chris@87
|
113 return_char_star = 1
|
Chris@87
|
114 if f90mode: l = 'character(len=10)'+l[13:]
|
Chris@87
|
115 else: l = 'character*10'+l[13:]
|
Chris@87
|
116 charselect = vars[name]['charselector']
|
Chris@87
|
117 if charselect.get('*', '')=='(*)':
|
Chris@87
|
118 charselect['*'] = '10'
|
Chris@87
|
119 sargs = ', '.join(args)
|
Chris@87
|
120 if f90mode:
|
Chris@87
|
121 add('subroutine f2pywrap_%s_%s (%s)'%(rout['modulename'], name, sargs))
|
Chris@87
|
122 if not signature:
|
Chris@87
|
123 add('use %s, only : %s'%(rout['modulename'], fortranname))
|
Chris@87
|
124 else:
|
Chris@87
|
125 add('subroutine f2pywrap%s (%s)'%(name, sargs))
|
Chris@87
|
126 if not need_interface:
|
Chris@87
|
127 add('external %s'%(fortranname))
|
Chris@87
|
128 l = l + ', '+fortranname
|
Chris@87
|
129 if need_interface:
|
Chris@87
|
130 for line in rout['saved_interface'].split('\n'):
|
Chris@87
|
131 if line.lstrip().startswith('use '):
|
Chris@87
|
132 add(line)
|
Chris@87
|
133
|
Chris@87
|
134 args = args[1:]
|
Chris@87
|
135 dumped_args = []
|
Chris@87
|
136 for a in args:
|
Chris@87
|
137 if isexternal(vars[a]):
|
Chris@87
|
138 add('external %s'%(a))
|
Chris@87
|
139 dumped_args.append(a)
|
Chris@87
|
140 for a in args:
|
Chris@87
|
141 if a in dumped_args: continue
|
Chris@87
|
142 if isscalar(vars[a]):
|
Chris@87
|
143 add(var2fixfortran(vars, a, f90mode=f90mode))
|
Chris@87
|
144 dumped_args.append(a)
|
Chris@87
|
145 for a in args:
|
Chris@87
|
146 if a in dumped_args: continue
|
Chris@87
|
147 if isintent_in(vars[a]):
|
Chris@87
|
148 add(var2fixfortran(vars, a, f90mode=f90mode))
|
Chris@87
|
149 dumped_args.append(a)
|
Chris@87
|
150 for a in args:
|
Chris@87
|
151 if a in dumped_args: continue
|
Chris@87
|
152 add(var2fixfortran(vars, a, f90mode=f90mode))
|
Chris@87
|
153
|
Chris@87
|
154 add(l)
|
Chris@87
|
155
|
Chris@87
|
156 if need_interface:
|
Chris@87
|
157 if f90mode:
|
Chris@87
|
158 # f90 module already defines needed interface
|
Chris@87
|
159 pass
|
Chris@87
|
160 else:
|
Chris@87
|
161 add('interface')
|
Chris@87
|
162 add(rout['saved_interface'].lstrip())
|
Chris@87
|
163 add('end interface')
|
Chris@87
|
164
|
Chris@87
|
165 sargs = ', '.join([a for a in args if a not in extra_args])
|
Chris@87
|
166
|
Chris@87
|
167 if not signature:
|
Chris@87
|
168 if islogicalfunction(rout):
|
Chris@87
|
169 add('%s = .not.(.not.%s(%s))'%(newname, fortranname, sargs))
|
Chris@87
|
170 else:
|
Chris@87
|
171 add('%s = %s(%s)'%(newname, fortranname, sargs))
|
Chris@87
|
172 if f90mode:
|
Chris@87
|
173 add('end subroutine f2pywrap_%s_%s'%(rout['modulename'], name))
|
Chris@87
|
174 else:
|
Chris@87
|
175 add('end')
|
Chris@87
|
176 #print '**'*10
|
Chris@87
|
177 #print ret[0]
|
Chris@87
|
178 #print '**'*10
|
Chris@87
|
179 return ret[0]
|
Chris@87
|
180
|
Chris@87
|
181 def createsubrwrapper(rout,signature=0):
|
Chris@87
|
182 assert issubroutine(rout)
|
Chris@87
|
183
|
Chris@87
|
184 extra_args = []
|
Chris@87
|
185 vars = rout['vars']
|
Chris@87
|
186 for a in rout['args']:
|
Chris@87
|
187 v = rout['vars'][a]
|
Chris@87
|
188 for i, d in enumerate(v.get('dimension', [])):
|
Chris@87
|
189 if d==':':
|
Chris@87
|
190 dn = 'f2py_%s_d%s' % (a, i)
|
Chris@87
|
191 dv = dict(typespec='integer', intent=['hide'])
|
Chris@87
|
192 dv['='] = 'shape(%s, %s)' % (a, i)
|
Chris@87
|
193 extra_args.append(dn)
|
Chris@87
|
194 vars[dn] = dv
|
Chris@87
|
195 v['dimension'][i] = dn
|
Chris@87
|
196 rout['args'].extend(extra_args)
|
Chris@87
|
197 need_interface = bool(extra_args)
|
Chris@87
|
198
|
Chris@87
|
199 ret = ['']
|
Chris@87
|
200 def add(line,ret=ret):
|
Chris@87
|
201 ret[0] = '%s\n %s'%(ret[0], line)
|
Chris@87
|
202 name = rout['name']
|
Chris@87
|
203 fortranname = getfortranname(rout)
|
Chris@87
|
204 f90mode = ismoduleroutine(rout)
|
Chris@87
|
205
|
Chris@87
|
206 args = rout['args']
|
Chris@87
|
207
|
Chris@87
|
208 sargs = ', '.join(args)
|
Chris@87
|
209 if f90mode:
|
Chris@87
|
210 add('subroutine f2pywrap_%s_%s (%s)'%(rout['modulename'], name, sargs))
|
Chris@87
|
211 if not signature:
|
Chris@87
|
212 add('use %s, only : %s'%(rout['modulename'], fortranname))
|
Chris@87
|
213 else:
|
Chris@87
|
214 add('subroutine f2pywrap%s (%s)'%(name, sargs))
|
Chris@87
|
215 if not need_interface:
|
Chris@87
|
216 add('external %s'%(fortranname))
|
Chris@87
|
217
|
Chris@87
|
218 if need_interface:
|
Chris@87
|
219 for line in rout['saved_interface'].split('\n'):
|
Chris@87
|
220 if line.lstrip().startswith('use '):
|
Chris@87
|
221 add(line)
|
Chris@87
|
222
|
Chris@87
|
223 dumped_args = []
|
Chris@87
|
224 for a in args:
|
Chris@87
|
225 if isexternal(vars[a]):
|
Chris@87
|
226 add('external %s'%(a))
|
Chris@87
|
227 dumped_args.append(a)
|
Chris@87
|
228 for a in args:
|
Chris@87
|
229 if a in dumped_args: continue
|
Chris@87
|
230 if isscalar(vars[a]):
|
Chris@87
|
231 add(var2fixfortran(vars, a, f90mode=f90mode))
|
Chris@87
|
232 dumped_args.append(a)
|
Chris@87
|
233 for a in args:
|
Chris@87
|
234 if a in dumped_args: continue
|
Chris@87
|
235 add(var2fixfortran(vars, a, f90mode=f90mode))
|
Chris@87
|
236
|
Chris@87
|
237 if need_interface:
|
Chris@87
|
238 if f90mode:
|
Chris@87
|
239 # f90 module already defines needed interface
|
Chris@87
|
240 pass
|
Chris@87
|
241 else:
|
Chris@87
|
242 add('interface')
|
Chris@87
|
243 add(rout['saved_interface'].lstrip())
|
Chris@87
|
244 add('end interface')
|
Chris@87
|
245
|
Chris@87
|
246 sargs = ', '.join([a for a in args if a not in extra_args])
|
Chris@87
|
247
|
Chris@87
|
248 if not signature:
|
Chris@87
|
249 add('call %s(%s)'%(fortranname, sargs))
|
Chris@87
|
250 if f90mode:
|
Chris@87
|
251 add('end subroutine f2pywrap_%s_%s'%(rout['modulename'], name))
|
Chris@87
|
252 else:
|
Chris@87
|
253 add('end')
|
Chris@87
|
254 #print '**'*10
|
Chris@87
|
255 #print ret[0]
|
Chris@87
|
256 #print '**'*10
|
Chris@87
|
257 return ret[0]
|
Chris@87
|
258
|
Chris@87
|
259
|
Chris@87
|
260 def assubr(rout):
|
Chris@87
|
261 if isfunction_wrap(rout):
|
Chris@87
|
262 fortranname = getfortranname(rout)
|
Chris@87
|
263 name = rout['name']
|
Chris@87
|
264 outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n'%(name, fortranname))
|
Chris@87
|
265 rout = copy.copy(rout)
|
Chris@87
|
266 fname = name
|
Chris@87
|
267 rname = fname
|
Chris@87
|
268 if 'result' in rout:
|
Chris@87
|
269 rname = rout['result']
|
Chris@87
|
270 rout['vars'][fname]=rout['vars'][rname]
|
Chris@87
|
271 fvar = rout['vars'][fname]
|
Chris@87
|
272 if not isintent_out(fvar):
|
Chris@87
|
273 if 'intent' not in fvar:
|
Chris@87
|
274 fvar['intent']=[]
|
Chris@87
|
275 fvar['intent'].append('out')
|
Chris@87
|
276 flag=1
|
Chris@87
|
277 for i in fvar['intent']:
|
Chris@87
|
278 if i.startswith('out='):
|
Chris@87
|
279 flag = 0
|
Chris@87
|
280 break
|
Chris@87
|
281 if flag:
|
Chris@87
|
282 fvar['intent'].append('out=%s' % (rname))
|
Chris@87
|
283 rout['args'][:] = [fname] + rout['args']
|
Chris@87
|
284 return rout, createfuncwrapper(rout)
|
Chris@87
|
285 if issubroutine_wrap(rout):
|
Chris@87
|
286 fortranname = getfortranname(rout)
|
Chris@87
|
287 name = rout['name']
|
Chris@87
|
288 outmess('\t\tCreating wrapper for Fortran subroutine "%s"("%s")...\n'%(name, fortranname))
|
Chris@87
|
289 rout = copy.copy(rout)
|
Chris@87
|
290 return rout, createsubrwrapper(rout)
|
Chris@87
|
291 return rout, ''
|