You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

838 lines
31 KiB

5 months ago
#!/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',
}
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'}
# 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'
}
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'
}
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'}
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'}
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'},
'character': {'': 'string'}
}
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, 'r') 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',
}
# 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 '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 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 = 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['dims'] = getstrlength(var)
ret['size'] = ret['dims']
ret['rank'] = '1'
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 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']]
# 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']]
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']]
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