Viewing file: auxfuncs.py (19.08 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#!/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 NumPy (BSD style) LICENSE.
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 import types 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 'typespec' in var 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 'charselector' not in var
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 'dimension' in var 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') in ['integer', 'logical']\ and get_kind(var)=='-1'
def isunsigned_shortarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var)=='-2'
def isunsignedarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var)=='-4'
def isunsigned_long_longarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var)=='-8'
def issigned_chararray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var)=='1'
def issigned_shortarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var)=='2'
def issigned_array(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var)=='4'
def issigned_long_longarray(var): return isarray(var) and var.get('typespec') in ['integer', 'logical']\ and get_kind(var)=='8'
def isallocatable(var): return 'attrspec' in var and 'allocatable' in var['attrspec']
def ismutable(var): return not (not 'dimension' in var or isstring(var))
def ismoduleroutine(rout): return 'modulename' in rout
def ismodule(rout): return ('block' in rout and 'module'==rout['block'])
def isfunction(rout): return ('block' in rout 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 ('block' in rout and 'subroutine'==rout['block'])
def isroutine(rout): return isfunction(rout) or issubroutine(rout)
def islogicalfunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a=rout['result'] else: a=rout['name'] if a in rout['vars']: return islogical(rout['vars'][a]) return 0
def islong_longfunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a=rout['result'] else: a=rout['name'] if a in rout['vars']: return islong_long(rout['vars'][a]) return 0
def islong_doublefunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a=rout['result'] else: a=rout['name'] if a in rout['vars']: return islong_double(rout['vars'][a]) return 0
def iscomplexfunction(rout): if not isfunction(rout): return 0 if 'result' in rout: a=rout['result'] else: a=rout['name'] if a in rout['vars']: 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 'result' in rout: a=rout['result'] else: a=rout['name'] if a in rout['vars']: return isstring(rout['vars'][a]) return 0
def hasexternals(rout): return 'externals' in rout and rout['externals']
def isthreadsafe(rout): return 'f2pyenhancements' in rout and 'threadsafe' in rout['f2pyenhancements']
def hasvariables(rout): return 'vars' in rout and rout['vars']
def isoptional(var): return ('attrspec' in var and 'optional' in var['attrspec'] and 'required' not in var['attrspec']) and isintent_nothide(var)
def isexternal(var): return ('attrspec' in var and 'external' in var['attrspec'])
def isrequired(var): return not isoptional(var) and isintent_nothide(var)
def isintent_in(var): if 'intent' not in var: 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 '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']
def isintent_out(var): return 'out' in var.get('intent',[])
def isintent_hide(var): 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)))))
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',[])
def isintent_aligned4(var): return 'aligned4' in var.get('intent',[]) def isintent_aligned8(var): return 'aligned8' in var.get('intent',[]) def isintent_aligned16(var): return 'aligned16' 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', isintent_aligned4:'INTENT_ALIGNED4', isintent_aligned8:'INTENT_ALIGNED8', isintent_aligned16:'INTENT_ALIGNED16', }
def isprivate(var): return 'attrspec' in var and 'private' in var['attrspec']
def hasinitvalue(var): return '=' in var
def hasinitvalueasstring(var): if not hasinitvalue(var): return 0 return var['='][0] in ['"',"'"]
def hasnote(var): return 'note' in var
def hasresultnote(rout): if not isfunction(rout): return 0 if 'result' in rout: a=rout['result'] else: a=rout['name'] if a in rout['vars']: return hasnote(rout['vars'][a]) return 0
def hascommon(rout): return 'common' in rout
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 for b in block['body']: if containsmodule(b): return 1 return 0
def hasbody(rout): return 'body' in rout
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,' and '.join(l2)))
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,' or '.join(l2)))
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 n in cb_map: 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 = ','.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 'args' in rout: args=rout['args'] if 'sortvars' in rout: 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 'sortvars' in rout: 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 'f2pymultilines' not in rout: 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 'separatorsfor' in dict and k in dict['separatorsfor']: sep=dict['separatorsfor'][k] else: sep=defaultsep if type(dict[k])==types.ListType: str=str.replace('#%s#'%(k),sep.join(flatlist(dict[k]))) else: str=str.replace('#%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 k in rd: 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 k1 not in rd[k]: 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 '_break' in rr: break return ret if '_check' in rules and (not rules['_check'](var)): return ret if 'need' in rules: res = applyrules({'needs':rules['need']},dict,var) if 'needs' in res: 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 k in ar: 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 'supertext' in res: 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 'supertext' in res: 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
|