rules.py 61 KB

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