123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649 |
- #!/usr/bin/env python3
- """
- Build call-back mechanism for f2py2e.
- Copyright 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/07/20 11:27:58 $
- Pearu Peterson
- """
- from . import __version__
- from .auxfuncs import (
- applyrules, debugcapi, dictappend, errmess, getargs, hasnote, isarray,
- iscomplex, iscomplexarray, iscomplexfunction, isfunction, isintent_c,
- isintent_hide, isintent_in, isintent_inout, isintent_nothide,
- isintent_out, isoptional, isrequired, isscalar, isstring,
- isstringfunction, issubroutine, l_and, l_not, l_or, outmess, replace,
- stripcomma, throw_error
- )
- from . import cfuncs
- f2py_version = __version__.version
- ################## Rules for callback function ##############
- cb_routine_rules = {
- 'cbtypedefs': 'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);',
- 'body': """
- #begintitle#
- typedef struct {
- PyObject *capi;
- PyTupleObject *args_capi;
- int nofargs;
- jmp_buf jmpbuf;
- } #name#_t;
- #if defined(F2PY_THREAD_LOCAL_DECL) && !defined(F2PY_USE_PYTHON_TLS)
- static F2PY_THREAD_LOCAL_DECL #name#_t *_active_#name# = NULL;
- static #name#_t *swap_active_#name#(#name#_t *ptr) {
- #name#_t *prev = _active_#name#;
- _active_#name# = ptr;
- return prev;
- }
- static #name#_t *get_active_#name#(void) {
- return _active_#name#;
- }
- #else
- static #name#_t *swap_active_#name#(#name#_t *ptr) {
- char *key = "__f2py_cb_#name#";
- return (#name#_t *)F2PySwapThreadLocalCallbackPtr(key, ptr);
- }
- static #name#_t *get_active_#name#(void) {
- char *key = "__f2py_cb_#name#";
- return (#name#_t *)F2PyGetThreadLocalCallbackPtr(key);
- }
- #endif
- /*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/
- #static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) {
- #name#_t cb_local = { NULL, NULL, 0 };
- #name#_t *cb = NULL;
- PyTupleObject *capi_arglist = NULL;
- PyObject *capi_return = NULL;
- PyObject *capi_tmp = NULL;
- PyObject *capi_arglist_list = NULL;
- int capi_j,capi_i = 0;
- int capi_longjmp_ok = 1;
- #decl#
- #ifdef F2PY_REPORT_ATEXIT
- f2py_cb_start_clock();
- #endif
- cb = get_active_#name#();
- if (cb == NULL) {
- capi_longjmp_ok = 0;
- cb = &cb_local;
- }
- capi_arglist = cb->args_capi;
- CFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\");
- CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi);
- if (cb->capi==NULL) {
- capi_longjmp_ok = 0;
- cb->capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\");
- CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi);
- }
- if (cb->capi==NULL) {
- PyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\");
- goto capi_fail;
- }
- if (F2PyCapsule_Check(cb->capi)) {
- #name#_typedef #name#_cptr;
- #name#_cptr = F2PyCapsule_AsVoidPtr(cb->capi);
- #returncptr#(*#name#_cptr)(#optargs_nm##args_nm##strarglens_nm#);
- #return#
- }
- if (capi_arglist==NULL) {
- capi_longjmp_ok = 0;
- capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\");
- if (capi_tmp) {
- capi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp);
- Py_DECREF(capi_tmp);
- if (capi_arglist==NULL) {
- PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\");
- goto capi_fail;
- }
- } else {
- PyErr_Clear();
- capi_arglist = (PyTupleObject *)Py_BuildValue(\"()\");
- }
- }
- if (capi_arglist == NULL) {
- PyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\");
- goto capi_fail;
- }
- #setdims#
- #ifdef PYPY_VERSION
- #define CAPI_ARGLIST_SETITEM(idx, value) PyList_SetItem((PyObject *)capi_arglist_list, idx, value)
- capi_arglist_list = PySequence_List(capi_arglist);
- if (capi_arglist_list == NULL) goto capi_fail;
- #else
- #define CAPI_ARGLIST_SETITEM(idx, value) PyTuple_SetItem((PyObject *)capi_arglist, idx, value)
- #endif
- #pyobjfrom#
- #undef CAPI_ARGLIST_SETITEM
- #ifdef PYPY_VERSION
- CFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist_list);
- #else
- CFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist);
- #endif
- CFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\");
- #ifdef F2PY_REPORT_ATEXIT
- f2py_cb_start_call_clock();
- #endif
- #ifdef PYPY_VERSION
- capi_return = PyObject_CallObject(cb->capi,(PyObject *)capi_arglist_list);
- Py_DECREF(capi_arglist_list);
- capi_arglist_list = NULL;
- #else
- capi_return = PyObject_CallObject(cb->capi,(PyObject *)capi_arglist);
- #endif
- #ifdef F2PY_REPORT_ATEXIT
- f2py_cb_stop_call_clock();
- #endif
- CFUNCSMESSPY(\"cb:capi_return=\",capi_return);
- if (capi_return == NULL) {
- fprintf(stderr,\"capi_return is NULL\\n\");
- goto capi_fail;
- }
- if (capi_return == Py_None) {
- Py_DECREF(capi_return);
- capi_return = Py_BuildValue(\"()\");
- }
- else if (!PyTuple_Check(capi_return)) {
- capi_return = Py_BuildValue(\"(N)\",capi_return);
- }
- capi_j = PyTuple_Size(capi_return);
- capi_i = 0;
- #frompyobj#
- CFUNCSMESS(\"cb:#name#:successful\\n\");
- Py_DECREF(capi_return);
- #ifdef F2PY_REPORT_ATEXIT
- f2py_cb_stop_clock();
- #endif
- goto capi_return_pt;
- capi_fail:
- fprintf(stderr,\"Call-back #name# failed.\\n\");
- Py_XDECREF(capi_return);
- Py_XDECREF(capi_arglist_list);
- if (capi_longjmp_ok) {
- longjmp(cb->jmpbuf,-1);
- }
- capi_return_pt:
- ;
- #return#
- }
- #endtitle#
- """,
- 'need': ['setjmp.h', 'CFUNCSMESS', 'F2PY_THREAD_LOCAL_DECL'],
- 'maxnofargs': '#maxnofargs#',
- 'nofoptargs': '#nofoptargs#',
- 'docstr': """\
- def #argname#(#docsignature#): return #docreturn#\\n\\
- #docstrsigns#""",
- 'latexdocstr': """
- {{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}}
- #routnote#
- #latexdocstrsigns#""",
- 'docstrshort': 'def #argname#(#docsignature#): return #docreturn#'
- }
- cb_rout_rules = [
- { # Init
- 'separatorsfor': {'decl': '\n',
- 'args': ',', 'optargs': '', 'pyobjfrom': '\n', 'freemem': '\n',
- 'args_td': ',', 'optargs_td': '',
- 'args_nm': ',', 'optargs_nm': '',
- 'frompyobj': '\n', 'setdims': '\n',
- 'docstrsigns': '\\n"\n"',
- 'latexdocstrsigns': '\n',
- 'latexdocstrreq': '\n', 'latexdocstropt': '\n',
- 'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
- },
- 'decl': '/*decl*/', 'pyobjfrom': '/*pyobjfrom*/', 'frompyobj': '/*frompyobj*/',
- 'args': [], 'optargs': '', 'return': '', 'strarglens': '', 'freemem': '/*freemem*/',
- 'args_td': [], 'optargs_td': '', 'strarglens_td': '',
- 'args_nm': [], 'optargs_nm': '', 'strarglens_nm': '',
- 'noargs': '',
- 'setdims': '/*setdims*/',
- 'docstrsigns': '', 'latexdocstrsigns': '',
- 'docstrreq': ' Required arguments:',
- 'docstropt': ' Optional arguments:',
- 'docstrout': ' Return objects:',
- 'docstrcbs': ' Call-back functions:',
- 'docreturn': '', 'docsign': '', 'docsignopt': '',
- 'latexdocstrreq': '\\noindent Required arguments:',
- 'latexdocstropt': '\\noindent Optional arguments:',
- 'latexdocstrout': '\\noindent Return objects:',
- 'latexdocstrcbs': '\\noindent Call-back functions:',
- 'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
- }, { # Function
- 'decl': ' #ctype# return_value = 0;',
- 'frompyobj': [
- {debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'},
- '''\
- if (capi_j>capi_i) {
- GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,
- "#ctype#_from_pyobj failed in converting return_value of"
- " call-back function #name# to C #ctype#\\n");
- } else {
- fprintf(stderr,"Warning: call-back function #name# did not provide"
- " return value (index=%d, type=#ctype#)\\n",capi_i);
- }''',
- {debugcapi:
- ' fprintf(stderr,"#showvalueformat#.\\n",return_value);'}
- ],
- 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'],
- 'return': ' return return_value;',
- '_check': l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction))
- },
- { # String function
- 'pyobjfrom': {debugcapi: ' fprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'},
- 'args': '#ctype# return_value,int return_value_len',
- 'args_nm': 'return_value,&return_value_len',
- 'args_td': '#ctype# ,int',
- 'frompyobj': [
- {debugcapi: ' CFUNCSMESS("cb:Getting return_value->\\"");'},
- """\
- if (capi_j>capi_i) {
- GETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);
- } else {
- fprintf(stderr,"Warning: call-back function #name# did not provide"
- " return value (index=%d, type=#ctype#)\\n",capi_i);
- }""",
- {debugcapi:
- ' fprintf(stderr,"#showvalueformat#\\".\\n",return_value);'}
- ],
- 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
- 'string.h', 'GETSTRFROMPYTUPLE'],
- 'return': 'return;',
- '_check': isstringfunction
- },
- { # Complex function
- 'optargs': """
- #ifndef F2PY_CB_RETURNCOMPLEX
- #ctype# *return_value
- #endif
- """,
- 'optargs_nm': """
- #ifndef F2PY_CB_RETURNCOMPLEX
- return_value
- #endif
- """,
- 'optargs_td': """
- #ifndef F2PY_CB_RETURNCOMPLEX
- #ctype# *
- #endif
- """,
- 'decl': """
- #ifdef F2PY_CB_RETURNCOMPLEX
- #ctype# return_value = {0, 0};
- #endif
- """,
- 'frompyobj': [
- {debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'},
- """\
- if (capi_j>capi_i) {
- #ifdef F2PY_CB_RETURNCOMPLEX
- GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,
- \"#ctype#_from_pyobj failed in converting return_value of call-back\"
- \" function #name# to C #ctype#\\n\");
- #else
- GETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,
- \"#ctype#_from_pyobj failed in converting return_value of call-back\"
- \" function #name# to C #ctype#\\n\");
- #endif
- } else {
- fprintf(stderr,
- \"Warning: call-back function #name# did not provide\"
- \" return value (index=%d, type=#ctype#)\\n\",capi_i);
- }""",
- {debugcapi: """\
- #ifdef F2PY_CB_RETURNCOMPLEX
- fprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i);
- #else
- fprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i);
- #endif
- """}
- ],
- 'return': """
- #ifdef F2PY_CB_RETURNCOMPLEX
- return return_value;
- #else
- return;
- #endif
- """,
- 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
- 'string.h', 'GETSCALARFROMPYTUPLE', '#ctype#'],
- '_check': iscomplexfunction
- },
- {'docstrout': ' #pydocsignout#',
- 'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
- {hasnote: '--- #note#'}],
- 'docreturn': '#rname#,',
- '_check': isfunction},
- {'_check': issubroutine, 'return': 'return;'}
- ]
- cb_arg_rules = [
- { # Doc
- 'docstropt': {l_and(isoptional, isintent_nothide): ' #pydocsign#'},
- 'docstrreq': {l_and(isrequired, isintent_nothide): ' #pydocsign#'},
- 'docstrout': {isintent_out: ' #pydocsignout#'},
- 'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
- {hasnote: '--- #note#'}]},
- 'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
- {hasnote: '--- #note#'}]},
- 'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
- {l_and(hasnote, isintent_hide): '--- #note#',
- l_and(hasnote, isintent_nothide): '--- See above.'}]},
- 'docsign': {l_and(isrequired, isintent_nothide): '#varname#,'},
- 'docsignopt': {l_and(isoptional, isintent_nothide): '#varname#,'},
- 'depend': ''
- },
- {
- 'args': {
- l_and(isscalar, isintent_c): '#ctype# #varname_i#',
- l_and(isscalar, l_not(isintent_c)): '#ctype# *#varname_i#_cb_capi',
- isarray: '#ctype# *#varname_i#',
- isstring: '#ctype# #varname_i#'
- },
- 'args_nm': {
- l_and(isscalar, isintent_c): '#varname_i#',
- l_and(isscalar, l_not(isintent_c)): '#varname_i#_cb_capi',
- isarray: '#varname_i#',
- isstring: '#varname_i#'
- },
- 'args_td': {
- l_and(isscalar, isintent_c): '#ctype#',
- l_and(isscalar, l_not(isintent_c)): '#ctype# *',
- isarray: '#ctype# *',
- isstring: '#ctype#'
- },
- 'need': {l_or(isscalar, isarray, isstring): '#ctype#'},
- # untested with multiple args
- 'strarglens': {isstring: ',int #varname_i#_cb_len'},
- 'strarglens_td': {isstring: ',int'}, # untested with multiple args
- # untested with multiple args
- 'strarglens_nm': {isstring: ',#varname_i#_cb_len'},
- },
- { # Scalars
- 'decl': {l_not(isintent_c): ' #ctype# #varname_i#=(*#varname_i#_cb_capi);'},
- 'error': {l_and(isintent_c, isintent_out,
- throw_error('intent(c,out) is forbidden for callback scalar arguments')):
- ''},
- 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->");'},
- {isintent_out:
- ' if (capi_j>capi_i)\n GETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname_i#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'},
- {l_and(debugcapi, l_and(l_not(iscomplex), isintent_c)):
- ' fprintf(stderr,"#showvalueformat#.\\n",#varname_i#);'},
- {l_and(debugcapi, l_and(l_not(iscomplex), l_not( isintent_c))):
- ' fprintf(stderr,"#showvalueformat#.\\n",*#varname_i#_cb_capi);'},
- {l_and(debugcapi, l_and(iscomplex, isintent_c)):
- ' fprintf(stderr,"#showvalueformat#.\\n",(#varname_i#).r,(#varname_i#).i);'},
- {l_and(debugcapi, l_and(iscomplex, l_not( isintent_c))):
- ' fprintf(stderr,"#showvalueformat#.\\n",(*#varname_i#_cb_capi).r,(*#varname_i#_cb_capi).i);'},
- ],
- 'need': [{isintent_out: ['#ctype#_from_pyobj', 'GETSCALARFROMPYTUPLE']},
- {debugcapi: 'CFUNCSMESS'}],
- '_check': isscalar
- }, {
- 'pyobjfrom': [{isintent_in: """\
- if (cb->nofargs>capi_i)
- if (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1(#varname_i#)))
- goto capi_fail;"""},
- {isintent_inout: """\
- if (cb->nofargs>capi_i)
- if (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
- goto capi_fail;"""}],
- 'need': [{isintent_in: 'pyobj_from_#ctype#1'},
- {isintent_inout: 'pyarr_from_p_#ctype#1'},
- {iscomplex: '#ctype#'}],
- '_check': l_and(isscalar, isintent_nothide),
- '_optional': ''
- }, { # String
- 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->\\"");'},
- """ if (capi_j>capi_i)
- GETSTRFROMPYTUPLE(capi_return,capi_i++,#varname_i#,#varname_i#_cb_len);""",
- {debugcapi:
- ' fprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname_i#,#varname_i#_cb_len);'},
- ],
- 'need': ['#ctype#', 'GETSTRFROMPYTUPLE',
- {debugcapi: 'CFUNCSMESS'}, 'string.h'],
- '_check': l_and(isstring, isintent_out)
- }, {
- 'pyobjfrom': [
- {debugcapi:
- (' fprintf(stderr,"debug-capi:cb:#varname#=#showvalueformat#:'
- '%d:\\n",#varname_i#,#varname_i#_cb_len);')},
- {isintent_in: """\
- if (cb->nofargs>capi_i)
- if (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
- goto capi_fail;"""},
- {isintent_inout: """\
- if (cb->nofargs>capi_i) {
- int #varname_i#_cb_dims[] = {#varname_i#_cb_len};
- if (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
- goto capi_fail;
- }"""}],
- 'need': [{isintent_in: 'pyobj_from_#ctype#1size'},
- {isintent_inout: 'pyarr_from_p_#ctype#1'}],
- '_check': l_and(isstring, isintent_nothide),
- '_optional': ''
- },
- # Array ...
- {
- 'decl': ' npy_intp #varname_i#_Dims[#rank#] = {#rank*[-1]#};',
- 'setdims': ' #cbsetdims#;',
- '_check': isarray,
- '_depend': ''
- },
- {
- 'pyobjfrom': [{debugcapi: ' fprintf(stderr,"debug-capi:cb:#varname#\\n");'},
- {isintent_c: """\
- if (cb->nofargs>capi_i) {
- /* tmp_arr will be inserted to capi_arglist_list that will be
- destroyed when leaving callback function wrapper together
- with tmp_arr. */
- PyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,
- #rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,#elsize#,
- NPY_ARRAY_CARRAY,NULL);
- """,
- l_not(isintent_c): """\
- if (cb->nofargs>capi_i) {
- /* tmp_arr will be inserted to capi_arglist_list that will be
- destroyed when leaving callback function wrapper together
- with tmp_arr. */
- PyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,
- #rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,#elsize#,
- NPY_ARRAY_FARRAY,NULL);
- """,
- },
- """
- if (tmp_arr==NULL)
- goto capi_fail;
- if (CAPI_ARGLIST_SETITEM(capi_i++,(PyObject *)tmp_arr))
- goto capi_fail;
- }"""],
- '_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)),
- '_optional': '',
- }, {
- 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->");'},
- """ if (capi_j>capi_i) {
- PyArrayObject *rv_cb_arr = NULL;
- if ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail;
- rv_cb_arr = array_from_pyobj(#atype#,#varname_i#_Dims,#rank#,F2PY_INTENT_IN""",
- {isintent_c: '|F2PY_INTENT_C'},
- """,capi_tmp);
- if (rv_cb_arr == NULL) {
- fprintf(stderr,\"rv_cb_arr is NULL\\n\");
- goto capi_fail;
- }
- MEMCOPY(#varname_i#,PyArray_DATA(rv_cb_arr),PyArray_NBYTES(rv_cb_arr));
- if (capi_tmp != (PyObject *)rv_cb_arr) {
- Py_DECREF(rv_cb_arr);
- }
- }""",
- {debugcapi: ' fprintf(stderr,"<-.\\n");'},
- ],
- 'need': ['MEMCOPY', {iscomplexarray: '#ctype#'}],
- '_check': l_and(isarray, isintent_out)
- }, {
- 'docreturn': '#varname#,',
- '_check': isintent_out
- }
- ]
- ################## Build call-back module #############
- cb_map = {}
- def buildcallbacks(m):
- cb_map[m['name']] = []
- for bi in m['body']:
- if bi['block'] == 'interface':
- for b in bi['body']:
- if b:
- buildcallback(b, m['name'])
- else:
- errmess('warning: empty body for %s\n' % (m['name']))
- def buildcallback(rout, um):
- from . import capi_maps
- outmess(' Constructing call-back function "cb_%s_in_%s"\n' %
- (rout['name'], um))
- args, depargs = getargs(rout)
- capi_maps.depargs = depargs
- var = rout['vars']
- vrd = capi_maps.cb_routsign2map(rout, um)
- rd = dictappend({}, vrd)
- cb_map[um].append([rout['name'], rd['name']])
- for r in cb_rout_rules:
- if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
- ar = applyrules(r, vrd, rout)
- rd = dictappend(rd, ar)
- savevrd = {}
- for i, a in enumerate(args):
- vrd = capi_maps.cb_sign2map(a, var[a], index=i)
- savevrd[a] = vrd
- for r in cb_arg_rules:
- if '_depend' in r:
- continue
- if '_optional' in r and isoptional(var[a]):
- continue
- if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
- ar = applyrules(r, vrd, var[a])
- rd = dictappend(rd, ar)
- if '_break' in r:
- break
- for a in args:
- vrd = savevrd[a]
- for r in cb_arg_rules:
- if '_depend' in r:
- continue
- if ('_optional' not in r) or ('_optional' in r and isrequired(var[a])):
- continue
- if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
- ar = applyrules(r, vrd, var[a])
- rd = dictappend(rd, ar)
- if '_break' in r:
- break
- for a in depargs:
- vrd = savevrd[a]
- for r in cb_arg_rules:
- if '_depend' not in r:
- continue
- if '_optional' in r:
- continue
- if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
- ar = applyrules(r, vrd, var[a])
- rd = dictappend(rd, ar)
- if '_break' in r:
- break
- if 'args' in rd and 'optargs' in rd:
- if isinstance(rd['optargs'], list):
- rd['optargs'] = rd['optargs'] + ["""
- #ifndef F2PY_CB_RETURNCOMPLEX
- ,
- #endif
- """]
- rd['optargs_nm'] = rd['optargs_nm'] + ["""
- #ifndef F2PY_CB_RETURNCOMPLEX
- ,
- #endif
- """]
- rd['optargs_td'] = rd['optargs_td'] + ["""
- #ifndef F2PY_CB_RETURNCOMPLEX
- ,
- #endif
- """]
- if isinstance(rd['docreturn'], list):
- rd['docreturn'] = stripcomma(
- replace('#docreturn#', {'docreturn': rd['docreturn']}))
- optargs = stripcomma(replace('#docsignopt#',
- {'docsignopt': rd['docsignopt']}
- ))
- if optargs == '':
- rd['docsignature'] = stripcomma(
- replace('#docsign#', {'docsign': rd['docsign']}))
- else:
- rd['docsignature'] = replace('#docsign#[#docsignopt#]',
- {'docsign': rd['docsign'],
- 'docsignopt': optargs,
- })
- rd['latexdocsignature'] = rd['docsignature'].replace('_', '\\_')
- rd['latexdocsignature'] = rd['latexdocsignature'].replace(',', ', ')
- rd['docstrsigns'] = []
- rd['latexdocstrsigns'] = []
- for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
- if k in rd and isinstance(rd[k], list):
- rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
- k = 'latex' + k
- if k in rd and isinstance(rd[k], list):
- rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
- ['\\begin{description}'] + rd[k][1:] +\
- ['\\end{description}']
- if 'args' not in rd:
- rd['args'] = ''
- rd['args_td'] = ''
- rd['args_nm'] = ''
- if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')):
- rd['noargs'] = 'void'
- ar = applyrules(cb_routine_rules, rd)
- cfuncs.callbacks[rd['name']] = ar['body']
- if isinstance(ar['need'], str):
- ar['need'] = [ar['need']]
- if 'need' in rd:
- for t in cfuncs.typedefs.keys():
- if t in rd['need']:
- ar['need'].append(t)
- cfuncs.typedefs_generated[rd['name'] + '_typedef'] = ar['cbtypedefs']
- ar['need'].append(rd['name'] + '_typedef')
- cfuncs.needs[rd['name']] = ar['need']
- capi_maps.lcb2_map[rd['name']] = {'maxnofargs': ar['maxnofargs'],
- 'nofoptargs': ar['nofoptargs'],
- 'docstr': ar['docstr'],
- 'latexdocstr': ar['latexdocstr'],
- 'argname': rd['argname']
- }
- outmess(' %s\n' % (ar['docstrshort']))
- return
- ################## Build call-back function #############
|