Chris@87: #!/usr/bin/env python Chris@87: """ Chris@87: Chris@87: Copyright 1999,2000 Pearu Peterson all rights reserved, Chris@87: Pearu Peterson Chris@87: Permission to use, modify, and distribute this software is given under the Chris@87: terms of the NumPy License. Chris@87: Chris@87: NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. Chris@87: $Date: 2005/05/06 10:57:33 $ Chris@87: Pearu Peterson Chris@87: Chris@87: """ Chris@87: from __future__ import division, absolute_import, print_function Chris@87: Chris@87: __version__ = "$Revision: 1.60 $"[10:-1] Chris@87: Chris@87: from . import __version__ Chris@87: f2py_version = __version__.version Chris@87: Chris@87: import copy Chris@87: import re Chris@87: import os Chris@87: import sys Chris@87: from .auxfuncs import * Chris@87: from .crackfortran import markoutercomma Chris@87: from . import cb_rules Chris@87: Chris@87: # Numarray and Numeric users should set this False Chris@87: using_newcore = True Chris@87: Chris@87: depargs=[] Chris@87: lcb_map={} Chris@87: lcb2_map={} Chris@87: # forced casting: mainly caused by the fact that Python or Numeric Chris@87: # C/APIs do not support the corresponding C types. Chris@87: c2py_map={'double': 'float', Chris@87: 'float': 'float', # forced casting Chris@87: 'long_double': 'float', # forced casting Chris@87: 'char': 'int', # forced casting Chris@87: 'signed_char': 'int', # forced casting Chris@87: 'unsigned_char': 'int', # forced casting Chris@87: 'short': 'int', # forced casting Chris@87: 'unsigned_short': 'int', # forced casting Chris@87: 'int': 'int', # (forced casting) Chris@87: 'long': 'int', Chris@87: 'long_long': 'long', Chris@87: 'unsigned': 'int', # forced casting Chris@87: 'complex_float': 'complex', # forced casting Chris@87: 'complex_double': 'complex', Chris@87: 'complex_long_double': 'complex', # forced casting Chris@87: 'string': 'string', Chris@87: } Chris@87: c2capi_map={'double':'NPY_DOUBLE', Chris@87: 'float':'NPY_FLOAT', Chris@87: 'long_double':'NPY_DOUBLE', # forced casting Chris@87: 'char':'NPY_CHAR', Chris@87: 'unsigned_char':'NPY_UBYTE', Chris@87: 'signed_char':'NPY_BYTE', Chris@87: 'short':'NPY_SHORT', Chris@87: 'unsigned_short':'NPY_USHORT', Chris@87: 'int':'NPY_INT', Chris@87: 'unsigned':'NPY_UINT', Chris@87: 'long':'NPY_LONG', Chris@87: 'long_long':'NPY_LONG', # forced casting Chris@87: 'complex_float':'NPY_CFLOAT', Chris@87: 'complex_double':'NPY_CDOUBLE', Chris@87: 'complex_long_double':'NPY_CDOUBLE', # forced casting Chris@87: 'string':'NPY_CHAR'} Chris@87: Chris@87: #These new maps aren't used anyhere yet, but should be by default Chris@87: # unless building numeric or numarray extensions. Chris@87: if using_newcore: Chris@87: c2capi_map={'double': 'NPY_DOUBLE', Chris@87: 'float': 'NPY_FLOAT', Chris@87: 'long_double': 'NPY_LONGDOUBLE', Chris@87: 'char': 'NPY_BYTE', Chris@87: 'unsigned_char': 'NPY_UBYTE', Chris@87: 'signed_char': 'NPY_BYTE', Chris@87: 'short': 'NPY_SHORT', Chris@87: 'unsigned_short': 'NPY_USHORT', Chris@87: 'int': 'NPY_INT', Chris@87: 'unsigned': 'NPY_UINT', Chris@87: 'long': 'NPY_LONG', Chris@87: 'unsigned_long': 'NPY_ULONG', Chris@87: 'long_long': 'NPY_LONGLONG', Chris@87: 'unsigned_long_long': 'NPY_ULONGLONG', Chris@87: 'complex_float': 'NPY_CFLOAT', Chris@87: 'complex_double': 'NPY_CDOUBLE', Chris@87: 'complex_long_double': 'NPY_CDOUBLE', Chris@87: 'string': 'NPY_CHAR', # f2py 2e is not ready for NPY_STRING (must set itemisize etc) Chris@87: #'string':'NPY_STRING' Chris@87: Chris@87: } Chris@87: c2pycode_map={'double':'d', Chris@87: 'float':'f', Chris@87: 'long_double':'d', # forced casting Chris@87: 'char':'1', Chris@87: 'signed_char':'1', Chris@87: 'unsigned_char':'b', Chris@87: 'short':'s', Chris@87: 'unsigned_short':'w', Chris@87: 'int':'i', Chris@87: 'unsigned':'u', Chris@87: 'long':'l', Chris@87: 'long_long':'L', Chris@87: 'complex_float':'F', Chris@87: 'complex_double':'D', Chris@87: 'complex_long_double':'D', # forced casting Chris@87: 'string':'c' Chris@87: } Chris@87: if using_newcore: Chris@87: c2pycode_map={'double':'d', Chris@87: 'float':'f', Chris@87: 'long_double':'g', Chris@87: 'char':'b', Chris@87: 'unsigned_char':'B', Chris@87: 'signed_char':'b', Chris@87: 'short':'h', Chris@87: 'unsigned_short':'H', Chris@87: 'int':'i', Chris@87: 'unsigned':'I', Chris@87: 'long':'l', Chris@87: 'unsigned_long':'L', Chris@87: 'long_long':'q', Chris@87: 'unsigned_long_long':'Q', Chris@87: 'complex_float':'F', Chris@87: 'complex_double':'D', Chris@87: 'complex_long_double':'G', Chris@87: 'string':'S'} Chris@87: c2buildvalue_map={'double':'d', Chris@87: 'float':'f', Chris@87: 'char':'b', Chris@87: 'signed_char':'b', Chris@87: 'short':'h', Chris@87: 'int':'i', Chris@87: 'long':'l', Chris@87: 'long_long':'L', Chris@87: 'complex_float':'N', Chris@87: 'complex_double':'N', Chris@87: 'complex_long_double':'N', Chris@87: 'string':'z'} Chris@87: Chris@87: if sys.version_info[0] >= 3: Chris@87: # Bytes, not Unicode strings Chris@87: c2buildvalue_map['string'] = 'y' Chris@87: Chris@87: if using_newcore: Chris@87: #c2buildvalue_map=??? Chris@87: pass Chris@87: Chris@87: f2cmap_all={'real':{'':'float','4':'float','8':'double','12':'long_double','16':'long_double'}, Chris@87: 'integer':{'':'int','1':'signed_char','2':'short','4':'int','8':'long_long', Chris@87: '-1':'unsigned_char','-2':'unsigned_short','-4':'unsigned', Chris@87: '-8':'unsigned_long_long'}, Chris@87: 'complex':{'':'complex_float','8':'complex_float', Chris@87: '16':'complex_double','24':'complex_long_double', Chris@87: '32':'complex_long_double'}, Chris@87: 'complexkind':{'':'complex_float','4':'complex_float', Chris@87: '8':'complex_double','12':'complex_long_double', Chris@87: '16':'complex_long_double'}, Chris@87: 'logical':{'':'int','1':'char','2':'short','4':'int','8':'long_long'}, Chris@87: 'double complex':{'':'complex_double'}, Chris@87: 'double precision':{'':'double'}, Chris@87: 'byte':{'':'char'}, Chris@87: 'character':{'':'string'} Chris@87: } Chris@87: Chris@87: if os.path.isfile('.f2py_f2cmap'): Chris@87: # User defined additions to f2cmap_all. Chris@87: # .f2py_f2cmap must contain a dictionary of dictionaries, only. Chris@87: # For example, {'real':{'low':'float'}} means that Fortran 'real(low)' is Chris@87: # interpreted as C 'float'. Chris@87: # This feature is useful for F90/95 users if they use PARAMETERSs Chris@87: # in type specifications. Chris@87: try: Chris@87: outmess('Reading .f2py_f2cmap ...\n') Chris@87: f = open('.f2py_f2cmap', 'r') Chris@87: d = eval(f.read(), {}, {}) Chris@87: f.close() Chris@87: for k, d1 in d.items(): Chris@87: for k1 in d1.keys(): Chris@87: d1[k1.lower()] = d1[k1] Chris@87: d[k.lower()] = d[k] Chris@87: for k in d.keys(): Chris@87: if k not in f2cmap_all: Chris@87: f2cmap_all[k]={} Chris@87: for k1 in d[k].keys(): Chris@87: if d[k][k1] in c2py_map: Chris@87: if k1 in f2cmap_all[k]: Chris@87: outmess("\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n"%(k, k1, f2cmap_all[k][k1], d[k][k1])) Chris@87: f2cmap_all[k][k1] = d[k][k1] Chris@87: outmess('\tMapping "%s(kind=%s)" to "%s"\n' % (k, k1, d[k][k1])) Chris@87: else: Chris@87: errmess("\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n"%(k, k1, d[k][k1], d[k][k1], list(c2py_map.keys()))) Chris@87: outmess('Succesfully applied user defined changes from .f2py_f2cmap\n') Chris@87: except Exception as msg: Chris@87: errmess('Failed to apply user defined changes from .f2py_f2cmap: %s. Skipping.\n' % (msg)) Chris@87: cformat_map={'double': '%g', Chris@87: 'float': '%g', Chris@87: 'long_double': '%Lg', Chris@87: 'char': '%d', Chris@87: 'signed_char': '%d', Chris@87: 'unsigned_char': '%hhu', Chris@87: 'short': '%hd', Chris@87: 'unsigned_short': '%hu', Chris@87: 'int': '%d', Chris@87: 'unsigned': '%u', Chris@87: 'long': '%ld', Chris@87: 'unsigned_long': '%lu', Chris@87: 'long_long': '%ld', Chris@87: 'complex_float': '(%g,%g)', Chris@87: 'complex_double': '(%g,%g)', Chris@87: 'complex_long_double': '(%Lg,%Lg)', Chris@87: 'string': '%s', Chris@87: } Chris@87: Chris@87: ############### Auxiliary functions Chris@87: def getctype(var): Chris@87: """ Chris@87: Determines C type Chris@87: """ Chris@87: ctype='void' Chris@87: if isfunction(var): Chris@87: if 'result' in var: Chris@87: a=var['result'] Chris@87: else: Chris@87: a=var['name'] Chris@87: if a in var['vars']: Chris@87: return getctype(var['vars'][a]) Chris@87: else: Chris@87: errmess('getctype: function %s has no return value?!\n'%a) Chris@87: elif issubroutine(var): Chris@87: return ctype Chris@87: elif 'typespec' in var and var['typespec'].lower() in f2cmap_all: Chris@87: typespec = var['typespec'].lower() Chris@87: f2cmap=f2cmap_all[typespec] Chris@87: ctype=f2cmap[''] # default type Chris@87: if 'kindselector' in var: Chris@87: if '*' in var['kindselector']: Chris@87: try: Chris@87: ctype=f2cmap[var['kindselector']['*']] Chris@87: except KeyError: Chris@87: errmess('getctype: "%s %s %s" not supported.\n'%(var['typespec'], '*', var['kindselector']['*'])) Chris@87: elif 'kind' in var['kindselector']: Chris@87: if typespec+'kind' in f2cmap_all: Chris@87: f2cmap=f2cmap_all[typespec+'kind'] Chris@87: try: Chris@87: ctype=f2cmap[var['kindselector']['kind']] Chris@87: except KeyError: Chris@87: if typespec in f2cmap_all: Chris@87: f2cmap=f2cmap_all[typespec] Chris@87: try: Chris@87: ctype=f2cmap[str(var['kindselector']['kind'])] Chris@87: except KeyError: Chris@87: errmess('getctype: "%s(kind=%s)" is mapped to C "%s" (to override define dict(%s = dict(%s="")) in %s/.f2py_f2cmap file).\n'\ Chris@87: %(typespec, var['kindselector']['kind'], ctype, Chris@87: typespec, var['kindselector']['kind'], os.getcwd())) Chris@87: Chris@87: else: Chris@87: if not isexternal(var): Chris@87: errmess('getctype: No C-type found in "%s", assuming void.\n'%var) Chris@87: return ctype Chris@87: Chris@87: def getstrlength(var): Chris@87: if isstringfunction(var): Chris@87: if 'result' in var: Chris@87: a=var['result'] Chris@87: else: Chris@87: a=var['name'] Chris@87: if a in var['vars']: Chris@87: return getstrlength(var['vars'][a]) Chris@87: else: Chris@87: errmess('getstrlength: function %s has no return value?!\n'%a) Chris@87: if not isstring(var): Chris@87: errmess('getstrlength: expected a signature of a string but got: %s\n'%(repr(var))) Chris@87: len='1' Chris@87: if 'charselector' in var: Chris@87: a=var['charselector'] Chris@87: if '*' in a: Chris@87: len=a['*'] Chris@87: elif 'len' in a: Chris@87: len=a['len'] Chris@87: if re.match(r'\(\s*([*]|[:])\s*\)', len) or re.match(r'([*]|[:])', len): Chris@87: #if len in ['(*)','*','(:)',':']: Chris@87: if isintent_hide(var): Chris@87: errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n'%(repr(var))) Chris@87: len='-1' Chris@87: return len Chris@87: Chris@87: def getarrdims(a,var,verbose=0): Chris@87: global depargs Chris@87: ret={} Chris@87: if isstring(var) and not isarray(var): Chris@87: ret['dims']=getstrlength(var) Chris@87: ret['size']=ret['dims'] Chris@87: ret['rank']='1' Chris@87: elif isscalar(var): Chris@87: ret['size']='1' Chris@87: ret['rank']='0' Chris@87: ret['dims']='' Chris@87: elif isarray(var): Chris@87: # if not isintent_c(var): Chris@87: # var['dimension'].reverse() Chris@87: dim=copy.copy(var['dimension']) Chris@87: ret['size']='*'.join(dim) Chris@87: try: ret['size']=repr(eval(ret['size'])) Chris@87: except: pass Chris@87: ret['dims']=','.join(dim) Chris@87: ret['rank']=repr(len(dim)) Chris@87: ret['rank*[-1]']=repr(len(dim)*[-1])[1:-1] Chris@87: for i in range(len(dim)): # solve dim for dependecies Chris@87: v=[] Chris@87: if dim[i] in depargs: v=[dim[i]] Chris@87: else: Chris@87: for va in depargs: Chris@87: if re.match(r'.*?\b%s\b.*'%va, dim[i]): Chris@87: v.append(va) Chris@87: for va in v: Chris@87: if depargs.index(va)>depargs.index(a): Chris@87: dim[i]='*' Chris@87: break Chris@87: ret['setdims'], i='', -1 Chris@87: for d in dim: Chris@87: i=i+1 Chris@87: if d not in ['*', ':', '(*)', '(:)']: Chris@87: ret['setdims']='%s#varname#_Dims[%d]=%s,'%(ret['setdims'], i, d) Chris@87: if ret['setdims']: ret['setdims']=ret['setdims'][:-1] Chris@87: ret['cbsetdims'], i='', -1 Chris@87: for d in var['dimension']: Chris@87: i=i+1 Chris@87: if d not in ['*', ':', '(*)', '(:)']: Chris@87: ret['cbsetdims']='%s#varname#_Dims[%d]=%s,'%(ret['cbsetdims'], i, d) Chris@87: elif isintent_in(var): Chris@87: outmess('getarrdims:warning: assumed shape array, using 0 instead of %r\n' \ Chris@87: % (d)) Chris@87: ret['cbsetdims']='%s#varname#_Dims[%d]=%s,'%(ret['cbsetdims'], i, 0) Chris@87: elif verbose : Chris@87: errmess('getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n'%(repr(a), repr(d))) Chris@87: if ret['cbsetdims']: ret['cbsetdims']=ret['cbsetdims'][:-1] Chris@87: # if not isintent_c(var): Chris@87: # var['dimension'].reverse() Chris@87: return ret Chris@87: Chris@87: def getpydocsign(a, var): Chris@87: global lcb_map Chris@87: if isfunction(var): Chris@87: if 'result' in var: Chris@87: af=var['result'] Chris@87: else: Chris@87: af=var['name'] Chris@87: if af in var['vars']: Chris@87: return getpydocsign(af, var['vars'][af]) Chris@87: else: Chris@87: errmess('getctype: function %s has no return value?!\n'%af) Chris@87: return '', '' Chris@87: sig, sigout=a, a Chris@87: opt='' Chris@87: if isintent_in(var): opt='input' Chris@87: elif isintent_inout(var): opt='in/output' Chris@87: out_a = a Chris@87: if isintent_out(var): Chris@87: for k in var['intent']: Chris@87: if k[:4]=='out=': Chris@87: out_a = k[4:] Chris@87: break Chris@87: init='' Chris@87: ctype=getctype(var) Chris@87: Chris@87: if hasinitvalue(var): Chris@87: init, showinit=getinit(a, var) Chris@87: init = ', optional\\n Default: %s' % showinit Chris@87: if isscalar(var): Chris@87: if isintent_inout(var): Chris@87: sig='%s : %s rank-0 array(%s,\'%s\')%s'%(a, opt, c2py_map[ctype], Chris@87: c2pycode_map[ctype], init) Chris@87: else: Chris@87: sig='%s : %s %s%s'%(a, opt, c2py_map[ctype], init) Chris@87: sigout='%s : %s'%(out_a, c2py_map[ctype]) Chris@87: elif isstring(var): Chris@87: if isintent_inout(var): Chris@87: sig='%s : %s rank-0 array(string(len=%s),\'c\')%s'%(a, opt, getstrlength(var), init) Chris@87: else: Chris@87: sig='%s : %s string(len=%s)%s'%(a, opt, getstrlength(var), init) Chris@87: sigout='%s : string(len=%s)'%(out_a, getstrlength(var)) Chris@87: elif isarray(var): Chris@87: dim=var['dimension'] Chris@87: rank=repr(len(dim)) Chris@87: sig='%s : %s rank-%s array(\'%s\') with bounds (%s)%s'%(a, opt, rank, Chris@87: c2pycode_map[ctype], Chris@87: ','.join(dim), init) Chris@87: if a==out_a: Chris@87: sigout='%s : rank-%s array(\'%s\') with bounds (%s)'\ Chris@87: %(a, rank, c2pycode_map[ctype], ','.join(dim)) Chris@87: else: Chris@87: sigout='%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\ Chris@87: %(out_a, rank, c2pycode_map[ctype], ','.join(dim), a) Chris@87: elif isexternal(var): Chris@87: ua='' Chris@87: if a in lcb_map and lcb_map[a] in lcb2_map and 'argname' in lcb2_map[lcb_map[a]]: Chris@87: ua=lcb2_map[lcb_map[a]]['argname'] Chris@87: if not ua==a: ua=' => %s'%ua Chris@87: else: ua='' Chris@87: sig='%s : call-back function%s'%(a, ua) Chris@87: sigout=sig Chris@87: else: Chris@87: errmess('getpydocsign: Could not resolve docsignature for "%s".\\n'%a) Chris@87: return sig, sigout Chris@87: Chris@87: def getarrdocsign(a, var): Chris@87: ctype=getctype(var) Chris@87: if isstring(var) and (not isarray(var)): Chris@87: sig='%s : rank-0 array(string(len=%s),\'c\')'%(a, getstrlength(var)) Chris@87: elif isscalar(var): Chris@87: sig='%s : rank-0 array(%s,\'%s\')'%(a, c2py_map[ctype], Chris@87: c2pycode_map[ctype],) Chris@87: elif isarray(var): Chris@87: dim=var['dimension'] Chris@87: rank=repr(len(dim)) Chris@87: sig='%s : rank-%s array(\'%s\') with bounds (%s)'%(a, rank, Chris@87: c2pycode_map[ctype], Chris@87: ','.join(dim)) Chris@87: return sig Chris@87: Chris@87: def getinit(a, var): Chris@87: if isstring(var): init, showinit='""', "''" Chris@87: else: init, showinit='', '' Chris@87: if hasinitvalue(var): Chris@87: init=var['='] Chris@87: showinit=init Chris@87: if iscomplex(var) or iscomplexarray(var): Chris@87: ret={} Chris@87: Chris@87: try: Chris@87: v = var["="] Chris@87: if ',' in v: Chris@87: ret['init.r'], ret['init.i']=markoutercomma(v[1:-1]).split('@,@') Chris@87: else: Chris@87: v = eval(v, {}, {}) Chris@87: ret['init.r'], ret['init.i']=str(v.real), str(v.imag) Chris@87: except: Chris@87: raise ValueError('getinit: expected complex number `(r,i)\' but got `%s\' as initial value of %r.' % (init, a)) Chris@87: if isarray(var): Chris@87: init='(capi_c.r=%s,capi_c.i=%s,capi_c)'%(ret['init.r'], ret['init.i']) Chris@87: elif isstring(var): Chris@87: if not init: init, showinit='""', "''" Chris@87: if init[0]=="'": Chris@87: init='"%s"'%(init[1:-1].replace('"', '\\"')) Chris@87: if init[0]=='"': showinit="'%s'"%(init[1:-1]) Chris@87: return init, showinit Chris@87: Chris@87: def sign2map(a, var): Chris@87: """ Chris@87: varname,ctype,atype Chris@87: init,init.r,init.i,pytype Chris@87: vardebuginfo,vardebugshowvalue,varshowvalue Chris@87: varrfromat Chris@87: intent Chris@87: """ Chris@87: global lcb_map, cb_map Chris@87: out_a = a Chris@87: if isintent_out(var): Chris@87: for k in var['intent']: Chris@87: if k[:4]=='out=': Chris@87: out_a = k[4:] Chris@87: break Chris@87: ret={'varname':a,'outvarname':out_a} Chris@87: ret['ctype']=getctype(var) Chris@87: intent_flags = [] Chris@87: for f, s in isintent_dict.items(): Chris@87: if f(var): intent_flags.append('F2PY_%s'%s) Chris@87: if intent_flags: Chris@87: #XXX: Evaluate intent_flags here. Chris@87: ret['intent'] = '|'.join(intent_flags) Chris@87: else: Chris@87: ret['intent'] = 'F2PY_INTENT_IN' Chris@87: if isarray(var): ret['varrformat']='N' Chris@87: elif ret['ctype'] in c2buildvalue_map: Chris@87: ret['varrformat']=c2buildvalue_map[ret['ctype']] Chris@87: else: ret['varrformat']='O' Chris@87: ret['init'], ret['showinit']=getinit(a, var) Chris@87: if hasinitvalue(var) and iscomplex(var) and not isarray(var): Chris@87: ret['init.r'], ret['init.i'] = markoutercomma(ret['init'][1:-1]).split('@,@') Chris@87: if isexternal(var): Chris@87: ret['cbnamekey']=a Chris@87: if a in lcb_map: Chris@87: ret['cbname']=lcb_map[a] Chris@87: ret['maxnofargs']=lcb2_map[lcb_map[a]]['maxnofargs'] Chris@87: ret['nofoptargs']=lcb2_map[lcb_map[a]]['nofoptargs'] Chris@87: ret['cbdocstr']=lcb2_map[lcb_map[a]]['docstr'] Chris@87: ret['cblatexdocstr']=lcb2_map[lcb_map[a]]['latexdocstr'] Chris@87: else: Chris@87: ret['cbname']=a Chris@87: errmess('sign2map: Confused: external %s is not in lcb_map%s.\n'%(a, list(lcb_map.keys()))) Chris@87: if isstring(var): Chris@87: ret['length']=getstrlength(var) Chris@87: if isarray(var): Chris@87: ret=dictappend(ret, getarrdims(a, var)) Chris@87: dim=copy.copy(var['dimension']) Chris@87: if ret['ctype'] in c2capi_map: Chris@87: ret['atype']=c2capi_map[ret['ctype']] Chris@87: # Debug info Chris@87: if debugcapi(var): Chris@87: il=[isintent_in, 'input', isintent_out, 'output', Chris@87: isintent_inout, 'inoutput', isrequired, 'required', Chris@87: isoptional, 'optional', isintent_hide, 'hidden', Chris@87: iscomplex, 'complex scalar', Chris@87: l_and(isscalar, l_not(iscomplex)), 'scalar', Chris@87: isstring, 'string', isarray, 'array', Chris@87: iscomplexarray, 'complex array', isstringarray, 'string array', Chris@87: iscomplexfunction, 'complex function', Chris@87: l_and(isfunction, l_not(iscomplexfunction)), 'function', Chris@87: isexternal, 'callback', Chris@87: isintent_callback, 'callback', Chris@87: isintent_aux, 'auxiliary', Chris@87: #ismutable,'mutable',l_not(ismutable),'immutable', Chris@87: ] Chris@87: rl=[] Chris@87: for i in range(0, len(il), 2): Chris@87: if il[i](var): rl.append(il[i+1]) Chris@87: if isstring(var): Chris@87: rl.append('slen(%s)=%s'%(a, ret['length'])) Chris@87: if isarray(var): Chris@87: # if not isintent_c(var): Chris@87: # var['dimension'].reverse() Chris@87: ddim=','.join(map(lambda x, y:'%s|%s'%(x, y), var['dimension'], dim)) Chris@87: rl.append('dims(%s)'%ddim) Chris@87: # if not isintent_c(var): Chris@87: # var['dimension'].reverse() Chris@87: if isexternal(var): Chris@87: ret['vardebuginfo']='debug-capi:%s=>%s:%s'%(a, ret['cbname'], ','.join(rl)) Chris@87: else: Chris@87: ret['vardebuginfo']='debug-capi:%s %s=%s:%s'%(ret['ctype'], a, ret['showinit'], ','.join(rl)) Chris@87: if isscalar(var): Chris@87: if ret['ctype'] in cformat_map: Chris@87: ret['vardebugshowvalue']='debug-capi:%s=%s'%(a, cformat_map[ret['ctype']]) Chris@87: if isstring(var): Chris@87: ret['vardebugshowvalue']='debug-capi:slen(%s)=%%d %s=\\"%%s\\"'%(a, a) Chris@87: if isexternal(var): Chris@87: ret['vardebugshowvalue']='debug-capi:%s=%%p'%(a) Chris@87: if ret['ctype'] in cformat_map: Chris@87: ret['varshowvalue']='#name#:%s=%s'%(a, cformat_map[ret['ctype']]) Chris@87: ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) Chris@87: if isstring(var): Chris@87: ret['varshowvalue']='#name#:slen(%s)=%%d %s=\\"%%s\\"'%(a, a) Chris@87: ret['pydocsign'], ret['pydocsignout']=getpydocsign(a, var) Chris@87: if hasnote(var): Chris@87: ret['note']=var['note'] Chris@87: return ret Chris@87: Chris@87: def routsign2map(rout): Chris@87: """ Chris@87: name,NAME,begintitle,endtitle Chris@87: rname,ctype,rformat Chris@87: routdebugshowvalue Chris@87: """ Chris@87: global lcb_map Chris@87: name = rout['name'] Chris@87: fname = getfortranname(rout) Chris@87: ret={'name': name, Chris@87: 'texname': name.replace('_', '\\_'), Chris@87: 'name_lower': name.lower(), Chris@87: 'NAME': name.upper(), Chris@87: 'begintitle': gentitle(name), Chris@87: 'endtitle': gentitle('end of %s'%name), Chris@87: 'fortranname': fname, Chris@87: 'FORTRANNAME': fname.upper(), Chris@87: 'callstatement': getcallstatement(rout) or '', Chris@87: 'usercode': getusercode(rout) or '', Chris@87: 'usercode1': getusercode1(rout) or '', Chris@87: } Chris@87: if '_' in fname: Chris@87: ret['F_FUNC'] = 'F_FUNC_US' Chris@87: else: Chris@87: ret['F_FUNC'] = 'F_FUNC' Chris@87: if '_' in name: Chris@87: ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US' Chris@87: else: Chris@87: ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC' Chris@87: lcb_map={} Chris@87: if 'use' in rout: Chris@87: for u in rout['use'].keys(): Chris@87: if u in cb_rules.cb_map: Chris@87: for un in cb_rules.cb_map[u]: Chris@87: ln=un[0] Chris@87: if 'map' in rout['use'][u]: Chris@87: for k in rout['use'][u]['map'].keys(): Chris@87: if rout['use'][u]['map'][k]==un[0]: ln=k;break Chris@87: lcb_map[ln]=un[1] Chris@87: #else: Chris@87: # errmess('routsign2map: cb_map does not contain module "%s" used in "use" statement.\n'%(u)) Chris@87: elif 'externals' in rout and rout['externals']: Chris@87: errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n'%(ret['name'], repr(rout['externals']))) Chris@87: ret['callprotoargument'] = getcallprotoargument(rout, lcb_map) or '' Chris@87: if isfunction(rout): Chris@87: if 'result' in rout: Chris@87: a=rout['result'] Chris@87: else: Chris@87: a=rout['name'] Chris@87: ret['rname']=a Chris@87: ret['pydocsign'], ret['pydocsignout']=getpydocsign(a, rout) Chris@87: ret['ctype']=getctype(rout['vars'][a]) Chris@87: if hasresultnote(rout): Chris@87: ret['resultnote']=rout['vars'][a]['note'] Chris@87: rout['vars'][a]['note']=['See elsewhere.'] Chris@87: if ret['ctype'] in c2buildvalue_map: Chris@87: ret['rformat']=c2buildvalue_map[ret['ctype']] Chris@87: else: Chris@87: ret['rformat']='O' Chris@87: errmess('routsign2map: no c2buildvalue key for type %s\n'%(repr(ret['ctype']))) Chris@87: if debugcapi(rout): Chris@87: if ret['ctype'] in cformat_map: Chris@87: ret['routdebugshowvalue']='debug-capi:%s=%s'%(a, cformat_map[ret['ctype']]) Chris@87: if isstringfunction(rout): Chris@87: ret['routdebugshowvalue']='debug-capi:slen(%s)=%%d %s=\\"%%s\\"'%(a, a) Chris@87: if isstringfunction(rout): Chris@87: ret['rlength']=getstrlength(rout['vars'][a]) Chris@87: if ret['rlength']=='-1': Chris@87: errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n'%(repr(rout['name']))) Chris@87: ret['rlength']='10' Chris@87: if hasnote(rout): Chris@87: ret['note']=rout['note'] Chris@87: rout['note']=['See elsewhere.'] Chris@87: return ret Chris@87: Chris@87: def modsign2map(m): Chris@87: """ Chris@87: modulename Chris@87: """ Chris@87: if ismodule(m): Chris@87: ret={'f90modulename':m['name'], Chris@87: 'F90MODULENAME':m['name'].upper(), Chris@87: 'texf90modulename':m['name'].replace('_', '\\_')} Chris@87: else: Chris@87: ret={'modulename':m['name'], Chris@87: 'MODULENAME':m['name'].upper(), Chris@87: 'texmodulename':m['name'].replace('_', '\\_')} Chris@87: ret['restdoc'] = getrestdoc(m) or [] Chris@87: if hasnote(m): Chris@87: ret['note']=m['note'] Chris@87: #m['note']=['See elsewhere.'] Chris@87: ret['usercode'] = getusercode(m) or '' Chris@87: ret['usercode1'] = getusercode1(m) or '' Chris@87: if m['body']: Chris@87: ret['interface_usercode'] = getusercode(m['body'][0]) or '' Chris@87: else: Chris@87: ret['interface_usercode'] = '' Chris@87: ret['pymethoddef'] = getpymethoddef(m) or '' Chris@87: if 'coutput' in m: Chris@87: ret['coutput'] = m['coutput'] Chris@87: if 'f2py_wrapper_output' in m: Chris@87: ret['f2py_wrapper_output'] = m['f2py_wrapper_output'] Chris@87: return ret Chris@87: Chris@87: def cb_sign2map(a,var,index=None): Chris@87: ret={'varname':a} Chris@87: if index is None or 1: # disable 7712 patch Chris@87: ret['varname_i'] = ret['varname'] Chris@87: else: Chris@87: ret['varname_i'] = ret['varname'] + '_' + str(index) Chris@87: ret['ctype']=getctype(var) Chris@87: if ret['ctype'] in c2capi_map: Chris@87: ret['atype']=c2capi_map[ret['ctype']] Chris@87: if ret['ctype'] in cformat_map: Chris@87: ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) Chris@87: if isarray(var): Chris@87: ret=dictappend(ret, getarrdims(a, var)) Chris@87: ret['pydocsign'], ret['pydocsignout']=getpydocsign(a, var) Chris@87: if hasnote(var): Chris@87: ret['note']=var['note'] Chris@87: var['note']=['See elsewhere.'] Chris@87: return ret Chris@87: Chris@87: def cb_routsign2map(rout, um): Chris@87: """ Chris@87: name,begintitle,endtitle,argname Chris@87: ctype,rctype,maxnofargs,nofoptargs,returncptr Chris@87: """ Chris@87: ret={'name':'cb_%s_in_%s'%(rout['name'], um), Chris@87: 'returncptr':''} Chris@87: if isintent_callback(rout): Chris@87: if '_' in rout['name']: Chris@87: F_FUNC='F_FUNC_US' Chris@87: else: Chris@87: F_FUNC='F_FUNC' Chris@87: ret['callbackname'] = '%s(%s,%s)' \ Chris@87: % (F_FUNC, Chris@87: rout['name'].lower(), Chris@87: rout['name'].upper(), Chris@87: ) Chris@87: ret['static'] = 'extern' Chris@87: else: Chris@87: ret['callbackname'] = ret['name'] Chris@87: ret['static'] = 'static' Chris@87: ret['argname']=rout['name'] Chris@87: ret['begintitle']=gentitle(ret['name']) Chris@87: ret['endtitle']=gentitle('end of %s'%ret['name']) Chris@87: ret['ctype']=getctype(rout) Chris@87: ret['rctype']='void' Chris@87: if ret['ctype']=='string': ret['rctype']='void' Chris@87: else: Chris@87: ret['rctype']=ret['ctype'] Chris@87: if ret['rctype']!='void': Chris@87: if iscomplexfunction(rout): Chris@87: ret['returncptr'] = """ Chris@87: #ifdef F2PY_CB_RETURNCOMPLEX Chris@87: return_value= Chris@87: #endif Chris@87: """ Chris@87: else: Chris@87: ret['returncptr'] = 'return_value=' Chris@87: if ret['ctype'] in cformat_map: Chris@87: ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) Chris@87: if isstringfunction(rout): Chris@87: ret['strlength']=getstrlength(rout) Chris@87: if isfunction(rout): Chris@87: if 'result' in rout: Chris@87: a=rout['result'] Chris@87: else: Chris@87: a=rout['name'] Chris@87: if hasnote(rout['vars'][a]): Chris@87: ret['note']=rout['vars'][a]['note'] Chris@87: rout['vars'][a]['note']=['See elsewhere.'] Chris@87: ret['rname']=a Chris@87: ret['pydocsign'], ret['pydocsignout']=getpydocsign(a, rout) Chris@87: if iscomplexfunction(rout): Chris@87: ret['rctype']=""" Chris@87: #ifdef F2PY_CB_RETURNCOMPLEX Chris@87: #ctype# Chris@87: #else Chris@87: void Chris@87: #endif Chris@87: """ Chris@87: else: Chris@87: if hasnote(rout): Chris@87: ret['note']=rout['note'] Chris@87: rout['note']=['See elsewhere.'] Chris@87: nofargs=0 Chris@87: nofoptargs=0 Chris@87: if 'args' in rout and 'vars' in rout: Chris@87: for a in rout['args']: Chris@87: var=rout['vars'][a] Chris@87: if l_or(isintent_in, isintent_inout)(var): Chris@87: nofargs=nofargs+1 Chris@87: if isoptional(var): Chris@87: nofoptargs=nofoptargs+1 Chris@87: ret['maxnofargs']=repr(nofargs) Chris@87: ret['nofoptargs']=repr(nofoptargs) Chris@87: if hasnote(rout) and isfunction(rout) and 'result' in rout: Chris@87: ret['routnote']=rout['note'] Chris@87: rout['note']=['See elsewhere.'] Chris@87: return ret Chris@87: Chris@87: def common_sign2map(a, var): # obsolute Chris@87: ret={'varname':a} Chris@87: ret['ctype']=getctype(var) Chris@87: if isstringarray(var): Chris@87: ret['ctype']='char' Chris@87: if ret['ctype'] in c2capi_map: Chris@87: ret['atype']=c2capi_map[ret['ctype']] Chris@87: if ret['ctype'] in cformat_map: Chris@87: ret['showvalueformat']='%s'%(cformat_map[ret['ctype']]) Chris@87: if isarray(var): Chris@87: ret=dictappend(ret, getarrdims(a, var)) Chris@87: elif isstring(var): Chris@87: ret['size']=getstrlength(var) Chris@87: ret['rank']='1' Chris@87: ret['pydocsign'], ret['pydocsignout']=getpydocsign(a, var) Chris@87: if hasnote(var): Chris@87: ret['note']=var['note'] Chris@87: var['note']=['See elsewhere.'] Chris@87: ret['arrdocstr']=getarrdocsign(a, var) # for strings this returns 0-rank but actually is 1-rank Chris@87: return ret