codekingpro/portable-devtools
115k
1"""
2C declarations, CPP macros, and C functions for f2py2e.
3Only required declarations/macros/functions will be used.
4
5Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
6Copyright 2011 -- present NumPy Developers.
7Permission to use, modify, and distribute this software is given under the
8terms of the NumPy License.
9
10NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
11"""
12import copy
13import sys
14
15from . import __version__
16
17f2py_version = __version__.version
18
19
20def errmess(s: str) -> None:
21 """
22 Write an error message to stderr.
23
24 This indirection is needed because sys.stderr might not always be available (see #26862).
25 """
26 if sys.stderr is not None:
27 sys.stderr.write(s)
28
29##################### Definitions ##################
30
31
32outneeds = {'includes0': [], 'includes': [], 'typedefs': [], 'typedefs_generated': [],
33 'userincludes': [],
34 'cppmacros': [], 'cfuncs': [], 'callbacks': [], 'f90modhooks': [],
35 'commonhooks': []}
36needs = {}
37includes0 = {'includes0': '/*need_includes0*/'}
38includes = {'includes': '/*need_includes*/'}
39userincludes = {'userincludes': '/*need_userincludes*/'}
40typedefs = {'typedefs': '/*need_typedefs*/'}
41typedefs_generated = {'typedefs_generated': '/*need_typedefs_generated*/'}
42cppmacros = {'cppmacros': '/*need_cppmacros*/'}
43cfuncs = {'cfuncs': '/*need_cfuncs*/'}
44callbacks = {'callbacks': '/*need_callbacks*/'}
45f90modhooks = {'f90modhooks': '/*need_f90modhooks*/',
46 'initf90modhooksstatic': '/*initf90modhooksstatic*/',
47 'initf90modhooksdynamic': '/*initf90modhooksdynamic*/',
48 }
49commonhooks = {'commonhooks': '/*need_commonhooks*/',
50 'initcommonhooks': '/*need_initcommonhooks*/',
51 }
52
53############ Includes ###################
54
55includes0['math.h'] = '#include <math.h>'
56includes0['string.h'] = '#include <string.h>'
57includes0['setjmp.h'] = '#include <setjmp.h>'
58
59includes['arrayobject.h'] = '''#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
60#include "arrayobject.h"'''
61includes['npy_math.h'] = '#include "numpy/npy_math.h"'
62
63includes['arrayobject.h'] = '#include "fortranobject.h"'
64includes['stdarg.h'] = '#include <stdarg.h>'
65
66############# Type definitions ###############
67
68typedefs['unsigned_char'] = 'typedef unsigned char unsigned_char;'
69typedefs['unsigned_short'] = 'typedef unsigned short unsigned_short;'
70typedefs['unsigned_long'] = 'typedef unsigned long unsigned_long;'
71typedefs['signed_char'] = 'typedef signed char signed_char;'
72typedefs['long_long'] = """
73#if defined(NPY_OS_WIN32)
74typedef __int64 long_long;
75#else
76typedef long long long_long;
77typedef unsigned long long unsigned_long_long;
78#endif
79"""
80typedefs['unsigned_long_long'] = """
81#if defined(NPY_OS_WIN32)
82typedef __uint64 long_long;
83#else
84typedef unsigned long long unsigned_long_long;
85#endif
86"""
87typedefs['long_double'] = """
88#ifndef _LONG_DOUBLE
89typedef long double long_double;
90#endif
91"""
92typedefs[
93 'complex_long_double'] = 'typedef struct {long double r,i;} complex_long_double;'
94typedefs['complex_float'] = 'typedef struct {float r,i;} complex_float;'
95typedefs['complex_double'] = 'typedef struct {double r,i;} complex_double;'
96typedefs['string'] = """typedef char * string;"""
97typedefs['character'] = """typedef char character;"""
98
99
100############### CPP macros ####################
101cppmacros['CFUNCSMESS'] = """
102#ifdef DEBUGCFUNCS
103#define CFUNCSMESS(mess) fprintf(stderr,\"debug-capi:\"mess);
104#define CFUNCSMESSPY(mess,obj) CFUNCSMESS(mess) \\
105 PyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
106 fprintf(stderr,\"\\n\");
107#else
108#define CFUNCSMESS(mess)
109#define CFUNCSMESSPY(mess,obj)
110#endif
111"""
112cppmacros['F_FUNC'] = """
113#if defined(PREPEND_FORTRAN)
114#if defined(NO_APPEND_FORTRAN)
115#if defined(UPPERCASE_FORTRAN)
116#define F_FUNC(f,F) _##F
117#else
118#define F_FUNC(f,F) _##f
119#endif
120#else
121#if defined(UPPERCASE_FORTRAN)
122#define F_FUNC(f,F) _##F##_
123#else
124#define F_FUNC(f,F) _##f##_
125#endif
126#endif
127#else
128#if defined(NO_APPEND_FORTRAN)
129#if defined(UPPERCASE_FORTRAN)
130#define F_FUNC(f,F) F
131#else
132#define F_FUNC(f,F) f
133#endif
134#else
135#if defined(UPPERCASE_FORTRAN)
136#define F_FUNC(f,F) F##_
137#else
138#define F_FUNC(f,F) f##_
139#endif
140#endif
141#endif
142#if defined(UNDERSCORE_G77)
143#define F_FUNC_US(f,F) F_FUNC(f##_,F##_)
144#else
145#define F_FUNC_US(f,F) F_FUNC(f,F)
146#endif
147"""
148cppmacros['F_WRAPPEDFUNC'] = """
149#if defined(PREPEND_FORTRAN)
150#if defined(NO_APPEND_FORTRAN)
151#if defined(UPPERCASE_FORTRAN)
152#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F
153#else
154#define F_WRAPPEDFUNC(f,F) _f2pywrap##f
155#endif
156#else
157#if defined(UPPERCASE_FORTRAN)
158#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F##_
159#else
160#define F_WRAPPEDFUNC(f,F) _f2pywrap##f##_
161#endif
162#endif
163#else
164#if defined(NO_APPEND_FORTRAN)
165#if defined(UPPERCASE_FORTRAN)
166#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F
167#else
168#define F_WRAPPEDFUNC(f,F) f2pywrap##f
169#endif
170#else
171#if defined(UPPERCASE_FORTRAN)
172#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F##_
173#else
174#define F_WRAPPEDFUNC(f,F) f2pywrap##f##_
175#endif
176#endif
177#endif
178#if defined(UNDERSCORE_G77)
179#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f##_,F##_)
180#else
181#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f,F)
182#endif
183"""
184cppmacros['F_MODFUNC'] = """
185#if defined(F90MOD2CCONV1) /*E.g. Compaq Fortran */
186#if defined(NO_APPEND_FORTRAN)
187#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f
188#else
189#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f ## _
190#endif
191#endif
192
193#if defined(F90MOD2CCONV2) /*E.g. IBM XL Fortran, not tested though */
194#if defined(NO_APPEND_FORTRAN)
195#define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f
196#else
197#define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f ## _
198#endif
199#endif
200
201#if defined(F90MOD2CCONV3) /*E.g. MIPSPro Compilers */
202#if defined(NO_APPEND_FORTRAN)
203#define F_MODFUNCNAME(m,f) f ## .in. ## m
204#else
205#define F_MODFUNCNAME(m,f) f ## .in. ## m ## _
206#endif
207#endif
208/*
209#if defined(UPPERCASE_FORTRAN)
210#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(M,F)
211#else
212#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(m,f)
213#endif
214*/
215
216#define F_MODFUNC(m,f) (*(f2pymodstruct##m##.##f))
217"""
218cppmacros['SWAPUNSAFE'] = """
219#define SWAP(a,b) (size_t)(a) = ((size_t)(a) ^ (size_t)(b));\\
220 (size_t)(b) = ((size_t)(a) ^ (size_t)(b));\\
221 (size_t)(a) = ((size_t)(a) ^ (size_t)(b))
222"""
223cppmacros['SWAP'] = """
224#define SWAP(a,b,t) {\\
225 t *c;\\
226 c = a;\\
227 a = b;\\
228 b = c;}
229"""
230# cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) &
231# NPY_ARRAY_C_CONTIGUOUS)'
232cppmacros['PRINTPYOBJERR'] = """
233#define PRINTPYOBJERR(obj)\\
234 fprintf(stderr,\"#modulename#.error is related to \");\\
235 PyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
236 fprintf(stderr,\"\\n\");
237"""
238cppmacros['MINMAX'] = """
239#ifndef max
240#define max(a,b) ((a > b) ? (a) : (b))
241#endif
242#ifndef min
243#define min(a,b) ((a < b) ? (a) : (b))
244#endif
245#ifndef MAX
246#define MAX(a,b) ((a > b) ? (a) : (b))
247#endif
248#ifndef MIN
249#define MIN(a,b) ((a < b) ? (a) : (b))
250#endif
251"""
252cppmacros['len..'] = """
253/* See fortranobject.h for definitions. The macros here are provided for BC. */
254#define rank f2py_rank
255#define shape f2py_shape
256#define fshape f2py_shape
257#define len f2py_len
258#define flen f2py_flen
259#define slen f2py_slen
260#define size f2py_size
261"""
262cppmacros['pyobj_from_char1'] = r"""
263#define pyobj_from_char1(v) (PyLong_FromLong(v))
264"""
265cppmacros['pyobj_from_short1'] = r"""
266#define pyobj_from_short1(v) (PyLong_FromLong(v))
267"""
268needs['pyobj_from_int1'] = ['signed_char']
269cppmacros['pyobj_from_int1'] = r"""
270#define pyobj_from_int1(v) (PyLong_FromLong(v))
271"""
272cppmacros['pyobj_from_long1'] = r"""
273#define pyobj_from_long1(v) (PyLong_FromLong(v))
274"""
275needs['pyobj_from_long_long1'] = ['long_long']
276cppmacros['pyobj_from_long_long1'] = """
277#ifdef HAVE_LONG_LONG
278#define pyobj_from_long_long1(v) (PyLong_FromLongLong(v))
279#else
280#warning HAVE_LONG_LONG is not available. Redefining pyobj_from_long_long.
281#define pyobj_from_long_long1(v) (PyLong_FromLong(v))
282#endif
283"""
284needs['pyobj_from_long_double1'] = ['long_double']
285cppmacros['pyobj_from_long_double1'] = """
286#define pyobj_from_long_double1(v) (PyFloat_FromDouble(v))"""
287cppmacros['pyobj_from_double1'] = """
288#define pyobj_from_double1(v) (PyFloat_FromDouble(v))"""
289cppmacros['pyobj_from_float1'] = """
290#define pyobj_from_float1(v) (PyFloat_FromDouble(v))"""
291needs['pyobj_from_complex_long_double1'] = ['complex_long_double']
292cppmacros['pyobj_from_complex_long_double1'] = """
293#define pyobj_from_complex_long_double1(v) (PyComplex_FromDoubles(v.r,v.i))"""
294needs['pyobj_from_complex_double1'] = ['complex_double']
295cppmacros['pyobj_from_complex_double1'] = """
296#define pyobj_from_complex_double1(v) (PyComplex_FromDoubles(v.r,v.i))"""
297needs['pyobj_from_complex_float1'] = ['complex_float']
298cppmacros['pyobj_from_complex_float1'] = """
299#define pyobj_from_complex_float1(v) (PyComplex_FromDoubles(v.r,v.i))"""
300needs['pyobj_from_string1'] = ['string']
301cppmacros['pyobj_from_string1'] = """
302#define pyobj_from_string1(v) (PyUnicode_FromString((char *)v))"""
303needs['pyobj_from_string1size'] = ['string']
304cppmacros['pyobj_from_string1size'] = """
305#define pyobj_from_string1size(v,len) (PyUnicode_FromStringAndSize((char *)v, len))"""
306needs['TRYPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
307cppmacros['TRYPYARRAYTEMPLATE'] = """
308/* New SciPy */
309#define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(PyArray_DATA(arr))=*v; break;
310#define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;
311#define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: PyArray_SETITEM(arr,PyArray_DATA(arr),pyobj_from_ ## ctype ## 1(*v)); break;
312
313#define TRYPYARRAYTEMPLATE(ctype,typecode) \\
314 PyArrayObject *arr = NULL;\\
315 if (!obj) return -2;\\
316 if (!PyArray_Check(obj)) return -1;\\
317 if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
318 if (PyArray_DESCR(arr)->type==typecode) {*(ctype *)(PyArray_DATA(arr))=*v; return 1;}\\
319 switch (PyArray_TYPE(arr)) {\\
320 case NPY_DOUBLE: *(npy_double *)(PyArray_DATA(arr))=*v; break;\\
321 case NPY_INT: *(npy_int *)(PyArray_DATA(arr))=*v; break;\\
322 case NPY_LONG: *(npy_long *)(PyArray_DATA(arr))=*v; break;\\
323 case NPY_FLOAT: *(npy_float *)(PyArray_DATA(arr))=*v; break;\\
324 case NPY_CDOUBLE: *(npy_double *)(PyArray_DATA(arr))=*v; break;\\
325 case NPY_CFLOAT: *(npy_float *)(PyArray_DATA(arr))=*v; break;\\
326 case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=(*v!=0); break;\\
327 case NPY_UBYTE: *(npy_ubyte *)(PyArray_DATA(arr))=*v; break;\\
328 case NPY_BYTE: *(npy_byte *)(PyArray_DATA(arr))=*v; break;\\
329 case NPY_SHORT: *(npy_short *)(PyArray_DATA(arr))=*v; break;\\
330 case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=*v; break;\\
331 case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=*v; break;\\
332 case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=*v; break;\\
333 case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=*v; break;\\
334 case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=*v; break;\\
335 case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
336 case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
337 case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_ ## ctype ## 1(*v)); break;\\
338 default: return -2;\\
339 };\\
340 return 1
341"""
342
343needs['TRYCOMPLEXPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
344cppmacros['TRYCOMPLEXPYARRAYTEMPLATE'] = """
345#define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_complex_ ## ctype ## 1((*v))); break;
346#define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\
347 PyArrayObject *arr = NULL;\\
348 if (!obj) return -2;\\
349 if (!PyArray_Check(obj)) return -1;\\
350 if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
351 if (PyArray_DESCR(arr)->type==typecode) {\\
352 *(ctype *)(PyArray_DATA(arr))=(*v).r;\\
353 *(ctype *)(PyArray_DATA(arr)+sizeof(ctype))=(*v).i;\\
354 return 1;\\
355 }\\
356 switch (PyArray_TYPE(arr)) {\\
357 case NPY_CDOUBLE: *(npy_double *)(PyArray_DATA(arr))=(*v).r;\\
358 *(npy_double *)(PyArray_DATA(arr)+sizeof(npy_double))=(*v).i;\\
359 break;\\
360 case NPY_CFLOAT: *(npy_float *)(PyArray_DATA(arr))=(*v).r;\\
361 *(npy_float *)(PyArray_DATA(arr)+sizeof(npy_float))=(*v).i;\\
362 break;\\
363 case NPY_DOUBLE: *(npy_double *)(PyArray_DATA(arr))=(*v).r; break;\\
364 case NPY_LONG: *(npy_long *)(PyArray_DATA(arr))=(*v).r; break;\\
365 case NPY_FLOAT: *(npy_float *)(PyArray_DATA(arr))=(*v).r; break;\\
366 case NPY_INT: *(npy_int *)(PyArray_DATA(arr))=(*v).r; break;\\
367 case NPY_SHORT: *(npy_short *)(PyArray_DATA(arr))=(*v).r; break;\\
368 case NPY_UBYTE: *(npy_ubyte *)(PyArray_DATA(arr))=(*v).r; break;\\
369 case NPY_BYTE: *(npy_byte *)(PyArray_DATA(arr))=(*v).r; break;\\
370 case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=((*v).r!=0 && (*v).i!=0); break;\\
371 case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=(*v).r; break;\\
372 case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=(*v).r; break;\\
373 case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=(*v).r; break;\\
374 case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=(*v).r; break;\\
375 case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=(*v).r; break;\\
376 case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r; break;\\
377 case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r;\\
378 *(npy_longdouble *)(PyArray_DATA(arr)+sizeof(npy_longdouble))=(*v).i;\\
379 break;\\
380 case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_complex_ ## ctype ## 1((*v))); break;\\
381 default: return -2;\\
382 };\\
383 return -1;
384"""
385# cppmacros['NUMFROMARROBJ']="""
386# define NUMFROMARROBJ(typenum,ctype) \\
387# if (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
388# else arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
389# if (arr) {\\
390# if (PyArray_TYPE(arr)==NPY_OBJECT) {\\
391# if (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
392# goto capi_fail;\\
393# } else {\\
394# (PyArray_DESCR(arr)->cast[typenum])(PyArray_DATA(arr),1,(char*)v,1,1);\\
395# }\\
396# if ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
397# return 1;\\
398# }
399# """
400# XXX: Note that CNUMFROMARROBJ is identical with NUMFROMARROBJ
401# cppmacros['CNUMFROMARROBJ']="""
402# define CNUMFROMARROBJ(typenum,ctype) \\
403# if (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
404# else arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
405# if (arr) {\\
406# if (PyArray_TYPE(arr)==NPY_OBJECT) {\\
407# if (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
408# goto capi_fail;\\
409# } else {\\
410# (PyArray_DESCR(arr)->cast[typenum])((void *)(PyArray_DATA(arr)),1,(void *)(v),1,1);\\
411# }\\
412# if ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
413# return 1;\\
414# }
415# """
416
417
418needs['GETSTRFROMPYTUPLE'] = ['STRINGCOPYN', 'PRINTPYOBJERR']
419cppmacros['GETSTRFROMPYTUPLE'] = """
420#define GETSTRFROMPYTUPLE(tuple,index,str,len) {\\
421 PyObject *rv_cb_str = PyTuple_GetItem((tuple),(index));\\
422 if (rv_cb_str == NULL)\\
423 goto capi_fail;\\
424 if (PyBytes_Check(rv_cb_str)) {\\
425 str[len-1]='\\0';\\
426 STRINGCOPYN((str),PyBytes_AS_STRING((PyBytesObject*)rv_cb_str),(len));\\
427 } else {\\
428 PRINTPYOBJERR(rv_cb_str);\\
429 PyErr_SetString(#modulename#_error,\"string object expected\");\\
430 goto capi_fail;\\
431 }\\
432 }
433"""
434cppmacros['GETSCALARFROMPYTUPLE'] = """
435#define GETSCALARFROMPYTUPLE(tuple,index,var,ctype,mess) {\\
436 if ((capi_tmp = PyTuple_GetItem((tuple),(index)))==NULL) goto capi_fail;\\
437 if (!(ctype ## _from_pyobj((var),capi_tmp,mess)))\\
438 goto capi_fail;\\
439 }
440"""
441
442cppmacros['FAILNULL'] = """\
443#define FAILNULL(p) do { \\
444 if ((p) == NULL) { \\
445 PyErr_SetString(PyExc_MemoryError, "NULL pointer found"); \\
446 goto capi_fail; \\
447 } \\
448} while (0)
449"""
450needs['MEMCOPY'] = ['string.h', 'FAILNULL']
451cppmacros['MEMCOPY'] = """
452#define MEMCOPY(to,from,n)\\
453 do { FAILNULL(to); FAILNULL(from); (void)memcpy(to,from,n); } while (0)
454"""
455cppmacros['STRINGMALLOC'] = """
456#define STRINGMALLOC(str,len)\\
457 if ((str = (string)malloc(len+1)) == NULL) {\\
458 PyErr_SetString(PyExc_MemoryError, \"out of memory\");\\
459 goto capi_fail;\\
460 } else {\\
461 (str)[len] = '\\0';\\
462 }
463"""
464cppmacros['STRINGFREE'] = """
465#define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0)
466"""
467needs['STRINGPADN'] = ['string.h']
468cppmacros['STRINGPADN'] = """
469/*
470STRINGPADN replaces null values with padding values from the right.
471
472`to` must have size of at least N bytes.
473
474If the `to[N-1]` has null value, then replace it and all the
475preceding, nulls with the given padding.
476
477STRINGPADN(to, N, PADDING, NULLVALUE) is an inverse operation.
478*/
479#define STRINGPADN(to, N, NULLVALUE, PADDING) \\
480 do { \\
481 int _m = (N); \\
482 char *_to = (to); \\
483 for (_m -= 1; _m >= 0 && _to[_m] == NULLVALUE; _m--) { \\
484 _to[_m] = PADDING; \\
485 } \\
486 } while (0)
487"""
488needs['STRINGCOPYN'] = ['string.h', 'FAILNULL']
489cppmacros['STRINGCOPYN'] = """
490/*
491STRINGCOPYN copies N bytes.
492
493`to` and `from` buffers must have sizes of at least N bytes.
494*/
495#define STRINGCOPYN(to,from,N) \\
496 do { \\
497 int _m = (N); \\
498 char *_to = (to); \\
499 char *_from = (from); \\
500 FAILNULL(_to); FAILNULL(_from); \\
501 (void)strncpy(_to, _from, _m); \\
502 } while (0)
503"""
504needs['STRINGCOPY'] = ['string.h', 'FAILNULL']
505cppmacros['STRINGCOPY'] = """
506#define STRINGCOPY(to,from)\\
507 do { FAILNULL(to); FAILNULL(from); (void)strcpy(to,from); } while (0)
508"""
509cppmacros['CHECKGENERIC'] = """
510#define CHECKGENERIC(check,tcheck,name) \\
511 if (!(check)) {\\
512 PyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
513 /*goto capi_fail;*/\\
514 } else """
515cppmacros['CHECKARRAY'] = """
516#define CHECKARRAY(check,tcheck,name) \\
517 if (!(check)) {\\
518 PyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
519 /*goto capi_fail;*/\\
520 } else """
521cppmacros['CHECKSTRING'] = """
522#define CHECKSTRING(check,tcheck,name,show,var)\\
523 if (!(check)) {\\
524 char errstring[256];\\
525 sprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, slen(var), var);\\
526 PyErr_SetString(#modulename#_error, errstring);\\
527 /*goto capi_fail;*/\\
528 } else """
529cppmacros['CHECKSCALAR'] = """
530#define CHECKSCALAR(check,tcheck,name,show,var)\\
531 if (!(check)) {\\
532 char errstring[256];\\
533 sprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, var);\\
534 PyErr_SetString(#modulename#_error,errstring);\\
535 /*goto capi_fail;*/\\
536 } else """
537# cppmacros['CHECKDIMS']="""
538# define CHECKDIMS(dims,rank) \\
539# for (int i=0;i<(rank);i++)\\
540# if (dims[i]<0) {\\
541# fprintf(stderr,\"Unspecified array argument requires a complete dimension specification.\\n\");\\
542# goto capi_fail;\\
543# }
544# """
545cppmacros[
546 'ARRSIZE'] = '#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))'
547cppmacros['OLDPYNUM'] = """
548#ifdef OLDPYNUM
549#error You need to install NumPy version 0.13 or higher. See https://scipy.org/install.html
550#endif
551"""
552
553# Defining the correct value to indicate thread-local storage in C without
554# running a compile-time check (which we have no control over in generated
555# code used outside of NumPy) is hard. Therefore we support overriding this
556# via an external define - the f2py-using package can then use the same
557# compile-time checks as we use for `NPY_TLS` when building NumPy (see
558# scipy#21860 for an example of that).
559#
560# __STDC_NO_THREADS__ should not be coupled to the availability of _Thread_local.
561# In case we get a bug report, guard it with __STDC_NO_THREADS__ after all.
562#
563# `thread_local` has become a keyword in C23, but don't try to use that yet
564# (too new, doing so while C23 support is preliminary will likely cause more
565# problems than it solves).
566#
567# Note: do not try to use `threads.h`, its availability is very low
568# *and* threads.h isn't actually used where `F2PY_THREAD_LOCAL_DECL` is
569# in the generated code. See gh-27718 for more details.
570cppmacros["F2PY_THREAD_LOCAL_DECL"] = """
571#ifndef F2PY_THREAD_LOCAL_DECL
572#if defined(_MSC_VER)
573#define F2PY_THREAD_LOCAL_DECL __declspec(thread)
574#elif defined(NPY_OS_MINGW)
575#define F2PY_THREAD_LOCAL_DECL __thread
576#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
577#define F2PY_THREAD_LOCAL_DECL _Thread_local
578#elif defined(__GNUC__) \\
579 && (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 4)))
580#define F2PY_THREAD_LOCAL_DECL __thread
581#endif
582#endif
583"""
584################# C functions ###############
585
586cfuncs['calcarrindex'] = """
587static int calcarrindex(int *i,PyArrayObject *arr) {
588 int k,ii = i[0];
589 for (k=1; k < PyArray_NDIM(arr); k++)
590 ii += (ii*(PyArray_DIM(arr,k) - 1)+i[k]); /* assuming contiguous arr */
591 return ii;
592}"""
593cfuncs['calcarrindextr'] = """
594static int calcarrindextr(int *i,PyArrayObject *arr) {
595 int k,ii = i[PyArray_NDIM(arr)-1];
596 for (k=1; k < PyArray_NDIM(arr); k++)
597 ii += (ii*(PyArray_DIM(arr,PyArray_NDIM(arr)-k-1) - 1)+i[PyArray_NDIM(arr)-k-1]); /* assuming contiguous arr */
598 return ii;
599}"""
600cfuncs['forcomb'] = """
601struct ForcombCache { int nd;npy_intp *d;int *i,*i_tr,tr; };
602static int initforcomb(struct ForcombCache *cache, npy_intp *dims,int nd,int tr) {
603 int k;
604 if (dims==NULL) return 0;
605 if (nd<0) return 0;
606 cache->nd = nd;
607 cache->d = dims;
608 cache->tr = tr;
609
610 cache->i = (int *)malloc(sizeof(int)*nd);
611 if (cache->i==NULL) return 0;
612 cache->i_tr = (int *)malloc(sizeof(int)*nd);
613 if (cache->i_tr==NULL) {free(cache->i); return 0;};
614
615 for (k=1;k<nd;k++) {
616 cache->i[k] = cache->i_tr[nd-k-1] = 0;
617 }
618 cache->i[0] = cache->i_tr[nd-1] = -1;
619 return 1;
620}
621static int *nextforcomb(struct ForcombCache *cache) {
622 if (cache==NULL) return NULL;
623 int j,*i,*i_tr,k;
624 int nd=cache->nd;
625 if ((i=cache->i) == NULL) return NULL;
626 if ((i_tr=cache->i_tr) == NULL) return NULL;
627 if (cache->d == NULL) return NULL;
628 i[0]++;
629 if (i[0]==cache->d[0]) {
630 j=1;
631 while ((j<nd) && (i[j]==cache->d[j]-1)) j++;
632 if (j==nd) {
633 free(i);
634 free(i_tr);
635 return NULL;
636 }
637 for (k=0;k<j;k++) i[k] = i_tr[nd-k-1] = 0;
638 i[j]++;
639 i_tr[nd-j-1]++;
640 } else
641 i_tr[nd-1]++;
642 if (cache->tr) return i_tr;
643 return i;
644}"""
645needs['try_pyarr_from_string'] = ['STRINGCOPYN', 'PRINTPYOBJERR', 'string']
646cfuncs['try_pyarr_from_string'] = """
647/*
648 try_pyarr_from_string copies str[:len(obj)] to the data of an `ndarray`.
649
650 If obj is an `ndarray`, it is assumed to be contiguous.
651
652 If the specified len==-1, str must be null-terminated.
653*/
654static int try_pyarr_from_string(PyObject *obj,
655 const string str, const int len) {
656#ifdef DEBUGCFUNCS
657fprintf(stderr, "try_pyarr_from_string(str='%s', len=%d, obj=%p)\\n",
658 (char*)str,len, obj);
659#endif
660 if (!obj) return -2; /* Object missing */
661 if (obj == Py_None) return -1; /* None */
662 if (!PyArray_Check(obj)) goto capi_fail; /* not an ndarray */
663 if (PyArray_Check(obj)) {
664 PyArrayObject *arr = (PyArrayObject *)obj;
665 assert(ISCONTIGUOUS(arr));
666 string buf = PyArray_DATA(arr);
667 npy_intp n = len;
668 if (n == -1) {
669 /* Assuming null-terminated str. */
670 n = strlen(str);
671 }
672 if (n > PyArray_NBYTES(arr)) {
673 n = PyArray_NBYTES(arr);
674 }
675 STRINGCOPYN(buf, str, n);
676 return 1;
677 }
678capi_fail:
679 PRINTPYOBJERR(obj);
680 PyErr_SetString(#modulename#_error, \"try_pyarr_from_string failed\");
681 return 0;
682}
683"""
684needs['string_from_pyobj'] = ['string', 'STRINGMALLOC', 'STRINGCOPYN']
685cfuncs['string_from_pyobj'] = """
686/*
687 Create a new string buffer `str` of at most length `len` from a
688 Python string-like object `obj`.
689
690 The string buffer has given size (len) or the size of inistr when len==-1.
691
692 The string buffer is padded with blanks: in Fortran, trailing blanks
693 are insignificant contrary to C nulls.
694 */
695static int
696string_from_pyobj(string *str, int *len, const string inistr, PyObject *obj,
697 const char *errmess)
698{
699 PyObject *tmp = NULL;
700 string buf = NULL;
701 npy_intp n = -1;
702#ifdef DEBUGCFUNCS
703fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",
704 (char*)str, *len, (char *)inistr, obj);
705#endif
706 if (obj == Py_None) {
707 n = strlen(inistr);
708 buf = inistr;
709 }
710 else if (PyArray_Check(obj)) {
711 PyArrayObject *arr = (PyArrayObject *)obj;
712 if (!ISCONTIGUOUS(arr)) {
713 PyErr_SetString(PyExc_ValueError,
714 \"array object is non-contiguous.\");
715 goto capi_fail;
716 }
717 n = PyArray_NBYTES(arr);
718 buf = PyArray_DATA(arr);
719 n = strnlen(buf, n);
720 }
721 else {
722 if (PyBytes_Check(obj)) {
723 tmp = obj;
724 Py_INCREF(tmp);
725 }
726 else if (PyUnicode_Check(obj)) {
727 tmp = PyUnicode_AsASCIIString(obj);
728 }
729 else {
730 PyObject *tmp2;
731 tmp2 = PyObject_Str(obj);
732 if (tmp2) {
733 tmp = PyUnicode_AsASCIIString(tmp2);
734 Py_DECREF(tmp2);
735 }
736 else {
737 tmp = NULL;
738 }
739 }
740 if (tmp == NULL) goto capi_fail;
741 n = PyBytes_GET_SIZE(tmp);
742 buf = PyBytes_AS_STRING(tmp);
743 }
744 if (*len == -1) {
745 /* TODO: change the type of `len` so that we can remove this */
746 if (n > NPY_MAX_INT) {
747 PyErr_SetString(PyExc_OverflowError,
748 "object too large for a 32-bit int");
749 goto capi_fail;
750 }
751 *len = n;
752 }
753 else if (*len < n) {
754 /* discard the last (len-n) bytes of input buf */
755 n = *len;
756 }
757 if (n < 0 || *len < 0 || buf == NULL) {
758 goto capi_fail;
759 }
760 STRINGMALLOC(*str, *len); // *str is allocated with size (*len + 1)
761 if (n < *len) {
762 /*
763 Pad fixed-width string with nulls. The caller will replace
764 nulls with blanks when the corresponding argument is not
765 intent(c).
766 */
767 memset(*str + n, '\\0', *len - n);
768 }
769 STRINGCOPYN(*str, buf, n);
770 Py_XDECREF(tmp);
771 return 1;
772capi_fail:
773 Py_XDECREF(tmp);
774 {
775 PyObject* err = PyErr_Occurred();
776 if (err == NULL) {
777 err = #modulename#_error;
778 }
779 PyErr_SetString(err, errmess);
780 }
781 return 0;
782}
783"""
784
785cfuncs['character_from_pyobj'] = """
786static int
787character_from_pyobj(character* v, PyObject *obj, const char *errmess) {
788 if (PyBytes_Check(obj)) {
789 /* empty bytes has trailing null, so dereferencing is always safe */
790 *v = PyBytes_AS_STRING(obj)[0];
791 return 1;
792 } else if (PyUnicode_Check(obj)) {
793 PyObject* tmp = PyUnicode_AsASCIIString(obj);
794 if (tmp != NULL) {
795 *v = PyBytes_AS_STRING(tmp)[0];
796 Py_DECREF(tmp);
797 return 1;
798 }
799 } else if (PyArray_Check(obj)) {
800 PyArrayObject* arr = (PyArrayObject*)obj;
801 if (F2PY_ARRAY_IS_CHARACTER_COMPATIBLE(arr)) {
802 *v = PyArray_BYTES(arr)[0];
803 return 1;
804 } else if (F2PY_IS_UNICODE_ARRAY(arr)) {
805 // TODO: update when numpy will support 1-byte and
806 // 2-byte unicode dtypes
807 PyObject* tmp = PyUnicode_FromKindAndData(
808 PyUnicode_4BYTE_KIND,
809 PyArray_BYTES(arr),
810 (PyArray_NBYTES(arr)>0?1:0));
811 if (tmp != NULL) {
812 if (character_from_pyobj(v, tmp, errmess)) {
813 Py_DECREF(tmp);
814 return 1;
815 }
816 Py_DECREF(tmp);
817 }
818 }
819 } else if (PySequence_Check(obj)) {
820 PyObject* tmp = PySequence_GetItem(obj,0);
821 if (tmp != NULL) {
822 if (character_from_pyobj(v, tmp, errmess)) {
823 Py_DECREF(tmp);
824 return 1;
825 }
826 Py_DECREF(tmp);
827 }
828 }
829 {
830 /* TODO: This error (and most other) error handling needs cleaning. */
831 char mess[F2PY_MESSAGE_BUFFER_SIZE];
832 strcpy(mess, errmess);
833 PyObject* err = PyErr_Occurred();
834 if (err == NULL) {
835 err = PyExc_TypeError;
836 Py_INCREF(err);
837 }
838 else {
839 Py_INCREF(err);
840 PyErr_Clear();
841 }
842 sprintf(mess + strlen(mess),
843 " -- expected str|bytes|sequence-of-str-or-bytes, got ");
844 f2py_describe(obj, mess + strlen(mess));
845 PyErr_SetString(err, mess);
846 Py_DECREF(err);
847 }
848 return 0;
849}
850"""
851
852# TODO: These should be dynamically generated, too many mapped to int things,
853# see note in _isocbind.py
854needs['char_from_pyobj'] = ['int_from_pyobj']
855cfuncs['char_from_pyobj'] = """
856static int
857char_from_pyobj(char* v, PyObject *obj, const char *errmess) {
858 int i = 0;
859 if (int_from_pyobj(&i, obj, errmess)) {
860 *v = (char)i;
861 return 1;
862 }
863 return 0;
864}
865"""
866
867
868needs['signed_char_from_pyobj'] = ['int_from_pyobj', 'signed_char']
869cfuncs['signed_char_from_pyobj'] = """
870static int
871signed_char_from_pyobj(signed_char* v, PyObject *obj, const char *errmess) {
872 int i = 0;
873 if (int_from_pyobj(&i, obj, errmess)) {
874 *v = (signed_char)i;
875 return 1;
876 }
877 return 0;
878}
879"""
880
881
882needs['short_from_pyobj'] = ['int_from_pyobj']
883cfuncs['short_from_pyobj'] = """
884static int
885short_from_pyobj(short* v, PyObject *obj, const char *errmess) {
886 int i = 0;
887 if (int_from_pyobj(&i, obj, errmess)) {
888 *v = (short)i;
889 return 1;
890 }
891 return 0;
892}
893"""
894
895
896cfuncs['int_from_pyobj'] = """
897static int
898int_from_pyobj(int* v, PyObject *obj, const char *errmess)
899{
900 PyObject* tmp = NULL;
901
902 if (PyLong_Check(obj)) {
903 *v = Npy__PyLong_AsInt(obj);
904 return !(*v == -1 && PyErr_Occurred());
905 }
906
907 tmp = PyNumber_Long(obj);
908 if (tmp) {
909 *v = Npy__PyLong_AsInt(tmp);
910 Py_DECREF(tmp);
911 return !(*v == -1 && PyErr_Occurred());
912 }
913
914 if (PyComplex_Check(obj)) {
915 PyErr_Clear();
916 tmp = PyObject_GetAttrString(obj,\"real\");
917 }
918 else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
919 /*pass*/;
920 }
921 else if (PySequence_Check(obj)) {
922 PyErr_Clear();
923 tmp = PySequence_GetItem(obj, 0);
924 }
925
926 if (tmp) {
927 if (int_from_pyobj(v, tmp, errmess)) {
928 Py_DECREF(tmp);
929 return 1;
930 }
931 Py_DECREF(tmp);
932 }
933
934 {
935 PyObject* err = PyErr_Occurred();
936 if (err == NULL) {
937 err = #modulename#_error;
938 }
939 PyErr_SetString(err, errmess);
940 }
941 return 0;
942}
943"""
944
945
946cfuncs['long_from_pyobj'] = """
947static int
948long_from_pyobj(long* v, PyObject *obj, const char *errmess) {
949 PyObject* tmp = NULL;
950
951 if (PyLong_Check(obj)) {
952 *v = PyLong_AsLong(obj);
953 return !(*v == -1 && PyErr_Occurred());
954 }
955
956 tmp = PyNumber_Long(obj);
957 if (tmp) {
958 *v = PyLong_AsLong(tmp);
959 Py_DECREF(tmp);
960 return !(*v == -1 && PyErr_Occurred());
961 }
962
963 if (PyComplex_Check(obj)) {
964 PyErr_Clear();
965 tmp = PyObject_GetAttrString(obj,\"real\");
966 }
967 else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
968 /*pass*/;
969 }
970 else if (PySequence_Check(obj)) {
971 PyErr_Clear();
972 tmp = PySequence_GetItem(obj, 0);
973 }
974
975 if (tmp) {
976 if (long_from_pyobj(v, tmp, errmess)) {
977 Py_DECREF(tmp);
978 return 1;
979 }
980 Py_DECREF(tmp);
981 }
982 {
983 PyObject* err = PyErr_Occurred();
984 if (err == NULL) {
985 err = #modulename#_error;
986 }
987 PyErr_SetString(err, errmess);
988 }
989 return 0;
990}
991"""
992
993
994needs['long_long_from_pyobj'] = ['long_long']
995cfuncs['long_long_from_pyobj'] = """
996static int
997long_long_from_pyobj(long_long* v, PyObject *obj, const char *errmess)
998{
999 PyObject* tmp = NULL;
1000
1001 if (PyLong_Check(obj)) {
1002 *v = PyLong_AsLongLong(obj);
1003 return !(*v == -1 && PyErr_Occurred());
1004 }
1005
1006 tmp = PyNumber_Long(obj);
1007 if (tmp) {
1008 *v = PyLong_AsLongLong(tmp);
1009 Py_DECREF(tmp);
1010 return !(*v == -1 && PyErr_Occurred());
1011 }
1012
1013 if (PyComplex_Check(obj)) {
1014 PyErr_Clear();
1015 tmp = PyObject_GetAttrString(obj,\"real\");
1016 }
1017 else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
1018 /*pass*/;
1019 }
1020 else if (PySequence_Check(obj)) {
1021 PyErr_Clear();
1022 tmp = PySequence_GetItem(obj, 0);
1023 }
1024
1025 if (tmp) {
1026 if (long_long_from_pyobj(v, tmp, errmess)) {
1027 Py_DECREF(tmp);
1028 return 1;
1029 }
1030 Py_DECREF(tmp);
1031 }
1032 {
1033 PyObject* err = PyErr_Occurred();
1034 if (err == NULL) {
1035 err = #modulename#_error;
1036 }
1037 PyErr_SetString(err,errmess);
1038 }
1039 return 0;
1040}
1041"""
1042
1043
1044needs['long_double_from_pyobj'] = ['double_from_pyobj', 'long_double']
1045cfuncs['long_double_from_pyobj'] = """
1046static int
1047long_double_from_pyobj(long_double* v, PyObject *obj, const char *errmess)
1048{
1049 double d=0;
1050 if (PyArray_CheckScalar(obj)){
1051 if PyArray_IsScalar(obj, LongDouble) {
1052 PyArray_ScalarAsCtype(obj, v);
1053 return 1;
1054 }
1055 else if (PyArray_Check(obj)) {
1056 PyArrayObject *arr = (PyArrayObject *)obj;
1057 if (PyArray_TYPE(arr) == NPY_LONGDOUBLE) {
1058 (*v) = *((npy_longdouble *)PyArray_DATA(arr));
1059 return 1;
1060 }
1061 }
1062 }
1063 if (double_from_pyobj(&d, obj, errmess)) {
1064 *v = (long_double)d;
1065 return 1;
1066 }
1067 return 0;
1068}
1069"""
1070
1071
1072cfuncs['double_from_pyobj'] = """
1073static int
1074double_from_pyobj(double* v, PyObject *obj, const char *errmess)
1075{
1076 PyObject* tmp = NULL;
1077 if (PyFloat_Check(obj)) {
1078 *v = PyFloat_AsDouble(obj);
1079 return !(*v == -1.0 && PyErr_Occurred());
1080 }
1081
1082 tmp = PyNumber_Float(obj);
1083 if (tmp) {
1084 *v = PyFloat_AsDouble(tmp);
1085 Py_DECREF(tmp);
1086 return !(*v == -1.0 && PyErr_Occurred());
1087 }
1088
1089 if (PyComplex_Check(obj)) {
1090 PyErr_Clear();
1091 tmp = PyObject_GetAttrString(obj,\"real\");
1092 }
1093 else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
1094 /*pass*/;
1095 }
1096 else if (PySequence_Check(obj)) {
1097 PyErr_Clear();
1098 tmp = PySequence_GetItem(obj, 0);
1099 }
1100
1101 if (tmp) {
1102 if (double_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
1103 Py_DECREF(tmp);
1104 }
1105 {
1106 PyObject* err = PyErr_Occurred();
1107 if (err==NULL) err = #modulename#_error;
1108 PyErr_SetString(err,errmess);
1109 }
1110 return 0;
1111}
1112"""
1113
1114
1115needs['float_from_pyobj'] = ['double_from_pyobj']
1116cfuncs['float_from_pyobj'] = """
1117static int
1118float_from_pyobj(float* v, PyObject *obj, const char *errmess)
1119{
1120 double d=0.0;
1121 if (double_from_pyobj(&d,obj,errmess)) {
1122 *v = (float)d;
1123 return 1;
1124 }
1125 return 0;
1126}
1127"""
1128
1129
1130needs['complex_long_double_from_pyobj'] = ['complex_long_double', 'long_double',
1131 'complex_double_from_pyobj', 'npy_math.h']
1132cfuncs['complex_long_double_from_pyobj'] = """
1133static int
1134complex_long_double_from_pyobj(complex_long_double* v, PyObject *obj, const char *errmess)
1135{
1136 complex_double cd = {0.0,0.0};
1137 if (PyArray_CheckScalar(obj)){
1138 if PyArray_IsScalar(obj, CLongDouble) {
1139 PyArray_ScalarAsCtype(obj, v);
1140 return 1;
1141 }
1142 else if (PyArray_Check(obj)) {
1143 PyArrayObject *arr = (PyArrayObject *)obj;
1144 if (PyArray_TYPE(arr)==NPY_CLONGDOUBLE) {
1145 (*v).r = npy_creall(*(((npy_clongdouble *)PyArray_DATA(arr))));
1146 (*v).i = npy_cimagl(*(((npy_clongdouble *)PyArray_DATA(arr))));
1147 return 1;
1148 }
1149 }
1150 }
1151 if (complex_double_from_pyobj(&cd,obj,errmess)) {
1152 (*v).r = (long_double)cd.r;
1153 (*v).i = (long_double)cd.i;
1154 return 1;
1155 }
1156 return 0;
1157}
1158"""
1159
1160
1161needs['complex_double_from_pyobj'] = ['complex_double', 'npy_math.h']
1162cfuncs['complex_double_from_pyobj'] = """
1163static int
1164complex_double_from_pyobj(complex_double* v, PyObject *obj, const char *errmess) {
1165 Py_complex c;
1166 if (PyComplex_Check(obj)) {
1167 c = PyComplex_AsCComplex(obj);
1168 (*v).r = c.real;
1169 (*v).i = c.imag;
1170 return 1;
1171 }
1172 if (PyArray_IsScalar(obj, ComplexFloating)) {
1173 if (PyArray_IsScalar(obj, CFloat)) {
1174 npy_cfloat new;
1175 PyArray_ScalarAsCtype(obj, &new);
1176 (*v).r = (double)npy_crealf(new);
1177 (*v).i = (double)npy_cimagf(new);
1178 }
1179 else if (PyArray_IsScalar(obj, CLongDouble)) {
1180 npy_clongdouble new;
1181 PyArray_ScalarAsCtype(obj, &new);
1182 (*v).r = (double)npy_creall(new);
1183 (*v).i = (double)npy_cimagl(new);
1184 }
1185 else { /* if (PyArray_IsScalar(obj, CDouble)) */
1186 PyArray_ScalarAsCtype(obj, v);
1187 }
1188 return 1;
1189 }
1190 if (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */
1191 PyArrayObject *arr;
1192 if (PyArray_Check(obj)) {
1193 arr = (PyArrayObject *)PyArray_Cast((PyArrayObject *)obj, NPY_CDOUBLE);
1194 }
1195 else {
1196 arr = (PyArrayObject *)PyArray_FromScalar(obj, PyArray_DescrFromType(NPY_CDOUBLE));
1197 }
1198 if (arr == NULL) {
1199 return 0;
1200 }
