rules.py 61 KB

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