rules.py 61 KB

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