rules.py 57 KB

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