comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/f2py/auxfuncs.py @ 87:2a2c65a20a8b

Add Python libs and headers
author Chris Cannam
date Wed, 25 Feb 2015 14:05:22 +0000
parents
children
comparison
equal deleted inserted replaced
86:413a9d26189e 87:2a2c65a20a8b
1 #!/usr/bin/env python
2 """
3
4 Auxiliary functions for f2py2e.
5
6 Copyright 1999,2000 Pearu Peterson all rights reserved,
7 Pearu Peterson <pearu@ioc.ee>
8 Permission to use, modify, and distribute this software is given under the
9 terms of the NumPy (BSD style) LICENSE.
10
11
12 NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
13 $Date: 2005/07/24 19:01:55 $
14 Pearu Peterson
15
16 """
17 from __future__ import division, absolute_import, print_function
18
19 import pprint
20 import sys
21 import types
22 from functools import reduce
23
24 from . import __version__
25 from . import cfuncs
26
27 f2py_version = __version__.version
28
29
30 errmess=sys.stderr.write
31 #outmess=sys.stdout.write
32 show=pprint.pprint
33
34 options={}
35 debugoptions=[]
36 wrapfuncs = 1
37
38
39 def outmess(t):
40 if options.get('verbose', 1):
41 sys.stdout.write(t)
42
43 def debugcapi(var):
44 return 'capi' in debugoptions
45
46 def _isstring(var):
47 return 'typespec' in var and var['typespec']=='character' and (not isexternal(var))
48
49 def isstring(var):
50 return _isstring(var) and not isarray(var)
51
52 def ischaracter(var):
53 return isstring(var) and 'charselector' not in var
54
55 def isstringarray(var):
56 return isarray(var) and _isstring(var)
57
58 def isarrayofstrings(var):
59 # leaving out '*' for now so that
60 # `character*(*) a(m)` and `character a(m,*)`
61 # are treated differently. Luckily `character**` is illegal.
62 return isstringarray(var) and var['dimension'][-1]=='(*)'
63
64 def isarray(var):
65 return 'dimension' in var and (not isexternal(var))
66
67 def isscalar(var):
68 return not (isarray(var) or isstring(var) or isexternal(var))
69
70 def iscomplex(var):
71 return isscalar(var) and var.get('typespec') in ['complex', 'double complex']
72
73 def islogical(var):
74 return isscalar(var) and var.get('typespec')=='logical'
75
76 def isinteger(var):
77 return isscalar(var) and var.get('typespec')=='integer'
78
79 def isreal(var):
80 return isscalar(var) and var.get('typespec')=='real'
81
82 def get_kind(var):
83 try:
84 return var['kindselector']['*']
85 except KeyError:
86 try:
87 return var['kindselector']['kind']
88 except KeyError:
89 pass
90
91 def islong_long(var):
92 if not isscalar(var):
93 return 0
94 if var.get('typespec') not in ['integer', 'logical']:
95 return 0
96 return get_kind(var)=='8'
97
98 def isunsigned_char(var):
99 if not isscalar(var):
100 return 0
101 if var.get('typespec') != 'integer':
102 return 0
103 return get_kind(var)=='-1'
104
105 def isunsigned_short(var):
106 if not isscalar(var):
107 return 0
108 if var.get('typespec') != 'integer':
109 return 0
110 return get_kind(var)=='-2'
111
112 def isunsigned(var):
113 if not isscalar(var):
114 return 0
115 if var.get('typespec') != 'integer':
116 return 0
117 return get_kind(var)=='-4'
118
119 def isunsigned_long_long(var):
120 if not isscalar(var):
121 return 0
122 if var.get('typespec') != 'integer':
123 return 0
124 return get_kind(var)=='-8'
125
126 def isdouble(var):
127 if not isscalar(var):
128 return 0
129 if not var.get('typespec')=='real':
130 return 0
131 return get_kind(var)=='8'
132
133 def islong_double(var):
134 if not isscalar(var):
135 return 0
136 if not var.get('typespec')=='real':
137 return 0
138 return get_kind(var)=='16'
139
140 def islong_complex(var):
141 if not iscomplex(var):
142 return 0
143 return get_kind(var)=='32'
144
145 def iscomplexarray(var):
146 return isarray(var) and var.get('typespec') in ['complex', 'double complex']
147
148 def isint1array(var):
149 return isarray(var) and var.get('typespec')=='integer' \
150 and get_kind(var)=='1'
151
152 def isunsigned_chararray(var):
153 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
154 and get_kind(var)=='-1'
155
156 def isunsigned_shortarray(var):
157 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
158 and get_kind(var)=='-2'
159
160 def isunsignedarray(var):
161 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
162 and get_kind(var)=='-4'
163
164 def isunsigned_long_longarray(var):
165 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
166 and get_kind(var)=='-8'
167
168 def issigned_chararray(var):
169 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
170 and get_kind(var)=='1'
171
172 def issigned_shortarray(var):
173 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
174 and get_kind(var)=='2'
175
176 def issigned_array(var):
177 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
178 and get_kind(var)=='4'
179
180 def issigned_long_longarray(var):
181 return isarray(var) and var.get('typespec') in ['integer', 'logical']\
182 and get_kind(var)=='8'
183
184 def isallocatable(var):
185 return 'attrspec' in var and 'allocatable' in var['attrspec']
186
187 def ismutable(var):
188 return not (not 'dimension' in var or isstring(var))
189
190 def ismoduleroutine(rout):
191 return 'modulename' in rout
192
193 def ismodule(rout):
194 return ('block' in rout and 'module'==rout['block'])
195
196 def isfunction(rout):
197 return ('block' in rout and 'function'==rout['block'])
198
199 #def isfunction_wrap(rout):
200 # return wrapfuncs and (iscomplexfunction(rout) or isstringfunction(rout)) and (not isexternal(rout))
201
202 def isfunction_wrap(rout):
203 if isintent_c(rout):
204 return 0
205 return wrapfuncs and isfunction(rout) and (not isexternal(rout))
206
207 def issubroutine(rout):
208 return ('block' in rout and 'subroutine'==rout['block'])
209
210 def issubroutine_wrap(rout):
211 if isintent_c(rout):
212 return 0
213 return issubroutine(rout) and hasassumedshape(rout)
214
215 def hasassumedshape(rout):
216 if rout.get('hasassumedshape'):
217 return True
218 for a in rout['args']:
219 for d in rout['vars'].get(a, {}).get('dimension', []):
220 if d==':':
221 rout['hasassumedshape'] = True
222 return True
223 return False
224
225 def isroutine(rout):
226 return isfunction(rout) or issubroutine(rout)
227
228 def islogicalfunction(rout):
229 if not isfunction(rout):
230 return 0
231 if 'result' in rout:
232 a=rout['result']
233 else:
234 a=rout['name']
235 if a in rout['vars']:
236 return islogical(rout['vars'][a])
237 return 0
238
239 def islong_longfunction(rout):
240 if not isfunction(rout):
241 return 0
242 if 'result' in rout:
243 a=rout['result']
244 else:
245 a=rout['name']
246 if a in rout['vars']:
247 return islong_long(rout['vars'][a])
248 return 0
249
250 def islong_doublefunction(rout):
251 if not isfunction(rout):
252 return 0
253 if 'result' in rout:
254 a=rout['result']
255 else:
256 a=rout['name']
257 if a in rout['vars']:
258 return islong_double(rout['vars'][a])
259 return 0
260
261 def iscomplexfunction(rout):
262 if not isfunction(rout):
263 return 0
264 if 'result' in rout:
265 a=rout['result']
266 else:
267 a=rout['name']
268 if a in rout['vars']:
269 return iscomplex(rout['vars'][a])
270 return 0
271
272 def iscomplexfunction_warn(rout):
273 if iscomplexfunction(rout):
274 outmess("""\
275 **************************************************************
276 Warning: code with a function returning complex value
277 may not work correctly with your Fortran compiler.
278 Run the following test before using it in your applications:
279 $(f2py install dir)/test-site/{b/runme_scalar,e/runme}
280 When using GNU gcc/g77 compilers, codes should work correctly.
281 **************************************************************\n""")
282 return 1
283 return 0
284
285 def isstringfunction(rout):
286 if not isfunction(rout):
287 return 0
288 if 'result' in rout:
289 a=rout['result']
290 else:
291 a=rout['name']
292 if a in rout['vars']:
293 return isstring(rout['vars'][a])
294 return 0
295
296 def hasexternals(rout):
297 return 'externals' in rout and rout['externals']
298
299 def isthreadsafe(rout):
300 return 'f2pyenhancements' in rout and 'threadsafe' in rout['f2pyenhancements']
301
302 def hasvariables(rout):
303 return 'vars' in rout and rout['vars']
304
305 def isoptional(var):
306 return ('attrspec' in var and 'optional' in var['attrspec'] and 'required' not in var['attrspec']) and isintent_nothide(var)
307
308 def isexternal(var):
309 return ('attrspec' in var and 'external' in var['attrspec'])
310
311 def isrequired(var):
312 return not isoptional(var) and isintent_nothide(var)
313
314 def isintent_in(var):
315 if 'intent' not in var:
316 return 1
317 if 'hide' in var['intent']:
318 return 0
319 if 'inplace' in var['intent']:
320 return 0
321 if 'in' in var['intent']:
322 return 1
323 if 'out' in var['intent']:
324 return 0
325 if 'inout' in var['intent']:
326 return 0
327 if 'outin' in var['intent']:
328 return 0
329 return 1
330
331 def isintent_inout(var):
332 return 'intent' in var and ('inout' in var['intent'] or 'outin' in var['intent']) and 'in' not in var['intent'] and 'hide' not in var['intent'] and 'inplace' not in var['intent']
333
334 def isintent_out(var):
335 return 'out' in var.get('intent', [])
336
337 def isintent_hide(var):
338 return ('intent' in var and ('hide' in var['intent'] or ('out' in var['intent'] and 'in' not in var['intent'] and (not l_or(isintent_inout, isintent_inplace)(var)))))
339
340 def isintent_nothide(var):
341 return not isintent_hide(var)
342
343 def isintent_c(var):
344 return 'c' in var.get('intent', [])
345
346 # def isintent_f(var):
347 # return not isintent_c(var)
348
349 def isintent_cache(var):
350 return 'cache' in var.get('intent', [])
351
352 def isintent_copy(var):
353 return 'copy' in var.get('intent', [])
354
355 def isintent_overwrite(var):
356 return 'overwrite' in var.get('intent', [])
357
358 def isintent_callback(var):
359 return 'callback' in var.get('intent', [])
360
361 def isintent_inplace(var):
362 return 'inplace' in var.get('intent', [])
363
364 def isintent_aux(var):
365 return 'aux' in var.get('intent', [])
366
367 def isintent_aligned4(var):
368 return 'aligned4' in var.get('intent', [])
369 def isintent_aligned8(var):
370 return 'aligned8' in var.get('intent', [])
371 def isintent_aligned16(var):
372 return 'aligned16' in var.get('intent', [])
373
374 isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT',
375 isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE',
376 isintent_cache: 'INTENT_CACHE',
377 isintent_c: 'INTENT_C', isoptional: 'OPTIONAL',
378 isintent_inplace: 'INTENT_INPLACE',
379 isintent_aligned4: 'INTENT_ALIGNED4',
380 isintent_aligned8: 'INTENT_ALIGNED8',
381 isintent_aligned16: 'INTENT_ALIGNED16',
382 }
383
384 def isprivate(var):
385 return 'attrspec' in var and 'private' in var['attrspec']
386
387 def hasinitvalue(var):
388 return '=' in var
389
390 def hasinitvalueasstring(var):
391 if not hasinitvalue(var):
392 return 0
393 return var['='][0] in ['"', "'"]
394
395 def hasnote(var):
396 return 'note' in var
397
398 def hasresultnote(rout):
399 if not isfunction(rout):
400 return 0
401 if 'result' in rout:
402 a=rout['result']
403 else:
404 a=rout['name']
405 if a in rout['vars']:
406 return hasnote(rout['vars'][a])
407 return 0
408
409 def hascommon(rout):
410 return 'common' in rout
411
412 def containscommon(rout):
413 if hascommon(rout):
414 return 1
415 if hasbody(rout):
416 for b in rout['body']:
417 if containscommon(b):
418 return 1
419 return 0
420
421 def containsmodule(block):
422 if ismodule(block):
423 return 1
424 if not hasbody(block):
425 return 0
426 for b in block['body']:
427 if containsmodule(b):
428 return 1
429 return 0
430
431 def hasbody(rout):
432 return 'body' in rout
433
434 def hascallstatement(rout):
435 return getcallstatement(rout) is not None
436
437 def istrue(var):
438 return 1
439
440 def isfalse(var):
441 return 0
442
443 class F2PYError(Exception):
444 pass
445
446 class throw_error:
447 def __init__(self, mess):
448 self.mess = mess
449 def __call__(self, var):
450 mess = '\n\n var = %s\n Message: %s\n' % (var, self.mess)
451 raise F2PYError(mess)
452
453 def l_and(*f):
454 l, l2='lambda v', []
455 for i in range(len(f)):
456 l='%s,f%d=f[%d]'%(l, i, i)
457 l2.append('f%d(v)'%(i))
458 return eval('%s:%s'%(l, ' and '.join(l2)))
459
460 def l_or(*f):
461 l, l2='lambda v', []
462 for i in range(len(f)):
463 l='%s,f%d=f[%d]'%(l, i, i)
464 l2.append('f%d(v)'%(i))
465 return eval('%s:%s'%(l, ' or '.join(l2)))
466
467 def l_not(f):
468 return eval('lambda v,f=f:not f(v)')
469
470 def isdummyroutine(rout):
471 try:
472 return rout['f2pyenhancements']['fortranname']==''
473 except KeyError:
474 return 0
475
476 def getfortranname(rout):
477 try:
478 name = rout['f2pyenhancements']['fortranname']
479 if name=='':
480 raise KeyError
481 if not name:
482 errmess('Failed to use fortranname from %s\n'%(rout['f2pyenhancements']))
483 raise KeyError
484 except KeyError:
485 name = rout['name']
486 return name
487
488 def getmultilineblock(rout,blockname,comment=1,counter=0):
489 try:
490 r = rout['f2pyenhancements'].get(blockname)
491 except KeyError:
492 return
493 if not r: return
494 if counter > 0 and isinstance(r, str):
495 return
496 if isinstance(r, list):
497 if counter>=len(r): return
498 r = r[counter]
499 if r[:3]=="'''":
500 if comment:
501 r = '\t/* start ' + blockname + ' multiline ('+repr(counter)+') */\n' + r[3:]
502 else:
503 r = r[3:]
504 if r[-3:]=="'''":
505 if comment:
506 r = r[:-3] + '\n\t/* end multiline ('+repr(counter)+')*/'
507 else:
508 r = r[:-3]
509 else:
510 errmess("%s multiline block should end with `'''`: %s\n" \
511 % (blockname, repr(r)))
512 return r
513
514 def getcallstatement(rout):
515 return getmultilineblock(rout, 'callstatement')
516
517 def getcallprotoargument(rout,cb_map={}):
518 r = getmultilineblock(rout, 'callprotoargument', comment=0)
519 if r: return r
520 if hascallstatement(rout):
521 outmess('warning: callstatement is defined without callprotoargument\n')
522 return
523 from .capi_maps import getctype
524 arg_types, arg_types2 = [], []
525 if l_and(isstringfunction, l_not(isfunction_wrap))(rout):
526 arg_types.extend(['char*', 'size_t'])
527 for n in rout['args']:
528 var = rout['vars'][n]
529 if isintent_callback(var):
530 continue
531 if n in cb_map:
532 ctype = cb_map[n]+'_typedef'
533 else:
534 ctype = getctype(var)
535 if l_and(isintent_c, l_or(isscalar, iscomplex))(var):
536 pass
537 elif isstring(var):
538 pass
539 #ctype = 'void*'
540 else:
541 ctype = ctype+'*'
542 if isstring(var) or isarrayofstrings(var):
543 arg_types2.append('size_t')
544 arg_types.append(ctype)
545
546 proto_args = ','.join(arg_types+arg_types2)
547 if not proto_args:
548 proto_args = 'void'
549 #print proto_args
550 return proto_args
551
552 def getusercode(rout):
553 return getmultilineblock(rout, 'usercode')
554
555 def getusercode1(rout):
556 return getmultilineblock(rout, 'usercode', counter=1)
557
558 def getpymethoddef(rout):
559 return getmultilineblock(rout, 'pymethoddef')
560
561 def getargs(rout):
562 sortargs, args=[], []
563 if 'args' in rout:
564 args=rout['args']
565 if 'sortvars' in rout:
566 for a in rout['sortvars']:
567 if a in args: sortargs.append(a)
568 for a in args:
569 if a not in sortargs:
570 sortargs.append(a)
571 else: sortargs=rout['args']
572 return args, sortargs
573
574 def getargs2(rout):
575 sortargs, args=[], rout.get('args', [])
576 auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])\
577 and a not in args]
578 args = auxvars + args
579 if 'sortvars' in rout:
580 for a in rout['sortvars']:
581 if a in args: sortargs.append(a)
582 for a in args:
583 if a not in sortargs:
584 sortargs.append(a)
585 else: sortargs=auxvars + rout['args']
586 return args, sortargs
587
588 def getrestdoc(rout):
589 if 'f2pymultilines' not in rout:
590 return None
591 k = None
592 if rout['block']=='python module':
593 k = rout['block'], rout['name']
594 return rout['f2pymultilines'].get(k, None)
595
596 def gentitle(name):
597 l=(80-len(name)-6)//2
598 return '/*%s %s %s*/'%(l*'*', name, l*'*')
599
600 def flatlist(l):
601 if isinstance(l, list):
602 return reduce(lambda x,y,f=flatlist:x+f(y), l, [])
603 return [l]
604
605 def stripcomma(s):
606 if s and s[-1]==',': return s[:-1]
607 return s
608
609 def replace(str,d,defaultsep=''):
610 if isinstance(d, list):
611 return [replace(str, _m, defaultsep) for _m in d]
612 if isinstance(str, list):
613 return [replace(_m, d, defaultsep) for _m in str]
614 for k in 2*list(d.keys()):
615 if k=='separatorsfor':
616 continue
617 if 'separatorsfor' in d and k in d['separatorsfor']:
618 sep=d['separatorsfor'][k]
619 else:
620 sep=defaultsep
621 if isinstance(d[k], list):
622 str=str.replace('#%s#'%(k), sep.join(flatlist(d[k])))
623 else:
624 str=str.replace('#%s#'%(k), d[k])
625 return str
626
627 def dictappend(rd, ar):
628 if isinstance(ar, list):
629 for a in ar:
630 rd=dictappend(rd, a)
631 return rd
632 for k in ar.keys():
633 if k[0]=='_':
634 continue
635 if k in rd:
636 if isinstance(rd[k], str):
637 rd[k]=[rd[k]]
638 if isinstance(rd[k], list):
639 if isinstance(ar[k], list):
640 rd[k]=rd[k]+ar[k]
641 else:
642 rd[k].append(ar[k])
643 elif isinstance(rd[k], dict):
644 if isinstance(ar[k], dict):
645 if k=='separatorsfor':
646 for k1 in ar[k].keys():
647 if k1 not in rd[k]:
648 rd[k][k1]=ar[k][k1]
649 else:
650 rd[k]=dictappend(rd[k], ar[k])
651 else:
652 rd[k]=ar[k]
653 return rd
654
655 def applyrules(rules,d,var={}):
656 ret={}
657 if isinstance(rules, list):
658 for r in rules:
659 rr=applyrules(r, d, var)
660 ret=dictappend(ret, rr)
661 if '_break' in rr:
662 break
663 return ret
664 if '_check' in rules and (not rules['_check'](var)):
665 return ret
666 if 'need' in rules:
667 res = applyrules({'needs':rules['need']}, d, var)
668 if 'needs' in res:
669 cfuncs.append_needs(res['needs'])
670
671 for k in rules.keys():
672 if k=='separatorsfor':
673 ret[k]=rules[k]; continue
674 if isinstance(rules[k], str):
675 ret[k]=replace(rules[k], d)
676 elif isinstance(rules[k], list):
677 ret[k]=[]
678 for i in rules[k]:
679 ar=applyrules({k:i}, d, var)
680 if k in ar:
681 ret[k].append(ar[k])
682 elif k[0]=='_':
683 continue
684 elif isinstance(rules[k], dict):
685 ret[k]=[]
686 for k1 in rules[k].keys():
687 if isinstance(k1, types.FunctionType) and k1(var):
688 if isinstance(rules[k][k1], list):
689 for i in rules[k][k1]:
690 if isinstance(i, dict):
691 res=applyrules({'supertext':i}, d, var)
692 if 'supertext' in res:
693 i=res['supertext']
694 else: i=''
695 ret[k].append(replace(i, d))
696 else:
697 i=rules[k][k1]
698 if isinstance(i, dict):
699 res=applyrules({'supertext':i}, d)
700 if 'supertext' in res:
701 i=res['supertext']
702 else: i=''
703 ret[k].append(replace(i, d))
704 else:
705 errmess('applyrules: ignoring rule %s.\n'%repr(rules[k]))
706 if isinstance(ret[k], list):
707 if len(ret[k])==1:
708 ret[k]=ret[k][0]
709 if ret[k]==[]:
710 del ret[k]
711 return ret