diff options
Diffstat (limited to 'numpy/f2py/rules.py')
-rw-r--r-- | numpy/f2py/rules.py | 1345 |
1 files changed, 1345 insertions, 0 deletions
diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py new file mode 100644 index 000000000..cb2d78e65 --- /dev/null +++ b/numpy/f2py/rules.py @@ -0,0 +1,1345 @@ +#!/usr/bin/env python +""" + +Rules for building C/API module with f2py2e. + +Here is a skeleton of a new wrapper function (13Dec2001): + +wrapper_function(args) + declarations + get_python_arguments, say, `a' and `b' + + get_a_from_python + if (successful) { + + get_b_from_python + if (successful) { + + callfortran + if (succesful) { + + put_a_to_python + if (succesful) { + + put_b_to_python + if (succesful) { + + buildvalue = ... + + } + + } + + } + + } + cleanup_b + + } + cleanup_a + + return buildvalue +""" +""" +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 LGPL. See http://www.fsf.org + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/08/30 08:58:42 $ +Pearu Peterson +""" + +__version__ = "$Revision: 1.129 $"[10:-1] + +import __version__ +f2py_version = __version__.version + +import pprint +import sys,string,time,types,copy +errmess=sys.stderr.write +outmess=sys.stdout.write +show=pprint.pprint + +from auxfuncs import * +import capi_maps +from capi_maps import * +import cfuncs +import common_rules +import use_rules +import f90mod_rules +import func2subr +options={} + +sepdict={} +#for k in ['need_cfuncs']: sepdict[k]=',' +for k in ['decl', + 'frompyobj', + 'cleanupfrompyobj', + 'topyarr','method', + 'pyobjfrom','closepyobjfrom', + 'freemem', + 'userincludes', + 'includes0','includes','typedefs','typedefs_generated', + 'cppmacros','cfuncs','callbacks', + 'latexdoc', + 'restdoc', + 'routine_defs','externroutines', + 'initf2pywraphooks', + 'commonhooks','initcommonhooks', + 'f90modhooks','initf90modhooks']: + sepdict[k]='\n' + +#################### Rules for C/API module ################# + +module_rules={ + 'modulebody':"""\ +/* File: #modulename#module.c + * This file is auto-generated with f2py (version:#f2py_version#). + * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition, + * written by Pearu Peterson <pearu@cens.ioc.ee>. + * See http://cens.ioc.ee/projects/f2py2e/ + * Generation date: """+time.asctime(time.localtime(time.time()))+""" + * $R"""+"""evision:$ + * $D"""+"""ate:$ + * Do not edit this file directly unless you know what you are doing!!! + */ +#ifdef __cplusplus +extern \"C\" { +#endif + +"""+gentitle("See f2py2e/cfuncs.py: includes")+""" +#includes# +#includes0# + +"""+gentitle("See f2py2e/rules.py: mod_rules['modulebody']")+""" +static PyObject *#modulename#_error; +static PyObject *#modulename#_module; + +"""+gentitle("See f2py2e/cfuncs.py: typedefs")+""" +#typedefs# + +"""+gentitle("See f2py2e/cfuncs.py: typedefs_generated")+""" +#typedefs_generated# + +"""+gentitle("See f2py2e/cfuncs.py: cppmacros")+""" +#cppmacros# + +"""+gentitle("See f2py2e/cfuncs.py: cfuncs")+""" +#cfuncs# + +"""+gentitle("See f2py2e/cfuncs.py: userincludes")+""" +#userincludes# + +"""+gentitle("See f2py2e/capi_rules.py: usercode")+""" +#usercode# + +/* See f2py2e/rules.py */ +#externroutines# + +"""+gentitle("See f2py2e/capi_rules.py: usercode1")+""" +#usercode1# + +"""+gentitle("See f2py2e/cb_rules.py: buildcallback")+""" +#callbacks# + +"""+gentitle("See f2py2e/rules.py: buildapi")+""" +#body# + +"""+gentitle("See f2py2e/f90mod_rules.py: buildhooks")+""" +#f90modhooks# + +"""+gentitle("See f2py2e/rules.py: module_rules['modulebody']")+""" + +"""+gentitle("See f2py2e/common_rules.py: buildhooks")+""" +#commonhooks# + +"""+gentitle("See f2py2e/rules.py")+""" + +static FortranDataDef f2py_routine_defs[] = { +#routine_defs# +\t{NULL} +}; + +static PyMethodDef f2py_module_methods[] = { +#pymethoddef# +\t{NULL,NULL} +}; + +DL_EXPORT(void) init#modulename#(void) { +\tint i; +\tPyObject *m,*d, *s; +\tm = #modulename#_module = Py_InitModule(\"#modulename#\", f2py_module_methods); +\tPyFortran_Type.ob_type = &PyType_Type; +\timport_array(); +\tif (PyErr_Occurred()) +\t\tPy_FatalError(\"can't initialize module #modulename# (failed to import scipy.base)\"); +\td = PyModule_GetDict(m); +\ts = PyString_FromString(\"$R"""+"""evision: $\"); +\tPyDict_SetItemString(d, \"__version__\", s); +\ts = PyString_FromString(\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\"); +\tPyDict_SetItemString(d, \"__doc__\", s); +\t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL); +\tPy_DECREF(s); +\tfor(i=0;f2py_routine_defs[i].name!=NULL;i++) +\t\tPyDict_SetItemString(d, f2py_routine_defs[i].name,PyFortranObject_NewAsAttr(&f2py_routine_defs[i])); +#initf2pywraphooks# +#initf90modhooks# +#initcommonhooks# +#interface_usercode# +\tif (PyErr_Occurred()) +\t\tPy_FatalError(\"can't initialize module #modulename#\"); + +#ifdef F2PY_REPORT_ATEXIT +\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\"); +#endif + +} +#ifdef __cplusplus +} +#endif +""", + 'separatorsfor':{'latexdoc':'\n\n', + 'restdoc':'\n\n'}, + 'latexdoc':['\\section{Module \\texttt{#texmodulename#}}\n', + '#modnote#\n', + '#latexdoc#'], + 'restdoc':['Module #modulename#\n'+'='*80, + '\n#restdoc#'] + } + +defmod_rules=[ + {'body':'/*eof body*/', + 'method':'/*eof method*/', + 'externroutines':'/*eof externroutines*/', + 'routine_defs':'/*eof routine_defs*/', + 'initf90modhooks':'/*eof initf90modhooks*/', + 'initf2pywraphooks':'/*eof initf2pywraphooks*/', + 'initcommonhooks':'/*eof initcommonhooks*/', + 'latexdoc':'', + 'restdoc':'', + 'modnote':{hasnote:'#note#',l_not(hasnote):''}, + } + ] + +routine_rules={ + 'separatorsfor':sepdict, + 'body':""" +#begintitle# +static char doc_#apiname#[] = \"\\\nFunction signature:\\n\\\n\t#docreturn##name#(#docsignatureshort#)\\n\\\n#docstrsigns#\"; +/* #declfortranroutine# */ +static PyObject *#apiname#(const PyObject *capi_self, + PyObject *capi_args, + PyObject *capi_keywds, + #functype# (*f2py_func)(#callprotoargument#)) { +\tPyObject * volatile capi_buildvalue = NULL; +\tvolatile int f2py_success = 1; +#decl# +\tstatic char *capi_kwlist[] = {#kwlist##kwlistopt##kwlistxa#NULL}; +#usercode# +#routdebugenter# +#ifdef F2PY_REPORT_ATEXIT +f2py_start_clock(); +#endif +\tif (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\\ +\t\t\"#argformat#|#keyformat##xaformat#:#pyname#\",\\ +\t\tcapi_kwlist#args_capi##keys_capi##keys_xa#))\n\t\treturn NULL; +#frompyobj# +/*end of frompyobj*/ +#ifdef F2PY_REPORT_ATEXIT +f2py_start_call_clock(); +#endif +#callfortranroutine# +if (PyErr_Occurred()) + f2py_success = 0; +#ifdef F2PY_REPORT_ATEXIT +f2py_stop_call_clock(); +#endif +/*end of callfortranroutine*/ +\t\tif (f2py_success) { +#pyobjfrom# +/*end of pyobjfrom*/ +\t\tCFUNCSMESS(\"Building return value.\\n\"); +\t\tcapi_buildvalue = Py_BuildValue(\"#returnformat#\"#return#); +/*closepyobjfrom*/ +#closepyobjfrom# +\t\t} /*if (f2py_success) after callfortranroutine*/ +/*cleanupfrompyobj*/ +#cleanupfrompyobj# +\tif (capi_buildvalue == NULL) { +#routdebugfailure# +\t} else { +#routdebugleave# +\t} +\tCFUNCSMESS(\"Freeing memory.\\n\"); +#freemem# +#ifdef F2PY_REPORT_ATEXIT +f2py_stop_clock(); +#endif +\treturn capi_buildvalue; +} +#endtitle# +""", + 'routine_defs':'#routine_def#', + 'initf2pywraphooks':'#initf2pywraphook#', + 'externroutines':'#declfortranroutine#', + 'doc':'#docreturn##name#(#docsignature#)', + 'docshort':'#docreturn##name#(#docsignatureshort#)', + 'docs':'"\t#docreturn##name#(#docsignature#)\\n"\n', + 'need':['arrayobject.h','CFUNCSMESS','MINMAX'], + 'cppmacros':{debugcapi:'#define DEBUGCFUNCS'}, + 'latexdoc':['\\subsection{Wrapper function \\texttt{#texname#}}\n', + """ +\\noindent{{}\\verb@#docreturn##name#@{}}\\texttt{(#latexdocsignatureshort#)} +#routnote# + +#latexdocstrsigns# +"""], + 'restdoc':['Wrapped function ``#name#``\n'+'-'*80, + + ] + } + +################## Rules for C/API function ############## + +rout_rules=[ + { # Init + 'separatorsfor': {'callfortranroutine':'\n','routdebugenter':'\n','decl':'\n', + 'routdebugleave':'\n','routdebugfailure':'\n', + 'setjmpbuf':' || ', + 'docstrreq':'\n','docstropt':'\n','docstrout':'\n', + 'docstrcbs':'\n','docstrsigns':'\\n"\n"', + 'latexdocstrsigns':'\n', + 'latexdocstrreq':'\n','latexdocstropt':'\n', + 'latexdocstrout':'\n','latexdocstrcbs':'\n', + }, + 'kwlist':'','kwlistopt':'','callfortran':'','callfortranappend':'', + 'docsign':'','docsignopt':'','decl':'/*decl*/', + 'freemem':'/*freemem*/', + 'docsignshort':'','docsignoptshort':'', + 'docstrsigns':'','latexdocstrsigns':'', + 'docstrreq':'Required arguments:', + 'docstropt':'Optional arguments:', + 'docstrout':'Return objects:', + 'docstrcbs':'Call-back functions:', + 'latexdocstrreq':'\\noindent Required arguments:', + 'latexdocstropt':'\\noindent Optional arguments:', + 'latexdocstrout':'\\noindent Return objects:', + 'latexdocstrcbs':'\\noindent Call-back functions:', + 'args_capi':'','keys_capi':'','functype':'', + 'frompyobj':'/*frompyobj*/', + 'cleanupfrompyobj':['/*end of cleanupfrompyobj*/'], #this list will be reversed + 'pyobjfrom':'/*pyobjfrom*/', + 'closepyobjfrom':['/*end of closepyobjfrom*/'], #this list will be reversed + 'topyarr':'/*topyarr*/','routdebugleave':'/*routdebugleave*/', + 'routdebugenter':'/*routdebugenter*/', + 'routdebugfailure':'/*routdebugfailure*/', + 'callfortranroutine':'/*callfortranroutine*/', + 'argformat':'','keyformat':'','need_cfuncs':'', + 'docreturn':'','return':'','returnformat':'','rformat':'', + 'kwlistxa':'','keys_xa':'','xaformat':'','docsignxa':'','docsignxashort':'', + 'initf2pywraphook':'', + 'routnote':{hasnote:'--- #note#',l_not(hasnote):''}, + },{ + 'apiname':'f2py_rout_#modulename#_#name#', + 'pyname':'#modulename#.#name#', + 'decl':'', + '_check':l_not(ismoduleroutine) + },{ + 'apiname':'f2py_rout_#modulename#_#f90modulename#_#name#', + 'pyname':'#modulename#.#f90modulename#.#name#', + 'decl':'', + '_check':ismoduleroutine + },{ # Subroutine + 'functype':'void', + 'declfortranroutine':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', + l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'extern void #fortranname#(#callprotoargument#);', + ismoduleroutine:'', + isdummyroutine:'' + }, + 'routine_def':{l_not(l_or(ismoduleroutine,isintent_c,isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine),isdummyroutine):'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', + }, + 'need':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'F_FUNC'}, + 'callfortranroutine':[ + {debugcapi:["""\tfprintf(stderr,\"debug-capi:Fortran subroutine `#fortranname#(#callfortran#)\'\\n\");"""]}, + {hasexternals:"""\ +\t\tif (#setjmpbuf#) { +\t\t\tf2py_success = 0; +\t\t} else {"""}, + {isthreadsafe:'\t\t\tPy_BEGIN_ALLOW_THREADS'}, + {hascallstatement:'''\t\t\t\t#callstatement#; +\t\t\t\t/*(*f2py_func)(#callfortran#);*/'''}, + {l_not(l_or(hascallstatement,isdummyroutine)):'\t\t\t\t(*f2py_func)(#callfortran#);'}, + {isthreadsafe:'\t\t\tPy_END_ALLOW_THREADS'}, + {hasexternals:"""\t\t}"""} + ], + '_check':issubroutine, + },{ # Wrapped function + 'functype':'void', + 'declfortranroutine':{l_not(l_or(ismoduleroutine,isdummyroutine)):'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);', + isdummyroutine:'', + }, + + 'routine_def':{l_not(l_or(ismoduleroutine,isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + isdummyroutine:'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', + }, + 'initf2pywraphook':{l_not(l_or(ismoduleroutine,isdummyroutine)):''' + { + extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void); + PyObject* o = PyDict_GetItemString(d,"#name#"); + PyObject_SetAttrString(o,"_cpointer", PyCObject_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL)); + } + '''}, + 'need':{l_not(l_or(ismoduleroutine,isdummyroutine)):['F_WRAPPEDFUNC','F_FUNC']}, + 'callfortranroutine':[ + {debugcapi:["""\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]}, + {hasexternals:"""\ +\tif (#setjmpbuf#) { +\t\tf2py_success = 0; +\t} else {"""}, + {isthreadsafe:'\tPy_BEGIN_ALLOW_THREADS'}, + {l_not(l_or(hascallstatement,isdummyroutine)):'\t(*f2py_func)(#callfortran#);'}, + {hascallstatement:'\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'}, + {isthreadsafe:'\tPy_END_ALLOW_THREADS'}, + {hasexternals:'\t}'} + ], + '_check':isfunction_wrap, + },{ # Function + 'functype':'#ctype#', + 'docreturn':{l_not(isintent_hide):'#rname#,'}, + 'docstrout':'\t#pydocsignout#', + 'latexdocstrout':['\\item[]{{}\\verb@#pydocsignout#@{}}', + {hasresultnote:'--- #resultnote#'}], + 'callfortranroutine':[{l_and(debugcapi,isstringfunction):"""\ +#ifdef USESCOMPAQFORTRAN +\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callcompaqfortran#)\\n\"); +#else +\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\"); +#endif +"""}, + {l_and(debugcapi,l_not(isstringfunction)):"""\ +\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\"); +"""} + ], + '_check':l_and(isfunction,l_not(isfunction_wrap)) + },{ # Scalar function + 'declfortranroutine':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'extern #ctype# #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', + l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'extern #ctype# #fortranname#(#callprotoargument#);', + isdummyroutine:'' + }, + 'routine_def':{l_and(l_not(l_or(ismoduleroutine,isintent_c)),l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine),isintent_c,l_not(isdummyroutine)):'\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},', + isdummyroutine:'\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', + }, + 'decl':[{iscomplexfunction_warn:'\t#ctype# #name#_return_value={0,0};', + l_not(iscomplexfunction):'\t#ctype# #name#_return_value=0;'}, + {iscomplexfunction:'\tPyObject *#name#_return_value_capi = Py_None;'} + ], + 'callfortranroutine':[ + {hasexternals:"""\ +\tif (#setjmpbuf#) { +\t\tf2py_success = 0; +\t} else {"""}, + {isthreadsafe:'\tPy_BEGIN_ALLOW_THREADS'}, + {hascallstatement:'''\t#callstatement#; +/*\t#name#_return_value = (*f2py_func)(#callfortran#);*/ +'''}, + {l_not(l_or(hascallstatement,isdummyroutine)):'\t#name#_return_value = (*f2py_func)(#callfortran#);'}, + {isthreadsafe:'\tPy_END_ALLOW_THREADS'}, + {hasexternals:'\t}'}, + {l_and(debugcapi,iscomplexfunction):'\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value.r,#name#_return_value.i);'}, + {l_and(debugcapi,l_not(iscomplexfunction)):'\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value);'}], + 'pyobjfrom':{iscomplexfunction:'\t#name#_return_value_capi = pyobj_from_#ctype#1(#name#_return_value);'}, + 'need':[{l_not(isdummyroutine):'F_FUNC'}, + {iscomplexfunction:'pyobj_from_#ctype#1'}, + {islong_longfunction:'long_long'}, + {islong_doublefunction:'long_double'}], + 'returnformat':{l_not(isintent_hide):'#rformat#'}, + 'return':{iscomplexfunction:',#name#_return_value_capi', + l_not(l_or(iscomplexfunction,isintent_hide)):',#name#_return_value'}, + '_check':l_and(isfunction,l_not(isstringfunction),l_not(isfunction_wrap)) + },{ # String function # in use for --no-wrap + 'declfortranroutine':'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', + 'routine_def':{l_not(l_or(ismoduleroutine,isintent_c)): +# '\t{\"#name#\",-1,{{-1}},0,(char *)F_FUNC(#fortranname#,#FORTRANNAME#),(void *)#apiname#,doc_#apiname#},', + '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine),isintent_c): +# '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(void *)#apiname#,doc_#apiname#},' + '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},' + }, + 'decl':['\t#ctype# #name#_return_value = NULL;', + '\tint #name#_return_value_len = 0;'], + 'callfortran':'#name#_return_value,#name#_return_value_len,', + 'callfortranroutine':['\t#name#_return_value_len = #rlength#;', + '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {', + '\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");', + '\t\tf2py_success = 0;', + '\t} else {', + "\t\t(#name#_return_value)[#name#_return_value_len] = '\\0';", + '\t}', + '\tif (f2py_success) {', + {hasexternals:"""\ +\t\tif (#setjmpbuf#) { +\t\t\tf2py_success = 0; +\t\t} else {"""}, + {isthreadsafe:'\t\tPy_BEGIN_ALLOW_THREADS'}, + """\ +#ifdef USESCOMPAQFORTRAN +\t\t(*f2py_func)(#callcompaqfortran#); +#else +\t\t(*f2py_func)(#callfortran#); +#endif +""", + {isthreadsafe:'\t\tPy_END_ALLOW_THREADS'}, + {hasexternals:'\t\t}'}, + {debugcapi:'\t\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value_len,#name#_return_value);'}, + '\t} /* if (f2py_success) after (string)malloc */', + ], + 'returnformat':'#rformat#', + 'return':',#name#_return_value', + 'freemem':'\tSTRINGFREE(#name#_return_value);', + 'need':['F_FUNC','#ctype#','STRINGFREE'], + '_check':l_and(isstringfunction,l_not(isfunction_wrap)) # ???obsolete + }, + { # Debugging + 'routdebugenter':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#(#docsignature#)\\n");', + 'routdebugleave':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: successful.\\n");', + 'routdebugfailure':'\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: failure.\\n");', + '_check':debugcapi + } + ] + +################ Rules for arguments ################## + +typedef_need_dict = {islong_long:'long_long', + islong_double:'long_double', + islong_complex:'complex_long_double', + isunsigned_char:'unsigned_char', + isunsigned_short:'unsigned_short', + isunsigned:'unsigned', + isunsigned_long_long:'unsigned_long_long'} + +aux_rules=[ + { + 'separatorsfor':sepdict + }, + { # Common + 'frompyobj':['\t/* Processing auxiliary variable #varname# */', + {debugcapi:'\tfprintf(stderr,"#vardebuginfo#\\n");'},], + 'cleanupfrompyobj':'\t/* End of cleaning variable #varname# */', + 'need':typedef_need_dict, + }, +# Scalars (not complex) + { # Common + 'decl':'\t#ctype# #varname# = 0;', + 'need':{hasinitvalue:'math.h'}, + 'frompyobj':{hasinitvalue:'\t#varname# = #init#;'}, + '_check':l_and(isscalar,l_not(iscomplex)), + }, + { + 'return':',#varname#', + 'docstrout':'\t#pydocsignout#', + 'docreturn':'#outvarname#,', + 'returnformat':'#varrformat#', + '_check':l_and(isscalar,l_not(iscomplex),isintent_out), + }, +# Complex scalars + { # Common + 'decl':'\t#ctype# #varname#;', + 'frompyobj': {hasinitvalue:'\t#varname#.r = #init.r#, #varname#.i = #init.i#;'}, + '_check':iscomplex + }, +# String + { # Common + 'decl':['\t#ctype# #varname# = NULL;', + '\tint slen(#varname#);', + ], + 'need':['len..'], + '_check':isstring + }, +# Array + { # Common + 'decl':['\t#ctype# *#varname# = NULL;', + '\tintp #varname#_Dims[#rank#] = {#rank*[-1]#};', + '\tconst int #varname#_Rank = #rank#;', + ], + 'need':['len..',{hasinitvalue:'forcomb'},{hasinitvalue:'CFUNCSMESS'}], + '_check':isarray + }, +# Scalararray + { # Common + '_check':l_and(isarray,l_not(iscomplexarray)) + },{ # Not hidden + '_check':l_and(isarray,l_not(iscomplexarray),isintent_nothide) + }, +# Integer*1 array + {'need':'#ctype#', + '_check':isint1array, + '_depend':'' + }, +# Integer*-1 array + {'need':'#ctype#', + '_check':isunsigned_chararray, + '_depend':'' + }, +# Integer*-2 array + {'need':'#ctype#', + '_check':isunsigned_shortarray, + '_depend':'' + }, +# Integer*-8 array + {'need':'#ctype#', + '_check':isunsigned_long_longarray, + '_depend':'' + }, +# Complexarray + {'need':'#ctype#', + '_check':iscomplexarray, + '_depend':'' + }, +# Stringarray + { + 'callfortranappend':{isarrayofstrings:'flen(#varname#),'}, + 'need':'string', + '_check':isstringarray + } + ] + +arg_rules=[ + { + 'separatorsfor':sepdict + }, + { # Common + 'frompyobj':['\t/* Processing variable #varname# */', + {debugcapi:'\tfprintf(stderr,"#vardebuginfo#\\n");'},], + 'cleanupfrompyobj':'\t/* End of cleaning variable #varname# */', + '_depend':'', + 'need':typedef_need_dict, + }, +# Doc signatures + { + 'docstropt':{l_and(isoptional,isintent_nothide):'\t#pydocsign#'}, + 'docstrreq':{l_and(isrequired,isintent_nothide):'\t#pydocsign#'}, + 'docstrout':{isintent_out:'\t#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.'}]}, + 'depend':'' + }, +# Required/Optional arguments + { + 'kwlist':'"#varname#",', + 'docsign':'#varname#,', + '_check':l_and(isintent_nothide,l_not(isoptional)) + }, + { + 'kwlistopt':'"#varname#",', + 'docsignopt':'#varname#=#showinit#,', + 'docsignoptshort':'#varname#,', + '_check':l_and(isintent_nothide,isoptional) + }, +# Docstring/BuildValue + { + 'docreturn':'#outvarname#,', + 'returnformat':'#varrformat#', + '_check':isintent_out + }, +# Externals (call-back functions) + { # Common + 'docsignxa':{isintent_nothide:'#varname#_extra_args=(),'}, + 'docsignxashort':{isintent_nothide:'#varname#_extra_args,'}, + 'docstropt':{isintent_nothide:'\t#varname#_extra_args := () input tuple'}, + 'docstrcbs':'#cbdocstr#', + 'latexdocstrcbs':'\\item[] #cblatexdocstr#', + 'latexdocstropt':{isintent_nothide:'\\item[]{{}\\verb@#varname#_extra_args := () input tuple@{}} --- Extra arguments for call-back function {{}\\verb@#varname#@{}}.'}, + 'decl':['\tPyObject *#varname#_capi = Py_None;', + '\tPyTupleObject *#varname#_xa_capi = NULL;', + '\tPyTupleObject *#varname#_args_capi = NULL;', + '\tint #varname#_nofargs_capi = 0;', + {l_not(isintent_callback):'\t#cbname#_typedef #varname#_cptr;'} + ], + 'kwlistxa':{isintent_nothide:'"#varname#_extra_args",'}, + 'argformat':{isrequired:'O'}, + 'keyformat':{isoptional:'O'}, + 'xaformat':{isintent_nothide:'O!'}, + 'args_capi':{isrequired:',&#varname#_capi'}, + 'keys_capi':{isoptional:',&#varname#_capi'}, + 'keys_xa':',&PyTuple_Type,&#varname#_xa_capi', + 'setjmpbuf':'(setjmp(#cbname#_jmpbuf))', + 'callfortran':{l_not(isintent_callback):'#varname#_cptr,'}, + 'need':['#cbname#','setjmp.h'], + '_check':isexternal + }, + { + 'frompyobj':[{l_not(isintent_callback):"""\ +if(PyCObject_Check(#varname#_capi)) { + #varname#_cptr = PyCObject_AsVoidPtr(#varname#_capi); +} else { + #varname#_cptr = #cbname#; +} +"""},{isintent_callback:"""\ +if (#varname#_capi==Py_None) { + #varname#_capi = PyObject_GetAttrString(#modulename#_module,\"#varname#\"); + if (#varname#_capi) { + if (#varname#_xa_capi==NULL) { + if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) { + PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\"); + if (capi_tmp) + #varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp); + else + #varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\"); + if (#varname#_xa_capi==NULL) { + PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\"); + return NULL; + } + } + } + } + if (#varname#_capi==NULL) { + PyErr_SetString(#modulename#_error,\"Callback #varname# not defined (as an argument or module #modulename# attribute).\\n\"); + return NULL; + } +} +"""}, +## {l_not(isintent_callback):"""\ +## if (#varname#_capi==Py_None) { +## printf(\"hoi\\n\"); +## } +## """}, +"""\ +\t#varname#_nofargs_capi = #cbname#_nofargs; +\tif (create_cb_arglist(#varname#_capi,#varname#_xa_capi,#maxnofargs#,#nofoptargs#,&#cbname#_nofargs,&#varname#_args_capi,\"failed in processing argument list for call-back #varname#.\")) { +\t\tjmp_buf #varname#_jmpbuf;""", +{debugcapi:["""\ +\t\tfprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#cbname#_nofargs); +\t\tCFUNCSMESSPY(\"for #varname#=\",#cbname#_capi);""", +{l_not(isintent_callback):"""\t\tfprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]}, + """\ +\t\tCFUNCSMESS(\"Saving jmpbuf for `#varname#`.\\n\"); +\t\tSWAP(#varname#_capi,#cbname#_capi,PyObject); +\t\tSWAP(#varname#_args_capi,#cbname#_args_capi,PyTupleObject); +\t\tmemcpy(&#varname#_jmpbuf,&#cbname#_jmpbuf,sizeof(jmp_buf));""", + ], +'cleanupfrompyobj': +"""\ +\t\tCFUNCSMESS(\"Restoring jmpbuf for `#varname#`.\\n\"); +\t\t#cbname#_capi = #varname#_capi; +\t\tPy_DECREF(#cbname#_args_capi); +\t\t#cbname#_args_capi = #varname#_args_capi; +\t\t#cbname#_nofargs = #varname#_nofargs_capi; +\t\tmemcpy(&#cbname#_jmpbuf,&#varname#_jmpbuf,sizeof(jmp_buf)); +\t}""", + 'need':['SWAP','create_cb_arglist'], + '_check':isexternal, + '_depend':'' + }, +# Scalars (not complex) + { # Common + 'decl':'\t#ctype# #varname# = 0;', + 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'}, + 'callfortran':{isintent_c:'#varname#,',l_not(isintent_c):'&#varname#,'}, + 'return':{isintent_out:',#varname#'}, + '_check':l_and(isscalar,l_not(iscomplex)) + },{ + 'need':{hasinitvalue:'math.h'}, + '_check':l_and(isscalar,l_not(iscomplex)), + #'_depend':'' + },{ # Not hidden + 'decl':'\tPyObject *#varname#_capi = Py_None;', + 'argformat':{isrequired:'O'}, + 'keyformat':{isoptional:'O'}, + 'args_capi':{isrequired:',&#varname#_capi'}, + 'keys_capi':{isoptional:',&#varname#_capi'}, + 'pyobjfrom':{isintent_inout:"""\ +\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#); +\tif (f2py_success) {"""}, + 'closepyobjfrom':{isintent_inout:"\t} /*if (f2py_success) of #varname# pyobjfrom*/"}, + 'need':{isintent_inout:'try_pyarr_from_#ctype#'}, + '_check':l_and(isscalar,l_not(iscomplex),isintent_nothide) + },{ + 'frompyobj':[ +# hasinitvalue... +# if pyobj is None: +# varname = init +# else +# from_pyobj(varname) +# +# isoptional and noinitvalue... +# if pyobj is not None: +# from_pyobj(varname) +# else: +# varname is uninitialized +# +# ... +# from_pyobj(varname) +# + {hasinitvalue:'\tif (#varname#_capi == Py_None) #varname# = #init#; else', + '_depend':''}, + {l_and(isoptional,l_not(hasinitvalue)):'\tif (#varname#_capi != Py_None)', + '_depend':''}, + {l_not(islogical):'''\ +\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#"); +\tif (f2py_success) {'''}, + {islogical:'''\ +\t\t#varname# = (#ctype#)PyObject_IsTrue(#varname#_capi); +\t\tf2py_success = 1; +\tif (f2py_success) {'''}, + ], + 'cleanupfrompyobj':'\t} /*if (f2py_success) of #varname#*/', + 'need':{l_not(islogical):'#ctype#_from_pyobj'}, + '_check':l_and(isscalar,l_not(iscomplex),isintent_nothide), + '_depend':'' +# },{ # Hidden +# '_check':l_and(isscalar,l_not(iscomplex),isintent_hide) + },{ # Hidden + 'frompyobj':{hasinitvalue:'\t#varname# = #init#;'}, + 'need':typedef_need_dict, + '_check':l_and(isscalar,l_not(iscomplex),isintent_hide), + '_depend':'' + },{ # Common + 'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'}, + '_check':l_and(isscalar,l_not(iscomplex)), + '_depend':'' + }, +# Complex scalars + { # Common + 'decl':'\t#ctype# #varname#;', + 'callfortran':{isintent_c:'#varname#,',l_not(isintent_c):'&#varname#,'}, + 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'}, + 'return':{isintent_out:',#varname#_capi'}, + '_check':iscomplex + },{ # Not hidden + 'decl':'\tPyObject *#varname#_capi = Py_None;', + 'argformat':{isrequired:'O'}, + 'keyformat':{isoptional:'O'}, + 'args_capi':{isrequired:',&#varname#_capi'}, + 'keys_capi':{isoptional:',&#varname#_capi'}, + 'need':{isintent_inout:'try_pyarr_from_#ctype#'}, + 'pyobjfrom':{isintent_inout:"""\ +\t\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#); +\t\tif (f2py_success) {"""}, + 'closepyobjfrom':{isintent_inout:"\t\t} /*if (f2py_success) of #varname# pyobjfrom*/"}, + '_check':l_and(iscomplex,isintent_nothide) + },{ + 'frompyobj':[{hasinitvalue:'\tif (#varname#_capi==Py_None) {#varname#.r = #init.r#, #varname#.i = #init.i#;} else'}, + {l_and(isoptional,l_not(hasinitvalue)):'\tif (#varname#_capi != Py_None)'}, +# '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\\n");' + '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");' + '\n\tif (f2py_success) {'], + 'cleanupfrompyobj':'\t} /*if (f2py_success) of #varname# frompyobj*/', + 'need':['#ctype#_from_pyobj'], + '_check':l_and(iscomplex,isintent_nothide), + '_depend':'' + },{ # Hidden + 'decl':{isintent_out:'\tPyObject *#varname#_capi = Py_None;'}, + '_check':l_and(iscomplex,isintent_hide) + },{ + 'frompyobj': {hasinitvalue:'\t#varname#.r = #init.r#, #varname#.i = #init.i#;'}, + '_check':l_and(iscomplex,isintent_hide), + '_depend':'' + },{ # Common + 'pyobjfrom':{isintent_out:'\t#varname#_capi = pyobj_from_#ctype#1(#varname#);'}, + 'need':['pyobj_from_#ctype#1'], + '_check':iscomplex + },{ + 'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'}, + '_check':iscomplex, + '_depend':'' + }, +# String + { # Common + 'decl':['\t#ctype# #varname# = NULL;', + '\tint slen(#varname#);', + '\tPyObject *#varname#_capi = Py_None;'], + 'callfortran':'#varname#,', + 'callfortranappend':'slen(#varname#),', + 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'}, +# 'freemem':'\tSTRINGFREE(#varname#);', + 'return':{isintent_out:',#varname#'}, + 'need':['len..'],#'STRINGFREE'], + '_check':isstring + },{ # Common + 'frompyobj':"""\ +\tslen(#varname#) = #length#; +\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\"); +\tif (f2py_success) {""", + 'cleanupfrompyobj':"""\ +\t\tSTRINGFREE(#varname#); +\t} /*if (f2py_success) of #varname#*/""", + 'need':['#ctype#_from_pyobj','len..','STRINGFREE'], + '_check':isstring, + '_depend':'' + },{ # Not hidden + 'argformat':{isrequired:'O'}, + 'keyformat':{isoptional:'O'}, + 'args_capi':{isrequired:',&#varname#_capi'}, + 'keys_capi':{isoptional:',&#varname#_capi'}, + 'pyobjfrom':{isintent_inout:'''\ +\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#); +\tif (f2py_success) {'''}, + 'closepyobjfrom':{isintent_inout:'\t} /*if (f2py_success) of #varname# pyobjfrom*/'}, + 'need':{isintent_inout:'try_pyarr_from_#ctype#'}, + '_check':l_and(isstring,isintent_nothide) + },{ # Hidden + '_check':l_and(isstring,isintent_hide) + },{ + 'frompyobj':{debugcapi:'\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'}, + '_check':isstring, + '_depend':'' + }, +# Array + { # Common + 'decl':['\t#ctype# *#varname# = NULL;', + '\tintp #varname#_Dims[#rank#] = {#rank*[-1]#};', + '\tconst int #varname#_Rank = #rank#;', + '\tPyArrayObject *capi_#varname#_tmp = NULL;', + '\tint capi_#varname#_intent = 0;', + ], + 'callfortran':'#varname#,', + 'return':{isintent_out:',capi_#varname#_tmp'}, + 'need':'len..', + '_check':isarray + },{ # intent(overwrite) array + 'decl':'\tint capi_overwrite_#varname# = 1;', + 'kwlistxa':'"overwrite_#varname#",', + 'xaformat':'i', + 'keys_xa':',&capi_overwrite_#varname#', + 'docsignxa':'overwrite_#varname#=1,', + 'docsignxashort':'overwrite_#varname#,', + 'docstropt':'\toverwrite_#varname# := 1 input int', + '_check':l_and(isarray,isintent_overwrite), + },{ + 'frompyobj':'\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);', + '_check':l_and(isarray,isintent_overwrite), + '_depend':'', + }, + { # intent(copy) array + 'decl':'\tint capi_overwrite_#varname# = 0;', + 'kwlistxa':'"overwrite_#varname#",', + 'xaformat':'i', + 'keys_xa':',&capi_overwrite_#varname#', + 'docsignxa':'overwrite_#varname#=0,', + 'docsignxashort':'overwrite_#varname#,', + 'docstropt':'\toverwrite_#varname# := 0 input int', + '_check':l_and(isarray,isintent_copy), + },{ + 'frompyobj':'\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);', + '_check':l_and(isarray,isintent_copy), + '_depend':'', + },{ + 'need':[{hasinitvalue:'forcomb'},{hasinitvalue:'CFUNCSMESS'}], + '_check':isarray, + '_depend':'' + },{ # Not hidden + 'decl':'\tPyObject *#varname#_capi = Py_None;', + 'argformat':{isrequired:'O'}, + 'keyformat':{isoptional:'O'}, + 'args_capi':{isrequired:',&#varname#_capi'}, + 'keys_capi':{isoptional:',&#varname#_capi'}, +# 'pyobjfrom':{isintent_inout:"""\ +# /* Partly because of the following hack, intent(inout) is depreciated, +# Use intent(in,out) instead. + +# \tif ((#varname#_capi != Py_None) && PyArray_Check(#varname#_capi) \\ +# \t\t&& (#varname#_capi != (PyObject *)capi_#varname#_tmp)) { +# \t\tif (((PyArrayObject *)#varname#_capi)->nd != capi_#varname#_tmp->nd) { +# \t\t\tif (#varname#_capi != capi_#varname#_tmp->base) +# \t\t\t\tcopy_ND_array((PyArrayObject *)capi_#varname#_tmp->base,(PyArrayObject *)#varname#_capi); +# \t\t} else +# \t\t\tcopy_ND_array(capi_#varname#_tmp,(PyArrayObject *)#varname#_capi); +# \t} +# */ +# """}, +# 'need':{isintent_inout:'copy_ND_array'}, + '_check':l_and(isarray,isintent_nothide) + },{ + 'frompyobj':['\t#setdims#;', + '\tcapi_#varname#_intent |= #intent#;', + {isintent_hide:'\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,Py_None);'}, + {isintent_nothide:'\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,#varname#_capi);'}, + """\ +\tif (capi_#varname#_tmp == NULL) { +\t\tif (!PyErr_Occurred()) +\t\t\tPyErr_SetString(#modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" ); +\t} else { +\t\t#varname# = (#ctype# *)(capi_#varname#_tmp->data); +""", +{hasinitvalue:[ + {isintent_nothide:'\tif (#varname#_capi == Py_None) {'}, + {isintent_hide:'\t{'}, + {iscomplexarray:'\t\t#ctype# capi_c;'}, + """\ +\t\tint *_i,capi_i=0; +\t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\"); +\t\tif (initforcomb(capi_#varname#_tmp->dimensions,capi_#varname#_tmp->nd,1)) { +\t\t\twhile ((_i = nextforcomb())) +\t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */ +\t\t} else { +\t\t\tif (!PyErr_Occurred()) +\t\t\t\tPyErr_SetString(#modulename#_error,\"Initialization of #nth# #varname# failed (initforcomb).\"); +\t\t\tf2py_success = 0; +\t\t} +\t} +\tif (f2py_success) {"""]}, + ], + 'cleanupfrompyobj':[ # note that this list will be reversed + '\t} /*if (capi_#varname#_tmp == NULL) ... else of #varname#*/', + {l_not(l_or(isintent_out,isintent_hide)):"""\ +\tif((PyObject *)capi_#varname#_tmp!=#varname#_capi) { +\t\tPy_XDECREF(capi_#varname#_tmp); }"""}, + {l_and(isintent_hide,l_not(isintent_out)):"""\t\tPy_XDECREF(capi_#varname#_tmp);"""}, + {hasinitvalue:'\t} /*if (f2py_success) of #varname# init*/'}, + ], + '_check':isarray, + '_depend':'' + }, +# { # Hidden +# 'freemem':{l_not(isintent_out):'\tPy_XDECREF(capi_#varname#_tmp);'}, +# '_check':l_and(isarray,isintent_hide) +# }, +# Scalararray + { # Common + '_check':l_and(isarray,l_not(iscomplexarray)) + },{ # Not hidden + '_check':l_and(isarray,l_not(iscomplexarray),isintent_nothide) + }, +# Integer*1 array + {'need':'#ctype#', + '_check':isint1array, + '_depend':'' + }, +# Integer*-1 array + {'need':'#ctype#', + '_check':isunsigned_chararray, + '_depend':'' + }, +# Integer*-2 array + {'need':'#ctype#', + '_check':isunsigned_shortarray, + '_depend':'' + }, +# Integer*-8 array + {'need':'#ctype#', + '_check':isunsigned_long_longarray, + '_depend':'' + }, +# Complexarray + {'need':'#ctype#', + '_check':iscomplexarray, + '_depend':'' + }, +# Stringarray + { + 'callfortranappend':{isarrayofstrings:'flen(#varname#),'}, + 'need':'string', + '_check':isstringarray + } + ] + +################# Rules for checking ############### + +check_rules=[ + { + 'frompyobj':{debugcapi:'\tfprintf(stderr,\"debug-capi:Checking `#check#\'\\n\");'}, + 'need':'len..' + },{ + 'frompyobj':'\tCHECKSCALAR(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {', + 'cleanupfrompyobj':'\t} /*CHECKSCALAR(#check#)*/', + 'need':'CHECKSCALAR', + '_check':l_and(isscalar,l_not(iscomplex)), + '_break':'' + },{ + 'frompyobj':'\tCHECKSTRING(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {', + 'cleanupfrompyobj':'\t} /*CHECKSTRING(#check#)*/', + 'need':'CHECKSTRING', + '_check':isstring, + '_break':'' + },{ + 'need':'CHECKARRAY', + 'frompyobj':'\tCHECKARRAY(#check#,\"#check#\",\"#nth# #varname#\") {', + 'cleanupfrompyobj':'\t} /*CHECKARRAY(#check#)*/', + '_check':isarray, + '_break':'' + },{ + 'need':'CHECKGENERIC', + 'frompyobj':'\tCHECKGENERIC(#check#,\"#check#\",\"#nth# #varname#\") {', + 'cleanupfrompyobj':'\t} /*CHECKGENERIC(#check#)*/', + } +] + +########## Applying the rules. No need to modify what follows ############# + +#################### Build C/API module ####################### + +def buildmodule(m,um): + """ + Return + """ + global f2py_version,options + outmess('\tBuilding module "%s"...\n'%(m['name'])) + ret = {} + mod_rules=defmod_rules[:] + vrd=modsign2map(m) + rd=dictappend({'f2py_version':f2py_version},vrd) + funcwrappers = [] + funcwrappers2 = [] # F90 codes + for n in m['interfaced']: + nb=None + for bi in m['body']: + if not bi['block']=='interface': + errmess('buildmodule: Expected interface block. Skipping.\n') + continue + for b in bi['body']: + if b['name']==n: nb=b;break + + if not nb: + errmess('buildmodule: Could not found the body of interfaced routine "%s". Skipping.\n'%(n)) + continue + nb_list = [nb] + if nb.has_key('entry'): + for k,a in nb['entry'].items(): + nb1 = copy.deepcopy(nb) + del nb1['entry'] + nb1['name'] = k + nb1['args'] = a + nb_list.append(nb1) + for nb in nb_list: + api,wrap=buildapi(nb) + if wrap: + if ismoduleroutine(nb): + funcwrappers2.append(wrap) + else: + funcwrappers.append(wrap) + ar=applyrules(api,vrd) + rd=dictappend(rd,ar) + + # Construct COMMON block support + cr,wrap = common_rules.buildhooks(m) + if wrap: + funcwrappers.append(wrap) + ar=applyrules(cr,vrd) + rd=dictappend(rd,ar) + + # Construct F90 module support + mr,wrap = f90mod_rules.buildhooks(m) + if wrap: + funcwrappers2.append(wrap) + ar=applyrules(mr,vrd) + rd=dictappend(rd,ar) + + for u in um: + ar=use_rules.buildusevars(u,m['use'][u['name']]) + rd=dictappend(rd,ar) + + needs=cfuncs.get_needs() + code={} + for n in needs.keys(): + code[n]=[] + for k in needs[n]: + c='' + if cfuncs.includes0.has_key(k): c=cfuncs.includes0[k] + elif cfuncs.includes.has_key(k): c=cfuncs.includes[k] + elif cfuncs.userincludes.has_key(k): c=cfuncs.userincludes[k] + elif cfuncs.typedefs.has_key(k): c=cfuncs.typedefs[k] + elif cfuncs.typedefs_generated.has_key(k): + c=cfuncs.typedefs_generated[k] + elif cfuncs.cppmacros.has_key(k): c=cfuncs.cppmacros[k] + elif cfuncs.cfuncs.has_key(k): c=cfuncs.cfuncs[k] + elif cfuncs.callbacks.has_key(k): c=cfuncs.callbacks[k] + elif cfuncs.f90modhooks.has_key(k): c=cfuncs.f90modhooks[k] + elif cfuncs.commonhooks.has_key(k): c=cfuncs.commonhooks[k] + else: errmess('buildmodule: unknown need %s.\n'%(`k`));continue + code[n].append(c) + mod_rules.append(code) + for r in mod_rules: + if (r.has_key('_check') and r['_check'](m)) or (not r.has_key('_check')): + ar=applyrules(r,vrd,m) + rd=dictappend(rd,ar) + ar=applyrules(module_rules,rd) + + fn = os.path.join(options['buildpath'],vrd['modulename']+'module.c') + ret['csrc'] = fn + f=open(fn,'w') + f.write(string.replace(ar['modulebody'],'\t',2*' ')) + f.close() + outmess('\tWrote C/API module "%s" to file "%s/%smodule.c"\n'%(m['name'],options['buildpath'],vrd['modulename'])) + + if options['dorestdoc']: + fn = os.path.join(options['buildpath'],vrd['modulename']+'module.rest') + f=open(fn,'w') + f.write('.. -*- rest -*-\n') + f.write(string.join(ar['restdoc'],'\n')) + f.close() + outmess('\tReST Documentation is saved to file "%s/%smodule.rest"\n'%(options['buildpath'],vrd['modulename'])) + if options['dolatexdoc']: + fn = os.path.join(options['buildpath'],vrd['modulename']+'module.tex') + ret['ltx'] = fn + f=open(fn,'w') + f.write('%% This file is auto-generated with f2py (version:%s)\n'%(f2py_version)) + if not options.has_key('shortlatex'): + f.write('\\documentclass{article}\n\\usepackage{a4wide}\n\\begin{document}\n\\tableofcontents\n\n') + f.write(string.join(ar['latexdoc'],'\n')) + if not options.has_key('shortlatex'): + f.write('\\end{document}') + f.close() + outmess('\tDocumentation is saved to file "%s/%smodule.tex"\n'%(options['buildpath'],vrd['modulename'])) + if funcwrappers: + wn = os.path.join(options['buildpath'],'%s-f2pywrappers.f'%(vrd['modulename'])) + ret['fsrc'] = wn + f=open(wn,'w') + f.write('C -*- fortran -*-\n') + f.write('C This file is autogenerated with f2py (version:%s)\n'%(f2py_version)) + f.write('C It contains Fortran 77 wrappers to fortran functions.\n') + lines = [] + for l in string.split(string.join(funcwrappers,'\n\n')+'\n','\n'): + if l and l[0]==' ': + while len(l)>=66: + lines.append(l[:66]+'\n &') + l = l[66:] + lines.append(l+'\n') + else: lines.append(l+'\n') + lines = string.join(lines,'').replace('\n &\n','\n') + f.write(lines) + f.close() + outmess('\tFortran 77 wrappers are saved to "%s"\n'%(wn)) + if funcwrappers2: + wn = os.path.join(options['buildpath'],'%s-f2pywrappers2.f90'%(vrd['modulename'])) + ret['fsrc'] = wn + f=open(wn,'w') + f.write('! -*- f90 -*-\n') + f.write('! This file is autogenerated with f2py (version:%s)\n'%(f2py_version)) + f.write('! It contains Fortran 90 wrappers to fortran functions.\n') + lines = [] + for l in string.split(string.join(funcwrappers2,'\n\n')+'\n','\n'): + if len(l)>72 and l[0]==' ': + lines.append(l[:72]+'&\n &') + l = l[72:] + while len(l)>66: + lines.append(l[:66]+'&\n &') + l = l[66:] + lines.append(l+'\n') + else: lines.append(l+'\n') + lines = string.join(lines,'').replace('\n &\n','\n') + f.write(lines) + f.close() + outmess('\tFortran 90 wrappers are saved to "%s"\n'%(wn)) + return ret + +################## Build C/API function ############# + +stnd={1:'st',2:'nd',3:'rd',4:'th',5:'th',6:'th',7:'th',8:'th',9:'th',0:'th'} +def buildapi(rout): + rout,wrap = func2subr.assubr(rout) + args,depargs=getargs2(rout) + capi_maps.depargs=depargs + var=rout['vars'] + auxvars = [a for a in var.keys() if isintent_aux(var[a])] + + if ismoduleroutine(rout): + outmess('\t\t\tConstructing wrapper function "%s.%s"...\n'%(rout['modulename'],rout['name'])) + else: + outmess('\t\tConstructing wrapper function "%s"...\n'%(rout['name'])) + # Routine + vrd=routsign2map(rout) + rd=dictappend({},vrd) + for r in rout_rules: + if (r.has_key('_check') and r['_check'](rout)) or (not r.has_key('_check')): + ar=applyrules(r,vrd,rout) + rd=dictappend(rd,ar) + + # Args + nth,nthk=0,0 + savevrd={} + for a in args: + vrd=sign2map(a,var[a]) + if isintent_aux(var[a]): + _rules = aux_rules + else: + _rules = arg_rules + if not isintent_hide(var[a]): + if not isoptional(var[a]): + nth=nth+1 + vrd['nth']=`nth`+stnd[nth%10]+' argument' + else: + nthk=nthk+1 + vrd['nth']=`nthk`+stnd[nthk%10]+' keyword' + else: vrd['nth']='hidden' + savevrd[a]=vrd + for r in _rules: + if r.has_key('_depend'): continue + if (r.has_key('_check') and r['_check'](var[a])) or (not r.has_key('_check')): + ar=applyrules(r,vrd,var[a]) + rd=dictappend(rd,ar) + if r.has_key('_break'): break + for a in depargs: + if isintent_aux(var[a]): + _rules = aux_rules + else: + _rules = arg_rules + vrd=savevrd[a] + for r in _rules: + if not r.has_key('_depend'): continue + if (r.has_key('_check') and r['_check'](var[a])) or (not r.has_key('_check')): + ar=applyrules(r,vrd,var[a]) + rd=dictappend(rd,ar) + if r.has_key('_break'): break + if var[a].has_key('check'): + for c in var[a]['check']: + vrd['check']=c + ar=applyrules(check_rules,vrd,var[a]) + rd=dictappend(rd,ar) + if type(rd['cleanupfrompyobj']) is types.ListType: + rd['cleanupfrompyobj'].reverse() + if type(rd['closepyobjfrom']) is types.ListType: + rd['closepyobjfrom'].reverse() + rd['docsignature']=stripcomma(replace('#docsign##docsignopt##docsignxa#', + {'docsign':rd['docsign'], + 'docsignopt':rd['docsignopt'], + 'docsignxa':rd['docsignxa']})) + optargs=stripcomma(replace('#docsignopt##docsignxa#', + {'docsignxa':rd['docsignxashort'], + 'docsignopt':rd['docsignoptshort']} + )) + if optargs=='': + rd['docsignatureshort']=stripcomma(replace('#docsign#',{'docsign':rd['docsign']})) + else: + rd['docsignatureshort']=replace('#docsign#[#docsignopt#]', + {'docsign':rd['docsign'], + 'docsignopt':optargs, + }) + rd['latexdocsignatureshort']=string.replace(rd['docsignatureshort'],'_','\\_') + rd['latexdocsignatureshort']=string.replace(rd['latexdocsignatureshort'],',',', ') + cfs=stripcomma(replace('#callfortran##callfortranappend#',{'callfortran':rd['callfortran'],'callfortranappend':rd['callfortranappend']})) + if len(rd['callfortranappend'])>1: + rd['callcompaqfortran']=stripcomma(replace('#callfortran# 0,#callfortranappend#',{'callfortran':rd['callfortran'],'callfortranappend':rd['callfortranappend']})) + else: + rd['callcompaqfortran']=cfs + rd['callfortran']=cfs + if type(rd['docreturn'])==types.ListType: + rd['docreturn']=stripcomma(replace('#docreturn#',{'docreturn':rd['docreturn']}))+' = ' + rd['docstrsigns']=[] + rd['latexdocstrsigns']=[] + for k in ['docstrreq','docstropt','docstrout','docstrcbs']: + if rd.has_key(k) and type(rd[k])==types.ListType: + rd['docstrsigns']=rd['docstrsigns']+rd[k] + k='latex'+k + if rd.has_key(k) and type(rd[k])==types.ListType: + rd['latexdocstrsigns']=rd['latexdocstrsigns']+rd[k][0:1]+\ + ['\\begin{description}']+rd[k][1:]+\ + ['\\end{description}'] + ar=applyrules(routine_rules,rd) + if ismoduleroutine(rout): + outmess('\t\t\t %s\n'%(ar['docshort'])) + else: + outmess('\t\t %s\n'%(ar['docshort'])) + return ar,wrap + + +#################### EOF rules.py ####################### |