| Viewing file:  capi_maps.py (32.23 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
#!/usr/bin/env python3"""
 
 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 License.
 
 NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
 $Date: 2005/05/06 10:57:33 $
 Pearu Peterson
 
 """
 from . import __version__
 f2py_version = __version__.version
 
 import copy
 import re
 import os
 from .crackfortran import markoutercomma
 from . import cb_rules
 
 # The environment provided by auxfuncs.py is needed for some calls to eval.
 # As the needed functions cannot be determined by static inspection of the
 # code, it is safest to use import * pending a major refactoring of f2py.
 from .auxfuncs import *
 
 __all__ = [
 'getctype', 'getstrlength', 'getarrdims', 'getpydocsign',
 'getarrdocsign', 'getinit', 'sign2map', 'routsign2map', 'modsign2map',
 'cb_sign2map', 'cb_routsign2map', 'common_sign2map'
 ]
 
 
 # Numarray and Numeric users should set this False
 using_newcore = True
 
 depargs = []
 lcb_map = {}
 lcb2_map = {}
 # forced casting: mainly caused by the fact that Python or Numeric
 #                 C/APIs do not support the corresponding C types.
 c2py_map = {'double': 'float',
 'float': 'float',                          # forced casting
 'long_double': 'float',                    # forced casting
 'char': 'int',                             # forced casting
 'signed_char': 'int',                      # forced casting
 'unsigned_char': 'int',                    # forced casting
 'short': 'int',                            # forced casting
 'unsigned_short': 'int',                   # forced casting
 'int': 'int',                              # forced casting
 'long': 'int',
 'long_long': 'long',
 'unsigned': 'int',                         # forced casting
 'complex_float': 'complex',                # forced casting
 'complex_double': 'complex',
 'complex_long_double': 'complex',          # forced casting
 'string': 'string',
 'character': 'bytes',
 }
 c2capi_map = {'double': 'NPY_DOUBLE',
 'float': 'NPY_FLOAT',
 'long_double': 'NPY_DOUBLE',           # forced casting
 'char': 'NPY_STRING',
 'unsigned_char': 'NPY_UBYTE',
 'signed_char': 'NPY_BYTE',
 'short': 'NPY_SHORT',
 'unsigned_short': 'NPY_USHORT',
 'int': 'NPY_INT',
 'unsigned': 'NPY_UINT',
 'long': 'NPY_LONG',
 'long_long': 'NPY_LONG',                # forced casting
 'complex_float': 'NPY_CFLOAT',
 'complex_double': 'NPY_CDOUBLE',
 'complex_long_double': 'NPY_CDOUBLE',   # forced casting
 'string': 'NPY_STRING',
 'character': 'NPY_CHAR'}
 
 # These new maps aren't used anywhere yet, but should be by default
 #  unless building numeric or numarray extensions.
 if using_newcore:
 c2capi_map = {'double': 'NPY_DOUBLE',
 'float': 'NPY_FLOAT',
 'long_double': 'NPY_LONGDOUBLE',
 'char': 'NPY_BYTE',
 'unsigned_char': 'NPY_UBYTE',
 'signed_char': 'NPY_BYTE',
 'short': 'NPY_SHORT',
 'unsigned_short': 'NPY_USHORT',
 'int': 'NPY_INT',
 'unsigned': 'NPY_UINT',
 'long': 'NPY_LONG',
 'unsigned_long': 'NPY_ULONG',
 'long_long': 'NPY_LONGLONG',
 'unsigned_long_long': 'NPY_ULONGLONG',
 'complex_float': 'NPY_CFLOAT',
 'complex_double': 'NPY_CDOUBLE',
 'complex_long_double': 'NPY_CDOUBLE',
 'string': 'NPY_STRING',
 'character': 'NPY_STRING'}
 
 c2pycode_map = {'double': 'd',
 'float': 'f',
 'long_double': 'd',                       # forced casting
 'char': '1',
 'signed_char': '1',
 'unsigned_char': 'b',
 'short': 's',
 'unsigned_short': 'w',
 'int': 'i',
 'unsigned': 'u',
 'long': 'l',
 'long_long': 'L',
 'complex_float': 'F',
 'complex_double': 'D',
 'complex_long_double': 'D',               # forced casting
 'string': 'c',
 'character': 'c'
 }
 
 if using_newcore:
 c2pycode_map = {'double': 'd',
 'float': 'f',
 'long_double': 'g',
 'char': 'b',
 'unsigned_char': 'B',
 'signed_char': 'b',
 'short': 'h',
 'unsigned_short': 'H',
 'int': 'i',
 'unsigned': 'I',
 'long': 'l',
 'unsigned_long': 'L',
 'long_long': 'q',
 'unsigned_long_long': 'Q',
 'complex_float': 'F',
 'complex_double': 'D',
 'complex_long_double': 'G',
 'string': 'S',
 'character': 'c'}
 
 # https://docs.python.org/3/c-api/arg.html#building-values
 # c2buildvalue_map is NumPy agnostic, so no need to bother with using_newcore
 c2buildvalue_map = {'double': 'd',
 'float': 'f',
 'char': 'b',
 'signed_char': 'b',
 'short': 'h',
 'int': 'i',
 'long': 'l',
 'long_long': 'L',
 'complex_float': 'N',
 'complex_double': 'N',
 'complex_long_double': 'N',
 'string': 'y',
 'character': 'c'}
 
 f2cmap_all = {'real': {'': 'float', '4': 'float', '8': 'double',
 '12': 'long_double', '16': 'long_double'},
 'integer': {'': 'int', '1': 'signed_char', '2': 'short',
 '4': 'int', '8': 'long_long',
 '-1': 'unsigned_char', '-2': 'unsigned_short',
 '-4': 'unsigned', '-8': 'unsigned_long_long'},
 'complex': {'': 'complex_float', '8': 'complex_float',
 '16': 'complex_double', '24': 'complex_long_double',
 '32': 'complex_long_double'},
 'complexkind': {'': 'complex_float', '4': 'complex_float',
 '8': 'complex_double', '12': 'complex_long_double',
 '16': 'complex_long_double'},
 'logical': {'': 'int', '1': 'char', '2': 'short', '4': 'int',
 '8': 'long_long'},
 'double complex': {'': 'complex_double'},
 'double precision': {'': 'double'},
 'byte': {'': 'char'},
 }
 
 f2cmap_default = copy.deepcopy(f2cmap_all)
 
 f2cmap_mapped = []
 
 def load_f2cmap_file(f2cmap_file):
 global f2cmap_all
 
 f2cmap_all = copy.deepcopy(f2cmap_default)
 
 if f2cmap_file is None:
 # Default value
 f2cmap_file = '.f2py_f2cmap'
 if not os.path.isfile(f2cmap_file):
 return
 
 # User defined additions to f2cmap_all.
 # f2cmap_file must contain a dictionary of dictionaries, only. For
 # example, {'real':{'low':'float'}} means that Fortran 'real(low)' is
 # interpreted as C 'float'. This feature is useful for F90/95 users if
 # they use PARAMETERS in type specifications.
 try:
 outmess('Reading f2cmap from {!r} ...\n'.format(f2cmap_file))
 with open(f2cmap_file) as f:
 d = eval(f.read().lower(), {}, {})
 for k, d1 in d.items():
 for k1 in d1.keys():
 d1[k1.lower()] = d1[k1]
 d[k.lower()] = d[k]
 for k in d.keys():
 if k not in f2cmap_all:
 f2cmap_all[k] = {}
 for k1 in d[k].keys():
 if d[k][k1] in c2py_map:
 if k1 in f2cmap_all[k]:
 outmess(
 "\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n" % (k, k1, f2cmap_all[k][k1], d[k][k1]))
 f2cmap_all[k][k1] = d[k][k1]
 outmess('\tMapping "%s(kind=%s)" to "%s"\n' %
 (k, k1, d[k][k1]))
 f2cmap_mapped.append(d[k][k1])
 else:
 errmess("\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n" % (
 k, k1, d[k][k1], d[k][k1], list(c2py_map.keys())))
 outmess('Successfully applied user defined f2cmap changes\n')
 except Exception as msg:
 errmess(
 'Failed to apply user defined f2cmap changes: %s. Skipping.\n' % (msg))
 
 cformat_map = {'double': '%g',
 'float': '%g',
 'long_double': '%Lg',
 'char': '%d',
 'signed_char': '%d',
 'unsigned_char': '%hhu',
 'short': '%hd',
 'unsigned_short': '%hu',
 'int': '%d',
 'unsigned': '%u',
 'long': '%ld',
 'unsigned_long': '%lu',
 'long_long': '%ld',
 'complex_float': '(%g,%g)',
 'complex_double': '(%g,%g)',
 'complex_long_double': '(%Lg,%Lg)',
 'string': '\\"%s\\"',
 'character': "'%c'",
 }
 
 # Auxiliary functions
 
 
 def getctype(var):
 """
 Determines C type
 """
 ctype = 'void'
 if isfunction(var):
 if 'result' in var:
 a = var['result']
 else:
 a = var['name']
 if a in var['vars']:
 return getctype(var['vars'][a])
 else:
 errmess('getctype: function %s has no return value?!\n' % a)
 elif issubroutine(var):
 return ctype
 elif ischaracter_or_characterarray(var):
 return 'character'
 elif isstring_or_stringarray(var):
 return 'string'
 elif 'typespec' in var and var['typespec'].lower() in f2cmap_all:
 typespec = var['typespec'].lower()
 f2cmap = f2cmap_all[typespec]
 ctype = f2cmap['']  # default type
 if 'kindselector' in var:
 if '*' in var['kindselector']:
 try:
 ctype = f2cmap[var['kindselector']['*']]
 except KeyError:
 errmess('getctype: "%s %s %s" not supported.\n' %
 (var['typespec'], '*', var['kindselector']['*']))
 elif 'kind' in var['kindselector']:
 if typespec + 'kind' in f2cmap_all:
 f2cmap = f2cmap_all[typespec + 'kind']
 try:
 ctype = f2cmap[var['kindselector']['kind']]
 except KeyError:
 if typespec in f2cmap_all:
 f2cmap = f2cmap_all[typespec]
 try:
 ctype = f2cmap[str(var['kindselector']['kind'])]
 except KeyError:
 errmess('getctype: "%s(kind=%s)" is mapped to C "%s" (to override define dict(%s = dict(%s="<C typespec>")) in %s/.f2py_f2cmap file).\n'
 % (typespec, var['kindselector']['kind'], ctype,
 typespec, var['kindselector']['kind'], os.getcwd()))
 else:
 if not isexternal(var):
 errmess('getctype: No C-type found in "%s", assuming void.\n' % var)
 return ctype
 
 
 def f2cexpr(expr):
 """Rewrite Fortran expression as f2py supported C expression.
 
 Due to the lack of a proper expression parser in f2py, this
 function uses a heuristic approach that assumes that Fortran
 arithmetic expressions are valid C arithmetic expressions when
 mapping Fortran function calls to the corresponding C function/CPP
 macros calls.
 
 """
 # TODO: support Fortran `len` function with optional kind parameter
 expr = re.sub(r'\blen\b', 'f2py_slen', expr)
 return expr
 
 
 def getstrlength(var):
 if isstringfunction(var):
 if 'result' in var:
 a = var['result']
 else:
 a = var['name']
 if a in var['vars']:
 return getstrlength(var['vars'][a])
 else:
 errmess('getstrlength: function %s has no return value?!\n' % a)
 if not isstring(var):
 errmess(
 'getstrlength: expected a signature of a string but got: %s\n' % (repr(var)))
 len = '1'
 if 'charselector' in var:
 a = var['charselector']
 if '*' in a:
 len = a['*']
 elif 'len' in a:
 len = f2cexpr(a['len'])
 if re.match(r'\(\s*(\*|:)\s*\)', len) or re.match(r'(\*|:)', len):
 if isintent_hide(var):
 errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n' % (
 repr(var)))
 len = '-1'
 return len
 
 
 def getarrdims(a, var, verbose=0):
 ret = {}
 if isstring(var) and not isarray(var):
 ret['size'] = getstrlength(var)
 ret['rank'] = '0'
 ret['dims'] = ''
 elif isscalar(var):
 ret['size'] = '1'
 ret['rank'] = '0'
 ret['dims'] = ''
 elif isarray(var):
 dim = copy.copy(var['dimension'])
 ret['size'] = '*'.join(dim)
 try:
 ret['size'] = repr(eval(ret['size']))
 except Exception:
 pass
 ret['dims'] = ','.join(dim)
 ret['rank'] = repr(len(dim))
 ret['rank*[-1]'] = repr(len(dim) * [-1])[1:-1]
 for i in range(len(dim)):  # solve dim for dependencies
 v = []
 if dim[i] in depargs:
 v = [dim[i]]
 else:
 for va in depargs:
 if re.match(r'.*?\b%s\b.*' % va, dim[i]):
 v.append(va)
 for va in v:
 if depargs.index(va) > depargs.index(a):
 dim[i] = '*'
 break
 ret['setdims'], i = '', -1
 for d in dim:
 i = i + 1
 if d not in ['*', ':', '(*)', '(:)']:
 ret['setdims'] = '%s#varname#_Dims[%d]=%s,' % (
 ret['setdims'], i, d)
 if ret['setdims']:
 ret['setdims'] = ret['setdims'][:-1]
 ret['cbsetdims'], i = '', -1
 for d in var['dimension']:
 i = i + 1
 if d not in ['*', ':', '(*)', '(:)']:
 ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
 ret['cbsetdims'], i, d)
 elif isintent_in(var):
 outmess('getarrdims:warning: assumed shape array, using 0 instead of %r\n'
 % (d))
 ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
 ret['cbsetdims'], i, 0)
 elif verbose:
 errmess(
 'getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n' % (repr(a), repr(d)))
 if ret['cbsetdims']:
 ret['cbsetdims'] = ret['cbsetdims'][:-1]
 #         if not isintent_c(var):
 #             var['dimension'].reverse()
 return ret
 
 
 def getpydocsign(a, var):
 global lcb_map
 if isfunction(var):
 if 'result' in var:
 af = var['result']
 else:
 af = var['name']
 if af in var['vars']:
 return getpydocsign(af, var['vars'][af])
 else:
 errmess('getctype: function %s has no return value?!\n' % af)
 return '', ''
 sig, sigout = a, a
 opt = ''
 if isintent_in(var):
 opt = 'input'
 elif isintent_inout(var):
 opt = 'in/output'
 out_a = a
 if isintent_out(var):
 for k in var['intent']:
 if k[:4] == 'out=':
 out_a = k[4:]
 break
 init = ''
 ctype = getctype(var)
 
 if hasinitvalue(var):
 init, showinit = getinit(a, var)
 init = ', optional\\n    Default: %s' % showinit
 if isscalar(var):
 if isintent_inout(var):
 sig = '%s : %s rank-0 array(%s,\'%s\')%s' % (a, opt, c2py_map[ctype],
 c2pycode_map[ctype], init)
 else:
 sig = '%s : %s %s%s' % (a, opt, c2py_map[ctype], init)
 sigout = '%s : %s' % (out_a, c2py_map[ctype])
 elif isstring(var):
 if isintent_inout(var):
 sig = '%s : %s rank-0 array(string(len=%s),\'c\')%s' % (
 a, opt, getstrlength(var), init)
 else:
 sig = '%s : %s string(len=%s)%s' % (
 a, opt, getstrlength(var), init)
 sigout = '%s : string(len=%s)' % (out_a, getstrlength(var))
 elif isarray(var):
 dim = var['dimension']
 rank = repr(len(dim))
 sig = '%s : %s rank-%s array(\'%s\') with bounds (%s)%s' % (a, opt, rank,
 c2pycode_map[
 ctype],
 ','.join(dim), init)
 if a == out_a:
 sigout = '%s : rank-%s array(\'%s\') with bounds (%s)'\
 % (a, rank, c2pycode_map[ctype], ','.join(dim))
 else:
 sigout = '%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\
 % (out_a, rank, c2pycode_map[ctype], ','.join(dim), a)
 elif isexternal(var):
 ua = ''
 if a in lcb_map and lcb_map[a] in lcb2_map and 'argname' in lcb2_map[lcb_map[a]]:
 ua = lcb2_map[lcb_map[a]]['argname']
 if not ua == a:
 ua = ' => %s' % ua
 else:
 ua = ''
 sig = '%s : call-back function%s' % (a, ua)
 sigout = sig
 else:
 errmess(
 'getpydocsign: Could not resolve docsignature for "%s".\n' % a)
 return sig, sigout
 
 
 def getarrdocsign(a, var):
 ctype = getctype(var)
 if isstring(var) and (not isarray(var)):
 sig = '%s : rank-0 array(string(len=%s),\'c\')' % (a,
 getstrlength(var))
 elif isscalar(var):
 sig = '%s : rank-0 array(%s,\'%s\')' % (a, c2py_map[ctype],
 c2pycode_map[ctype],)
 elif isarray(var):
 dim = var['dimension']
 rank = repr(len(dim))
 sig = '%s : rank-%s array(\'%s\') with bounds (%s)' % (a, rank,
 c2pycode_map[
 ctype],
 ','.join(dim))
 return sig
 
 
 def getinit(a, var):
 if isstring(var):
 init, showinit = '""', "''"
 else:
 init, showinit = '', ''
 if hasinitvalue(var):
 init = var['=']
 showinit = init
 if iscomplex(var) or iscomplexarray(var):
 ret = {}
 
 try:
 v = var["="]
 if ',' in v:
 ret['init.r'], ret['init.i'] = markoutercomma(
 v[1:-1]).split('@,@')
 else:
 v = eval(v, {}, {})
 ret['init.r'], ret['init.i'] = str(v.real), str(v.imag)
 except Exception:
 raise ValueError(
 'getinit: expected complex number `(r,i)\' but got `%s\' as initial value of %r.' % (init, a))
 if isarray(var):
 init = '(capi_c.r=%s,capi_c.i=%s,capi_c)' % (
 ret['init.r'], ret['init.i'])
 elif isstring(var):
 if not init:
 init, showinit = '""', "''"
 if init[0] == "'":
 init = '"%s"' % (init[1:-1].replace('"', '\\"'))
 if init[0] == '"':
 showinit = "'%s'" % (init[1:-1])
 return init, showinit
 
 
 def get_elsize(var):
 if isstring(var) or isstringarray(var):
 elsize = getstrlength(var)
 # override with user-specified length when available:
 elsize = var['charselector'].get('f2py_len', elsize)
 return elsize
 if ischaracter(var) or ischaracterarray(var):
 return '1'
 # for numerical types, PyArray_New* functions ignore specified
 # elsize, so we just return 1 and let elsize be determined at
 # runtime, see fortranobject.c
 return '1'
 
 
 def sign2map(a, var):
 """
 varname,ctype,atype
 init,init.r,init.i,pytype
 vardebuginfo,vardebugshowvalue,varshowvalue
 varrformat
 
 intent
 """
 out_a = a
 if isintent_out(var):
 for k in var['intent']:
 if k[:4] == 'out=':
 out_a = k[4:]
 break
 ret = {'varname': a, 'outvarname': out_a, 'ctype': getctype(var)}
 intent_flags = []
 for f, s in isintent_dict.items():
 if f(var):
 intent_flags.append('F2PY_%s' % s)
 if intent_flags:
 # TODO: Evaluate intent_flags here.
 ret['intent'] = '|'.join(intent_flags)
 else:
 ret['intent'] = 'F2PY_INTENT_IN'
 if isarray(var):
 ret['varrformat'] = 'N'
 elif ret['ctype'] in c2buildvalue_map:
 ret['varrformat'] = c2buildvalue_map[ret['ctype']]
 else:
 ret['varrformat'] = 'O'
 ret['init'], ret['showinit'] = getinit(a, var)
 if hasinitvalue(var) and iscomplex(var) and not isarray(var):
 ret['init.r'], ret['init.i'] = markoutercomma(
 ret['init'][1:-1]).split('@,@')
 if isexternal(var):
 ret['cbnamekey'] = a
 if a in lcb_map:
 ret['cbname'] = lcb_map[a]
 ret['maxnofargs'] = lcb2_map[lcb_map[a]]['maxnofargs']
 ret['nofoptargs'] = lcb2_map[lcb_map[a]]['nofoptargs']
 ret['cbdocstr'] = lcb2_map[lcb_map[a]]['docstr']
 ret['cblatexdocstr'] = lcb2_map[lcb_map[a]]['latexdocstr']
 else:
 ret['cbname'] = a
 errmess('sign2map: Confused: external %s is not in lcb_map%s.\n' % (
 a, list(lcb_map.keys())))
 if isstring(var):
 ret['length'] = getstrlength(var)
 if isarray(var):
 ret = dictappend(ret, getarrdims(a, var))
 dim = copy.copy(var['dimension'])
 if ret['ctype'] in c2capi_map:
 ret['atype'] = c2capi_map[ret['ctype']]
 ret['elsize'] = get_elsize(var)
 # Debug info
 if debugcapi(var):
 il = [isintent_in, 'input', isintent_out, 'output',
 isintent_inout, 'inoutput', isrequired, 'required',
 isoptional, 'optional', isintent_hide, 'hidden',
 iscomplex, 'complex scalar',
 l_and(isscalar, l_not(iscomplex)), 'scalar',
 isstring, 'string', isarray, 'array',
 iscomplexarray, 'complex array', isstringarray, 'string array',
 iscomplexfunction, 'complex function',
 l_and(isfunction, l_not(iscomplexfunction)), 'function',
 isexternal, 'callback',
 isintent_callback, 'callback',
 isintent_aux, 'auxiliary',
 ]
 rl = []
 for i in range(0, len(il), 2):
 if il[i](var):
 rl.append(il[i + 1])
 if isstring(var):
 rl.append('slen(%s)=%s' % (a, ret['length']))
 if isarray(var):
 ddim = ','.join(
 map(lambda x, y: '%s|%s' % (x, y), var['dimension'], dim))
 rl.append('dims(%s)' % ddim)
 if isexternal(var):
 ret['vardebuginfo'] = 'debug-capi:%s=>%s:%s' % (
 a, ret['cbname'], ','.join(rl))
 else:
 ret['vardebuginfo'] = 'debug-capi:%s %s=%s:%s' % (
 ret['ctype'], a, ret['showinit'], ','.join(rl))
 if isscalar(var):
 if ret['ctype'] in cformat_map:
 ret['vardebugshowvalue'] = 'debug-capi:%s=%s' % (
 a, cformat_map[ret['ctype']])
 if isstring(var):
 ret['vardebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
 a, a)
 if isexternal(var):
 ret['vardebugshowvalue'] = 'debug-capi:%s=%%p' % (a)
 if ret['ctype'] in cformat_map:
 ret['varshowvalue'] = '#name#:%s=%s' % (a, cformat_map[ret['ctype']])
 ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
 if isstring(var):
 ret['varshowvalue'] = '#name#:slen(%s)=%%d %s=\\"%%s\\"' % (a, a)
 ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
 if hasnote(var):
 ret['note'] = var['note']
 return ret
 
 
 def routsign2map(rout):
 """
 name,NAME,begintitle,endtitle
 rname,ctype,rformat
 routdebugshowvalue
 """
 global lcb_map
 name = rout['name']
 fname = getfortranname(rout)
 ret = {'name': name,
 'texname': name.replace('_', '\\_'),
 'name_lower': name.lower(),
 'NAME': name.upper(),
 'begintitle': gentitle(name),
 'endtitle': gentitle('end of %s' % name),
 'fortranname': fname,
 'FORTRANNAME': fname.upper(),
 'callstatement': getcallstatement(rout) or '',
 'usercode': getusercode(rout) or '',
 'usercode1': getusercode1(rout) or '',
 }
 if '_' in fname:
 ret['F_FUNC'] = 'F_FUNC_US'
 else:
 ret['F_FUNC'] = 'F_FUNC'
 if '_' in name:
 ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US'
 else:
 ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC'
 lcb_map = {}
 if 'use' in rout:
 for u in rout['use'].keys():
 if u in cb_rules.cb_map:
 for un in cb_rules.cb_map[u]:
 ln = un[0]
 if 'map' in rout['use'][u]:
 for k in rout['use'][u]['map'].keys():
 if rout['use'][u]['map'][k] == un[0]:
 ln = k
 break
 lcb_map[ln] = un[1]
 elif 'externals' in rout and rout['externals']:
 errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n' % (
 ret['name'], repr(rout['externals'])))
 ret['callprotoargument'] = getcallprotoargument(rout, lcb_map) or ''
 if isfunction(rout):
 if 'result' in rout:
 a = rout['result']
 else:
 a = rout['name']
 ret['rname'] = a
 ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
 ret['ctype'] = getctype(rout['vars'][a])
 if hasresultnote(rout):
 ret['resultnote'] = rout['vars'][a]['note']
 rout['vars'][a]['note'] = ['See elsewhere.']
 if ret['ctype'] in c2buildvalue_map:
 ret['rformat'] = c2buildvalue_map[ret['ctype']]
 else:
 ret['rformat'] = 'O'
 errmess('routsign2map: no c2buildvalue key for type %s\n' %
 (repr(ret['ctype'])))
 if debugcapi(rout):
 if ret['ctype'] in cformat_map:
 ret['routdebugshowvalue'] = 'debug-capi:%s=%s' % (
 a, cformat_map[ret['ctype']])
 if isstringfunction(rout):
 ret['routdebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
 a, a)
 if isstringfunction(rout):
 ret['rlength'] = getstrlength(rout['vars'][a])
 if ret['rlength'] == '-1':
 errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n' % (
 repr(rout['name'])))
 ret['rlength'] = '10'
 if hasnote(rout):
 ret['note'] = rout['note']
 rout['note'] = ['See elsewhere.']
 return ret
 
 
 def modsign2map(m):
 """
 modulename
 """
 if ismodule(m):
 ret = {'f90modulename': m['name'],
 'F90MODULENAME': m['name'].upper(),
 'texf90modulename': m['name'].replace('_', '\\_')}
 else:
 ret = {'modulename': m['name'],
 'MODULENAME': m['name'].upper(),
 'texmodulename': m['name'].replace('_', '\\_')}
 ret['restdoc'] = getrestdoc(m) or []
 if hasnote(m):
 ret['note'] = m['note']
 ret['usercode'] = getusercode(m) or ''
 ret['usercode1'] = getusercode1(m) or ''
 if m['body']:
 ret['interface_usercode'] = getusercode(m['body'][0]) or ''
 else:
 ret['interface_usercode'] = ''
 ret['pymethoddef'] = getpymethoddef(m) or ''
 if 'coutput' in m:
 ret['coutput'] = m['coutput']
 if 'f2py_wrapper_output' in m:
 ret['f2py_wrapper_output'] = m['f2py_wrapper_output']
 return ret
 
 
 def cb_sign2map(a, var, index=None):
 ret = {'varname': a}
 ret['varname_i'] = ret['varname']
 ret['ctype'] = getctype(var)
 if ret['ctype'] in c2capi_map:
 ret['atype'] = c2capi_map[ret['ctype']]
 ret['elsize'] = get_elsize(var)
 if ret['ctype'] in cformat_map:
 ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
 if isarray(var):
 ret = dictappend(ret, getarrdims(a, var))
 ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
 if hasnote(var):
 ret['note'] = var['note']
 var['note'] = ['See elsewhere.']
 return ret
 
 
 def cb_routsign2map(rout, um):
 """
 name,begintitle,endtitle,argname
 ctype,rctype,maxnofargs,nofoptargs,returncptr
 """
 ret = {'name': 'cb_%s_in_%s' % (rout['name'], um),
 'returncptr': ''}
 if isintent_callback(rout):
 if '_' in rout['name']:
 F_FUNC = 'F_FUNC_US'
 else:
 F_FUNC = 'F_FUNC'
 ret['callbackname'] = '%s(%s,%s)' \
 % (F_FUNC,
 rout['name'].lower(),
 rout['name'].upper(),
 )
 ret['static'] = 'extern'
 else:
 ret['callbackname'] = ret['name']
 ret['static'] = 'static'
 ret['argname'] = rout['name']
 ret['begintitle'] = gentitle(ret['name'])
 ret['endtitle'] = gentitle('end of %s' % ret['name'])
 ret['ctype'] = getctype(rout)
 ret['rctype'] = 'void'
 if ret['ctype'] == 'string':
 ret['rctype'] = 'void'
 else:
 ret['rctype'] = ret['ctype']
 if ret['rctype'] != 'void':
 if iscomplexfunction(rout):
 ret['returncptr'] = """
 #ifdef F2PY_CB_RETURNCOMPLEX
 return_value=
 #endif
 """
 else:
 ret['returncptr'] = 'return_value='
 if ret['ctype'] in cformat_map:
 ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
 if isstringfunction(rout):
 ret['strlength'] = getstrlength(rout)
 if isfunction(rout):
 if 'result' in rout:
 a = rout['result']
 else:
 a = rout['name']
 if hasnote(rout['vars'][a]):
 ret['note'] = rout['vars'][a]['note']
 rout['vars'][a]['note'] = ['See elsewhere.']
 ret['rname'] = a
 ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
 if iscomplexfunction(rout):
 ret['rctype'] = """
 #ifdef F2PY_CB_RETURNCOMPLEX
 #ctype#
 #else
 void
 #endif
 """
 else:
 if hasnote(rout):
 ret['note'] = rout['note']
 rout['note'] = ['See elsewhere.']
 nofargs = 0
 nofoptargs = 0
 if 'args' in rout and 'vars' in rout:
 for a in rout['args']:
 var = rout['vars'][a]
 if l_or(isintent_in, isintent_inout)(var):
 nofargs = nofargs + 1
 if isoptional(var):
 nofoptargs = nofoptargs + 1
 ret['maxnofargs'] = repr(nofargs)
 ret['nofoptargs'] = repr(nofoptargs)
 if hasnote(rout) and isfunction(rout) and 'result' in rout:
 ret['routnote'] = rout['note']
 rout['note'] = ['See elsewhere.']
 return ret
 
 
 def common_sign2map(a, var):  # obsolute
 ret = {'varname': a, 'ctype': getctype(var)}
 if isstringarray(var):
 ret['ctype'] = 'char'
 if ret['ctype'] in c2capi_map:
 ret['atype'] = c2capi_map[ret['ctype']]
 ret['elsize'] = get_elsize(var)
 if ret['ctype'] in cformat_map:
 ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
 if isarray(var):
 ret = dictappend(ret, getarrdims(a, var))
 elif isstring(var):
 ret['size'] = getstrlength(var)
 ret['rank'] = '1'
 ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
 if hasnote(var):
 ret['note'] = var['note']
 var['note'] = ['See elsewhere.']
 # for strings this returns 0-rank but actually is 1-rank
 ret['arrdocstr'] = getarrdocsign(a, var)
 return ret
 
 |