Chris@87
|
1 #!/usr/bin/env python
|
Chris@87
|
2 """
|
Chris@87
|
3
|
Chris@87
|
4 Build call-back mechanism for f2py2e.
|
Chris@87
|
5
|
Chris@87
|
6 Copyright 2000 Pearu Peterson all rights reserved,
|
Chris@87
|
7 Pearu Peterson <pearu@ioc.ee>
|
Chris@87
|
8 Permission to use, modify, and distribute this software is given under the
|
Chris@87
|
9 terms of the NumPy License.
|
Chris@87
|
10
|
Chris@87
|
11 NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
Chris@87
|
12 $Date: 2005/07/20 11:27:58 $
|
Chris@87
|
13 Pearu Peterson
|
Chris@87
|
14
|
Chris@87
|
15 """
|
Chris@87
|
16 from __future__ import division, absolute_import, print_function
|
Chris@87
|
17
|
Chris@87
|
18 import pprint
|
Chris@87
|
19 import sys
|
Chris@87
|
20
|
Chris@87
|
21 from . import __version__
|
Chris@87
|
22 from .auxfuncs import *
|
Chris@87
|
23 from . import cfuncs
|
Chris@87
|
24
|
Chris@87
|
25 f2py_version = __version__.version
|
Chris@87
|
26
|
Chris@87
|
27 errmess=sys.stderr.write
|
Chris@87
|
28 outmess=sys.stdout.write
|
Chris@87
|
29 show=pprint.pprint
|
Chris@87
|
30
|
Chris@87
|
31
|
Chris@87
|
32 ################## Rules for callback function ##############
|
Chris@87
|
33
|
Chris@87
|
34 cb_routine_rules={
|
Chris@87
|
35 'cbtypedefs':'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);',
|
Chris@87
|
36 'body':"""
|
Chris@87
|
37 #begintitle#
|
Chris@87
|
38 PyObject *#name#_capi = NULL;/*was Py_None*/
|
Chris@87
|
39 PyTupleObject *#name#_args_capi = NULL;
|
Chris@87
|
40 int #name#_nofargs = 0;
|
Chris@87
|
41 jmp_buf #name#_jmpbuf;
|
Chris@87
|
42 /*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/
|
Chris@87
|
43 #static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) {
|
Chris@87
|
44 \tPyTupleObject *capi_arglist = #name#_args_capi;
|
Chris@87
|
45 \tPyObject *capi_return = NULL;
|
Chris@87
|
46 \tPyObject *capi_tmp = NULL;
|
Chris@87
|
47 \tint capi_j,capi_i = 0;
|
Chris@87
|
48 \tint capi_longjmp_ok = 1;
|
Chris@87
|
49 #decl#
|
Chris@87
|
50 #ifdef F2PY_REPORT_ATEXIT
|
Chris@87
|
51 f2py_cb_start_clock();
|
Chris@87
|
52 #endif
|
Chris@87
|
53 \tCFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\");
|
Chris@87
|
54 \tCFUNCSMESSPY(\"cb:#name#_capi=\",#name#_capi);
|
Chris@87
|
55 \tif (#name#_capi==NULL) {
|
Chris@87
|
56 \t\tcapi_longjmp_ok = 0;
|
Chris@87
|
57 \t\t#name#_capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\");
|
Chris@87
|
58 \t}
|
Chris@87
|
59 \tif (#name#_capi==NULL) {
|
Chris@87
|
60 \t\tPyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\");
|
Chris@87
|
61 \t\tgoto capi_fail;
|
Chris@87
|
62 \t}
|
Chris@87
|
63 \tif (F2PyCapsule_Check(#name#_capi)) {
|
Chris@87
|
64 \t#name#_typedef #name#_cptr;
|
Chris@87
|
65 \t#name#_cptr = F2PyCapsule_AsVoidPtr(#name#_capi);
|
Chris@87
|
66 \t#returncptr#(*#name#_cptr)(#optargs_nm##args_nm##strarglens_nm#);
|
Chris@87
|
67 \t#return#
|
Chris@87
|
68 \t}
|
Chris@87
|
69 \tif (capi_arglist==NULL) {
|
Chris@87
|
70 \t\tcapi_longjmp_ok = 0;
|
Chris@87
|
71 \t\tcapi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\");
|
Chris@87
|
72 \t\tif (capi_tmp) {
|
Chris@87
|
73 \t\t\tcapi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp);
|
Chris@87
|
74 \t\t\tif (capi_arglist==NULL) {
|
Chris@87
|
75 \t\t\t\tPyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\");
|
Chris@87
|
76 \t\t\t\tgoto capi_fail;
|
Chris@87
|
77 \t\t\t}
|
Chris@87
|
78 \t\t} else {
|
Chris@87
|
79 \t\t\tPyErr_Clear();
|
Chris@87
|
80 \t\t\tcapi_arglist = (PyTupleObject *)Py_BuildValue(\"()\");
|
Chris@87
|
81 \t\t}
|
Chris@87
|
82 \t}
|
Chris@87
|
83 \tif (capi_arglist == NULL) {
|
Chris@87
|
84 \t\tPyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\");
|
Chris@87
|
85 \t\tgoto capi_fail;
|
Chris@87
|
86 \t}
|
Chris@87
|
87 #setdims#
|
Chris@87
|
88 #pyobjfrom#
|
Chris@87
|
89 \tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist);
|
Chris@87
|
90 \tCFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\");
|
Chris@87
|
91 #ifdef F2PY_REPORT_ATEXIT
|
Chris@87
|
92 f2py_cb_start_call_clock();
|
Chris@87
|
93 #endif
|
Chris@87
|
94 \tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist);
|
Chris@87
|
95 #ifdef F2PY_REPORT_ATEXIT
|
Chris@87
|
96 f2py_cb_stop_call_clock();
|
Chris@87
|
97 #endif
|
Chris@87
|
98 \tCFUNCSMESSPY(\"cb:capi_return=\",capi_return);
|
Chris@87
|
99 \tif (capi_return == NULL) {
|
Chris@87
|
100 \t\tfprintf(stderr,\"capi_return is NULL\\n\");
|
Chris@87
|
101 \t\tgoto capi_fail;
|
Chris@87
|
102 \t}
|
Chris@87
|
103 \tif (capi_return == Py_None) {
|
Chris@87
|
104 \t\tPy_DECREF(capi_return);
|
Chris@87
|
105 \t\tcapi_return = Py_BuildValue(\"()\");
|
Chris@87
|
106 \t}
|
Chris@87
|
107 \telse if (!PyTuple_Check(capi_return)) {
|
Chris@87
|
108 \t\tcapi_return = Py_BuildValue(\"(N)\",capi_return);
|
Chris@87
|
109 \t}
|
Chris@87
|
110 \tcapi_j = PyTuple_Size(capi_return);
|
Chris@87
|
111 \tcapi_i = 0;
|
Chris@87
|
112 #frompyobj#
|
Chris@87
|
113 \tCFUNCSMESS(\"cb:#name#:successful\\n\");
|
Chris@87
|
114 \tPy_DECREF(capi_return);
|
Chris@87
|
115 #ifdef F2PY_REPORT_ATEXIT
|
Chris@87
|
116 f2py_cb_stop_clock();
|
Chris@87
|
117 #endif
|
Chris@87
|
118 \tgoto capi_return_pt;
|
Chris@87
|
119 capi_fail:
|
Chris@87
|
120 \tfprintf(stderr,\"Call-back #name# failed.\\n\");
|
Chris@87
|
121 \tPy_XDECREF(capi_return);
|
Chris@87
|
122 \tif (capi_longjmp_ok)
|
Chris@87
|
123 \t\tlongjmp(#name#_jmpbuf,-1);
|
Chris@87
|
124 capi_return_pt:
|
Chris@87
|
125 \t;
|
Chris@87
|
126 #return#
|
Chris@87
|
127 }
|
Chris@87
|
128 #endtitle#
|
Chris@87
|
129 """,
|
Chris@87
|
130 'need':['setjmp.h', 'CFUNCSMESS'],
|
Chris@87
|
131 'maxnofargs':'#maxnofargs#',
|
Chris@87
|
132 'nofoptargs':'#nofoptargs#',
|
Chris@87
|
133 'docstr':"""\
|
Chris@87
|
134 \tdef #argname#(#docsignature#): return #docreturn#\\n\\
|
Chris@87
|
135 #docstrsigns#""",
|
Chris@87
|
136 'latexdocstr':"""
|
Chris@87
|
137 {{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}}
|
Chris@87
|
138 #routnote#
|
Chris@87
|
139
|
Chris@87
|
140 #latexdocstrsigns#""",
|
Chris@87
|
141 'docstrshort':'def #argname#(#docsignature#): return #docreturn#'
|
Chris@87
|
142 }
|
Chris@87
|
143 cb_rout_rules=[
|
Chris@87
|
144 {# Init
|
Chris@87
|
145 'separatorsfor': {'decl': '\n',
|
Chris@87
|
146 'args': ',', 'optargs': '', 'pyobjfrom': '\n', 'freemem': '\n',
|
Chris@87
|
147 'args_td': ',', 'optargs_td': '',
|
Chris@87
|
148 'args_nm': ',', 'optargs_nm': '',
|
Chris@87
|
149 'frompyobj': '\n', 'setdims': '\n',
|
Chris@87
|
150 'docstrsigns': '\\n"\n"',
|
Chris@87
|
151 'latexdocstrsigns': '\n',
|
Chris@87
|
152 'latexdocstrreq': '\n', 'latexdocstropt': '\n',
|
Chris@87
|
153 'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
|
Chris@87
|
154 },
|
Chris@87
|
155 'decl': '/*decl*/', 'pyobjfrom': '/*pyobjfrom*/', 'frompyobj': '/*frompyobj*/',
|
Chris@87
|
156 'args': [], 'optargs': '', 'return': '', 'strarglens': '', 'freemem': '/*freemem*/',
|
Chris@87
|
157 'args_td': [], 'optargs_td': '', 'strarglens_td': '',
|
Chris@87
|
158 'args_nm': [], 'optargs_nm': '', 'strarglens_nm': '',
|
Chris@87
|
159 'noargs': '',
|
Chris@87
|
160 'setdims': '/*setdims*/',
|
Chris@87
|
161 'docstrsigns': '', 'latexdocstrsigns': '',
|
Chris@87
|
162 'docstrreq': '\tRequired arguments:',
|
Chris@87
|
163 'docstropt': '\tOptional arguments:',
|
Chris@87
|
164 'docstrout': '\tReturn objects:',
|
Chris@87
|
165 'docstrcbs': '\tCall-back functions:',
|
Chris@87
|
166 'docreturn': '', 'docsign': '', 'docsignopt': '',
|
Chris@87
|
167 'latexdocstrreq': '\\noindent Required arguments:',
|
Chris@87
|
168 'latexdocstropt': '\\noindent Optional arguments:',
|
Chris@87
|
169 'latexdocstrout': '\\noindent Return objects:',
|
Chris@87
|
170 'latexdocstrcbs': '\\noindent Call-back functions:',
|
Chris@87
|
171 'routnote': {hasnote:'--- #note#',l_not(hasnote):''},
|
Chris@87
|
172 }, { # Function
|
Chris@87
|
173 'decl':'\t#ctype# return_value;',
|
Chris@87
|
174 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting return_value->");'},
|
Chris@87
|
175 '\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n");',
|
Chris@87
|
176 {debugcapi:'\tfprintf(stderr,"#showvalueformat#.\\n",return_value);'}
|
Chris@87
|
177 ],
|
Chris@87
|
178 'need':['#ctype#_from_pyobj', {debugcapi:'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'],
|
Chris@87
|
179 'return':'\treturn return_value;',
|
Chris@87
|
180 '_check':l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction))
|
Chris@87
|
181 },
|
Chris@87
|
182 {# String function
|
Chris@87
|
183 'pyobjfrom':{debugcapi:'\tfprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'},
|
Chris@87
|
184 'args':'#ctype# return_value,int return_value_len',
|
Chris@87
|
185 'args_nm':'return_value,&return_value_len',
|
Chris@87
|
186 'args_td':'#ctype# ,int',
|
Chris@87
|
187 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting return_value->\\"");'},
|
Chris@87
|
188 """\tif (capi_j>capi_i)
|
Chris@87
|
189 \t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);""",
|
Chris@87
|
190 {debugcapi:'\tfprintf(stderr,"#showvalueformat#\\".\\n",return_value);'}
|
Chris@87
|
191 ],
|
Chris@87
|
192 'need':['#ctype#_from_pyobj', {debugcapi:'CFUNCSMESS'},
|
Chris@87
|
193 'string.h', 'GETSTRFROMPYTUPLE'],
|
Chris@87
|
194 'return':'return;',
|
Chris@87
|
195 '_check':isstringfunction
|
Chris@87
|
196 },
|
Chris@87
|
197 {# Complex function
|
Chris@87
|
198 'optargs':"""
|
Chris@87
|
199 #ifndef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
200 #ctype# *return_value
|
Chris@87
|
201 #endif
|
Chris@87
|
202 """,
|
Chris@87
|
203 'optargs_nm':"""
|
Chris@87
|
204 #ifndef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
205 return_value
|
Chris@87
|
206 #endif
|
Chris@87
|
207 """,
|
Chris@87
|
208 'optargs_td':"""
|
Chris@87
|
209 #ifndef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
210 #ctype# *
|
Chris@87
|
211 #endif
|
Chris@87
|
212 """,
|
Chris@87
|
213 'decl':"""
|
Chris@87
|
214 #ifdef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
215 \t#ctype# return_value;
|
Chris@87
|
216 #endif
|
Chris@87
|
217 """,
|
Chris@87
|
218 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting return_value->");'},
|
Chris@87
|
219 """\
|
Chris@87
|
220 \tif (capi_j>capi_i)
|
Chris@87
|
221 #ifdef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
222 \t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
|
Chris@87
|
223 #else
|
Chris@87
|
224 \t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
|
Chris@87
|
225 #endif
|
Chris@87
|
226 """,
|
Chris@87
|
227 {debugcapi:"""
|
Chris@87
|
228 #ifdef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
229 \tfprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i);
|
Chris@87
|
230 #else
|
Chris@87
|
231 \tfprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i);
|
Chris@87
|
232 #endif
|
Chris@87
|
233
|
Chris@87
|
234 """}
|
Chris@87
|
235 ],
|
Chris@87
|
236 'return':"""
|
Chris@87
|
237 #ifdef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
238 \treturn return_value;
|
Chris@87
|
239 #else
|
Chris@87
|
240 \treturn;
|
Chris@87
|
241 #endif
|
Chris@87
|
242 """,
|
Chris@87
|
243 'need':['#ctype#_from_pyobj', {debugcapi:'CFUNCSMESS'},
|
Chris@87
|
244 'string.h', 'GETSCALARFROMPYTUPLE', '#ctype#'],
|
Chris@87
|
245 '_check':iscomplexfunction
|
Chris@87
|
246 },
|
Chris@87
|
247 {'docstrout':'\t\t#pydocsignout#',
|
Chris@87
|
248 'latexdocstrout':['\\item[]{{}\\verb@#pydocsignout#@{}}',
|
Chris@87
|
249 {hasnote:'--- #note#'}],
|
Chris@87
|
250 'docreturn':'#rname#,',
|
Chris@87
|
251 '_check':isfunction},
|
Chris@87
|
252 {'_check':issubroutine,'return':'return;'}
|
Chris@87
|
253 ]
|
Chris@87
|
254
|
Chris@87
|
255 cb_arg_rules=[
|
Chris@87
|
256 { # Doc
|
Chris@87
|
257 'docstropt':{l_and(isoptional, isintent_nothide):'\t\t#pydocsign#'},
|
Chris@87
|
258 'docstrreq':{l_and(isrequired, isintent_nothide):'\t\t#pydocsign#'},
|
Chris@87
|
259 'docstrout':{isintent_out:'\t\t#pydocsignout#'},
|
Chris@87
|
260 'latexdocstropt':{l_and(isoptional, isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}',
|
Chris@87
|
261 {hasnote:'--- #note#'}]},
|
Chris@87
|
262 'latexdocstrreq':{l_and(isrequired, isintent_nothide):['\\item[]{{}\\verb@#pydocsign#@{}}',
|
Chris@87
|
263 {hasnote:'--- #note#'}]},
|
Chris@87
|
264 'latexdocstrout':{isintent_out:['\\item[]{{}\\verb@#pydocsignout#@{}}',
|
Chris@87
|
265 {l_and(hasnote, isintent_hide):'--- #note#',
|
Chris@87
|
266 l_and(hasnote, isintent_nothide):'--- See above.'}]},
|
Chris@87
|
267 'docsign':{l_and(isrequired, isintent_nothide):'#varname#,'},
|
Chris@87
|
268 'docsignopt':{l_and(isoptional, isintent_nothide):'#varname#,'},
|
Chris@87
|
269 'depend':''
|
Chris@87
|
270 },
|
Chris@87
|
271 {
|
Chris@87
|
272 'args': {
|
Chris@87
|
273 l_and (isscalar, isintent_c):'#ctype# #varname_i#',
|
Chris@87
|
274 l_and (isscalar, l_not(isintent_c)):'#ctype# *#varname_i#_cb_capi',
|
Chris@87
|
275 isarray:'#ctype# *#varname_i#',
|
Chris@87
|
276 isstring:'#ctype# #varname_i#'
|
Chris@87
|
277 },
|
Chris@87
|
278 'args_nm': {
|
Chris@87
|
279 l_and (isscalar, isintent_c):'#varname_i#',
|
Chris@87
|
280 l_and (isscalar, l_not(isintent_c)):'#varname_i#_cb_capi',
|
Chris@87
|
281 isarray:'#varname_i#',
|
Chris@87
|
282 isstring:'#varname_i#'
|
Chris@87
|
283 },
|
Chris@87
|
284 'args_td': {
|
Chris@87
|
285 l_and (isscalar, isintent_c):'#ctype#',
|
Chris@87
|
286 l_and (isscalar, l_not(isintent_c)):'#ctype# *',
|
Chris@87
|
287 isarray:'#ctype# *',
|
Chris@87
|
288 isstring:'#ctype#'
|
Chris@87
|
289 },
|
Chris@87
|
290 'strarglens': {isstring:',int #varname_i#_cb_len'}, # untested with multiple args
|
Chris@87
|
291 'strarglens_td': {isstring:',int'}, # untested with multiple args
|
Chris@87
|
292 'strarglens_nm': {isstring:',#varname_i#_cb_len'}, # untested with multiple args
|
Chris@87
|
293 },
|
Chris@87
|
294 { # Scalars
|
Chris@87
|
295 'decl':{l_not(isintent_c):'\t#ctype# #varname_i#=(*#varname_i#_cb_capi);'},
|
Chris@87
|
296 'error': {l_and(isintent_c, isintent_out,
|
Chris@87
|
297 throw_error('intent(c,out) is forbidden for callback scalar arguments')):\
|
Chris@87
|
298 ''},
|
Chris@87
|
299 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting #varname#->");'},
|
Chris@87
|
300 {isintent_out:'\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname_i#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'},
|
Chris@87
|
301 {l_and(debugcapi, l_and(l_not(iscomplex), isintent_c)):'\tfprintf(stderr,"#showvalueformat#.\\n",#varname_i#);'},
|
Chris@87
|
302 {l_and(debugcapi, l_and(l_not(iscomplex), l_not(isintent_c))):'\tfprintf(stderr,"#showvalueformat#.\\n",*#varname_i#_cb_capi);'},
|
Chris@87
|
303 {l_and(debugcapi, l_and(iscomplex, isintent_c)):'\tfprintf(stderr,"#showvalueformat#.\\n",(#varname_i#).r,(#varname_i#).i);'},
|
Chris@87
|
304 {l_and(debugcapi, l_and(iscomplex, l_not(isintent_c))):'\tfprintf(stderr,"#showvalueformat#.\\n",(*#varname_i#_cb_capi).r,(*#varname_i#_cb_capi).i);'},
|
Chris@87
|
305 ],
|
Chris@87
|
306 'need':[{isintent_out:['#ctype#_from_pyobj', 'GETSCALARFROMPYTUPLE']},
|
Chris@87
|
307 {debugcapi:'CFUNCSMESS'}],
|
Chris@87
|
308 '_check':isscalar
|
Chris@87
|
309 }, {
|
Chris@87
|
310 'pyobjfrom':[{isintent_in:"""\
|
Chris@87
|
311 \tif (#name#_nofargs>capi_i)
|
Chris@87
|
312 \t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1(#varname_i#)))
|
Chris@87
|
313 \t\t\tgoto capi_fail;"""},
|
Chris@87
|
314 {isintent_inout:"""\
|
Chris@87
|
315 \tif (#name#_nofargs>capi_i)
|
Chris@87
|
316 \t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
|
Chris@87
|
317 \t\t\tgoto capi_fail;"""}],
|
Chris@87
|
318 'need':[{isintent_in:'pyobj_from_#ctype#1'},
|
Chris@87
|
319 {isintent_inout:'pyarr_from_p_#ctype#1'},
|
Chris@87
|
320 {iscomplex:'#ctype#'}],
|
Chris@87
|
321 '_check':l_and(isscalar, isintent_nothide),
|
Chris@87
|
322 '_optional':''
|
Chris@87
|
323 }, {# String
|
Chris@87
|
324 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting #varname#->\\"");'},
|
Chris@87
|
325 """\tif (capi_j>capi_i)
|
Chris@87
|
326 \t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,#varname_i#,#varname_i#_cb_len);""",
|
Chris@87
|
327 {debugcapi:'\tfprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname_i#,#varname_i#_cb_len);'},
|
Chris@87
|
328 ],
|
Chris@87
|
329 'need':['#ctype#', 'GETSTRFROMPYTUPLE',
|
Chris@87
|
330 {debugcapi:'CFUNCSMESS'}, 'string.h'],
|
Chris@87
|
331 '_check':l_and(isstring, isintent_out)
|
Chris@87
|
332 }, {
|
Chris@87
|
333 'pyobjfrom':[{debugcapi:'\tfprintf(stderr,"debug-capi:cb:#varname#=\\"#showvalueformat#\\":%d:\\n",#varname_i#,#varname_i#_cb_len);'},
|
Chris@87
|
334 {isintent_in:"""\
|
Chris@87
|
335 \tif (#name#_nofargs>capi_i)
|
Chris@87
|
336 \t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
|
Chris@87
|
337 \t\t\tgoto capi_fail;"""},
|
Chris@87
|
338 {isintent_inout:"""\
|
Chris@87
|
339 \tif (#name#_nofargs>capi_i) {
|
Chris@87
|
340 \t\tint #varname_i#_cb_dims[] = {#varname_i#_cb_len};
|
Chris@87
|
341 \t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
|
Chris@87
|
342 \t\t\tgoto capi_fail;
|
Chris@87
|
343 \t}"""}],
|
Chris@87
|
344 'need':[{isintent_in:'pyobj_from_#ctype#1size'},
|
Chris@87
|
345 {isintent_inout:'pyarr_from_p_#ctype#1'}],
|
Chris@87
|
346 '_check':l_and(isstring, isintent_nothide),
|
Chris@87
|
347 '_optional':''
|
Chris@87
|
348 },
|
Chris@87
|
349 # Array ...
|
Chris@87
|
350 {
|
Chris@87
|
351 'decl':'\tnpy_intp #varname_i#_Dims[#rank#] = {#rank*[-1]#};',
|
Chris@87
|
352 'setdims':'\t#cbsetdims#;',
|
Chris@87
|
353 '_check':isarray,
|
Chris@87
|
354 '_depend':''
|
Chris@87
|
355 },
|
Chris@87
|
356 {
|
Chris@87
|
357 'pyobjfrom': [{debugcapi:'\tfprintf(stderr,"debug-capi:cb:#varname#\\n");'},
|
Chris@87
|
358 {isintent_c: """\
|
Chris@87
|
359 \tif (#name#_nofargs>capi_i) {
|
Chris@87
|
360 \t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_CARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */
|
Chris@87
|
361 """,
|
Chris@87
|
362 l_not(isintent_c): """\
|
Chris@87
|
363 \tif (#name#_nofargs>capi_i) {
|
Chris@87
|
364 \t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_FARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */
|
Chris@87
|
365 """,
|
Chris@87
|
366 },
|
Chris@87
|
367 """
|
Chris@87
|
368 \t\tif (tmp_arr==NULL)
|
Chris@87
|
369 \t\t\tgoto capi_fail;
|
Chris@87
|
370 \t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,(PyObject *)tmp_arr))
|
Chris@87
|
371 \t\t\tgoto capi_fail;
|
Chris@87
|
372 }"""],
|
Chris@87
|
373 '_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)),
|
Chris@87
|
374 '_optional': '',
|
Chris@87
|
375 }, {
|
Chris@87
|
376 'frompyobj':[{debugcapi:'\tCFUNCSMESS("cb:Getting #varname#->");'},
|
Chris@87
|
377 """\tif (capi_j>capi_i) {
|
Chris@87
|
378 \t\tPyArrayObject *rv_cb_arr = NULL;
|
Chris@87
|
379 \t\tif ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail;
|
Chris@87
|
380 \t\trv_cb_arr = array_from_pyobj(#atype#,#varname_i#_Dims,#rank#,F2PY_INTENT_IN""",
|
Chris@87
|
381 {isintent_c:'|F2PY_INTENT_C'},
|
Chris@87
|
382 """,capi_tmp);
|
Chris@87
|
383 \t\tif (rv_cb_arr == NULL) {
|
Chris@87
|
384 \t\t\tfprintf(stderr,\"rv_cb_arr is NULL\\n\");
|
Chris@87
|
385 \t\t\tgoto capi_fail;
|
Chris@87
|
386 \t\t}
|
Chris@87
|
387 \t\tMEMCOPY(#varname_i#,rv_cb_arr->data,PyArray_NBYTES(rv_cb_arr));
|
Chris@87
|
388 \t\tif (capi_tmp != (PyObject *)rv_cb_arr) {
|
Chris@87
|
389 \t\t\tPy_DECREF(rv_cb_arr);
|
Chris@87
|
390 \t\t}
|
Chris@87
|
391 \t}""",
|
Chris@87
|
392 {debugcapi:'\tfprintf(stderr,"<-.\\n");'},
|
Chris@87
|
393 ],
|
Chris@87
|
394 'need':['MEMCOPY', {iscomplexarray:'#ctype#'}],
|
Chris@87
|
395 '_check':l_and(isarray, isintent_out)
|
Chris@87
|
396 }, {
|
Chris@87
|
397 'docreturn':'#varname#,',
|
Chris@87
|
398 '_check':isintent_out
|
Chris@87
|
399 }
|
Chris@87
|
400 ]
|
Chris@87
|
401
|
Chris@87
|
402 ################## Build call-back module #############
|
Chris@87
|
403 cb_map={}
|
Chris@87
|
404 def buildcallbacks(m):
|
Chris@87
|
405 global cb_map
|
Chris@87
|
406 cb_map[m['name']]=[]
|
Chris@87
|
407 for bi in m['body']:
|
Chris@87
|
408 if bi['block']=='interface':
|
Chris@87
|
409 for b in bi['body']:
|
Chris@87
|
410 if b:
|
Chris@87
|
411 buildcallback(b, m['name'])
|
Chris@87
|
412 else:
|
Chris@87
|
413 errmess('warning: empty body for %s\n' % (m['name']))
|
Chris@87
|
414
|
Chris@87
|
415 def buildcallback(rout, um):
|
Chris@87
|
416 global cb_map
|
Chris@87
|
417 from . import capi_maps
|
Chris@87
|
418
|
Chris@87
|
419 outmess('\tConstructing call-back function "cb_%s_in_%s"\n'%(rout['name'], um))
|
Chris@87
|
420 args, depargs=getargs(rout)
|
Chris@87
|
421 capi_maps.depargs=depargs
|
Chris@87
|
422 var=rout['vars']
|
Chris@87
|
423 vrd=capi_maps.cb_routsign2map(rout, um)
|
Chris@87
|
424 rd=dictappend({}, vrd)
|
Chris@87
|
425 cb_map[um].append([rout['name'], rd['name']])
|
Chris@87
|
426 for r in cb_rout_rules:
|
Chris@87
|
427 if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
|
Chris@87
|
428 ar=applyrules(r, vrd, rout)
|
Chris@87
|
429 rd=dictappend(rd, ar)
|
Chris@87
|
430 savevrd={}
|
Chris@87
|
431 for i, a in enumerate(args):
|
Chris@87
|
432 vrd=capi_maps.cb_sign2map(a, var[a], index=i)
|
Chris@87
|
433 savevrd[a]=vrd
|
Chris@87
|
434 for r in cb_arg_rules:
|
Chris@87
|
435 if '_depend' in r:
|
Chris@87
|
436 continue
|
Chris@87
|
437 if '_optional' in r and isoptional(var[a]):
|
Chris@87
|
438 continue
|
Chris@87
|
439 if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
|
Chris@87
|
440 ar=applyrules(r, vrd, var[a])
|
Chris@87
|
441 rd=dictappend(rd, ar)
|
Chris@87
|
442 if '_break' in r:
|
Chris@87
|
443 break
|
Chris@87
|
444 for a in args:
|
Chris@87
|
445 vrd=savevrd[a]
|
Chris@87
|
446 for r in cb_arg_rules:
|
Chris@87
|
447 if '_depend' in r:
|
Chris@87
|
448 continue
|
Chris@87
|
449 if ('_optional' not in r) or ('_optional' in r and isrequired(var[a])):
|
Chris@87
|
450 continue
|
Chris@87
|
451 if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
|
Chris@87
|
452 ar=applyrules(r, vrd, var[a])
|
Chris@87
|
453 rd=dictappend(rd, ar)
|
Chris@87
|
454 if '_break' in r:
|
Chris@87
|
455 break
|
Chris@87
|
456 for a in depargs:
|
Chris@87
|
457 vrd=savevrd[a]
|
Chris@87
|
458 for r in cb_arg_rules:
|
Chris@87
|
459 if '_depend' not in r:
|
Chris@87
|
460 continue
|
Chris@87
|
461 if '_optional' in r:
|
Chris@87
|
462 continue
|
Chris@87
|
463 if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
|
Chris@87
|
464 ar=applyrules(r, vrd, var[a])
|
Chris@87
|
465 rd=dictappend(rd, ar)
|
Chris@87
|
466 if '_break' in r:
|
Chris@87
|
467 break
|
Chris@87
|
468 if 'args' in rd and 'optargs' in rd:
|
Chris@87
|
469 if isinstance(rd['optargs'], list):
|
Chris@87
|
470 rd['optargs']=rd['optargs']+["""
|
Chris@87
|
471 #ifndef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
472 ,
|
Chris@87
|
473 #endif
|
Chris@87
|
474 """]
|
Chris@87
|
475 rd['optargs_nm']=rd['optargs_nm']+["""
|
Chris@87
|
476 #ifndef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
477 ,
|
Chris@87
|
478 #endif
|
Chris@87
|
479 """]
|
Chris@87
|
480 rd['optargs_td']=rd['optargs_td']+["""
|
Chris@87
|
481 #ifndef F2PY_CB_RETURNCOMPLEX
|
Chris@87
|
482 ,
|
Chris@87
|
483 #endif
|
Chris@87
|
484 """]
|
Chris@87
|
485 if isinstance(rd['docreturn'], list):
|
Chris@87
|
486 rd['docreturn']=stripcomma(replace('#docreturn#', {'docreturn':rd['docreturn']}))
|
Chris@87
|
487 optargs=stripcomma(replace('#docsignopt#',
|
Chris@87
|
488 {'docsignopt':rd['docsignopt']}
|
Chris@87
|
489 ))
|
Chris@87
|
490 if optargs=='':
|
Chris@87
|
491 rd['docsignature']=stripcomma(replace('#docsign#', {'docsign':rd['docsign']}))
|
Chris@87
|
492 else:
|
Chris@87
|
493 rd['docsignature']=replace('#docsign#[#docsignopt#]',
|
Chris@87
|
494 {'docsign': rd['docsign'],
|
Chris@87
|
495 'docsignopt': optargs,
|
Chris@87
|
496 })
|
Chris@87
|
497 rd['latexdocsignature']=rd['docsignature'].replace('_', '\\_')
|
Chris@87
|
498 rd['latexdocsignature']=rd['latexdocsignature'].replace(',', ', ')
|
Chris@87
|
499 rd['docstrsigns']=[]
|
Chris@87
|
500 rd['latexdocstrsigns']=[]
|
Chris@87
|
501 for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
|
Chris@87
|
502 if k in rd and isinstance(rd[k], list):
|
Chris@87
|
503 rd['docstrsigns']=rd['docstrsigns']+rd[k]
|
Chris@87
|
504 k='latex'+k
|
Chris@87
|
505 if k in rd and isinstance(rd[k], list):
|
Chris@87
|
506 rd['latexdocstrsigns']=rd['latexdocstrsigns']+rd[k][0:1]+\
|
Chris@87
|
507 ['\\begin{description}']+rd[k][1:]+\
|
Chris@87
|
508 ['\\end{description}']
|
Chris@87
|
509 if 'args' not in rd:
|
Chris@87
|
510 rd['args']=''
|
Chris@87
|
511 rd['args_td']=''
|
Chris@87
|
512 rd['args_nm']=''
|
Chris@87
|
513 if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')):
|
Chris@87
|
514 rd['noargs'] = 'void'
|
Chris@87
|
515
|
Chris@87
|
516 ar=applyrules(cb_routine_rules, rd)
|
Chris@87
|
517 cfuncs.callbacks[rd['name']]=ar['body']
|
Chris@87
|
518 if isinstance(ar['need'], str):
|
Chris@87
|
519 ar['need']=[ar['need']]
|
Chris@87
|
520
|
Chris@87
|
521 if 'need' in rd:
|
Chris@87
|
522 for t in cfuncs.typedefs.keys():
|
Chris@87
|
523 if t in rd['need']:
|
Chris@87
|
524 ar['need'].append(t)
|
Chris@87
|
525
|
Chris@87
|
526 cfuncs.typedefs_generated[rd['name']+'_typedef'] = ar['cbtypedefs']
|
Chris@87
|
527 ar['need'].append(rd['name']+'_typedef')
|
Chris@87
|
528 cfuncs.needs[rd['name']]=ar['need']
|
Chris@87
|
529
|
Chris@87
|
530 capi_maps.lcb2_map[rd['name']]={'maxnofargs':ar['maxnofargs'],
|
Chris@87
|
531 'nofoptargs':ar['nofoptargs'],
|
Chris@87
|
532 'docstr':ar['docstr'],
|
Chris@87
|
533 'latexdocstr':ar['latexdocstr'],
|
Chris@87
|
534 'argname':rd['argname']
|
Chris@87
|
535 }
|
Chris@87
|
536 outmess('\t %s\n'%(ar['docstrshort']))
|
Chris@87
|
537 #print ar['body']
|
Chris@87
|
538 return
|
Chris@87
|
539 ################## Build call-back function #############
|