summaryrefslogtreecommitdiff
path: root/numpy/f2py/auxfuncs.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/f2py/auxfuncs.py')
-rw-r--r--numpy/f2py/auxfuncs.py489
1 files changed, 489 insertions, 0 deletions
diff --git a/numpy/f2py/auxfuncs.py b/numpy/f2py/auxfuncs.py
new file mode 100644
index 000000000..51eae0517
--- /dev/null
+++ b/numpy/f2py/auxfuncs.py
@@ -0,0 +1,489 @@
+#!/usr/bin/env python
+"""
+
+Auxiliary functions for f2py2e.
+
+Copyright 1999,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 LGPL. See http://www.fsf.org
+
+NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+$Date: 2005/07/24 19:01:55 $
+Pearu Peterson
+"""
+__version__ = "$Revision: 1.65 $"[10:-1]
+
+import __version__
+f2py_version = __version__.version
+
+import pprint
+import sys,string,time,types,os
+import cfuncs
+
+
+errmess=sys.stderr.write
+#outmess=sys.stdout.write
+show=pprint.pprint
+
+options={}
+debugoptions=[]
+wrapfuncs = 1
+
+def outmess(t):
+ if options.get('verbose',1):
+ sys.stdout.write(t)
+
+def debugcapi(var): return 'capi' in debugoptions
+def _isstring(var):
+ return var.has_key('typespec') and var['typespec']=='character' and (not isexternal(var))
+def isstring(var):
+ return _isstring(var) and not isarray(var)
+def ischaracter(var):
+ return isstring(var) and not (var.has_key('charselector'))
+def isstringarray(var):
+ return isarray(var) and _isstring(var)
+def isarrayofstrings(var):
+ # leaving out '*' for now so that
+ # `character*(*) a(m)` and `character a(m,*)`
+ # are treated differently. Luckily `character**` is illegal.
+ return isstringarray(var) and var['dimension'][-1]=='(*)'
+def isarray(var): return var.has_key('dimension') and (not isexternal(var))
+def isscalar(var): return not (isarray(var) or isstring(var) or isexternal(var))
+def iscomplex(var):
+ return isscalar(var) and var.get('typespec') in ['complex','double complex']
+def islogical(var):
+ return isscalar(var) and var.get('typespec')=='logical'
+def isinteger(var):
+ return isscalar(var) and var.get('typespec')=='integer'
+def isreal(var):
+ return isscalar(var) and var.get('typespec')=='real'
+def get_kind(var):
+ try: return var['kindselector']['*']
+ except KeyError:
+ try: return var['kindselector']['kind']
+ except KeyError: pass
+def islong_long(var):
+ if not isscalar(var): return 0
+ if var.get('typespec') not in ['integer','logical']: return 0
+ return get_kind(var)=='8'
+def isunsigned_char(var):
+ if not isscalar(var): return 0
+ if var.get('typespec') != 'integer': return 0
+ return get_kind(var)=='-1'
+def isunsigned_short(var):
+ if not isscalar(var): return 0
+ if var.get('typespec') != 'integer': return 0
+ return get_kind(var)=='-2'
+def isunsigned(var):
+ if not isscalar(var): return 0
+ if var.get('typespec') != 'integer': return 0
+ return get_kind(var)=='-4'
+def isunsigned_long_long(var):
+ if not isscalar(var): return 0
+ if var.get('typespec') != 'integer': return 0
+ return get_kind(var)=='-8'
+def isdouble(var):
+ if not isscalar(var): return 0
+ if not var.get('typespec')=='real': return 0
+ return get_kind(var)=='8'
+def islong_double(var):
+ if not isscalar(var): return 0
+ if not var.get('typespec')=='real': return 0
+ return get_kind(var)=='16'
+def islong_complex(var):
+ if not iscomplex(var): return 0
+ return get_kind(var)=='32'
+
+def iscomplexarray(var): return isarray(var) and var.get('typespec') in ['complex','double complex']
+def isint1array(var): return isarray(var) and var.get('typespec')=='integer' \
+ and get_kind(var)=='1'
+def isunsigned_chararray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-1'
+def isunsigned_shortarray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-2'
+def isunsignedarray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-4'
+def isunsigned_long_longarray(var): return isarray(var) and var.get('typespec')=='integer' and get_kind(var)=='-8'
+def isallocatable(var):
+ return var.has_key('attrspec') and 'allocatable' in var['attrspec']
+def ismutable(var): return not (not var.has_key('dimension') or isstring(var))
+def ismoduleroutine(rout): return rout.has_key('modulename')
+def ismodule(rout): return (rout.has_key('block') and 'module'==rout['block'])
+def isfunction(rout): return (rout.has_key('block') and 'function'==rout['block'])
+#def isfunction_wrap(rout):
+# return wrapfuncs and (iscomplexfunction(rout) or isstringfunction(rout)) and (not isexternal(rout))
+def isfunction_wrap(rout):
+ if isintent_c(rout): return 0
+ return wrapfuncs and isfunction(rout) and (not isexternal(rout))
+def issubroutine(rout): return (rout.has_key('block') and 'subroutine'==rout['block'])
+def isroutine(rout): return isfunction(rout) or issubroutine(rout)
+def islogicalfunction(rout):
+ if not isfunction(rout): return 0
+ if rout.has_key('result'): a=rout['result']
+ else: a=rout['name']
+ if rout['vars'].has_key(a): return islogical(rout['vars'][a])
+ return 0
+def islong_longfunction(rout):
+ if not isfunction(rout): return 0
+ if rout.has_key('result'): a=rout['result']
+ else: a=rout['name']
+ if rout['vars'].has_key(a): return islong_long(rout['vars'][a])
+ return 0
+def islong_doublefunction(rout):
+ if not isfunction(rout): return 0
+ if rout.has_key('result'): a=rout['result']
+ else: a=rout['name']
+ if rout['vars'].has_key(a): return islong_double(rout['vars'][a])
+ return 0
+def iscomplexfunction(rout):
+ if not isfunction(rout): return 0
+ if rout.has_key('result'): a=rout['result']
+ else: a=rout['name']
+ if rout['vars'].has_key(a): return iscomplex(rout['vars'][a])
+ return 0
+def iscomplexfunction_warn(rout):
+ if iscomplexfunction(rout):
+ outmess("""\
+ **************************************************************
+ Warning: code with a function returning complex value
+ may not work correctly with your Fortran compiler.
+ Run the following test before using it in your applications:
+ $(f2py install dir)/test-site/{b/runme_scalar,e/runme}
+ When using GNU gcc/g77 compilers, codes should work correctly.
+ **************************************************************\n""")
+ return 1
+ return 0
+def isstringfunction(rout):
+ if not isfunction(rout): return 0
+ if rout.has_key('result'): a=rout['result']
+ else: a=rout['name']
+ if rout['vars'].has_key(a): return isstring(rout['vars'][a])
+ return 0
+def hasexternals(rout): return rout.has_key('externals') and rout['externals']
+def isthreadsafe(rout): return rout.has_key('f2pyenhancements') and rout['f2pyenhancements'].has_key('threadsafe')
+def hasvariables(rout): return rout.has_key('vars') and rout['vars']
+def isoptional(var): return (var.has_key('attrspec') and 'optional' in var['attrspec'] and 'required' not in var['attrspec']) and isintent_nothide(var)
+def isexternal(var): return (var.has_key('attrspec') and 'external' in var['attrspec'])
+def isrequired(var): return not isoptional(var) and isintent_nothide(var)
+def isintent_in(var):
+ if not var.has_key('intent'): return 1
+ if 'hide' in var['intent']: return 0
+ if 'inplace' in var['intent']: return 0
+ if 'in' in var['intent']: return 1
+ if 'out' in var['intent']: return 0
+ if 'inout' in var['intent']: return 0
+ if 'outin' in var['intent']: return 0
+ return 1
+def isintent_inout(var): return var.has_key('intent') 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']
+def isintent_out(var):
+ return 'out' in var.get('intent',[])
+def isintent_hide(var): return (var.has_key('intent') 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)))))
+def isintent_nothide(var): return not isintent_hide(var)
+def isintent_c(var):
+ return 'c' in var.get('intent',[])
+# def isintent_f(var):
+# return not isintent_c(var)
+def isintent_cache(var):
+ return 'cache' in var.get('intent',[])
+def isintent_copy(var):
+ return 'copy' in var.get('intent',[])
+def isintent_overwrite(var):
+ return 'overwrite' in var.get('intent',[])
+def isintent_callback(var):
+ return 'callback' in var.get('intent',[])
+def isintent_inplace(var):
+ return 'inplace' in var.get('intent',[])
+def isintent_aux(var):
+ return 'aux' in var.get('intent',[])
+
+isintent_dict = {isintent_in:'INTENT_IN',isintent_inout:'INTENT_INOUT',
+ isintent_out:'INTENT_OUT',isintent_hide:'INTENT_HIDE',
+ isintent_cache:'INTENT_CACHE',
+ isintent_c:'INTENT_C',isoptional:'OPTIONAL',
+ isintent_inplace:'INTENT_INPLACE'
+ }
+
+def isprivate(var):
+ return var.has_key('attrspec') and 'private' in var['attrspec']
+
+def hasinitvalue(var): return var.has_key('=')
+def hasinitvalueasstring(var):
+ if not hasinitvalue(var): return 0
+ return var['='][0] in ['"',"'"]
+def hasnote(var):
+ return var.has_key('note')
+def hasresultnote(rout):
+ if not isfunction(rout): return 0
+ if rout.has_key('result'): a=rout['result']
+ else: a=rout['name']
+ if rout['vars'].has_key(a): return hasnote(rout['vars'][a])
+ return 0
+def hascommon(rout):
+ return rout.has_key('common')
+def containscommon(rout):
+ if hascommon(rout): return 1
+ if hasbody(rout):
+ for b in rout['body']:
+ if containscommon(b): return 1
+ return 0
+def containsmodule(block):
+ if ismodule(block): return 1
+ if not hasbody(block): return 0
+ ret = []
+ for b in block['body']:
+ if containsmodule(b): return 1
+ return 0
+def hasbody(rout):
+ return rout.has_key('body')
+def hascallstatement(rout):
+ return getcallstatement(rout) is not None
+
+def istrue(var): return 1
+def isfalse(var): return 0
+
+class F2PYError(Exception):
+ pass
+
+class throw_error:
+ def __init__(self,mess):
+ self.mess = mess
+ def __call__(self,var):
+ mess = '\n\n var = %s\n Message: %s\n' % (var,self.mess)
+ raise F2PYError,mess
+
+def l_and(*f):
+ l,l2='lambda v',[]
+ for i in range(len(f)):
+ l='%s,f%d=f[%d]'%(l,i,i)
+ l2.append('f%d(v)'%(i))
+ return eval('%s:%s'%(l,string.join(l2,' and ')))
+def l_or(*f):
+ l,l2='lambda v',[]
+ for i in range(len(f)):
+ l='%s,f%d=f[%d]'%(l,i,i)
+ l2.append('f%d(v)'%(i))
+ return eval('%s:%s'%(l,string.join(l2,' or ')))
+def l_not(f):
+ return eval('lambda v,f=f:not f(v)')
+
+def isdummyroutine(rout):
+ try:
+ return rout['f2pyenhancements']['fortranname']==''
+ except KeyError:
+ return 0
+
+def getfortranname(rout):
+ try:
+ name = rout['f2pyenhancements']['fortranname']
+ if name=='':
+ raise KeyError
+ if not name:
+ errmess('Failed to use fortranname from %s\n'%(rout['f2pyenhancements']))
+ raise KeyError
+ except KeyError:
+ name = rout['name']
+ return name
+
+def getmultilineblock(rout,blockname,comment=1,counter=0):
+ try:
+ r = rout['f2pyenhancements'].get(blockname)
+ except KeyError:
+ return
+ if not r: return
+ if counter>0 and type(r) is type(''):
+ return
+ if type(r) is type([]):
+ if counter>=len(r): return
+ r = r[counter]
+ if r[:3]=="'''":
+ if comment:
+ r = '\t/* start ' + blockname + ' multiline ('+`counter`+') */\n' + r[3:]
+ else:
+ r = r[3:]
+ if r[-3:]=="'''":
+ if comment:
+ r = r[:-3] + '\n\t/* end multiline ('+`counter`+')*/'
+ else:
+ r = r[:-3]
+ else:
+ errmess("%s multiline block should end with `'''`: %s\n" \
+ % (blockname,repr(r)))
+ return r
+
+def getcallstatement(rout):
+ return getmultilineblock(rout,'callstatement')
+
+def getcallprotoargument(rout,cb_map={}):
+ r = getmultilineblock(rout,'callprotoargument',comment=0)
+ if r: return r
+ if hascallstatement(rout):
+ outmess('warning: callstatement is defined without callprotoargument\n')
+ return
+ from capi_maps import getctype
+ arg_types,arg_types2 = [],[]
+ if l_and(isstringfunction,l_not(isfunction_wrap))(rout):
+ arg_types.extend(['char*','size_t'])
+ for n in rout['args']:
+ var = rout['vars'][n]
+ if isintent_callback(var):
+ continue
+ if cb_map.has_key(n):
+ ctype = cb_map[n]+'_typedef'
+ else:
+ ctype = getctype(var)
+ if l_and(isintent_c,l_or(isscalar,iscomplex))(var):
+ pass
+ elif isstring(var):
+ pass
+ #ctype = 'void*'
+ else:
+ ctype = ctype+'*'
+ if isstring(var) or isarrayofstrings(var):
+ arg_types2.append('size_t')
+ arg_types.append(ctype)
+
+ proto_args = string.join(arg_types+arg_types2,',')
+ if not proto_args:
+ proto_args = 'void'
+ #print proto_args
+ return proto_args
+
+def getusercode(rout):
+ return getmultilineblock(rout,'usercode')
+def getusercode1(rout):
+ return getmultilineblock(rout,'usercode',counter=1)
+
+def getpymethoddef(rout):
+ return getmultilineblock(rout,'pymethoddef')
+
+def getargs(rout):
+ sortargs,args=[],[]
+ if rout.has_key('args'):
+ args=rout['args']
+ if rout.has_key('sortvars'):
+ for a in rout['sortvars']:
+ if a in args: sortargs.append(a)
+ for a in args:
+ if a not in sortargs:
+ sortargs.append(a)
+ else: sortargs=rout['args']
+ return args,sortargs
+
+def getargs2(rout):
+ sortargs,args=[],rout.get('args',[])
+ auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])\
+ and a not in args]
+ args = auxvars + args
+ if rout.has_key('sortvars'):
+ for a in rout['sortvars']:
+ if a in args: sortargs.append(a)
+ for a in args:
+ if a not in sortargs:
+ sortargs.append(a)
+ else: sortargs=auxvars + rout['args']
+ return args,sortargs
+
+def getrestdoc(rout):
+ if not rout.has_key('f2pymultilines'):
+ return None
+ k = None
+ if rout['block']=='python module':
+ k = rout['block'],rout['name']
+ return rout['f2pymultilines'].get(k,None)
+
+def gentitle(name):
+ l=(80-len(name)-6)/2
+ return '/*%s %s %s*/'%(l*'*',name,l*'*')
+def flatlist(l):
+ if type(l)==types.ListType:
+ return reduce(lambda x,y,f=flatlist:x+f(y),l,[])
+ return [l]
+def stripcomma(s):
+ if s and s[-1]==',': return s[:-1]
+ return s
+def replace(str,dict,defaultsep=''):
+ if type(dict)==types.ListType:
+ return map(lambda d,f=replace,sep=defaultsep,s=str:f(s,d,sep),dict)
+ if type(str)==types.ListType:
+ return map(lambda s,f=replace,sep=defaultsep,d=dict:f(s,d,sep),str)
+ for k in 2*dict.keys():
+ if k=='separatorsfor': continue
+ if dict.has_key('separatorsfor') and dict['separatorsfor'].has_key(k):
+ sep=dict['separatorsfor'][k]
+ else:
+ sep=defaultsep
+ if type(dict[k])==types.ListType:
+ str=string.replace(str,'#%s#'%(k),string.join(flatlist(dict[k]),sep))
+ else:
+ str=string.replace(str,'#%s#'%(k),dict[k])
+ return str
+
+def dictappend(rd,ar):
+ if type(ar)==types.ListType:
+ for a in ar: rd=dictappend(rd,a)
+ return rd
+ for k in ar.keys():
+ if k[0]=='_': continue
+ if rd.has_key(k):
+ if type(rd[k])==types.StringType: rd[k]=[rd[k]]
+ if type(rd[k])==types.ListType:
+ if type(ar[k])==types.ListType: rd[k]=rd[k]+ar[k]
+ else: rd[k].append(ar[k])
+ elif type(rd[k])==types.DictType:
+ if type(ar[k])==types.DictType:
+ if k=='separatorsfor':
+ for k1 in ar[k].keys():
+ if not rd[k].has_key(k1): rd[k][k1]=ar[k][k1]
+ else: rd[k]=dictappend(rd[k],ar[k])
+ else: rd[k]=ar[k]
+ return rd
+
+def applyrules(rules,dict,var={}):
+ ret={}
+ if type(rules)==types.ListType:
+ for r in rules:
+ rr=applyrules(r,dict,var)
+ ret=dictappend(ret,rr)
+ if rr.has_key('_break'): break
+ return ret
+ if rules.has_key('_check') and (not rules['_check'](var)): return ret
+ if rules.has_key('need'):
+ res = applyrules({'needs':rules['need']},dict,var)
+ if res.has_key('needs'):
+ cfuncs.append_needs(res['needs'])
+
+ for k in rules.keys():
+ if k=='separatorsfor': ret[k]=rules[k]; continue
+ if type(rules[k])==types.StringType:
+ ret[k]=replace(rules[k],dict)
+ elif type(rules[k])==types.ListType:
+ ret[k]=[]
+ for i in rules[k]:
+ ar=applyrules({k:i},dict,var)
+ if ar.has_key(k): ret[k].append(ar[k])
+ elif k[0]=='_':
+ continue
+ elif type(rules[k])==types.DictType:
+ ret[k]=[]
+ for k1 in rules[k].keys():
+ if type(k1)==types.FunctionType and k1(var):
+ if type(rules[k][k1])==types.ListType:
+ for i in rules[k][k1]:
+ if type(i)==types.DictType:
+ res=applyrules({'supertext':i},dict,var)
+ if res.has_key('supertext'): i=res['supertext']
+ else: i=''
+ ret[k].append(replace(i,dict))
+ else:
+ i=rules[k][k1]
+ if type(i)==types.DictType:
+ res=applyrules({'supertext':i},dict)
+ if res.has_key('supertext'): i=res['supertext']
+ else: i=''
+ ret[k].append(replace(i,dict))
+ else:
+ errmess('applyrules: ignoring rule %s.\n'%`rules[k]`)
+ if type(ret[k])==types.ListType:
+ if len(ret[k])==1: ret[k]=ret[k][0]
+ if ret[k]==[]: del ret[k]
+ return ret
+
+