comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/f2py/rules.py @ 87:2a2c65a20a8b

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