Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
cfuncs.py1564 linesDownload Raw Back to f2py
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        }

Showing the first 1,200 of 1564 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai