123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530 |
- #!/usr/bin/env python3
- """
- C declarations, CPP macros, and C functions for f2py2e.
- Only required declarations/macros/functions will be used.
- Copyright 1999,2000 Pearu Peterson all rights reserved,
- Pearu Peterson <pearu@ioc.ee>
- Permission to use, modify, and distribute this software is given under the
- terms of the NumPy License.
- NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
- $Date: 2005/05/06 11:42:34 $
- Pearu Peterson
- """
- import sys
- import copy
- from . import __version__
- f2py_version = __version__.version
- errmess = sys.stderr.write
- ##################### Definitions ##################
- outneeds = {'includes0': [], 'includes': [], 'typedefs': [], 'typedefs_generated': [],
- 'userincludes': [],
- 'cppmacros': [], 'cfuncs': [], 'callbacks': [], 'f90modhooks': [],
- 'commonhooks': []}
- needs = {}
- includes0 = {'includes0': '/*need_includes0*/'}
- includes = {'includes': '/*need_includes*/'}
- userincludes = {'userincludes': '/*need_userincludes*/'}
- typedefs = {'typedefs': '/*need_typedefs*/'}
- typedefs_generated = {'typedefs_generated': '/*need_typedefs_generated*/'}
- cppmacros = {'cppmacros': '/*need_cppmacros*/'}
- cfuncs = {'cfuncs': '/*need_cfuncs*/'}
- callbacks = {'callbacks': '/*need_callbacks*/'}
- f90modhooks = {'f90modhooks': '/*need_f90modhooks*/',
- 'initf90modhooksstatic': '/*initf90modhooksstatic*/',
- 'initf90modhooksdynamic': '/*initf90modhooksdynamic*/',
- }
- commonhooks = {'commonhooks': '/*need_commonhooks*/',
- 'initcommonhooks': '/*need_initcommonhooks*/',
- }
- ############ Includes ###################
- includes0['math.h'] = '#include <math.h>'
- includes0['string.h'] = '#include <string.h>'
- includes0['setjmp.h'] = '#include <setjmp.h>'
- includes['arrayobject.h'] = '''#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
- #include "arrayobject.h"'''
- includes['npy_math.h'] = '#include "numpy/npy_math.h"'
- includes['arrayobject.h'] = '#include "fortranobject.h"'
- includes['stdarg.h'] = '#include <stdarg.h>'
- ############# Type definitions ###############
- typedefs['unsigned_char'] = 'typedef unsigned char unsigned_char;'
- typedefs['unsigned_short'] = 'typedef unsigned short unsigned_short;'
- typedefs['unsigned_long'] = 'typedef unsigned long unsigned_long;'
- typedefs['signed_char'] = 'typedef signed char signed_char;'
- typedefs['long_long'] = """\
- #if defined(NPY_OS_WIN32)
- typedef __int64 long_long;
- #else
- typedef long long long_long;
- typedef unsigned long long unsigned_long_long;
- #endif
- """
- typedefs['unsigned_long_long'] = """\
- #if defined(NPY_OS_WIN32)
- typedef __uint64 long_long;
- #else
- typedef unsigned long long unsigned_long_long;
- #endif
- """
- typedefs['long_double'] = """\
- #ifndef _LONG_DOUBLE
- typedef long double long_double;
- #endif
- """
- typedefs[
- 'complex_long_double'] = 'typedef struct {long double r,i;} complex_long_double;'
- typedefs['complex_float'] = 'typedef struct {float r,i;} complex_float;'
- typedefs['complex_double'] = 'typedef struct {double r,i;} complex_double;'
- typedefs['string'] = """typedef char * string;"""
- typedefs['character'] = """typedef char character;"""
- ############### CPP macros ####################
- cppmacros['CFUNCSMESS'] = """\
- #ifdef DEBUGCFUNCS
- #define CFUNCSMESS(mess) fprintf(stderr,\"debug-capi:\"mess);
- #define CFUNCSMESSPY(mess,obj) CFUNCSMESS(mess) \\
- PyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
- fprintf(stderr,\"\\n\");
- #else
- #define CFUNCSMESS(mess)
- #define CFUNCSMESSPY(mess,obj)
- #endif
- """
- cppmacros['F_FUNC'] = """\
- #if defined(PREPEND_FORTRAN)
- #if defined(NO_APPEND_FORTRAN)
- #if defined(UPPERCASE_FORTRAN)
- #define F_FUNC(f,F) _##F
- #else
- #define F_FUNC(f,F) _##f
- #endif
- #else
- #if defined(UPPERCASE_FORTRAN)
- #define F_FUNC(f,F) _##F##_
- #else
- #define F_FUNC(f,F) _##f##_
- #endif
- #endif
- #else
- #if defined(NO_APPEND_FORTRAN)
- #if defined(UPPERCASE_FORTRAN)
- #define F_FUNC(f,F) F
- #else
- #define F_FUNC(f,F) f
- #endif
- #else
- #if defined(UPPERCASE_FORTRAN)
- #define F_FUNC(f,F) F##_
- #else
- #define F_FUNC(f,F) f##_
- #endif
- #endif
- #endif
- #if defined(UNDERSCORE_G77)
- #define F_FUNC_US(f,F) F_FUNC(f##_,F##_)
- #else
- #define F_FUNC_US(f,F) F_FUNC(f,F)
- #endif
- """
- cppmacros['F_WRAPPEDFUNC'] = """\
- #if defined(PREPEND_FORTRAN)
- #if defined(NO_APPEND_FORTRAN)
- #if defined(UPPERCASE_FORTRAN)
- #define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F
- #else
- #define F_WRAPPEDFUNC(f,F) _f2pywrap##f
- #endif
- #else
- #if defined(UPPERCASE_FORTRAN)
- #define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F##_
- #else
- #define F_WRAPPEDFUNC(f,F) _f2pywrap##f##_
- #endif
- #endif
- #else
- #if defined(NO_APPEND_FORTRAN)
- #if defined(UPPERCASE_FORTRAN)
- #define F_WRAPPEDFUNC(f,F) F2PYWRAP##F
- #else
- #define F_WRAPPEDFUNC(f,F) f2pywrap##f
- #endif
- #else
- #if defined(UPPERCASE_FORTRAN)
- #define F_WRAPPEDFUNC(f,F) F2PYWRAP##F##_
- #else
- #define F_WRAPPEDFUNC(f,F) f2pywrap##f##_
- #endif
- #endif
- #endif
- #if defined(UNDERSCORE_G77)
- #define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f##_,F##_)
- #else
- #define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f,F)
- #endif
- """
- cppmacros['F_MODFUNC'] = """\
- #if defined(F90MOD2CCONV1) /*E.g. Compaq Fortran */
- #if defined(NO_APPEND_FORTRAN)
- #define F_MODFUNCNAME(m,f) $ ## m ## $ ## f
- #else
- #define F_MODFUNCNAME(m,f) $ ## m ## $ ## f ## _
- #endif
- #endif
- #if defined(F90MOD2CCONV2) /*E.g. IBM XL Fortran, not tested though */
- #if defined(NO_APPEND_FORTRAN)
- #define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f
- #else
- #define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f ## _
- #endif
- #endif
- #if defined(F90MOD2CCONV3) /*E.g. MIPSPro Compilers */
- #if defined(NO_APPEND_FORTRAN)
- #define F_MODFUNCNAME(m,f) f ## .in. ## m
- #else
- #define F_MODFUNCNAME(m,f) f ## .in. ## m ## _
- #endif
- #endif
- /*
- #if defined(UPPERCASE_FORTRAN)
- #define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(M,F)
- #else
- #define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(m,f)
- #endif
- */
- #define F_MODFUNC(m,f) (*(f2pymodstruct##m##.##f))
- """
- cppmacros['SWAPUNSAFE'] = """\
- #define SWAP(a,b) (size_t)(a) = ((size_t)(a) ^ (size_t)(b));\\
- (size_t)(b) = ((size_t)(a) ^ (size_t)(b));\\
- (size_t)(a) = ((size_t)(a) ^ (size_t)(b))
- """
- cppmacros['SWAP'] = """\
- #define SWAP(a,b,t) {\\
- t *c;\\
- c = a;\\
- a = b;\\
- b = c;}
- """
- # cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) &
- # NPY_ARRAY_C_CONTIGUOUS)'
- cppmacros['PRINTPYOBJERR'] = """\
- #define PRINTPYOBJERR(obj)\\
- fprintf(stderr,\"#modulename#.error is related to \");\\
- PyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
- fprintf(stderr,\"\\n\");
- """
- cppmacros['MINMAX'] = """\
- #ifndef max
- #define max(a,b) ((a > b) ? (a) : (b))
- #endif
- #ifndef min
- #define min(a,b) ((a < b) ? (a) : (b))
- #endif
- #ifndef MAX
- #define MAX(a,b) ((a > b) ? (a) : (b))
- #endif
- #ifndef MIN
- #define MIN(a,b) ((a < b) ? (a) : (b))
- #endif
- """
- cppmacros['len..'] = """\
- /* See fortranobject.h for definitions. The macros here are provided for BC. */
- #define rank f2py_rank
- #define shape f2py_shape
- #define fshape f2py_shape
- #define len f2py_len
- #define flen f2py_flen
- #define slen f2py_slen
- #define size f2py_size
- """
- cppmacros[
- 'pyobj_from_char1'] = '#define pyobj_from_char1(v) (PyLong_FromLong(v))'
- cppmacros[
- 'pyobj_from_short1'] = '#define pyobj_from_short1(v) (PyLong_FromLong(v))'
- needs['pyobj_from_int1'] = ['signed_char']
- cppmacros['pyobj_from_int1'] = '#define pyobj_from_int1(v) (PyLong_FromLong(v))'
- cppmacros[
- 'pyobj_from_long1'] = '#define pyobj_from_long1(v) (PyLong_FromLong(v))'
- needs['pyobj_from_long_long1'] = ['long_long']
- cppmacros['pyobj_from_long_long1'] = """\
- #ifdef HAVE_LONG_LONG
- #define pyobj_from_long_long1(v) (PyLong_FromLongLong(v))
- #else
- #warning HAVE_LONG_LONG is not available. Redefining pyobj_from_long_long.
- #define pyobj_from_long_long1(v) (PyLong_FromLong(v))
- #endif
- """
- needs['pyobj_from_long_double1'] = ['long_double']
- cppmacros[
- 'pyobj_from_long_double1'] = '#define pyobj_from_long_double1(v) (PyFloat_FromDouble(v))'
- cppmacros[
- 'pyobj_from_double1'] = '#define pyobj_from_double1(v) (PyFloat_FromDouble(v))'
- cppmacros[
- 'pyobj_from_float1'] = '#define pyobj_from_float1(v) (PyFloat_FromDouble(v))'
- needs['pyobj_from_complex_long_double1'] = ['complex_long_double']
- cppmacros[
- 'pyobj_from_complex_long_double1'] = '#define pyobj_from_complex_long_double1(v) (PyComplex_FromDoubles(v.r,v.i))'
- needs['pyobj_from_complex_double1'] = ['complex_double']
- cppmacros[
- 'pyobj_from_complex_double1'] = '#define pyobj_from_complex_double1(v) (PyComplex_FromDoubles(v.r,v.i))'
- needs['pyobj_from_complex_float1'] = ['complex_float']
- cppmacros[
- 'pyobj_from_complex_float1'] = '#define pyobj_from_complex_float1(v) (PyComplex_FromDoubles(v.r,v.i))'
- needs['pyobj_from_string1'] = ['string']
- cppmacros[
- 'pyobj_from_string1'] = '#define pyobj_from_string1(v) (PyUnicode_FromString((char *)v))'
- needs['pyobj_from_string1size'] = ['string']
- cppmacros[
- 'pyobj_from_string1size'] = '#define pyobj_from_string1size(v,len) (PyUnicode_FromStringAndSize((char *)v, len))'
- needs['TRYPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
- cppmacros['TRYPYARRAYTEMPLATE'] = """\
- /* New SciPy */
- #define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(PyArray_DATA(arr))=*v; break;
- #define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;
- #define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: PyArray_SETITEM(arr,PyArray_DATA(arr),pyobj_from_ ## ctype ## 1(*v)); break;
- #define TRYPYARRAYTEMPLATE(ctype,typecode) \\
- PyArrayObject *arr = NULL;\\
- if (!obj) return -2;\\
- if (!PyArray_Check(obj)) return -1;\\
- if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
- if (PyArray_DESCR(arr)->type==typecode) {*(ctype *)(PyArray_DATA(arr))=*v; return 1;}\\
- switch (PyArray_TYPE(arr)) {\\
- case NPY_DOUBLE: *(npy_double *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_INT: *(npy_int *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_LONG: *(npy_long *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_FLOAT: *(npy_float *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_CDOUBLE: *(npy_double *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_CFLOAT: *(npy_float *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=(*v!=0); break;\\
- case NPY_UBYTE: *(npy_ubyte *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_BYTE: *(npy_byte *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_SHORT: *(npy_short *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
- case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_ ## ctype ## 1(*v)); break;\\
- default: return -2;\\
- };\\
- return 1
- """
- needs['TRYCOMPLEXPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
- cppmacros['TRYCOMPLEXPYARRAYTEMPLATE'] = """\
- #define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_complex_ ## ctype ## 1((*v))); break;
- #define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\
- PyArrayObject *arr = NULL;\\
- if (!obj) return -2;\\
- if (!PyArray_Check(obj)) return -1;\\
- if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
- if (PyArray_DESCR(arr)->type==typecode) {\\
- *(ctype *)(PyArray_DATA(arr))=(*v).r;\\
- *(ctype *)(PyArray_DATA(arr)+sizeof(ctype))=(*v).i;\\
- return 1;\\
- }\\
- switch (PyArray_TYPE(arr)) {\\
- case NPY_CDOUBLE: *(npy_double *)(PyArray_DATA(arr))=(*v).r;\\
- *(npy_double *)(PyArray_DATA(arr)+sizeof(npy_double))=(*v).i;\\
- break;\\
- case NPY_CFLOAT: *(npy_float *)(PyArray_DATA(arr))=(*v).r;\\
- *(npy_float *)(PyArray_DATA(arr)+sizeof(npy_float))=(*v).i;\\
- break;\\
- case NPY_DOUBLE: *(npy_double *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_LONG: *(npy_long *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_FLOAT: *(npy_float *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_INT: *(npy_int *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_SHORT: *(npy_short *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_UBYTE: *(npy_ubyte *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_BYTE: *(npy_byte *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=((*v).r!=0 && (*v).i!=0); break;\\
- case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r; break;\\
- case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r;\\
- *(npy_longdouble *)(PyArray_DATA(arr)+sizeof(npy_longdouble))=(*v).i;\\
- break;\\
- case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_complex_ ## ctype ## 1((*v))); break;\\
- default: return -2;\\
- };\\
- return -1;
- """
- # cppmacros['NUMFROMARROBJ']="""\
- # define NUMFROMARROBJ(typenum,ctype) \\
- # if (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
- # else arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
- # if (arr) {\\
- # if (PyArray_TYPE(arr)==NPY_OBJECT) {\\
- # if (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
- # goto capi_fail;\\
- # } else {\\
- # (PyArray_DESCR(arr)->cast[typenum])(PyArray_DATA(arr),1,(char*)v,1,1);\\
- # }\\
- # if ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
- # return 1;\\
- # }
- # """
- # XXX: Note that CNUMFROMARROBJ is identical with NUMFROMARROBJ
- # cppmacros['CNUMFROMARROBJ']="""\
- # define CNUMFROMARROBJ(typenum,ctype) \\
- # if (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
- # else arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
- # if (arr) {\\
- # if (PyArray_TYPE(arr)==NPY_OBJECT) {\\
- # if (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
- # goto capi_fail;\\
- # } else {\\
- # (PyArray_DESCR(arr)->cast[typenum])((void *)(PyArray_DATA(arr)),1,(void *)(v),1,1);\\
- # }\\
- # if ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
- # return 1;\\
- # }
- # """
- needs['GETSTRFROMPYTUPLE'] = ['STRINGCOPYN', 'PRINTPYOBJERR']
- cppmacros['GETSTRFROMPYTUPLE'] = """\
- #define GETSTRFROMPYTUPLE(tuple,index,str,len) {\\
- PyObject *rv_cb_str = PyTuple_GetItem((tuple),(index));\\
- if (rv_cb_str == NULL)\\
- goto capi_fail;\\
- if (PyBytes_Check(rv_cb_str)) {\\
- str[len-1]='\\0';\\
- STRINGCOPYN((str),PyBytes_AS_STRING((PyBytesObject*)rv_cb_str),(len));\\
- } else {\\
- PRINTPYOBJERR(rv_cb_str);\\
- PyErr_SetString(#modulename#_error,\"string object expected\");\\
- goto capi_fail;\\
- }\\
- }
- """
- cppmacros['GETSCALARFROMPYTUPLE'] = """\
- #define GETSCALARFROMPYTUPLE(tuple,index,var,ctype,mess) {\\
- if ((capi_tmp = PyTuple_GetItem((tuple),(index)))==NULL) goto capi_fail;\\
- if (!(ctype ## _from_pyobj((var),capi_tmp,mess)))\\
- goto capi_fail;\\
- }
- """
- cppmacros['FAILNULL'] = """\\
- #define FAILNULL(p) do { \\
- if ((p) == NULL) { \\
- PyErr_SetString(PyExc_MemoryError, "NULL pointer found"); \\
- goto capi_fail; \\
- } \\
- } while (0)
- """
- needs['MEMCOPY'] = ['string.h', 'FAILNULL']
- cppmacros['MEMCOPY'] = """\
- #define MEMCOPY(to,from,n)\\
- do { FAILNULL(to); FAILNULL(from); (void)memcpy(to,from,n); } while (0)
- """
- cppmacros['STRINGMALLOC'] = """\
- #define STRINGMALLOC(str,len)\\
- if ((str = (string)malloc(len+1)) == NULL) {\\
- PyErr_SetString(PyExc_MemoryError, \"out of memory\");\\
- goto capi_fail;\\
- } else {\\
- (str)[len] = '\\0';\\
- }
- """
- cppmacros['STRINGFREE'] = """\
- #define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0)
- """
- needs['STRINGPADN'] = ['string.h']
- cppmacros['STRINGPADN'] = """\
- /*
- STRINGPADN replaces null values with padding values from the right.
- `to` must have size of at least N bytes.
- If the `to[N-1]` has null value, then replace it and all the
- preceding, nulls with the given padding.
- STRINGPADN(to, N, PADDING, NULLVALUE) is an inverse operation.
- */
- #define STRINGPADN(to, N, NULLVALUE, PADDING) \\
- do { \\
- int _m = (N); \\
- char *_to = (to); \\
- for (_m -= 1; _m >= 0 && _to[_m] == NULLVALUE; _m--) { \\
- _to[_m] = PADDING; \\
- } \\
- } while (0)
- """
- needs['STRINGCOPYN'] = ['string.h', 'FAILNULL']
- cppmacros['STRINGCOPYN'] = """\
- /*
- STRINGCOPYN copies N bytes.
- `to` and `from` buffers must have sizes of at least N bytes.
- */
- #define STRINGCOPYN(to,from,N) \\
- do { \\
- int _m = (N); \\
- char *_to = (to); \\
- char *_from = (from); \\
- FAILNULL(_to); FAILNULL(_from); \\
- (void)strncpy(_to, _from, _m); \\
- } while (0)
- """
- needs['STRINGCOPY'] = ['string.h', 'FAILNULL']
- cppmacros['STRINGCOPY'] = """\
- #define STRINGCOPY(to,from)\\
- do { FAILNULL(to); FAILNULL(from); (void)strcpy(to,from); } while (0)
- """
- cppmacros['CHECKGENERIC'] = """\
- #define CHECKGENERIC(check,tcheck,name) \\
- if (!(check)) {\\
- PyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
- /*goto capi_fail;*/\\
- } else """
- cppmacros['CHECKARRAY'] = """\
- #define CHECKARRAY(check,tcheck,name) \\
- if (!(check)) {\\
- PyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
- /*goto capi_fail;*/\\
- } else """
- cppmacros['CHECKSTRING'] = """\
- #define CHECKSTRING(check,tcheck,name,show,var)\\
- if (!(check)) {\\
- char errstring[256];\\
- sprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, slen(var), var);\\
- PyErr_SetString(#modulename#_error, errstring);\\
- /*goto capi_fail;*/\\
- } else """
- cppmacros['CHECKSCALAR'] = """\
- #define CHECKSCALAR(check,tcheck,name,show,var)\\
- if (!(check)) {\\
- char errstring[256];\\
- sprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, var);\\
- PyErr_SetString(#modulename#_error,errstring);\\
- /*goto capi_fail;*/\\
- } else """
- # cppmacros['CHECKDIMS']="""\
- # define CHECKDIMS(dims,rank) \\
- # for (int i=0;i<(rank);i++)\\
- # if (dims[i]<0) {\\
- # fprintf(stderr,\"Unspecified array argument requires a complete dimension specification.\\n\");\\
- # goto capi_fail;\\
- # }
- # """
- cppmacros[
- 'ARRSIZE'] = '#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))'
- cppmacros['OLDPYNUM'] = """\
- #ifdef OLDPYNUM
- #error You need to install NumPy version 0.13 or higher. See https://scipy.org/install.html
- #endif
- """
- cppmacros["F2PY_THREAD_LOCAL_DECL"] = """\
- #ifndef F2PY_THREAD_LOCAL_DECL
- #if defined(_MSC_VER)
- #define F2PY_THREAD_LOCAL_DECL __declspec(thread)
- #elif defined(NPY_OS_MINGW)
- #define F2PY_THREAD_LOCAL_DECL __thread
- #elif defined(__STDC_VERSION__) \\
- && (__STDC_VERSION__ >= 201112L) \\
- && !defined(__STDC_NO_THREADS__) \\
- && (!defined(__GLIBC__) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12)) \\
- && !defined(NPY_OS_OPENBSD) && !defined(NPY_OS_HAIKU)
- /* __STDC_NO_THREADS__ was first defined in a maintenance release of glibc 2.12,
- see https://lists.gnu.org/archive/html/commit-hurd/2012-07/msg00180.html,
- so `!defined(__STDC_NO_THREADS__)` may give false positive for the existence
- of `threads.h` when using an older release of glibc 2.12
- See gh-19437 for details on OpenBSD */
- #include <threads.h>
- #define F2PY_THREAD_LOCAL_DECL thread_local
- #elif defined(__GNUC__) \\
- && (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 4)))
- #define F2PY_THREAD_LOCAL_DECL __thread
- #endif
- #endif
- """
- ################# C functions ###############
- cfuncs['calcarrindex'] = """\
- static int calcarrindex(int *i,PyArrayObject *arr) {
- int k,ii = i[0];
- for (k=1; k < PyArray_NDIM(arr); k++)
- ii += (ii*(PyArray_DIM(arr,k) - 1)+i[k]); /* assuming contiguous arr */
- return ii;
- }"""
- cfuncs['calcarrindextr'] = """\
- static int calcarrindextr(int *i,PyArrayObject *arr) {
- int k,ii = i[PyArray_NDIM(arr)-1];
- for (k=1; k < PyArray_NDIM(arr); k++)
- ii += (ii*(PyArray_DIM(arr,PyArray_NDIM(arr)-k-1) - 1)+i[PyArray_NDIM(arr)-k-1]); /* assuming contiguous arr */
- return ii;
- }"""
- cfuncs['forcomb'] = """\
- static struct { int nd;npy_intp *d;int *i,*i_tr,tr; } forcombcache;
- static int initforcomb(npy_intp *dims,int nd,int tr) {
- int k;
- if (dims==NULL) return 0;
- if (nd<0) return 0;
- forcombcache.nd = nd;
- forcombcache.d = dims;
- forcombcache.tr = tr;
- if ((forcombcache.i = (int *)malloc(sizeof(int)*nd))==NULL) return 0;
- if ((forcombcache.i_tr = (int *)malloc(sizeof(int)*nd))==NULL) return 0;
- for (k=1;k<nd;k++) {
- forcombcache.i[k] = forcombcache.i_tr[nd-k-1] = 0;
- }
- forcombcache.i[0] = forcombcache.i_tr[nd-1] = -1;
- return 1;
- }
- static int *nextforcomb(void) {
- int j,*i,*i_tr,k;
- int nd=forcombcache.nd;
- if ((i=forcombcache.i) == NULL) return NULL;
- if ((i_tr=forcombcache.i_tr) == NULL) return NULL;
- if (forcombcache.d == NULL) return NULL;
- i[0]++;
- if (i[0]==forcombcache.d[0]) {
- j=1;
- while ((j<nd) && (i[j]==forcombcache.d[j]-1)) j++;
- if (j==nd) {
- free(i);
- free(i_tr);
- return NULL;
- }
- for (k=0;k<j;k++) i[k] = i_tr[nd-k-1] = 0;
- i[j]++;
- i_tr[nd-j-1]++;
- } else
- i_tr[nd-1]++;
- if (forcombcache.tr) return i_tr;
- return i;
- }"""
- needs['try_pyarr_from_string'] = ['STRINGCOPYN', 'PRINTPYOBJERR', 'string']
- cfuncs['try_pyarr_from_string'] = """\
- /*
- try_pyarr_from_string copies str[:len(obj)] to the data of an `ndarray`.
- If obj is an `ndarray`, it is assumed to be contiguous.
- If the specified len==-1, str must be null-terminated.
- */
- static int try_pyarr_from_string(PyObject *obj,
- const string str, const int len) {
- #ifdef DEBUGCFUNCS
- fprintf(stderr, "try_pyarr_from_string(str='%s', len=%d, obj=%p)\\n",
- (char*)str,len, obj);
- #endif
- if (PyArray_Check(obj)) {
- PyArrayObject *arr = (PyArrayObject *)obj;
- assert(ISCONTIGUOUS(arr));
- string buf = PyArray_DATA(arr);
- npy_intp n = len;
- if (n == -1) {
- /* Assuming null-terminated str. */
- n = strlen(str);
- }
- if (n > PyArray_NBYTES(arr)) {
- n = PyArray_NBYTES(arr);
- }
- STRINGCOPYN(buf, str, n);
- return 1;
- }
- capi_fail:
- PRINTPYOBJERR(obj);
- PyErr_SetString(#modulename#_error, \"try_pyarr_from_string failed\");
- return 0;
- }
- """
- needs['string_from_pyobj'] = ['string', 'STRINGMALLOC', 'STRINGCOPYN']
- cfuncs['string_from_pyobj'] = """\
- /*
- Create a new string buffer `str` of at most length `len` from a
- Python string-like object `obj`.
- The string buffer has given size (len) or the size of inistr when len==-1.
- The string buffer is padded with blanks: in Fortran, trailing blanks
- are insignificant contrary to C nulls.
- */
- static int
- string_from_pyobj(string *str, int *len, const string inistr, PyObject *obj,
- const char *errmess)
- {
- PyObject *tmp = NULL;
- string buf = NULL;
- npy_intp n = -1;
- #ifdef DEBUGCFUNCS
- fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",
- (char*)str, *len, (char *)inistr, obj);
- #endif
- if (obj == Py_None) {
- n = strlen(inistr);
- buf = inistr;
- }
- else if (PyArray_Check(obj)) {
- PyArrayObject *arr = (PyArrayObject *)obj;
- if (!ISCONTIGUOUS(arr)) {
- PyErr_SetString(PyExc_ValueError,
- \"array object is non-contiguous.\");
- goto capi_fail;
- }
- n = PyArray_NBYTES(arr);
- buf = PyArray_DATA(arr);
- n = strnlen(buf, n);
- }
- else {
- if (PyBytes_Check(obj)) {
- tmp = obj;
- Py_INCREF(tmp);
- }
- else if (PyUnicode_Check(obj)) {
- tmp = PyUnicode_AsASCIIString(obj);
- }
- else {
- PyObject *tmp2;
- tmp2 = PyObject_Str(obj);
- if (tmp2) {
- tmp = PyUnicode_AsASCIIString(tmp2);
- Py_DECREF(tmp2);
- }
- else {
- tmp = NULL;
- }
- }
- if (tmp == NULL) goto capi_fail;
- n = PyBytes_GET_SIZE(tmp);
- buf = PyBytes_AS_STRING(tmp);
- }
- if (*len == -1) {
- /* TODO: change the type of `len` so that we can remove this */
- if (n > NPY_MAX_INT) {
- PyErr_SetString(PyExc_OverflowError,
- "object too large for a 32-bit int");
- goto capi_fail;
- }
- *len = n;
- }
- else if (*len < n) {
- /* discard the last (len-n) bytes of input buf */
- n = *len;
- }
- if (n < 0 || *len < 0 || buf == NULL) {
- goto capi_fail;
- }
- STRINGMALLOC(*str, *len); // *str is allocated with size (*len + 1)
- if (n < *len) {
- /*
- Pad fixed-width string with nulls. The caller will replace
- nulls with blanks when the corresponding argument is not
- intent(c).
- */
- memset(*str + n, '\\0', *len - n);
- }
- STRINGCOPYN(*str, buf, n);
- Py_XDECREF(tmp);
- return 1;
- capi_fail:
- Py_XDECREF(tmp);
- {
- PyObject* err = PyErr_Occurred();
- if (err == NULL) {
- err = #modulename#_error;
- }
- PyErr_SetString(err, errmess);
- }
- return 0;
- }
- """
- cfuncs['character_from_pyobj'] = """\
- static int
- character_from_pyobj(character* v, PyObject *obj, const char *errmess) {
- if (PyBytes_Check(obj)) {
- /* empty bytes has trailing null, so dereferencing is always safe */
- *v = PyBytes_AS_STRING(obj)[0];
- return 1;
- } else if (PyUnicode_Check(obj)) {
- PyObject* tmp = PyUnicode_AsASCIIString(obj);
- if (tmp != NULL) {
- *v = PyBytes_AS_STRING(tmp)[0];
- Py_DECREF(tmp);
- return 1;
- }
- } else if (PyArray_Check(obj)) {
- PyArrayObject* arr = (PyArrayObject*)obj;
- if (F2PY_ARRAY_IS_CHARACTER_COMPATIBLE(arr)) {
- *v = PyArray_BYTES(arr)[0];
- return 1;
- } else if (F2PY_IS_UNICODE_ARRAY(arr)) {
- // TODO: update when numpy will support 1-byte and
- // 2-byte unicode dtypes
- PyObject* tmp = PyUnicode_FromKindAndData(
- PyUnicode_4BYTE_KIND,
- PyArray_BYTES(arr),
- (PyArray_NBYTES(arr)>0?1:0));
- if (tmp != NULL) {
- if (character_from_pyobj(v, tmp, errmess)) {
- Py_DECREF(tmp);
- return 1;
- }
- Py_DECREF(tmp);
- }
- }
- } else if (PySequence_Check(obj)) {
- PyObject* tmp = PySequence_GetItem(obj,0);
- if (tmp != NULL) {
- if (character_from_pyobj(v, tmp, errmess)) {
- Py_DECREF(tmp);
- return 1;
- }
- Py_DECREF(tmp);
- }
- }
- {
- /* TODO: This error (and most other) error handling needs cleaning. */
- char mess[F2PY_MESSAGE_BUFFER_SIZE];
- strcpy(mess, errmess);
- PyObject* err = PyErr_Occurred();
- if (err == NULL) {
- err = PyExc_TypeError;
- Py_INCREF(err);
- }
- else {
- Py_INCREF(err);
- PyErr_Clear();
- }
- sprintf(mess + strlen(mess),
- " -- expected str|bytes|sequence-of-str-or-bytes, got ");
- f2py_describe(obj, mess + strlen(mess));
- PyErr_SetString(err, mess);
- Py_DECREF(err);
- }
- return 0;
- }
- """
- needs['char_from_pyobj'] = ['int_from_pyobj']
- cfuncs['char_from_pyobj'] = """\
- static int
- char_from_pyobj(char* v, PyObject *obj, const char *errmess) {
- int i = 0;
- if (int_from_pyobj(&i, obj, errmess)) {
- *v = (char)i;
- return 1;
- }
- return 0;
- }
- """
- needs['signed_char_from_pyobj'] = ['int_from_pyobj', 'signed_char']
- cfuncs['signed_char_from_pyobj'] = """\
- static int
- signed_char_from_pyobj(signed_char* v, PyObject *obj, const char *errmess) {
- int i = 0;
- if (int_from_pyobj(&i, obj, errmess)) {
- *v = (signed_char)i;
- return 1;
- }
- return 0;
- }
- """
- needs['short_from_pyobj'] = ['int_from_pyobj']
- cfuncs['short_from_pyobj'] = """\
- static int
- short_from_pyobj(short* v, PyObject *obj, const char *errmess) {
- int i = 0;
- if (int_from_pyobj(&i, obj, errmess)) {
- *v = (short)i;
- return 1;
- }
- return 0;
- }
- """
- cfuncs['int_from_pyobj'] = """\
- static int
- int_from_pyobj(int* v, PyObject *obj, const char *errmess)
- {
- PyObject* tmp = NULL;
- if (PyLong_Check(obj)) {
- *v = Npy__PyLong_AsInt(obj);
- return !(*v == -1 && PyErr_Occurred());
- }
- tmp = PyNumber_Long(obj);
- if (tmp) {
- *v = Npy__PyLong_AsInt(tmp);
- Py_DECREF(tmp);
- return !(*v == -1 && PyErr_Occurred());
- }
- if (PyComplex_Check(obj)) {
- PyErr_Clear();
- tmp = PyObject_GetAttrString(obj,\"real\");
- }
- else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
- /*pass*/;
- }
- else if (PySequence_Check(obj)) {
- PyErr_Clear();
- tmp = PySequence_GetItem(obj, 0);
- }
- if (tmp) {
- if (int_from_pyobj(v, tmp, errmess)) {
- Py_DECREF(tmp);
- return 1;
- }
- Py_DECREF(tmp);
- }
- {
- PyObject* err = PyErr_Occurred();
- if (err == NULL) {
- err = #modulename#_error;
- }
- PyErr_SetString(err, errmess);
- }
- return 0;
- }
- """
- cfuncs['long_from_pyobj'] = """\
- static int
- long_from_pyobj(long* v, PyObject *obj, const char *errmess) {
- PyObject* tmp = NULL;
- if (PyLong_Check(obj)) {
- *v = PyLong_AsLong(obj);
- return !(*v == -1 && PyErr_Occurred());
- }
- tmp = PyNumber_Long(obj);
- if (tmp) {
- *v = PyLong_AsLong(tmp);
- Py_DECREF(tmp);
- return !(*v == -1 && PyErr_Occurred());
- }
- if (PyComplex_Check(obj)) {
- PyErr_Clear();
- tmp = PyObject_GetAttrString(obj,\"real\");
- }
- else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
- /*pass*/;
- }
- else if (PySequence_Check(obj)) {
- PyErr_Clear();
- tmp = PySequence_GetItem(obj, 0);
- }
- if (tmp) {
- if (long_from_pyobj(v, tmp, errmess)) {
- Py_DECREF(tmp);
- return 1;
- }
- Py_DECREF(tmp);
- }
- {
- PyObject* err = PyErr_Occurred();
- if (err == NULL) {
- err = #modulename#_error;
- }
- PyErr_SetString(err, errmess);
- }
- return 0;
- }
- """
- needs['long_long_from_pyobj'] = ['long_long']
- cfuncs['long_long_from_pyobj'] = """\
- static int
- long_long_from_pyobj(long_long* v, PyObject *obj, const char *errmess)
- {
- PyObject* tmp = NULL;
- if (PyLong_Check(obj)) {
- *v = PyLong_AsLongLong(obj);
- return !(*v == -1 && PyErr_Occurred());
- }
- tmp = PyNumber_Long(obj);
- if (tmp) {
- *v = PyLong_AsLongLong(tmp);
- Py_DECREF(tmp);
- return !(*v == -1 && PyErr_Occurred());
- }
- if (PyComplex_Check(obj)) {
- PyErr_Clear();
- tmp = PyObject_GetAttrString(obj,\"real\");
- }
- else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
- /*pass*/;
- }
- else if (PySequence_Check(obj)) {
- PyErr_Clear();
- tmp = PySequence_GetItem(obj, 0);
- }
- if (tmp) {
- if (long_long_from_pyobj(v, tmp, errmess)) {
- Py_DECREF(tmp);
- return 1;
- }
- Py_DECREF(tmp);
- }
- {
- PyObject* err = PyErr_Occurred();
- if (err == NULL) {
- err = #modulename#_error;
- }
- PyErr_SetString(err,errmess);
- }
- return 0;
- }
- """
- needs['long_double_from_pyobj'] = ['double_from_pyobj', 'long_double']
- cfuncs['long_double_from_pyobj'] = """\
- static int
- long_double_from_pyobj(long_double* v, PyObject *obj, const char *errmess)
- {
- double d=0;
- if (PyArray_CheckScalar(obj)){
- if PyArray_IsScalar(obj, LongDouble) {
- PyArray_ScalarAsCtype(obj, v);
- return 1;
- }
- else if (PyArray_Check(obj) && PyArray_TYPE(obj) == NPY_LONGDOUBLE) {
- (*v) = *((npy_longdouble *)PyArray_DATA(obj));
- return 1;
- }
- }
- if (double_from_pyobj(&d, obj, errmess)) {
- *v = (long_double)d;
- return 1;
- }
- return 0;
- }
- """
- cfuncs['double_from_pyobj'] = """\
- static int
- double_from_pyobj(double* v, PyObject *obj, const char *errmess)
- {
- PyObject* tmp = NULL;
- if (PyFloat_Check(obj)) {
- *v = PyFloat_AsDouble(obj);
- return !(*v == -1.0 && PyErr_Occurred());
- }
- tmp = PyNumber_Float(obj);
- if (tmp) {
- *v = PyFloat_AsDouble(tmp);
- Py_DECREF(tmp);
- return !(*v == -1.0 && PyErr_Occurred());
- }
- if (PyComplex_Check(obj)) {
- PyErr_Clear();
- tmp = PyObject_GetAttrString(obj,\"real\");
- }
- else if (PyBytes_Check(obj) || PyUnicode_Check(obj)) {
- /*pass*/;
- }
- else if (PySequence_Check(obj)) {
- PyErr_Clear();
- tmp = PySequence_GetItem(obj, 0);
- }
- if (tmp) {
- if (double_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
- Py_DECREF(tmp);
- }
- {
- PyObject* err = PyErr_Occurred();
- if (err==NULL) err = #modulename#_error;
- PyErr_SetString(err,errmess);
- }
- return 0;
- }
- """
- needs['float_from_pyobj'] = ['double_from_pyobj']
- cfuncs['float_from_pyobj'] = """\
- static int
- float_from_pyobj(float* v, PyObject *obj, const char *errmess)
- {
- double d=0.0;
- if (double_from_pyobj(&d,obj,errmess)) {
- *v = (float)d;
- return 1;
- }
- return 0;
- }
- """
- needs['complex_long_double_from_pyobj'] = ['complex_long_double', 'long_double',
- 'complex_double_from_pyobj', 'npy_math.h']
- cfuncs['complex_long_double_from_pyobj'] = """\
- static int
- complex_long_double_from_pyobj(complex_long_double* v, PyObject *obj, const char *errmess)
- {
- complex_double cd = {0.0,0.0};
- if (PyArray_CheckScalar(obj)){
- if PyArray_IsScalar(obj, CLongDouble) {
- PyArray_ScalarAsCtype(obj, v);
- return 1;
- }
- else if (PyArray_Check(obj) && PyArray_TYPE(obj)==NPY_CLONGDOUBLE) {
- (*v).r = npy_creall(*(((npy_clongdouble *)PyArray_DATA(obj))));
- (*v).i = npy_cimagl(*(((npy_clongdouble *)PyArray_DATA(obj))));
- return 1;
- }
- }
- if (complex_double_from_pyobj(&cd,obj,errmess)) {
- (*v).r = (long_double)cd.r;
- (*v).i = (long_double)cd.i;
- return 1;
- }
- return 0;
- }
- """
- needs['complex_double_from_pyobj'] = ['complex_double', 'npy_math.h']
- cfuncs['complex_double_from_pyobj'] = """\
- static int
- complex_double_from_pyobj(complex_double* v, PyObject *obj, const char *errmess) {
- Py_complex c;
- if (PyComplex_Check(obj)) {
- c = PyComplex_AsCComplex(obj);
- (*v).r = c.real;
- (*v).i = c.imag;
- return 1;
- }
- if (PyArray_IsScalar(obj, ComplexFloating)) {
- if (PyArray_IsScalar(obj, CFloat)) {
- npy_cfloat new;
- PyArray_ScalarAsCtype(obj, &new);
- (*v).r = (double)npy_crealf(new);
- (*v).i = (double)npy_cimagf(new);
- }
- else if (PyArray_IsScalar(obj, CLongDouble)) {
- npy_clongdouble new;
- PyArray_ScalarAsCtype(obj, &new);
- (*v).r = (double)npy_creall(new);
- (*v).i = (double)npy_cimagl(new);
- }
- else { /* if (PyArray_IsScalar(obj, CDouble)) */
- PyArray_ScalarAsCtype(obj, v);
- }
- return 1;
- }
- if (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */
- PyArrayObject *arr;
- if (PyArray_Check(obj)) {
- arr = (PyArrayObject *)PyArray_Cast((PyArrayObject *)obj, NPY_CDOUBLE);
- }
- else {
- arr = (PyArrayObject *)PyArray_FromScalar(obj, PyArray_DescrFromType(NPY_CDOUBLE));
- }
- if (arr == NULL) {
- return 0;
- }
- (*v).r = npy_creal(*(((npy_cdouble *)PyArray_DATA(arr))));
- (*v).i = npy_cimag(*(((npy_cdouble *)PyArray_DATA(arr))));
- Py_DECREF(arr);
- return 1;
- }
- /* Python does not provide PyNumber_Complex function :-( */
- (*v).i = 0.0;
- if (PyFloat_Check(obj)) {
- (*v).r = PyFloat_AsDouble(obj);
- return !((*v).r == -1.0 && PyErr_Occurred());
- }
- if (PyLong_Check(obj)) {
- (*v).r = PyLong_AsDouble(obj);
- return !((*v).r == -1.0 && PyErr_Occurred());
- }
- if (PySequence_Check(obj) && !(PyBytes_Check(obj) || PyUnicode_Check(obj))) {
- PyObject *tmp = PySequence_GetItem(obj,0);
- if (tmp) {
- if (complex_double_from_pyobj(v,tmp,errmess)) {
- Py_DECREF(tmp);
- return 1;
- }
- Py_DECREF(tmp);
- }
- }
- {
- PyObject* err = PyErr_Occurred();
- if (err==NULL)
- err = PyExc_TypeError;
- PyErr_SetString(err,errmess);
- }
- return 0;
- }
- """
- needs['complex_float_from_pyobj'] = [
- 'complex_float', 'complex_double_from_pyobj']
- cfuncs['complex_float_from_pyobj'] = """\
- static int
- complex_float_from_pyobj(complex_float* v,PyObject *obj,const char *errmess)
- {
- complex_double cd={0.0,0.0};
- if (complex_double_from_pyobj(&cd,obj,errmess)) {
- (*v).r = (float)cd.r;
- (*v).i = (float)cd.i;
- return 1;
- }
- return 0;
- }
- """
- cfuncs['try_pyarr_from_character'] = """\
- static int try_pyarr_from_character(PyObject* obj, character* v) {
- PyArrayObject *arr = (PyArrayObject*)obj;
- if (!obj) return -2;
- if (PyArray_Check(obj)) {
- if (F2PY_ARRAY_IS_CHARACTER_COMPATIBLE(arr)) {
- *(character *)(PyArray_DATA(arr)) = *v;
- return 1;
- }
- }
- {
- char mess[F2PY_MESSAGE_BUFFER_SIZE];
- PyObject* err = PyErr_Occurred();
- if (err == NULL) {
- err = PyExc_ValueError;
- strcpy(mess, "try_pyarr_from_character failed"
- " -- expected bytes array-scalar|array, got ");
- f2py_describe(obj, mess + strlen(mess));
- PyErr_SetString(err, mess);
- }
- }
- return 0;
- }
- """
- needs['try_pyarr_from_char'] = ['pyobj_from_char1', 'TRYPYARRAYTEMPLATE']
- cfuncs[
- 'try_pyarr_from_char'] = 'static int try_pyarr_from_char(PyObject* obj,char* v) {\n TRYPYARRAYTEMPLATE(char,\'c\');\n}\n'
- needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'unsigned_char']
- cfuncs[
- 'try_pyarr_from_unsigned_char'] = 'static int try_pyarr_from_unsigned_char(PyObject* obj,unsigned_char* v) {\n TRYPYARRAYTEMPLATE(unsigned_char,\'b\');\n}\n'
- needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'signed_char']
- cfuncs[
- 'try_pyarr_from_signed_char'] = 'static int try_pyarr_from_signed_char(PyObject* obj,signed_char* v) {\n TRYPYARRAYTEMPLATE(signed_char,\'1\');\n}\n'
- needs['try_pyarr_from_short'] = ['pyobj_from_short1', 'TRYPYARRAYTEMPLATE']
- cfuncs[
- 'try_pyarr_from_short'] = 'static int try_pyarr_from_short(PyObject* obj,short* v) {\n TRYPYARRAYTEMPLATE(short,\'s\');\n}\n'
- needs['try_pyarr_from_int'] = ['pyobj_from_int1', 'TRYPYARRAYTEMPLATE']
- cfuncs[
- 'try_pyarr_from_int'] = 'static int try_pyarr_from_int(PyObject* obj,int* v) {\n TRYPYARRAYTEMPLATE(int,\'i\');\n}\n'
- needs['try_pyarr_from_long'] = ['pyobj_from_long1', 'TRYPYARRAYTEMPLATE']
- cfuncs[
- 'try_pyarr_from_long'] = 'static int try_pyarr_from_long(PyObject* obj,long* v) {\n TRYPYARRAYTEMPLATE(long,\'l\');\n}\n'
- needs['try_pyarr_from_long_long'] = [
- 'pyobj_from_long_long1', 'TRYPYARRAYTEMPLATE', 'long_long']
- cfuncs[
- 'try_pyarr_from_long_long'] = 'static int try_pyarr_from_long_long(PyObject* obj,long_long* v) {\n TRYPYARRAYTEMPLATE(long_long,\'L\');\n}\n'
- needs['try_pyarr_from_float'] = ['pyobj_from_float1', 'TRYPYARRAYTEMPLATE']
- cfuncs[
- 'try_pyarr_from_float'] = 'static int try_pyarr_from_float(PyObject* obj,float* v) {\n TRYPYARRAYTEMPLATE(float,\'f\');\n}\n'
- needs['try_pyarr_from_double'] = ['pyobj_from_double1', 'TRYPYARRAYTEMPLATE']
- cfuncs[
- 'try_pyarr_from_double'] = 'static int try_pyarr_from_double(PyObject* obj,double* v) {\n TRYPYARRAYTEMPLATE(double,\'d\');\n}\n'
- needs['try_pyarr_from_complex_float'] = [
- 'pyobj_from_complex_float1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_float']
- cfuncs[
- 'try_pyarr_from_complex_float'] = 'static int try_pyarr_from_complex_float(PyObject* obj,complex_float* v) {\n TRYCOMPLEXPYARRAYTEMPLATE(float,\'F\');\n}\n'
- needs['try_pyarr_from_complex_double'] = [
- 'pyobj_from_complex_double1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_double']
- cfuncs[
- 'try_pyarr_from_complex_double'] = 'static int try_pyarr_from_complex_double(PyObject* obj,complex_double* v) {\n TRYCOMPLEXPYARRAYTEMPLATE(double,\'D\');\n}\n'
- needs['create_cb_arglist'] = ['CFUNCSMESS', 'PRINTPYOBJERR', 'MINMAX']
- # create the list of arguments to be used when calling back to python
- cfuncs['create_cb_arglist'] = """\
- static int
- create_cb_arglist(PyObject* fun, PyTupleObject* xa , const int maxnofargs,
- const int nofoptargs, int *nofargs, PyTupleObject **args,
- const char *errmess)
- {
- PyObject *tmp = NULL;
- PyObject *tmp_fun = NULL;
- Py_ssize_t tot, opt, ext, siz, i, di = 0;
- CFUNCSMESS(\"create_cb_arglist\\n\");
- tot=opt=ext=siz=0;
- /* Get the total number of arguments */
- if (PyFunction_Check(fun)) {
- tmp_fun = fun;
- Py_INCREF(tmp_fun);
- }
- else {
- di = 1;
- if (PyObject_HasAttrString(fun,\"im_func\")) {
- tmp_fun = PyObject_GetAttrString(fun,\"im_func\");
- }
- else if (PyObject_HasAttrString(fun,\"__call__\")) {
- tmp = PyObject_GetAttrString(fun,\"__call__\");
- if (PyObject_HasAttrString(tmp,\"im_func\"))
- tmp_fun = PyObject_GetAttrString(tmp,\"im_func\");
- else {
- tmp_fun = fun; /* built-in function */
- Py_INCREF(tmp_fun);
- tot = maxnofargs;
- if (PyCFunction_Check(fun)) {
- /* In case the function has a co_argcount (like on PyPy) */
- di = 0;
- }
- if (xa != NULL)
- tot += PyTuple_Size((PyObject *)xa);
- }
- Py_XDECREF(tmp);
- }
- else if (PyFortran_Check(fun) || PyFortran_Check1(fun)) {
- tot = maxnofargs;
- if (xa != NULL)
- tot += PyTuple_Size((PyObject *)xa);
- tmp_fun = fun;
- Py_INCREF(tmp_fun);
- }
- else if (F2PyCapsule_Check(fun)) {
- tot = maxnofargs;
- if (xa != NULL)
- ext = PyTuple_Size((PyObject *)xa);
- if(ext>0) {
- fprintf(stderr,\"extra arguments tuple cannot be used with PyCapsule call-back\\n\");
- goto capi_fail;
- }
- tmp_fun = fun;
- Py_INCREF(tmp_fun);
- }
- }
- if (tmp_fun == NULL) {
- fprintf(stderr,
- \"Call-back argument must be function|instance|instance.__call__|f2py-function \"
- \"but got %s.\\n\",
- ((fun == NULL) ? \"NULL\" : Py_TYPE(fun)->tp_name));
- goto capi_fail;
- }
- if (PyObject_HasAttrString(tmp_fun,\"__code__\")) {
- if (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"__code__\"),\"co_argcount\")) {
- PyObject *tmp_argcount = PyObject_GetAttrString(tmp,\"co_argcount\");
- Py_DECREF(tmp);
- if (tmp_argcount == NULL) {
- goto capi_fail;
- }
- tot = PyLong_AsSsize_t(tmp_argcount) - di;
- Py_DECREF(tmp_argcount);
- }
- }
- /* Get the number of optional arguments */
- if (PyObject_HasAttrString(tmp_fun,\"__defaults__\")) {
- if (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"__defaults__\")))
- opt = PyTuple_Size(tmp);
- Py_XDECREF(tmp);
- }
- /* Get the number of extra arguments */
- if (xa != NULL)
- ext = PyTuple_Size((PyObject *)xa);
- /* Calculate the size of call-backs argument list */
- siz = MIN(maxnofargs+ext,tot);
- *nofargs = MAX(0,siz-ext);
- #ifdef DEBUGCFUNCS
- fprintf(stderr,
- \"debug-capi:create_cb_arglist:maxnofargs(-nofoptargs),\"
- \"tot,opt,ext,siz,nofargs = %d(-%d), %zd, %zd, %zd, %zd, %d\\n\",
- maxnofargs, nofoptargs, tot, opt, ext, siz, *nofargs);
- #endif
- if (siz < tot-opt) {
- fprintf(stderr,
- \"create_cb_arglist: Failed to build argument list \"
- \"(siz) with enough arguments (tot-opt) required by \"
- \"user-supplied function (siz,tot,opt=%zd, %zd, %zd).\\n\",
- siz, tot, opt);
- goto capi_fail;
- }
- /* Initialize argument list */
- *args = (PyTupleObject *)PyTuple_New(siz);
- for (i=0;i<*nofargs;i++) {
- Py_INCREF(Py_None);
- PyTuple_SET_ITEM((PyObject *)(*args),i,Py_None);
- }
- if (xa != NULL)
- for (i=(*nofargs);i<siz;i++) {
- tmp = PyTuple_GetItem((PyObject *)xa,i-(*nofargs));
- Py_INCREF(tmp);
- PyTuple_SET_ITEM(*args,i,tmp);
- }
- CFUNCSMESS(\"create_cb_arglist-end\\n\");
- Py_DECREF(tmp_fun);
- return 1;
- capi_fail:
- if (PyErr_Occurred() == NULL)
- PyErr_SetString(#modulename#_error, errmess);
- Py_XDECREF(tmp_fun);
- return 0;
- }
- """
- def buildcfuncs():
- from .capi_maps import c2capi_map
- for k in c2capi_map.keys():
- m = 'pyarr_from_p_%s1' % k
- cppmacros[
- m] = '#define %s(v) (PyArray_SimpleNewFromData(0,NULL,%s,(char *)v))' % (m, c2capi_map[k])
- k = 'string'
- m = 'pyarr_from_p_%s1' % k
- # NPY_CHAR compatibility, NPY_STRING with itemsize 1
- cppmacros[
- m] = '#define %s(v,dims) (PyArray_New(&PyArray_Type, 1, dims, NPY_STRING, NULL, v, 1, NPY_ARRAY_CARRAY, NULL))' % (m)
- ############ Auxiliary functions for sorting needs ###################
- def append_needs(need, flag=1):
- # This function modifies the contents of the global `outneeds` dict.
- if isinstance(need, list):
- for n in need:
- append_needs(n, flag)
- elif isinstance(need, str):
- if not need:
- return
- if need in includes0:
- n = 'includes0'
- elif need in includes:
- n = 'includes'
- elif need in typedefs:
- n = 'typedefs'
- elif need in typedefs_generated:
- n = 'typedefs_generated'
- elif need in cppmacros:
- n = 'cppmacros'
- elif need in cfuncs:
- n = 'cfuncs'
- elif need in callbacks:
- n = 'callbacks'
- elif need in f90modhooks:
- n = 'f90modhooks'
- elif need in commonhooks:
- n = 'commonhooks'
- else:
- errmess('append_needs: unknown need %s\n' % (repr(need)))
- return
- if need in outneeds[n]:
- return
- if flag:
- tmp = {}
- if need in needs:
- for nn in needs[need]:
- t = append_needs(nn, 0)
- if isinstance(t, dict):
- for nnn in t.keys():
- if nnn in tmp:
- tmp[nnn] = tmp[nnn] + t[nnn]
- else:
- tmp[nnn] = t[nnn]
- for nn in tmp.keys():
- for nnn in tmp[nn]:
- if nnn not in outneeds[nn]:
- outneeds[nn] = [nnn] + outneeds[nn]
- outneeds[n].append(need)
- else:
- tmp = {}
- if need in needs:
- for nn in needs[need]:
- t = append_needs(nn, flag)
- if isinstance(t, dict):
- for nnn in t.keys():
- if nnn in tmp:
- tmp[nnn] = t[nnn] + tmp[nnn]
- else:
- tmp[nnn] = t[nnn]
- if n not in tmp:
- tmp[n] = []
- tmp[n].append(need)
- return tmp
- else:
- errmess('append_needs: expected list or string but got :%s\n' %
- (repr(need)))
- def get_needs():
- # This function modifies the contents of the global `outneeds` dict.
- res = {}
- for n in outneeds.keys():
- out = []
- saveout = copy.copy(outneeds[n])
- while len(outneeds[n]) > 0:
- if outneeds[n][0] not in needs:
- out.append(outneeds[n][0])
- del outneeds[n][0]
- else:
- flag = 0
- for k in outneeds[n][1:]:
- if k in needs[outneeds[n][0]]:
- flag = 1
- break
- if flag:
- outneeds[n] = outneeds[n][1:] + [outneeds[n][0]]
- else:
- out.append(outneeds[n][0])
- del outneeds[n][0]
- if saveout and (0 not in map(lambda x, y: x == y, saveout, outneeds[n])) \
- and outneeds[n] != []:
- print(n, saveout)
- errmess(
- 'get_needs: no progress in sorting needs, probably circular dependence, skipping.\n')
- out = out + saveout
- break
- saveout = copy.copy(outneeds[n])
- if out == []:
- out = [n]
- res[n] = out
- return res
|