#!/usr/bin/env python """ Copyright 1999,2000 Pearu Peterson all rights reserved, Pearu Peterson 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 __future__ import division, absolute_import, print_function __version__ = "$Revision: 1.60 $"[10:-1] from . import __version__ f2py_version = __version__.version import copy import re import os import sys from .crackfortran import markoutercomma from . import cb_rules # The eviroment 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 anyhere 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': 'z'} if sys.version_info[0] >= 3: # Bytes, not Unicode strings c2buildvalue_map['string'] = 'y' if using_newcore: # c2buildvalue_map=??? pass 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'} } if os.path.isfile('.f2py_f2cmap'): # User defined additions to f2cmap_all. # .f2py_f2cmap 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 PARAMETERSs in type specifications. try: outmess('Reading .f2py_f2cmap ...\n') f = open('.f2py_f2cmap', 'r') d = eval(f.read(), {}, {}) f.close() for k, d1 in list(d.items()): for k1 in list(d1.keys()): d1[k1.lower()] = d1[k1] d[k.lower()] = d[k] for k in list(d.keys()): if k not in f2cmap_all: f2cmap_all[k] = {} for k1 in list(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])) 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 changes from .f2py_f2cmap\n') except Exception as msg: errmess( 'Failed to apply user defined changes from .f2py_f2cmap: %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="")) 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): global depargs 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: 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 dependecies 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: 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 varrfromat intent """ global lcb_map, cb_map 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: # XXX: 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} if index is None or 1: # disable 7712 patch ret['varname_i'] = ret['varname'] else: ret['varname_i'] = ret['varname'] + '_' + str(index) 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