rules.py 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. #!/usr/bin/env python3
  2. """
  3. Rules for building C/API module with f2py2e.
  4. Here is a skeleton of a new wrapper function (13Dec2001):
  5. wrapper_function(args)
  6. declarations
  7. get_python_arguments, say, `a' and `b'
  8. get_a_from_python
  9. if (successful) {
  10. get_b_from_python
  11. if (successful) {
  12. callfortran
  13. if (successful) {
  14. put_a_to_python
  15. if (successful) {
  16. put_b_to_python
  17. if (successful) {
  18. buildvalue = ...
  19. }
  20. }
  21. }
  22. }
  23. cleanup_b
  24. }
  25. cleanup_a
  26. return buildvalue
  27. Copyright 1999,2000 Pearu Peterson all rights reserved,
  28. Pearu Peterson <pearu@ioc.ee>
  29. Permission to use, modify, and distribute this software is given under the
  30. terms of the NumPy License.
  31. NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  32. $Date: 2005/08/30 08:58:42 $
  33. Pearu Peterson
  34. """
  35. __version__ = "$Revision: 1.129 $"[10:-1]
  36. from . import __version__
  37. f2py_version = __version__.version
  38. import os
  39. import time
  40. import copy
  41. from .auxfuncs import (
  42. applyrules, debugcapi, dictappend, errmess, gentitle, getargs2,
  43. hascallstatement, hasexternals, hasinitvalue, hasnote, hasresultnote,
  44. isarray, isarrayofstrings, iscomplex, iscomplexarray,
  45. iscomplexfunction, iscomplexfunction_warn, isdummyroutine, isexternal,
  46. isfunction, isfunction_wrap, isint1array, isintent_aux, isintent_c,
  47. isintent_callback, isintent_copy, isintent_hide, isintent_inout,
  48. isintent_nothide, isintent_out, isintent_overwrite, islogical,
  49. islong_complex, islong_double, islong_doublefunction, islong_long,
  50. islong_longfunction, ismoduleroutine, isoptional, isrequired, isscalar,
  51. issigned_long_longarray, isstring, isstringarray, isstringfunction,
  52. issubroutine, issubroutine_wrap, isthreadsafe, isunsigned,
  53. isunsigned_char, isunsigned_chararray, isunsigned_long_long,
  54. isunsigned_long_longarray, isunsigned_short, isunsigned_shortarray,
  55. l_and, l_not, l_or, outmess, replace, stripcomma,
  56. )
  57. from . import capi_maps
  58. from . import cfuncs
  59. from . import common_rules
  60. from . import use_rules
  61. from . import f90mod_rules
  62. from . import func2subr
  63. options = {}
  64. sepdict = {}
  65. #for k in ['need_cfuncs']: sepdict[k]=','
  66. for k in ['decl',
  67. 'frompyobj',
  68. 'cleanupfrompyobj',
  69. 'topyarr', 'method',
  70. 'pyobjfrom', 'closepyobjfrom',
  71. 'freemem',
  72. 'userincludes',
  73. 'includes0', 'includes', 'typedefs', 'typedefs_generated',
  74. 'cppmacros', 'cfuncs', 'callbacks',
  75. 'latexdoc',
  76. 'restdoc',
  77. 'routine_defs', 'externroutines',
  78. 'initf2pywraphooks',
  79. 'commonhooks', 'initcommonhooks',
  80. 'f90modhooks', 'initf90modhooks']:
  81. sepdict[k] = '\n'
  82. #################### Rules for C/API module #################
  83. generationtime = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
  84. module_rules = {
  85. 'modulebody': """\
  86. /* File: #modulename#module.c
  87. * This file is auto-generated with f2py (version:#f2py_version#).
  88. * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition,
  89. * written by Pearu Peterson <pearu@cens.ioc.ee>.
  90. * Generation date: """ + time.asctime(time.gmtime(generationtime)) + """
  91. * Do not edit this file directly unless you know what you are doing!!!
  92. */
  93. #ifdef __cplusplus
  94. extern \"C\" {
  95. #endif
  96. """ + gentitle("See f2py2e/cfuncs.py: includes") + """
  97. #includes#
  98. #includes0#
  99. """ + gentitle("See f2py2e/rules.py: mod_rules['modulebody']") + """
  100. static PyObject *#modulename#_error;
  101. static PyObject *#modulename#_module;
  102. """ + gentitle("See f2py2e/cfuncs.py: typedefs") + """
  103. #typedefs#
  104. """ + gentitle("See f2py2e/cfuncs.py: typedefs_generated") + """
  105. #typedefs_generated#
  106. """ + gentitle("See f2py2e/cfuncs.py: cppmacros") + """
  107. #cppmacros#
  108. """ + gentitle("See f2py2e/cfuncs.py: cfuncs") + """
  109. #cfuncs#
  110. """ + gentitle("See f2py2e/cfuncs.py: userincludes") + """
  111. #userincludes#
  112. """ + gentitle("See f2py2e/capi_rules.py: usercode") + """
  113. #usercode#
  114. /* See f2py2e/rules.py */
  115. #externroutines#
  116. """ + gentitle("See f2py2e/capi_rules.py: usercode1") + """
  117. #usercode1#
  118. """ + gentitle("See f2py2e/cb_rules.py: buildcallback") + """
  119. #callbacks#
  120. """ + gentitle("See f2py2e/rules.py: buildapi") + """
  121. #body#
  122. """ + gentitle("See f2py2e/f90mod_rules.py: buildhooks") + """
  123. #f90modhooks#
  124. """ + gentitle("See f2py2e/rules.py: module_rules['modulebody']") + """
  125. """ + gentitle("See f2py2e/common_rules.py: buildhooks") + """
  126. #commonhooks#
  127. """ + gentitle("See f2py2e/rules.py") + """
  128. static FortranDataDef f2py_routine_defs[] = {
  129. #routine_defs#
  130. \t{NULL}
  131. };
  132. static PyMethodDef f2py_module_methods[] = {
  133. #pymethoddef#
  134. \t{NULL,NULL}
  135. };
  136. static struct PyModuleDef moduledef = {
  137. \tPyModuleDef_HEAD_INIT,
  138. \t"#modulename#",
  139. \tNULL,
  140. \t-1,
  141. \tf2py_module_methods,
  142. \tNULL,
  143. \tNULL,
  144. \tNULL,
  145. \tNULL
  146. };
  147. PyMODINIT_FUNC PyInit_#modulename#(void) {
  148. \tint i;
  149. \tPyObject *m,*d, *s, *tmp;
  150. \tm = #modulename#_module = PyModule_Create(&moduledef);
  151. \tPy_SET_TYPE(&PyFortran_Type, &PyType_Type);
  152. \timport_array();
  153. \tif (PyErr_Occurred())
  154. \t\t{PyErr_SetString(PyExc_ImportError, \"can't initialize module #modulename# (failed to import numpy)\"); return m;}
  155. \td = PyModule_GetDict(m);
  156. \ts = PyString_FromString(\"$R""" + """evision: $\");
  157. \tPyDict_SetItemString(d, \"__version__\", s);
  158. \tPy_DECREF(s);
  159. \ts = PyUnicode_FromString(
  160. \t\t\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\");
  161. \tPyDict_SetItemString(d, \"__doc__\", s);
  162. \tPy_DECREF(s);
  163. \t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL);
  164. \t/*
  165. \t * Store the error object inside the dict, so that it could get deallocated.
  166. \t * (in practice, this is a module, so it likely will not and cannot.)
  167. \t */
  168. \tPyDict_SetItemString(d, \"_#modulename#_error\", #modulename#_error);
  169. \tPy_DECREF(#modulename#_error);
  170. \tfor(i=0;f2py_routine_defs[i].name!=NULL;i++) {
  171. \t\ttmp = PyFortranObject_NewAsAttr(&f2py_routine_defs[i]);
  172. \t\tPyDict_SetItemString(d, f2py_routine_defs[i].name, tmp);
  173. \t\tPy_DECREF(tmp);
  174. \t}
  175. #initf2pywraphooks#
  176. #initf90modhooks#
  177. #initcommonhooks#
  178. #interface_usercode#
  179. #ifdef F2PY_REPORT_ATEXIT
  180. \tif (! PyErr_Occurred())
  181. \t\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\");
  182. #endif
  183. \treturn m;
  184. }
  185. #ifdef __cplusplus
  186. }
  187. #endif
  188. """,
  189. 'separatorsfor': {'latexdoc': '\n\n',
  190. 'restdoc': '\n\n'},
  191. 'latexdoc': ['\\section{Module \\texttt{#texmodulename#}}\n',
  192. '#modnote#\n',
  193. '#latexdoc#'],
  194. 'restdoc': ['Module #modulename#\n' + '=' * 80,
  195. '\n#restdoc#']
  196. }
  197. defmod_rules = [
  198. {'body': '/*eof body*/',
  199. 'method': '/*eof method*/',
  200. 'externroutines': '/*eof externroutines*/',
  201. 'routine_defs': '/*eof routine_defs*/',
  202. 'initf90modhooks': '/*eof initf90modhooks*/',
  203. 'initf2pywraphooks': '/*eof initf2pywraphooks*/',
  204. 'initcommonhooks': '/*eof initcommonhooks*/',
  205. 'latexdoc': '',
  206. 'restdoc': '',
  207. 'modnote': {hasnote: '#note#', l_not(hasnote): ''},
  208. }
  209. ]
  210. routine_rules = {
  211. 'separatorsfor': sepdict,
  212. 'body': """
  213. #begintitle#
  214. static char doc_#apiname#[] = \"\\\n#docreturn##name#(#docsignatureshort#)\\n\\nWrapper for ``#name#``.\\\n\\n#docstrsigns#\";
  215. /* #declfortranroutine# */
  216. static PyObject *#apiname#(const PyObject *capi_self,
  217. PyObject *capi_args,
  218. PyObject *capi_keywds,
  219. #functype# (*f2py_func)(#callprotoargument#)) {
  220. \tPyObject * volatile capi_buildvalue = NULL;
  221. \tvolatile int f2py_success = 1;
  222. #decl#
  223. \tstatic char *capi_kwlist[] = {#kwlist##kwlistopt##kwlistxa#NULL};
  224. #usercode#
  225. #routdebugenter#
  226. #ifdef F2PY_REPORT_ATEXIT
  227. f2py_start_clock();
  228. #endif
  229. \tif (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\\
  230. \t\t\"#argformat#|#keyformat##xaformat#:#pyname#\",\\
  231. \t\tcapi_kwlist#args_capi##keys_capi##keys_xa#))\n\t\treturn NULL;
  232. #frompyobj#
  233. /*end of frompyobj*/
  234. #ifdef F2PY_REPORT_ATEXIT
  235. f2py_start_call_clock();
  236. #endif
  237. #callfortranroutine#
  238. if (PyErr_Occurred())
  239. f2py_success = 0;
  240. #ifdef F2PY_REPORT_ATEXIT
  241. f2py_stop_call_clock();
  242. #endif
  243. /*end of callfortranroutine*/
  244. \t\tif (f2py_success) {
  245. #pyobjfrom#
  246. /*end of pyobjfrom*/
  247. \t\tCFUNCSMESS(\"Building return value.\\n\");
  248. \t\tcapi_buildvalue = Py_BuildValue(\"#returnformat#\"#return#);
  249. /*closepyobjfrom*/
  250. #closepyobjfrom#
  251. \t\t} /*if (f2py_success) after callfortranroutine*/
  252. /*cleanupfrompyobj*/
  253. #cleanupfrompyobj#
  254. \tif (capi_buildvalue == NULL) {
  255. #routdebugfailure#
  256. \t} else {
  257. #routdebugleave#
  258. \t}
  259. \tCFUNCSMESS(\"Freeing memory.\\n\");
  260. #freemem#
  261. #ifdef F2PY_REPORT_ATEXIT
  262. f2py_stop_clock();
  263. #endif
  264. \treturn capi_buildvalue;
  265. }
  266. #endtitle#
  267. """,
  268. 'routine_defs': '#routine_def#',
  269. 'initf2pywraphooks': '#initf2pywraphook#',
  270. 'externroutines': '#declfortranroutine#',
  271. 'doc': '#docreturn##name#(#docsignature#)',
  272. 'docshort': '#docreturn##name#(#docsignatureshort#)',
  273. 'docs': '"\t#docreturn##name#(#docsignature#)\\n"\n',
  274. 'need': ['arrayobject.h', 'CFUNCSMESS', 'MINMAX'],
  275. 'cppmacros': {debugcapi: '#define DEBUGCFUNCS'},
  276. 'latexdoc': ['\\subsection{Wrapper function \\texttt{#texname#}}\n',
  277. """
  278. \\noindent{{}\\verb@#docreturn##name#@{}}\\texttt{(#latexdocsignatureshort#)}
  279. #routnote#
  280. #latexdocstrsigns#
  281. """],
  282. 'restdoc': ['Wrapped function ``#name#``\n' + '-' * 80,
  283. ]
  284. }
  285. ################## Rules for C/API function ##############
  286. rout_rules = [
  287. { # Init
  288. 'separatorsfor': {'callfortranroutine': '\n', 'routdebugenter': '\n', 'decl': '\n',
  289. 'routdebugleave': '\n', 'routdebugfailure': '\n',
  290. 'setjmpbuf': ' || ',
  291. 'docstrreq': '\n', 'docstropt': '\n', 'docstrout': '\n',
  292. 'docstrcbs': '\n', 'docstrsigns': '\\n"\n"',
  293. 'latexdocstrsigns': '\n',
  294. 'latexdocstrreq': '\n', 'latexdocstropt': '\n',
  295. 'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
  296. },
  297. 'kwlist': '', 'kwlistopt': '', 'callfortran': '', 'callfortranappend': '',
  298. 'docsign': '', 'docsignopt': '', 'decl': '/*decl*/',
  299. 'freemem': '/*freemem*/',
  300. 'docsignshort': '', 'docsignoptshort': '',
  301. 'docstrsigns': '', 'latexdocstrsigns': '',
  302. 'docstrreq': '\\nParameters\\n----------',
  303. 'docstropt': '\\nOther Parameters\\n----------------',
  304. 'docstrout': '\\nReturns\\n-------',
  305. 'docstrcbs': '\\nNotes\\n-----\\nCall-back functions::\\n',
  306. 'latexdocstrreq': '\\noindent Required arguments:',
  307. 'latexdocstropt': '\\noindent Optional arguments:',
  308. 'latexdocstrout': '\\noindent Return objects:',
  309. 'latexdocstrcbs': '\\noindent Call-back functions:',
  310. 'args_capi': '', 'keys_capi': '', 'functype': '',
  311. 'frompyobj': '/*frompyobj*/',
  312. # this list will be reversed
  313. 'cleanupfrompyobj': ['/*end of cleanupfrompyobj*/'],
  314. 'pyobjfrom': '/*pyobjfrom*/',
  315. # this list will be reversed
  316. 'closepyobjfrom': ['/*end of closepyobjfrom*/'],
  317. 'topyarr': '/*topyarr*/', 'routdebugleave': '/*routdebugleave*/',
  318. 'routdebugenter': '/*routdebugenter*/',
  319. 'routdebugfailure': '/*routdebugfailure*/',
  320. 'callfortranroutine': '/*callfortranroutine*/',
  321. 'argformat': '', 'keyformat': '', 'need_cfuncs': '',
  322. 'docreturn': '', 'return': '', 'returnformat': '', 'rformat': '',
  323. 'kwlistxa': '', 'keys_xa': '', 'xaformat': '', 'docsignxa': '', 'docsignxashort': '',
  324. 'initf2pywraphook': '',
  325. 'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
  326. }, {
  327. 'apiname': 'f2py_rout_#modulename#_#name#',
  328. 'pyname': '#modulename#.#name#',
  329. 'decl': '',
  330. '_check': l_not(ismoduleroutine)
  331. }, {
  332. 'apiname': 'f2py_rout_#modulename#_#f90modulename#_#name#',
  333. 'pyname': '#modulename#.#f90modulename#.#name#',
  334. 'decl': '',
  335. '_check': ismoduleroutine
  336. }, { # Subroutine
  337. 'functype': 'void',
  338. 'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
  339. l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern void #fortranname#(#callprotoargument#);',
  340. ismoduleroutine: '',
  341. isdummyroutine: ''
  342. },
  343. '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#},',
  344. l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
  345. l_and(l_not(ismoduleroutine), isdummyroutine): '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
  346. },
  347. 'need': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'F_FUNC'},
  348. 'callfortranroutine': [
  349. {debugcapi: [
  350. """\tfprintf(stderr,\"debug-capi:Fortran subroutine `#fortranname#(#callfortran#)\'\\n\");"""]},
  351. {hasexternals: """\
  352. \t\tif (#setjmpbuf#) {
  353. \t\t\tf2py_success = 0;
  354. \t\t} else {"""},
  355. {isthreadsafe: '\t\t\tPy_BEGIN_ALLOW_THREADS'},
  356. {hascallstatement: '''\t\t\t\t#callstatement#;
  357. \t\t\t\t/*(*f2py_func)(#callfortran#);*/'''},
  358. {l_not(l_or(hascallstatement, isdummyroutine))
  359. : '\t\t\t\t(*f2py_func)(#callfortran#);'},
  360. {isthreadsafe: '\t\t\tPy_END_ALLOW_THREADS'},
  361. {hasexternals: """\t\t}"""}
  362. ],
  363. '_check': l_and(issubroutine, l_not(issubroutine_wrap)),
  364. }, { # Wrapped function
  365. 'functype': 'void',
  366. 'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);',
  367. isdummyroutine: '',
  368. },
  369. '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#},',
  370. isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
  371. },
  372. 'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): '''
  373. {
  374. extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void);
  375. PyObject* o = PyDict_GetItemString(d,"#name#");
  376. tmp = F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL);
  377. PyObject_SetAttrString(o,"_cpointer", tmp);
  378. Py_DECREF(tmp);
  379. s = PyUnicode_FromString("#name#");
  380. PyObject_SetAttrString(o,"__name__", s);
  381. Py_DECREF(s);
  382. }
  383. '''},
  384. 'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
  385. 'callfortranroutine': [
  386. {debugcapi: [
  387. """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]},
  388. {hasexternals: """\
  389. \tif (#setjmpbuf#) {
  390. \t\tf2py_success = 0;
  391. \t} else {"""},
  392. {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
  393. {l_not(l_or(hascallstatement, isdummyroutine))
  394. : '\t(*f2py_func)(#callfortran#);'},
  395. {hascallstatement:
  396. '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'},
  397. {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
  398. {hasexternals: '\t}'}
  399. ],
  400. '_check': isfunction_wrap,
  401. }, { # Wrapped subroutine
  402. 'functype': 'void',
  403. 'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);',
  404. isdummyroutine: '',
  405. },
  406. '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#},',
  407. isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
  408. },
  409. 'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): '''
  410. {
  411. extern void #F_FUNC#(#name_lower#,#NAME#)(void);
  412. PyObject* o = PyDict_GetItemString(d,"#name#");
  413. tmp = F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL);
  414. PyObject_SetAttrString(o,"_cpointer", tmp);
  415. Py_DECREF(tmp);
  416. s = PyUnicode_FromString("#name#");
  417. PyObject_SetAttrString(o,"__name__", s);
  418. Py_DECREF(s);
  419. }
  420. '''},
  421. 'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
  422. 'callfortranroutine': [
  423. {debugcapi: [
  424. """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]},
  425. {hasexternals: """\
  426. \tif (#setjmpbuf#) {
  427. \t\tf2py_success = 0;
  428. \t} else {"""},
  429. {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
  430. {l_not(l_or(hascallstatement, isdummyroutine))
  431. : '\t(*f2py_func)(#callfortran#);'},
  432. {hascallstatement:
  433. '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'},
  434. {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
  435. {hasexternals: '\t}'}
  436. ],
  437. '_check': issubroutine_wrap,
  438. }, { # Function
  439. 'functype': '#ctype#',
  440. 'docreturn': {l_not(isintent_hide): '#rname#,'},
  441. 'docstrout': '#pydocsignout#',
  442. 'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
  443. {hasresultnote: '--- #resultnote#'}],
  444. 'callfortranroutine': [{l_and(debugcapi, isstringfunction): """\
  445. #ifdef USESCOMPAQFORTRAN
  446. \tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callcompaqfortran#)\\n\");
  447. #else
  448. \tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
  449. #endif
  450. """},
  451. {l_and(debugcapi, l_not(isstringfunction)): """\
  452. \tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
  453. """}
  454. ],
  455. '_check': l_and(isfunction, l_not(isfunction_wrap))
  456. }, { # Scalar function
  457. 'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern #ctype# #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
  458. l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern #ctype# #fortranname#(#callprotoargument#);',
  459. isdummyroutine: ''
  460. },
  461. '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#},',
  462. l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
  463. isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
  464. },
  465. 'decl': [{iscomplexfunction_warn: '\t#ctype# #name#_return_value={0,0};',
  466. l_not(iscomplexfunction): '\t#ctype# #name#_return_value=0;'},
  467. {iscomplexfunction:
  468. '\tPyObject *#name#_return_value_capi = Py_None;'}
  469. ],
  470. 'callfortranroutine': [
  471. {hasexternals: """\
  472. \tif (#setjmpbuf#) {
  473. \t\tf2py_success = 0;
  474. \t} else {"""},
  475. {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
  476. {hascallstatement: '''\t#callstatement#;
  477. /*\t#name#_return_value = (*f2py_func)(#callfortran#);*/
  478. '''},
  479. {l_not(l_or(hascallstatement, isdummyroutine))
  480. : '\t#name#_return_value = (*f2py_func)(#callfortran#);'},
  481. {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
  482. {hasexternals: '\t}'},
  483. {l_and(debugcapi, iscomplexfunction)
  484. : '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value.r,#name#_return_value.i);'},
  485. {l_and(debugcapi, l_not(iscomplexfunction)): '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value);'}],
  486. 'pyobjfrom': {iscomplexfunction: '\t#name#_return_value_capi = pyobj_from_#ctype#1(#name#_return_value);'},
  487. 'need': [{l_not(isdummyroutine): 'F_FUNC'},
  488. {iscomplexfunction: 'pyobj_from_#ctype#1'},
  489. {islong_longfunction: 'long_long'},
  490. {islong_doublefunction: 'long_double'}],
  491. 'returnformat': {l_not(isintent_hide): '#rformat#'},
  492. 'return': {iscomplexfunction: ',#name#_return_value_capi',
  493. l_not(l_or(iscomplexfunction, isintent_hide)): ',#name#_return_value'},
  494. '_check': l_and(isfunction, l_not(isstringfunction), l_not(isfunction_wrap))
  495. }, { # String function # in use for --no-wrap
  496. 'declfortranroutine': 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
  497. 'routine_def': {l_not(l_or(ismoduleroutine, isintent_c)):
  498. '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
  499. l_and(l_not(ismoduleroutine), isintent_c):
  500. '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},'
  501. },
  502. 'decl': ['\t#ctype# #name#_return_value = NULL;',
  503. '\tint #name#_return_value_len = 0;'],
  504. 'callfortran':'#name#_return_value,#name#_return_value_len,',
  505. 'callfortranroutine':['\t#name#_return_value_len = #rlength#;',
  506. '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {',
  507. '\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");',
  508. '\t\tf2py_success = 0;',
  509. '\t} else {',
  510. "\t\t(#name#_return_value)[#name#_return_value_len] = '\\0';",
  511. '\t}',
  512. '\tif (f2py_success) {',
  513. {hasexternals: """\
  514. \t\tif (#setjmpbuf#) {
  515. \t\t\tf2py_success = 0;
  516. \t\t} else {"""},
  517. {isthreadsafe: '\t\tPy_BEGIN_ALLOW_THREADS'},
  518. """\
  519. #ifdef USESCOMPAQFORTRAN
  520. \t\t(*f2py_func)(#callcompaqfortran#);
  521. #else
  522. \t\t(*f2py_func)(#callfortran#);
  523. #endif
  524. """,
  525. {isthreadsafe: '\t\tPy_END_ALLOW_THREADS'},
  526. {hasexternals: '\t\t}'},
  527. {debugcapi:
  528. '\t\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value_len,#name#_return_value);'},
  529. '\t} /* if (f2py_success) after (string)malloc */',
  530. ],
  531. 'returnformat': '#rformat#',
  532. 'return': ',#name#_return_value',
  533. 'freemem': '\tSTRINGFREE(#name#_return_value);',
  534. 'need': ['F_FUNC', '#ctype#', 'STRINGFREE'],
  535. '_check':l_and(isstringfunction, l_not(isfunction_wrap)) # ???obsolete
  536. },
  537. { # Debugging
  538. 'routdebugenter': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#(#docsignature#)\\n");',
  539. 'routdebugleave': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: successful.\\n");',
  540. 'routdebugfailure': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: failure.\\n");',
  541. '_check': debugcapi
  542. }
  543. ]
  544. ################ Rules for arguments ##################
  545. typedef_need_dict = {islong_long: 'long_long',
  546. islong_double: 'long_double',
  547. islong_complex: 'complex_long_double',
  548. isunsigned_char: 'unsigned_char',
  549. isunsigned_short: 'unsigned_short',
  550. isunsigned: 'unsigned',
  551. isunsigned_long_long: 'unsigned_long_long',
  552. isunsigned_chararray: 'unsigned_char',
  553. isunsigned_shortarray: 'unsigned_short',
  554. isunsigned_long_longarray: 'unsigned_long_long',
  555. issigned_long_longarray: 'long_long',
  556. }
  557. aux_rules = [
  558. {
  559. 'separatorsfor': sepdict
  560. },
  561. { # Common
  562. 'frompyobj': ['\t/* Processing auxiliary variable #varname# */',
  563. {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ],
  564. 'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */',
  565. 'need': typedef_need_dict,
  566. },
  567. # Scalars (not complex)
  568. { # Common
  569. 'decl': '\t#ctype# #varname# = 0;',
  570. 'need': {hasinitvalue: 'math.h'},
  571. 'frompyobj': {hasinitvalue: '\t#varname# = #init#;'},
  572. '_check': l_and(isscalar, l_not(iscomplex)),
  573. },
  574. {
  575. 'return': ',#varname#',
  576. 'docstrout': '#pydocsignout#',
  577. 'docreturn': '#outvarname#,',
  578. 'returnformat': '#varrformat#',
  579. '_check': l_and(isscalar, l_not(iscomplex), isintent_out),
  580. },
  581. # Complex scalars
  582. { # Common
  583. 'decl': '\t#ctype# #varname#;',
  584. 'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
  585. '_check': iscomplex
  586. },
  587. # String
  588. { # Common
  589. 'decl': ['\t#ctype# #varname# = NULL;',
  590. '\tint slen(#varname#);',
  591. ],
  592. 'need':['len..'],
  593. '_check':isstring
  594. },
  595. # Array
  596. { # Common
  597. 'decl': ['\t#ctype# *#varname# = NULL;',
  598. '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
  599. '\tconst int #varname#_Rank = #rank#;',
  600. ],
  601. 'need':['len..', {hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}],
  602. '_check': isarray
  603. },
  604. # Scalararray
  605. { # Common
  606. '_check': l_and(isarray, l_not(iscomplexarray))
  607. }, { # Not hidden
  608. '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide)
  609. },
  610. # Integer*1 array
  611. {'need': '#ctype#',
  612. '_check': isint1array,
  613. '_depend': ''
  614. },
  615. # Integer*-1 array
  616. {'need': '#ctype#',
  617. '_check': isunsigned_chararray,
  618. '_depend': ''
  619. },
  620. # Integer*-2 array
  621. {'need': '#ctype#',
  622. '_check': isunsigned_shortarray,
  623. '_depend': ''
  624. },
  625. # Integer*-8 array
  626. {'need': '#ctype#',
  627. '_check': isunsigned_long_longarray,
  628. '_depend': ''
  629. },
  630. # Complexarray
  631. {'need': '#ctype#',
  632. '_check': iscomplexarray,
  633. '_depend': ''
  634. },
  635. # Stringarray
  636. {
  637. 'callfortranappend': {isarrayofstrings: 'flen(#varname#),'},
  638. 'need': 'string',
  639. '_check': isstringarray
  640. }
  641. ]
  642. arg_rules = [
  643. {
  644. 'separatorsfor': sepdict
  645. },
  646. { # Common
  647. 'frompyobj': ['\t/* Processing variable #varname# */',
  648. {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ],
  649. 'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */',
  650. '_depend': '',
  651. 'need': typedef_need_dict,
  652. },
  653. # Doc signatures
  654. {
  655. 'docstropt': {l_and(isoptional, isintent_nothide): '#pydocsign#'},
  656. 'docstrreq': {l_and(isrequired, isintent_nothide): '#pydocsign#'},
  657. 'docstrout': {isintent_out: '#pydocsignout#'},
  658. 'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
  659. {hasnote: '--- #note#'}]},
  660. 'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
  661. {hasnote: '--- #note#'}]},
  662. 'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
  663. {l_and(hasnote, isintent_hide): '--- #note#',
  664. l_and(hasnote, isintent_nothide): '--- See above.'}]},
  665. 'depend': ''
  666. },
  667. # Required/Optional arguments
  668. {
  669. 'kwlist': '"#varname#",',
  670. 'docsign': '#varname#,',
  671. '_check': l_and(isintent_nothide, l_not(isoptional))
  672. },
  673. {
  674. 'kwlistopt': '"#varname#",',
  675. 'docsignopt': '#varname#=#showinit#,',
  676. 'docsignoptshort': '#varname#,',
  677. '_check': l_and(isintent_nothide, isoptional)
  678. },
  679. # Docstring/BuildValue
  680. {
  681. 'docreturn': '#outvarname#,',
  682. 'returnformat': '#varrformat#',
  683. '_check': isintent_out
  684. },
  685. # Externals (call-back functions)
  686. { # Common
  687. 'docsignxa': {isintent_nothide: '#varname#_extra_args=(),'},
  688. 'docsignxashort': {isintent_nothide: '#varname#_extra_args,'},
  689. 'docstropt': {isintent_nothide: '#varname#_extra_args : input tuple, optional\\n Default: ()'},
  690. 'docstrcbs': '#cbdocstr#',
  691. 'latexdocstrcbs': '\\item[] #cblatexdocstr#',
  692. 'latexdocstropt': {isintent_nothide: '\\item[]{{}\\verb@#varname#_extra_args := () input tuple@{}} --- Extra arguments for call-back function {{}\\verb@#varname#@{}}.'},
  693. 'decl': ['\tPyObject *#varname#_capi = Py_None;',
  694. '\tPyTupleObject *#varname#_xa_capi = NULL;',
  695. '\tPyTupleObject *#varname#_args_capi = NULL;',
  696. '\tint #varname#_nofargs_capi = 0;',
  697. {l_not(isintent_callback):
  698. '\t#cbname#_typedef #varname#_cptr;'}
  699. ],
  700. 'kwlistxa': {isintent_nothide: '"#varname#_extra_args",'},
  701. 'argformat': {isrequired: 'O'},
  702. 'keyformat': {isoptional: 'O'},
  703. 'xaformat': {isintent_nothide: 'O!'},
  704. 'args_capi': {isrequired: ',&#varname#_capi'},
  705. 'keys_capi': {isoptional: ',&#varname#_capi'},
  706. 'keys_xa': ',&PyTuple_Type,&#varname#_xa_capi',
  707. 'setjmpbuf': '(setjmp(#cbname#_jmpbuf))',
  708. 'callfortran': {l_not(isintent_callback): '#varname#_cptr,'},
  709. 'need': ['#cbname#', 'setjmp.h'],
  710. '_check':isexternal
  711. },
  712. {
  713. 'frompyobj': [{l_not(isintent_callback): """\
  714. if(F2PyCapsule_Check(#varname#_capi)) {
  715. #varname#_cptr = F2PyCapsule_AsVoidPtr(#varname#_capi);
  716. } else {
  717. #varname#_cptr = #cbname#;
  718. }
  719. """}, {isintent_callback: """\
  720. if (#varname#_capi==Py_None) {
  721. #varname#_capi = PyObject_GetAttrString(#modulename#_module,\"#varname#\");
  722. if (#varname#_capi) {
  723. if (#varname#_xa_capi==NULL) {
  724. if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) {
  725. PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\");
  726. if (capi_tmp) {
  727. #varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp);
  728. Py_DECREF(capi_tmp);
  729. }
  730. else {
  731. #varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\");
  732. }
  733. if (#varname#_xa_capi==NULL) {
  734. PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\");
  735. return NULL;
  736. }
  737. }
  738. }
  739. }
  740. if (#varname#_capi==NULL) {
  741. PyErr_SetString(#modulename#_error,\"Callback #varname# not defined (as an argument or module #modulename# attribute).\\n\");
  742. return NULL;
  743. }
  744. }
  745. """},
  746. """\
  747. \t#varname#_nofargs_capi = #cbname#_nofargs;
  748. \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#.\")) {
  749. \t\tjmp_buf #varname#_jmpbuf;""",
  750. {debugcapi: ["""\
  751. \t\tfprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#cbname#_nofargs);
  752. \t\tCFUNCSMESSPY(\"for #varname#=\",#cbname#_capi);""",
  753. {l_not(isintent_callback): """\t\tfprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]},
  754. """\
  755. \t\tCFUNCSMESS(\"Saving jmpbuf for `#varname#`.\\n\");
  756. \t\tSWAP(#varname#_capi,#cbname#_capi,PyObject);
  757. \t\tSWAP(#varname#_args_capi,#cbname#_args_capi,PyTupleObject);
  758. \t\tmemcpy(&#varname#_jmpbuf,&#cbname#_jmpbuf,sizeof(jmp_buf));""",
  759. ],
  760. 'cleanupfrompyobj':
  761. """\
  762. \t\tCFUNCSMESS(\"Restoring jmpbuf for `#varname#`.\\n\");
  763. \t\t#cbname#_capi = #varname#_capi;
  764. \t\tPy_DECREF(#cbname#_args_capi);
  765. \t\t#cbname#_args_capi = #varname#_args_capi;
  766. \t\t#cbname#_nofargs = #varname#_nofargs_capi;
  767. \t\tmemcpy(&#cbname#_jmpbuf,&#varname#_jmpbuf,sizeof(jmp_buf));
  768. \t}""",
  769. 'need': ['SWAP', 'create_cb_arglist'],
  770. '_check':isexternal,
  771. '_depend':''
  772. },
  773. # Scalars (not complex)
  774. { # Common
  775. 'decl': '\t#ctype# #varname# = 0;',
  776. 'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
  777. 'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'},
  778. 'return': {isintent_out: ',#varname#'},
  779. '_check': l_and(isscalar, l_not(iscomplex))
  780. }, {
  781. 'need': {hasinitvalue: 'math.h'},
  782. '_check': l_and(isscalar, l_not(iscomplex)),
  783. }, { # Not hidden
  784. 'decl': '\tPyObject *#varname#_capi = Py_None;',
  785. 'argformat': {isrequired: 'O'},
  786. 'keyformat': {isoptional: 'O'},
  787. 'args_capi': {isrequired: ',&#varname#_capi'},
  788. 'keys_capi': {isoptional: ',&#varname#_capi'},
  789. 'pyobjfrom': {isintent_inout: """\
  790. \tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
  791. \tif (f2py_success) {"""},
  792. 'closepyobjfrom': {isintent_inout: "\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
  793. 'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
  794. '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide)
  795. }, {
  796. 'frompyobj': [
  797. # hasinitvalue...
  798. # if pyobj is None:
  799. # varname = init
  800. # else
  801. # from_pyobj(varname)
  802. #
  803. # isoptional and noinitvalue...
  804. # if pyobj is not None:
  805. # from_pyobj(varname)
  806. # else:
  807. # varname is uninitialized
  808. #
  809. # ...
  810. # from_pyobj(varname)
  811. #
  812. {hasinitvalue: '\tif (#varname#_capi == Py_None) #varname# = #init#; else',
  813. '_depend': ''},
  814. {l_and(isoptional, l_not(hasinitvalue)): '\tif (#varname#_capi != Py_None)',
  815. '_depend': ''},
  816. {l_not(islogical): '''\
  817. \t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");
  818. \tif (f2py_success) {'''},
  819. {islogical: '''\
  820. \t\t#varname# = (#ctype#)PyObject_IsTrue(#varname#_capi);
  821. \t\tf2py_success = 1;
  822. \tif (f2py_success) {'''},
  823. ],
  824. 'cleanupfrompyobj': '\t} /*if (f2py_success) of #varname#*/',
  825. 'need': {l_not(islogical): '#ctype#_from_pyobj'},
  826. '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide),
  827. '_depend': ''
  828. }, { # Hidden
  829. 'frompyobj': {hasinitvalue: '\t#varname# = #init#;'},
  830. 'need': typedef_need_dict,
  831. '_check': l_and(isscalar, l_not(iscomplex), isintent_hide),
  832. '_depend': ''
  833. }, { # Common
  834. 'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
  835. '_check': l_and(isscalar, l_not(iscomplex)),
  836. '_depend': ''
  837. },
  838. # Complex scalars
  839. { # Common
  840. 'decl': '\t#ctype# #varname#;',
  841. 'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'},
  842. 'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
  843. 'return': {isintent_out: ',#varname#_capi'},
  844. '_check': iscomplex
  845. }, { # Not hidden
  846. 'decl': '\tPyObject *#varname#_capi = Py_None;',
  847. 'argformat': {isrequired: 'O'},
  848. 'keyformat': {isoptional: 'O'},
  849. 'args_capi': {isrequired: ',&#varname#_capi'},
  850. 'keys_capi': {isoptional: ',&#varname#_capi'},
  851. 'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
  852. 'pyobjfrom': {isintent_inout: """\
  853. \t\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
  854. \t\tif (f2py_success) {"""},
  855. 'closepyobjfrom': {isintent_inout: "\t\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
  856. '_check': l_and(iscomplex, isintent_nothide)
  857. }, {
  858. 'frompyobj': [{hasinitvalue: '\tif (#varname#_capi==Py_None) {#varname#.r = #init.r#, #varname#.i = #init.i#;} else'},
  859. {l_and(isoptional, l_not(hasinitvalue))
  860. : '\tif (#varname#_capi != Py_None)'},
  861. '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");'
  862. '\n\tif (f2py_success) {'],
  863. 'cleanupfrompyobj': '\t} /*if (f2py_success) of #varname# frompyobj*/',
  864. 'need': ['#ctype#_from_pyobj'],
  865. '_check': l_and(iscomplex, isintent_nothide),
  866. '_depend': ''
  867. }, { # Hidden
  868. 'decl': {isintent_out: '\tPyObject *#varname#_capi = Py_None;'},
  869. '_check': l_and(iscomplex, isintent_hide)
  870. }, {
  871. 'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
  872. '_check': l_and(iscomplex, isintent_hide),
  873. '_depend': ''
  874. }, { # Common
  875. 'pyobjfrom': {isintent_out: '\t#varname#_capi = pyobj_from_#ctype#1(#varname#);'},
  876. 'need': ['pyobj_from_#ctype#1'],
  877. '_check': iscomplex
  878. }, {
  879. 'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
  880. '_check': iscomplex,
  881. '_depend': ''
  882. },
  883. # String
  884. { # Common
  885. 'decl': ['\t#ctype# #varname# = NULL;',
  886. '\tint slen(#varname#);',
  887. '\tPyObject *#varname#_capi = Py_None;'],
  888. 'callfortran':'#varname#,',
  889. 'callfortranappend':'slen(#varname#),',
  890. 'pyobjfrom':{debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
  891. 'return': {isintent_out: ',#varname#'},
  892. 'need': ['len..'], # 'STRINGFREE'],
  893. '_check':isstring
  894. }, { # Common
  895. 'frompyobj': """\
  896. \tslen(#varname#) = #length#;
  897. \tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\");
  898. \tif (f2py_success) {""",
  899. 'cleanupfrompyobj': """\
  900. \t\tSTRINGFREE(#varname#);
  901. \t} /*if (f2py_success) of #varname#*/""",
  902. 'need': ['#ctype#_from_pyobj', 'len..', 'STRINGFREE'],
  903. '_check':isstring,
  904. '_depend':''
  905. }, { # Not hidden
  906. 'argformat': {isrequired: 'O'},
  907. 'keyformat': {isoptional: 'O'},
  908. 'args_capi': {isrequired: ',&#varname#_capi'},
  909. 'keys_capi': {isoptional: ',&#varname#_capi'},
  910. 'pyobjfrom': {isintent_inout: '''\
  911. \tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#);
  912. \tif (f2py_success) {'''},
  913. 'closepyobjfrom': {isintent_inout: '\t} /*if (f2py_success) of #varname# pyobjfrom*/'},
  914. 'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
  915. '_check': l_and(isstring, isintent_nothide)
  916. }, { # Hidden
  917. '_check': l_and(isstring, isintent_hide)
  918. }, {
  919. 'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
  920. '_check': isstring,
  921. '_depend': ''
  922. },
  923. # Array
  924. { # Common
  925. 'decl': ['\t#ctype# *#varname# = NULL;',
  926. '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
  927. '\tconst int #varname#_Rank = #rank#;',
  928. '\tPyArrayObject *capi_#varname#_tmp = NULL;',
  929. '\tint capi_#varname#_intent = 0;',
  930. ],
  931. 'callfortran':'#varname#,',
  932. 'return':{isintent_out: ',capi_#varname#_tmp'},
  933. 'need': 'len..',
  934. '_check': isarray
  935. }, { # intent(overwrite) array
  936. 'decl': '\tint capi_overwrite_#varname# = 1;',
  937. 'kwlistxa': '"overwrite_#varname#",',
  938. 'xaformat': 'i',
  939. 'keys_xa': ',&capi_overwrite_#varname#',
  940. 'docsignxa': 'overwrite_#varname#=1,',
  941. 'docsignxashort': 'overwrite_#varname#,',
  942. 'docstropt': 'overwrite_#varname# : input int, optional\\n Default: 1',
  943. '_check': l_and(isarray, isintent_overwrite),
  944. }, {
  945. 'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
  946. '_check': l_and(isarray, isintent_overwrite),
  947. '_depend': '',
  948. },
  949. { # intent(copy) array
  950. 'decl': '\tint capi_overwrite_#varname# = 0;',
  951. 'kwlistxa': '"overwrite_#varname#",',
  952. 'xaformat': 'i',
  953. 'keys_xa': ',&capi_overwrite_#varname#',
  954. 'docsignxa': 'overwrite_#varname#=0,',
  955. 'docsignxashort': 'overwrite_#varname#,',
  956. 'docstropt': 'overwrite_#varname# : input int, optional\\n Default: 0',
  957. '_check': l_and(isarray, isintent_copy),
  958. }, {
  959. 'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
  960. '_check': l_and(isarray, isintent_copy),
  961. '_depend': '',
  962. }, {
  963. 'need': [{hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}],
  964. '_check': isarray,
  965. '_depend': ''
  966. }, { # Not hidden
  967. 'decl': '\tPyObject *#varname#_capi = Py_None;',
  968. 'argformat': {isrequired: 'O'},
  969. 'keyformat': {isoptional: 'O'},
  970. 'args_capi': {isrequired: ',&#varname#_capi'},
  971. 'keys_capi': {isoptional: ',&#varname#_capi'},
  972. '_check': l_and(isarray, isintent_nothide)
  973. }, {
  974. 'frompyobj': ['\t#setdims#;',
  975. '\tcapi_#varname#_intent |= #intent#;',
  976. {isintent_hide:
  977. '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,Py_None);'},
  978. {isintent_nothide:
  979. '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,#varname#_capi);'},
  980. """\
  981. \tif (capi_#varname#_tmp == NULL) {
  982. \t\tPyObject *exc, *val, *tb;
  983. \t\tPyErr_Fetch(&exc, &val, &tb);
  984. \t\tPyErr_SetString(exc ? exc : #modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" );
  985. \t\tnpy_PyErr_ChainExceptionsCause(exc, val, tb);
  986. \t} else {
  987. \t\t#varname# = (#ctype# *)(PyArray_DATA(capi_#varname#_tmp));
  988. """,
  989. {hasinitvalue: [
  990. {isintent_nothide:
  991. '\tif (#varname#_capi == Py_None) {'},
  992. {isintent_hide: '\t{'},
  993. {iscomplexarray: '\t\t#ctype# capi_c;'},
  994. """\
  995. \t\tint *_i,capi_i=0;
  996. \t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\");
  997. \t\tif (initforcomb(PyArray_DIMS(capi_#varname#_tmp),PyArray_NDIM(capi_#varname#_tmp),1)) {
  998. \t\t\twhile ((_i = nextforcomb()))
  999. \t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */
  1000. \t\t} else {
  1001. \t\t\tPyObject *exc, *val, *tb;
  1002. \t\t\tPyErr_Fetch(&exc, &val, &tb);
  1003. \t\t\tPyErr_SetString(exc ? exc : #modulename#_error,\"Initialization of #nth# #varname# failed (initforcomb).\");
  1004. \t\t\tnpy_PyErr_ChainExceptionsCause(exc, val, tb);
  1005. \t\t\tf2py_success = 0;
  1006. \t\t}
  1007. \t}
  1008. \tif (f2py_success) {"""]},
  1009. ],
  1010. 'cleanupfrompyobj': [ # note that this list will be reversed
  1011. '\t} /*if (capi_#varname#_tmp == NULL) ... else of #varname#*/',
  1012. {l_not(l_or(isintent_out, isintent_hide)): """\
  1013. \tif((PyObject *)capi_#varname#_tmp!=#varname#_capi) {
  1014. \t\tPy_XDECREF(capi_#varname#_tmp); }"""},
  1015. {l_and(isintent_hide, l_not(isintent_out))
  1016. : """\t\tPy_XDECREF(capi_#varname#_tmp);"""},
  1017. {hasinitvalue: '\t} /*if (f2py_success) of #varname# init*/'},
  1018. ],
  1019. '_check': isarray,
  1020. '_depend': ''
  1021. },
  1022. # Scalararray
  1023. { # Common
  1024. '_check': l_and(isarray, l_not(iscomplexarray))
  1025. }, { # Not hidden
  1026. '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide)
  1027. },
  1028. # Integer*1 array
  1029. {'need': '#ctype#',
  1030. '_check': isint1array,
  1031. '_depend': ''
  1032. },
  1033. # Integer*-1 array
  1034. {'need': '#ctype#',
  1035. '_check': isunsigned_chararray,
  1036. '_depend': ''
  1037. },
  1038. # Integer*-2 array
  1039. {'need': '#ctype#',
  1040. '_check': isunsigned_shortarray,
  1041. '_depend': ''
  1042. },
  1043. # Integer*-8 array
  1044. {'need': '#ctype#',
  1045. '_check': isunsigned_long_longarray,
  1046. '_depend': ''
  1047. },
  1048. # Complexarray
  1049. {'need': '#ctype#',
  1050. '_check': iscomplexarray,
  1051. '_depend': ''
  1052. },
  1053. # Stringarray
  1054. {
  1055. 'callfortranappend': {isarrayofstrings: 'flen(#varname#),'},
  1056. 'need': 'string',
  1057. '_check': isstringarray
  1058. }
  1059. ]
  1060. ################# Rules for checking ###############
  1061. check_rules = [
  1062. {
  1063. 'frompyobj': {debugcapi: '\tfprintf(stderr,\"debug-capi:Checking `#check#\'\\n\");'},
  1064. 'need': 'len..'
  1065. }, {
  1066. 'frompyobj': '\tCHECKSCALAR(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
  1067. 'cleanupfrompyobj': '\t} /*CHECKSCALAR(#check#)*/',
  1068. 'need': 'CHECKSCALAR',
  1069. '_check': l_and(isscalar, l_not(iscomplex)),
  1070. '_break': ''
  1071. }, {
  1072. 'frompyobj': '\tCHECKSTRING(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
  1073. 'cleanupfrompyobj': '\t} /*CHECKSTRING(#check#)*/',
  1074. 'need': 'CHECKSTRING',
  1075. '_check': isstring,
  1076. '_break': ''
  1077. }, {
  1078. 'need': 'CHECKARRAY',
  1079. 'frompyobj': '\tCHECKARRAY(#check#,\"#check#\",\"#nth# #varname#\") {',
  1080. 'cleanupfrompyobj': '\t} /*CHECKARRAY(#check#)*/',
  1081. '_check': isarray,
  1082. '_break': ''
  1083. }, {
  1084. 'need': 'CHECKGENERIC',
  1085. 'frompyobj': '\tCHECKGENERIC(#check#,\"#check#\",\"#nth# #varname#\") {',
  1086. 'cleanupfrompyobj': '\t} /*CHECKGENERIC(#check#)*/',
  1087. }
  1088. ]
  1089. ########## Applying the rules. No need to modify what follows #############
  1090. #################### Build C/API module #######################
  1091. def buildmodule(m, um):
  1092. """
  1093. Return
  1094. """
  1095. outmess('\tBuilding module "%s"...\n' % (m['name']))
  1096. ret = {}
  1097. mod_rules = defmod_rules[:]
  1098. vrd = capi_maps.modsign2map(m)
  1099. rd = dictappend({'f2py_version': f2py_version}, vrd)
  1100. funcwrappers = []
  1101. funcwrappers2 = [] # F90 codes
  1102. for n in m['interfaced']:
  1103. nb = None
  1104. for bi in m['body']:
  1105. if not bi['block'] == 'interface':
  1106. errmess('buildmodule: Expected interface block. Skipping.\n')
  1107. continue
  1108. for b in bi['body']:
  1109. if b['name'] == n:
  1110. nb = b
  1111. break
  1112. if not nb:
  1113. errmess(
  1114. 'buildmodule: Could not found the body of interfaced routine "%s". Skipping.\n' % (n))
  1115. continue
  1116. nb_list = [nb]
  1117. if 'entry' in nb:
  1118. for k, a in nb['entry'].items():
  1119. nb1 = copy.deepcopy(nb)
  1120. del nb1['entry']
  1121. nb1['name'] = k
  1122. nb1['args'] = a
  1123. nb_list.append(nb1)
  1124. for nb in nb_list:
  1125. api, wrap = buildapi(nb)
  1126. if wrap:
  1127. if ismoduleroutine(nb):
  1128. funcwrappers2.append(wrap)
  1129. else:
  1130. funcwrappers.append(wrap)
  1131. ar = applyrules(api, vrd)
  1132. rd = dictappend(rd, ar)
  1133. # Construct COMMON block support
  1134. cr, wrap = common_rules.buildhooks(m)
  1135. if wrap:
  1136. funcwrappers.append(wrap)
  1137. ar = applyrules(cr, vrd)
  1138. rd = dictappend(rd, ar)
  1139. # Construct F90 module support
  1140. mr, wrap = f90mod_rules.buildhooks(m)
  1141. if wrap:
  1142. funcwrappers2.append(wrap)
  1143. ar = applyrules(mr, vrd)
  1144. rd = dictappend(rd, ar)
  1145. for u in um:
  1146. ar = use_rules.buildusevars(u, m['use'][u['name']])
  1147. rd = dictappend(rd, ar)
  1148. needs = cfuncs.get_needs()
  1149. code = {}
  1150. for n in needs.keys():
  1151. code[n] = []
  1152. for k in needs[n]:
  1153. c = ''
  1154. if k in cfuncs.includes0:
  1155. c = cfuncs.includes0[k]
  1156. elif k in cfuncs.includes:
  1157. c = cfuncs.includes[k]
  1158. elif k in cfuncs.userincludes:
  1159. c = cfuncs.userincludes[k]
  1160. elif k in cfuncs.typedefs:
  1161. c = cfuncs.typedefs[k]
  1162. elif k in cfuncs.typedefs_generated:
  1163. c = cfuncs.typedefs_generated[k]
  1164. elif k in cfuncs.cppmacros:
  1165. c = cfuncs.cppmacros[k]
  1166. elif k in cfuncs.cfuncs:
  1167. c = cfuncs.cfuncs[k]
  1168. elif k in cfuncs.callbacks:
  1169. c = cfuncs.callbacks[k]
  1170. elif k in cfuncs.f90modhooks:
  1171. c = cfuncs.f90modhooks[k]
  1172. elif k in cfuncs.commonhooks:
  1173. c = cfuncs.commonhooks[k]
  1174. else:
  1175. errmess('buildmodule: unknown need %s.\n' % (repr(k)))
  1176. continue
  1177. code[n].append(c)
  1178. mod_rules.append(code)
  1179. for r in mod_rules:
  1180. if ('_check' in r and r['_check'](m)) or ('_check' not in r):
  1181. ar = applyrules(r, vrd, m)
  1182. rd = dictappend(rd, ar)
  1183. ar = applyrules(module_rules, rd)
  1184. fn = os.path.join(options['buildpath'], vrd['coutput'])
  1185. ret['csrc'] = fn
  1186. with open(fn, 'w') as f:
  1187. f.write(ar['modulebody'].replace('\t', 2 * ' '))
  1188. outmess('\tWrote C/API module "%s" to file "%s"\n' % (m['name'], fn))
  1189. if options['dorestdoc']:
  1190. fn = os.path.join(
  1191. options['buildpath'], vrd['modulename'] + 'module.rest')
  1192. with open(fn, 'w') as f:
  1193. f.write('.. -*- rest -*-\n')
  1194. f.write('\n'.join(ar['restdoc']))
  1195. outmess('\tReST Documentation is saved to file "%s/%smodule.rest"\n' %
  1196. (options['buildpath'], vrd['modulename']))
  1197. if options['dolatexdoc']:
  1198. fn = os.path.join(
  1199. options['buildpath'], vrd['modulename'] + 'module.tex')
  1200. ret['ltx'] = fn
  1201. with open(fn, 'w') as f:
  1202. f.write(
  1203. '%% This file is auto-generated with f2py (version:%s)\n' % (f2py_version))
  1204. if 'shortlatex' not in options:
  1205. f.write(
  1206. '\\documentclass{article}\n\\usepackage{a4wide}\n\\begin{document}\n\\tableofcontents\n\n')
  1207. f.write('\n'.join(ar['latexdoc']))
  1208. if 'shortlatex' not in options:
  1209. f.write('\\end{document}')
  1210. outmess('\tDocumentation is saved to file "%s/%smodule.tex"\n' %
  1211. (options['buildpath'], vrd['modulename']))
  1212. if funcwrappers:
  1213. wn = os.path.join(options['buildpath'], vrd['f2py_wrapper_output'])
  1214. ret['fsrc'] = wn
  1215. with open(wn, 'w') as f:
  1216. f.write('C -*- fortran -*-\n')
  1217. f.write(
  1218. 'C This file is autogenerated with f2py (version:%s)\n' % (f2py_version))
  1219. f.write(
  1220. 'C It contains Fortran 77 wrappers to fortran functions.\n')
  1221. lines = []
  1222. for l in ('\n\n'.join(funcwrappers) + '\n').split('\n'):
  1223. if l and l[0] == ' ':
  1224. while len(l) >= 66:
  1225. lines.append(l[:66] + '\n &')
  1226. l = l[66:]
  1227. lines.append(l + '\n')
  1228. else:
  1229. lines.append(l + '\n')
  1230. lines = ''.join(lines).replace('\n &\n', '\n')
  1231. f.write(lines)
  1232. outmess('\tFortran 77 wrappers are saved to "%s"\n' % (wn))
  1233. if funcwrappers2:
  1234. wn = os.path.join(
  1235. options['buildpath'], '%s-f2pywrappers2.f90' % (vrd['modulename']))
  1236. ret['fsrc'] = wn
  1237. with open(wn, 'w') as f:
  1238. f.write('! -*- f90 -*-\n')
  1239. f.write(
  1240. '! This file is autogenerated with f2py (version:%s)\n' % (f2py_version))
  1241. f.write(
  1242. '! It contains Fortran 90 wrappers to fortran functions.\n')
  1243. lines = []
  1244. for l in ('\n\n'.join(funcwrappers2) + '\n').split('\n'):
  1245. if len(l) > 72 and l[0] == ' ':
  1246. lines.append(l[:72] + '&\n &')
  1247. l = l[72:]
  1248. while len(l) > 66:
  1249. lines.append(l[:66] + '&\n &')
  1250. l = l[66:]
  1251. lines.append(l + '\n')
  1252. else:
  1253. lines.append(l + '\n')
  1254. lines = ''.join(lines).replace('\n &\n', '\n')
  1255. f.write(lines)
  1256. outmess('\tFortran 90 wrappers are saved to "%s"\n' % (wn))
  1257. return ret
  1258. ################## Build C/API function #############
  1259. stnd = {1: 'st', 2: 'nd', 3: 'rd', 4: 'th', 5: 'th',
  1260. 6: 'th', 7: 'th', 8: 'th', 9: 'th', 0: 'th'}
  1261. def buildapi(rout):
  1262. rout, wrap = func2subr.assubr(rout)
  1263. args, depargs = getargs2(rout)
  1264. capi_maps.depargs = depargs
  1265. var = rout['vars']
  1266. if ismoduleroutine(rout):
  1267. outmess('\t\t\tConstructing wrapper function "%s.%s"...\n' %
  1268. (rout['modulename'], rout['name']))
  1269. else:
  1270. outmess('\t\tConstructing wrapper function "%s"...\n' % (rout['name']))
  1271. # Routine
  1272. vrd = capi_maps.routsign2map(rout)
  1273. rd = dictappend({}, vrd)
  1274. for r in rout_rules:
  1275. if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
  1276. ar = applyrules(r, vrd, rout)
  1277. rd = dictappend(rd, ar)
  1278. # Args
  1279. nth, nthk = 0, 0
  1280. savevrd = {}
  1281. for a in args:
  1282. vrd = capi_maps.sign2map(a, var[a])
  1283. if isintent_aux(var[a]):
  1284. _rules = aux_rules
  1285. else:
  1286. _rules = arg_rules
  1287. if not isintent_hide(var[a]):
  1288. if not isoptional(var[a]):
  1289. nth = nth + 1
  1290. vrd['nth'] = repr(nth) + stnd[nth % 10] + ' argument'
  1291. else:
  1292. nthk = nthk + 1
  1293. vrd['nth'] = repr(nthk) + stnd[nthk % 10] + ' keyword'
  1294. else:
  1295. vrd['nth'] = 'hidden'
  1296. savevrd[a] = vrd
  1297. for r in _rules:
  1298. if '_depend' in r:
  1299. continue
  1300. if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
  1301. ar = applyrules(r, vrd, var[a])
  1302. rd = dictappend(rd, ar)
  1303. if '_break' in r:
  1304. break
  1305. for a in depargs:
  1306. if isintent_aux(var[a]):
  1307. _rules = aux_rules
  1308. else:
  1309. _rules = arg_rules
  1310. vrd = savevrd[a]
  1311. for r in _rules:
  1312. if '_depend' not in r:
  1313. continue
  1314. if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
  1315. ar = applyrules(r, vrd, var[a])
  1316. rd = dictappend(rd, ar)
  1317. if '_break' in r:
  1318. break
  1319. if 'check' in var[a]:
  1320. for c in var[a]['check']:
  1321. vrd['check'] = c
  1322. ar = applyrules(check_rules, vrd, var[a])
  1323. rd = dictappend(rd, ar)
  1324. if isinstance(rd['cleanupfrompyobj'], list):
  1325. rd['cleanupfrompyobj'].reverse()
  1326. if isinstance(rd['closepyobjfrom'], list):
  1327. rd['closepyobjfrom'].reverse()
  1328. rd['docsignature'] = stripcomma(replace('#docsign##docsignopt##docsignxa#',
  1329. {'docsign': rd['docsign'],
  1330. 'docsignopt': rd['docsignopt'],
  1331. 'docsignxa': rd['docsignxa']}))
  1332. optargs = stripcomma(replace('#docsignopt##docsignxa#',
  1333. {'docsignxa': rd['docsignxashort'],
  1334. 'docsignopt': rd['docsignoptshort']}
  1335. ))
  1336. if optargs == '':
  1337. rd['docsignatureshort'] = stripcomma(
  1338. replace('#docsign#', {'docsign': rd['docsign']}))
  1339. else:
  1340. rd['docsignatureshort'] = replace('#docsign#[#docsignopt#]',
  1341. {'docsign': rd['docsign'],
  1342. 'docsignopt': optargs,
  1343. })
  1344. rd['latexdocsignatureshort'] = rd['docsignatureshort'].replace('_', '\\_')
  1345. rd['latexdocsignatureshort'] = rd[
  1346. 'latexdocsignatureshort'].replace(',', ', ')
  1347. cfs = stripcomma(replace('#callfortran##callfortranappend#', {
  1348. 'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']}))
  1349. if len(rd['callfortranappend']) > 1:
  1350. rd['callcompaqfortran'] = stripcomma(replace('#callfortran# 0,#callfortranappend#', {
  1351. 'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']}))
  1352. else:
  1353. rd['callcompaqfortran'] = cfs
  1354. rd['callfortran'] = cfs
  1355. if isinstance(rd['docreturn'], list):
  1356. rd['docreturn'] = stripcomma(
  1357. replace('#docreturn#', {'docreturn': rd['docreturn']})) + ' = '
  1358. rd['docstrsigns'] = []
  1359. rd['latexdocstrsigns'] = []
  1360. for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
  1361. if k in rd and isinstance(rd[k], list):
  1362. rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
  1363. k = 'latex' + k
  1364. if k in rd and isinstance(rd[k], list):
  1365. rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
  1366. ['\\begin{description}'] + rd[k][1:] +\
  1367. ['\\end{description}']
  1368. ar = applyrules(routine_rules, rd)
  1369. if ismoduleroutine(rout):
  1370. outmess('\t\t\t %s\n' % (ar['docshort']))
  1371. else:
  1372. outmess('\t\t %s\n' % (ar['docshort']))
  1373. return ar, wrap
  1374. #################### EOF rules.py #######################