Chris@87: #!/usr/bin/env python Chris@87: """ Chris@87: Chris@87: C declarations, CPP macros, and C functions for f2py2e. Chris@87: Only required declarations/macros/functions will be used. Chris@87: Chris@87: Copyright 1999,2000 Pearu Peterson all rights reserved, Chris@87: Pearu Peterson Chris@87: Permission to use, modify, and distribute this software is given under the Chris@87: terms of the NumPy License. Chris@87: Chris@87: NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. Chris@87: $Date: 2005/05/06 11:42:34 $ Chris@87: Pearu Peterson Chris@87: Chris@87: """ Chris@87: from __future__ import division, absolute_import, print_function Chris@87: Chris@87: import sys Chris@87: import copy Chris@87: Chris@87: from . import __version__ Chris@87: Chris@87: f2py_version = __version__.version Chris@87: errmess = sys.stderr.write Chris@87: Chris@87: ##################### Definitions ################## Chris@87: Chris@87: outneeds={'includes0':[],'includes':[],'typedefs':[],'typedefs_generated':[], Chris@87: 'userincludes':[], Chris@87: 'cppmacros':[],'cfuncs':[],'callbacks':[],'f90modhooks':[], Chris@87: 'commonhooks':[]} Chris@87: needs={} Chris@87: includes0={'includes0':'/*need_includes0*/'} Chris@87: includes={'includes':'/*need_includes*/'} Chris@87: userincludes={'userincludes':'/*need_userincludes*/'} Chris@87: typedefs={'typedefs':'/*need_typedefs*/'} Chris@87: typedefs_generated={'typedefs_generated':'/*need_typedefs_generated*/'} Chris@87: cppmacros={'cppmacros':'/*need_cppmacros*/'} Chris@87: cfuncs={'cfuncs':'/*need_cfuncs*/'} Chris@87: callbacks={'callbacks':'/*need_callbacks*/'} Chris@87: f90modhooks={'f90modhooks': '/*need_f90modhooks*/', Chris@87: 'initf90modhooksstatic': '/*initf90modhooksstatic*/', Chris@87: 'initf90modhooksdynamic': '/*initf90modhooksdynamic*/', Chris@87: } Chris@87: commonhooks={'commonhooks': '/*need_commonhooks*/', Chris@87: 'initcommonhooks': '/*need_initcommonhooks*/', Chris@87: } Chris@87: Chris@87: ############ Includes ################### Chris@87: Chris@87: includes0['math.h']='#include ' Chris@87: includes0['string.h']='#include ' Chris@87: includes0['setjmp.h']='#include ' Chris@87: Chris@87: includes['Python.h']='#include "Python.h"' Chris@87: needs['arrayobject.h']=['Python.h'] Chris@87: includes['arrayobject.h']='''#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API Chris@87: #include "arrayobject.h"''' Chris@87: Chris@87: includes['arrayobject.h']='#include "fortranobject.h"' Chris@87: includes['stdarg.h']='#include ' Chris@87: Chris@87: ############# Type definitions ############### Chris@87: Chris@87: typedefs['unsigned_char']='typedef unsigned char unsigned_char;' Chris@87: typedefs['unsigned_short']='typedef unsigned short unsigned_short;' Chris@87: typedefs['unsigned_long']='typedef unsigned long unsigned_long;' Chris@87: typedefs['signed_char']='typedef signed char signed_char;' Chris@87: typedefs['long_long']="""\ Chris@87: #ifdef _WIN32 Chris@87: typedef __int64 long_long; Chris@87: #else Chris@87: typedef long long long_long; Chris@87: typedef unsigned long long unsigned_long_long; Chris@87: #endif Chris@87: """ Chris@87: typedefs['unsigned_long_long']="""\ Chris@87: #ifdef _WIN32 Chris@87: typedef __uint64 long_long; Chris@87: #else Chris@87: typedef unsigned long long unsigned_long_long; Chris@87: #endif Chris@87: """ Chris@87: typedefs['long_double']="""\ Chris@87: #ifndef _LONG_DOUBLE Chris@87: typedef long double long_double; Chris@87: #endif Chris@87: """ Chris@87: typedefs['complex_long_double']='typedef struct {long double r,i;} complex_long_double;' Chris@87: typedefs['complex_float']='typedef struct {float r,i;} complex_float;' Chris@87: typedefs['complex_double']='typedef struct {double r,i;} complex_double;' Chris@87: typedefs['string']="""typedef char * string;""" Chris@87: Chris@87: Chris@87: ############### CPP macros #################### Chris@87: cppmacros['CFUNCSMESS']="""\ Chris@87: #ifdef DEBUGCFUNCS Chris@87: #define CFUNCSMESS(mess) fprintf(stderr,\"debug-capi:\"mess); Chris@87: #define CFUNCSMESSPY(mess,obj) CFUNCSMESS(mess) \\ Chris@87: \tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\ Chris@87: \tfprintf(stderr,\"\\n\"); Chris@87: #else Chris@87: #define CFUNCSMESS(mess) Chris@87: #define CFUNCSMESSPY(mess,obj) Chris@87: #endif Chris@87: """ Chris@87: cppmacros['F_FUNC']="""\ Chris@87: #if defined(PREPEND_FORTRAN) Chris@87: #if defined(NO_APPEND_FORTRAN) Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_FUNC(f,F) _##F Chris@87: #else Chris@87: #define F_FUNC(f,F) _##f Chris@87: #endif Chris@87: #else Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_FUNC(f,F) _##F##_ Chris@87: #else Chris@87: #define F_FUNC(f,F) _##f##_ Chris@87: #endif Chris@87: #endif Chris@87: #else Chris@87: #if defined(NO_APPEND_FORTRAN) Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_FUNC(f,F) F Chris@87: #else Chris@87: #define F_FUNC(f,F) f Chris@87: #endif Chris@87: #else Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_FUNC(f,F) F##_ Chris@87: #else Chris@87: #define F_FUNC(f,F) f##_ Chris@87: #endif Chris@87: #endif Chris@87: #endif Chris@87: #if defined(UNDERSCORE_G77) Chris@87: #define F_FUNC_US(f,F) F_FUNC(f##_,F##_) Chris@87: #else Chris@87: #define F_FUNC_US(f,F) F_FUNC(f,F) Chris@87: #endif Chris@87: """ Chris@87: cppmacros['F_WRAPPEDFUNC']="""\ Chris@87: #if defined(PREPEND_FORTRAN) Chris@87: #if defined(NO_APPEND_FORTRAN) Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F Chris@87: #else Chris@87: #define F_WRAPPEDFUNC(f,F) _f2pywrap##f Chris@87: #endif Chris@87: #else Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F##_ Chris@87: #else Chris@87: #define F_WRAPPEDFUNC(f,F) _f2pywrap##f##_ Chris@87: #endif Chris@87: #endif Chris@87: #else Chris@87: #if defined(NO_APPEND_FORTRAN) Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_WRAPPEDFUNC(f,F) F2PYWRAP##F Chris@87: #else Chris@87: #define F_WRAPPEDFUNC(f,F) f2pywrap##f Chris@87: #endif Chris@87: #else Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_WRAPPEDFUNC(f,F) F2PYWRAP##F##_ Chris@87: #else Chris@87: #define F_WRAPPEDFUNC(f,F) f2pywrap##f##_ Chris@87: #endif Chris@87: #endif Chris@87: #endif Chris@87: #if defined(UNDERSCORE_G77) Chris@87: #define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f##_,F##_) Chris@87: #else Chris@87: #define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f,F) Chris@87: #endif Chris@87: """ Chris@87: cppmacros['F_MODFUNC']="""\ Chris@87: #if defined(F90MOD2CCONV1) /*E.g. Compaq Fortran */ Chris@87: #if defined(NO_APPEND_FORTRAN) Chris@87: #define F_MODFUNCNAME(m,f) $ ## m ## $ ## f Chris@87: #else Chris@87: #define F_MODFUNCNAME(m,f) $ ## m ## $ ## f ## _ Chris@87: #endif Chris@87: #endif Chris@87: Chris@87: #if defined(F90MOD2CCONV2) /*E.g. IBM XL Fortran, not tested though */ Chris@87: #if defined(NO_APPEND_FORTRAN) Chris@87: #define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f Chris@87: #else Chris@87: #define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f ## _ Chris@87: #endif Chris@87: #endif Chris@87: Chris@87: #if defined(F90MOD2CCONV3) /*E.g. MIPSPro Compilers */ Chris@87: #if defined(NO_APPEND_FORTRAN) Chris@87: #define F_MODFUNCNAME(m,f) f ## .in. ## m Chris@87: #else Chris@87: #define F_MODFUNCNAME(m,f) f ## .in. ## m ## _ Chris@87: #endif Chris@87: #endif Chris@87: /* Chris@87: #if defined(UPPERCASE_FORTRAN) Chris@87: #define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(M,F) Chris@87: #else Chris@87: #define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(m,f) Chris@87: #endif Chris@87: */ Chris@87: Chris@87: #define F_MODFUNC(m,f) (*(f2pymodstruct##m##.##f)) Chris@87: """ Chris@87: cppmacros['SWAPUNSAFE']="""\ Chris@87: #define SWAP(a,b) (size_t)(a) = ((size_t)(a) ^ (size_t)(b));\\ Chris@87: (size_t)(b) = ((size_t)(a) ^ (size_t)(b));\\ Chris@87: (size_t)(a) = ((size_t)(a) ^ (size_t)(b)) Chris@87: """ Chris@87: cppmacros['SWAP']="""\ Chris@87: #define SWAP(a,b,t) {\\ Chris@87: \tt *c;\\ Chris@87: \tc = a;\\ Chris@87: \ta = b;\\ Chris@87: \tb = c;} Chris@87: """ Chris@87: #cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) ((m)->flags & NPY_CONTIGUOUS)' Chris@87: cppmacros['PRINTPYOBJERR']="""\ Chris@87: #define PRINTPYOBJERR(obj)\\ Chris@87: \tfprintf(stderr,\"#modulename#.error is related to \");\\ Chris@87: \tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\ Chris@87: \tfprintf(stderr,\"\\n\"); Chris@87: """ Chris@87: cppmacros['MINMAX']="""\ Chris@87: #ifndef max Chris@87: #define max(a,b) ((a > b) ? (a) : (b)) Chris@87: #endif Chris@87: #ifndef min Chris@87: #define min(a,b) ((a < b) ? (a) : (b)) Chris@87: #endif Chris@87: #ifndef MAX Chris@87: #define MAX(a,b) ((a > b) ? (a) : (b)) Chris@87: #endif Chris@87: #ifndef MIN Chris@87: #define MIN(a,b) ((a < b) ? (a) : (b)) Chris@87: #endif Chris@87: """ Chris@87: needs['len..']=['f2py_size'] Chris@87: cppmacros['len..']="""\ Chris@87: #define rank(var) var ## _Rank Chris@87: #define shape(var,dim) var ## _Dims[dim] Chris@87: #define old_rank(var) (((PyArrayObject *)(capi_ ## var ## _tmp))->nd) Chris@87: #define old_shape(var,dim) (((PyArrayObject *)(capi_ ## var ## _tmp))->dimensions[dim]) Chris@87: #define fshape(var,dim) shape(var,rank(var)-dim-1) Chris@87: #define len(var) shape(var,0) Chris@87: #define flen(var) fshape(var,0) Chris@87: #define old_size(var) PyArray_SIZE((PyArrayObject *)(capi_ ## var ## _tmp)) Chris@87: /* #define index(i) capi_i ## i */ Chris@87: #define slen(var) capi_ ## var ## _len Chris@87: #define size(var, ...) f2py_size((PyArrayObject *)(capi_ ## var ## _tmp), ## __VA_ARGS__, -1) Chris@87: """ Chris@87: needs['f2py_size']=['stdarg.h'] Chris@87: cfuncs['f2py_size']="""\ Chris@87: static int f2py_size(PyArrayObject* var, ...) Chris@87: { Chris@87: npy_int sz = 0; Chris@87: npy_int dim; Chris@87: npy_int rank; Chris@87: va_list argp; Chris@87: va_start(argp, var); Chris@87: dim = va_arg(argp, npy_int); Chris@87: if (dim==-1) Chris@87: { Chris@87: sz = PyArray_SIZE(var); Chris@87: } Chris@87: else Chris@87: { Chris@87: rank = PyArray_NDIM(var); Chris@87: if (dim>=1 && dim<=rank) Chris@87: sz = PyArray_DIM(var, dim-1); Chris@87: else Chris@87: fprintf(stderr, \"f2py_size: 2nd argument value=%d fails to satisfy 1<=value<=%d. Result will be 0.\\n\", dim, rank); Chris@87: } Chris@87: va_end(argp); Chris@87: return sz; Chris@87: } Chris@87: """ Chris@87: Chris@87: cppmacros['pyobj_from_char1']='#define pyobj_from_char1(v) (PyInt_FromLong(v))' Chris@87: cppmacros['pyobj_from_short1']='#define pyobj_from_short1(v) (PyInt_FromLong(v))' Chris@87: needs['pyobj_from_int1']=['signed_char'] Chris@87: cppmacros['pyobj_from_int1']='#define pyobj_from_int1(v) (PyInt_FromLong(v))' Chris@87: cppmacros['pyobj_from_long1']='#define pyobj_from_long1(v) (PyLong_FromLong(v))' Chris@87: needs['pyobj_from_long_long1']=['long_long'] Chris@87: cppmacros['pyobj_from_long_long1']="""\ Chris@87: #ifdef HAVE_LONG_LONG Chris@87: #define pyobj_from_long_long1(v) (PyLong_FromLongLong(v)) Chris@87: #else Chris@87: #warning HAVE_LONG_LONG is not available. Redefining pyobj_from_long_long. Chris@87: #define pyobj_from_long_long1(v) (PyLong_FromLong(v)) Chris@87: #endif Chris@87: """ Chris@87: needs['pyobj_from_long_double1']=['long_double'] Chris@87: cppmacros['pyobj_from_long_double1']='#define pyobj_from_long_double1(v) (PyFloat_FromDouble(v))' Chris@87: cppmacros['pyobj_from_double1']='#define pyobj_from_double1(v) (PyFloat_FromDouble(v))' Chris@87: cppmacros['pyobj_from_float1']='#define pyobj_from_float1(v) (PyFloat_FromDouble(v))' Chris@87: needs['pyobj_from_complex_long_double1']=['complex_long_double'] Chris@87: cppmacros['pyobj_from_complex_long_double1']='#define pyobj_from_complex_long_double1(v) (PyComplex_FromDoubles(v.r,v.i))' Chris@87: needs['pyobj_from_complex_double1']=['complex_double'] Chris@87: cppmacros['pyobj_from_complex_double1']='#define pyobj_from_complex_double1(v) (PyComplex_FromDoubles(v.r,v.i))' Chris@87: needs['pyobj_from_complex_float1']=['complex_float'] Chris@87: cppmacros['pyobj_from_complex_float1']='#define pyobj_from_complex_float1(v) (PyComplex_FromDoubles(v.r,v.i))' Chris@87: needs['pyobj_from_string1']=['string'] Chris@87: cppmacros['pyobj_from_string1']='#define pyobj_from_string1(v) (PyString_FromString((char *)v))' Chris@87: needs['pyobj_from_string1size']=['string'] Chris@87: cppmacros['pyobj_from_string1size']='#define pyobj_from_string1size(v,len) (PyUString_FromStringAndSize((char *)v, len))' Chris@87: needs['TRYPYARRAYTEMPLATE']=['PRINTPYOBJERR'] Chris@87: cppmacros['TRYPYARRAYTEMPLATE']="""\ Chris@87: /* New SciPy */ Chris@87: #define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(arr->data)=*v; break; Chris@87: #define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(arr->data)=*v; break; Chris@87: #define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_ ## ctype ## 1(*v),arr->data); break; Chris@87: Chris@87: #define TRYPYARRAYTEMPLATE(ctype,typecode) \\ Chris@87: PyArrayObject *arr = NULL;\\ Chris@87: if (!obj) return -2;\\ Chris@87: if (!PyArray_Check(obj)) return -1;\\ Chris@87: if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ Chris@87: if (arr->descr->type==typecode) {*(ctype *)(arr->data)=*v; return 1;}\\ Chris@87: switch (arr->descr->type_num) {\\ Chris@87: case NPY_DOUBLE: *(double *)(arr->data)=*v; break;\\ Chris@87: case NPY_INT: *(int *)(arr->data)=*v; break;\\ Chris@87: case NPY_LONG: *(long *)(arr->data)=*v; break;\\ Chris@87: case NPY_FLOAT: *(float *)(arr->data)=*v; break;\\ Chris@87: case NPY_CDOUBLE: *(double *)(arr->data)=*v; break;\\ Chris@87: case NPY_CFLOAT: *(float *)(arr->data)=*v; break;\\ Chris@87: case NPY_BOOL: *(npy_bool *)(arr->data)=(*v!=0); break;\\ Chris@87: case NPY_UBYTE: *(unsigned char *)(arr->data)=*v; break;\\ Chris@87: case NPY_BYTE: *(signed char *)(arr->data)=*v; break;\\ Chris@87: case NPY_SHORT: *(short *)(arr->data)=*v; break;\\ Chris@87: case NPY_USHORT: *(npy_ushort *)(arr->data)=*v; break;\\ Chris@87: case NPY_UINT: *(npy_uint *)(arr->data)=*v; break;\\ Chris@87: case NPY_ULONG: *(npy_ulong *)(arr->data)=*v; break;\\ Chris@87: case NPY_LONGLONG: *(npy_longlong *)(arr->data)=*v; break;\\ Chris@87: case NPY_ULONGLONG: *(npy_ulonglong *)(arr->data)=*v; break;\\ Chris@87: case NPY_LONGDOUBLE: *(npy_longdouble *)(arr->data)=*v; break;\\ Chris@87: case NPY_CLONGDOUBLE: *(npy_longdouble *)(arr->data)=*v; break;\\ Chris@87: case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_ ## ctype ## 1(*v),arr->data, arr); break;\\ Chris@87: default: return -2;\\ Chris@87: };\\ Chris@87: return 1 Chris@87: """ Chris@87: Chris@87: needs['TRYCOMPLEXPYARRAYTEMPLATE']=['PRINTPYOBJERR'] Chris@87: cppmacros['TRYCOMPLEXPYARRAYTEMPLATE']="""\ Chris@87: #define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),arr->data, arr); break; Chris@87: #define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\ Chris@87: PyArrayObject *arr = NULL;\\ Chris@87: if (!obj) return -2;\\ Chris@87: if (!PyArray_Check(obj)) return -1;\\ Chris@87: if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ Chris@87: if (arr->descr->type==typecode) {\\ Chris@87: *(ctype *)(arr->data)=(*v).r;\\ Chris@87: *(ctype *)(arr->data+sizeof(ctype))=(*v).i;\\ Chris@87: return 1;\\ Chris@87: }\\ Chris@87: switch (arr->descr->type_num) {\\ Chris@87: case NPY_CDOUBLE: *(double *)(arr->data)=(*v).r;*(double *)(arr->data+sizeof(double))=(*v).i;break;\\ Chris@87: case NPY_CFLOAT: *(float *)(arr->data)=(*v).r;*(float *)(arr->data+sizeof(float))=(*v).i;break;\\ Chris@87: case NPY_DOUBLE: *(double *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_LONG: *(long *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_FLOAT: *(float *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_INT: *(int *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_SHORT: *(short *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_UBYTE: *(unsigned char *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_BYTE: *(signed char *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_BOOL: *(npy_bool *)(arr->data)=((*v).r!=0 && (*v).i!=0); break;\\ Chris@87: case NPY_USHORT: *(npy_ushort *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_UINT: *(npy_uint *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_ULONG: *(npy_ulong *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_LONGLONG: *(npy_longlong *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_ULONGLONG: *(npy_ulonglong *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_LONGDOUBLE: *(npy_longdouble *)(arr->data)=(*v).r; break;\\ Chris@87: case NPY_CLONGDOUBLE: *(npy_longdouble *)(arr->data)=(*v).r;*(npy_longdouble *)(arr->data+sizeof(npy_longdouble))=(*v).i;break;\\ Chris@87: case NPY_OBJECT: (arr->descr->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),arr->data, arr); break;\\ Chris@87: default: return -2;\\ Chris@87: };\\ Chris@87: return -1; Chris@87: """ Chris@87: ## cppmacros['NUMFROMARROBJ']="""\ Chris@87: ## #define NUMFROMARROBJ(typenum,ctype) \\ Chris@87: ## \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ Chris@87: ## \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ Chris@87: ## \tif (arr) {\\ Chris@87: ## \t\tif (arr->descr->type_num==NPY_OBJECT) {\\ Chris@87: ## \t\t\tif (!ctype ## _from_pyobj(v,(arr->descr->getitem)(arr->data),\"\"))\\ Chris@87: ## \t\t\tgoto capi_fail;\\ Chris@87: ## \t\t} else {\\ Chris@87: ## \t\t\t(arr->descr->cast[typenum])(arr->data,1,(char*)v,1,1);\\ Chris@87: ## \t\t}\\ Chris@87: ## \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ Chris@87: ## \t\treturn 1;\\ Chris@87: ## \t} Chris@87: ## """ Chris@87: ## #XXX: Note that CNUMFROMARROBJ is identical with NUMFROMARROBJ Chris@87: ## cppmacros['CNUMFROMARROBJ']="""\ Chris@87: ## #define CNUMFROMARROBJ(typenum,ctype) \\ Chris@87: ## \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ Chris@87: ## \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ Chris@87: ## \tif (arr) {\\ Chris@87: ## \t\tif (arr->descr->type_num==NPY_OBJECT) {\\ Chris@87: ## \t\t\tif (!ctype ## _from_pyobj(v,(arr->descr->getitem)(arr->data),\"\"))\\ Chris@87: ## \t\t\tgoto capi_fail;\\ Chris@87: ## \t\t} else {\\ Chris@87: ## \t\t\t(arr->descr->cast[typenum])((void *)(arr->data),1,(void *)(v),1,1);\\ Chris@87: ## \t\t}\\ Chris@87: ## \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ Chris@87: ## \t\treturn 1;\\ Chris@87: ## \t} Chris@87: ## """ Chris@87: Chris@87: Chris@87: needs['GETSTRFROMPYTUPLE']=['STRINGCOPYN', 'PRINTPYOBJERR'] Chris@87: cppmacros['GETSTRFROMPYTUPLE']="""\ Chris@87: #define GETSTRFROMPYTUPLE(tuple,index,str,len) {\\ Chris@87: \t\tPyObject *rv_cb_str = PyTuple_GetItem((tuple),(index));\\ Chris@87: \t\tif (rv_cb_str == NULL)\\ Chris@87: \t\t\tgoto capi_fail;\\ Chris@87: \t\tif (PyString_Check(rv_cb_str)) {\\ Chris@87: \t\t\tstr[len-1]='\\0';\\ Chris@87: \t\t\tSTRINGCOPYN((str),PyString_AS_STRING((PyStringObject*)rv_cb_str),(len));\\ Chris@87: \t\t} else {\\ Chris@87: \t\t\tPRINTPYOBJERR(rv_cb_str);\\ Chris@87: \t\t\tPyErr_SetString(#modulename#_error,\"string object expected\");\\ Chris@87: \t\t\tgoto capi_fail;\\ Chris@87: \t\t}\\ Chris@87: \t} Chris@87: """ Chris@87: cppmacros['GETSCALARFROMPYTUPLE']="""\ Chris@87: #define GETSCALARFROMPYTUPLE(tuple,index,var,ctype,mess) {\\ Chris@87: \t\tif ((capi_tmp = PyTuple_GetItem((tuple),(index)))==NULL) goto capi_fail;\\ Chris@87: \t\tif (!(ctype ## _from_pyobj((var),capi_tmp,mess)))\\ Chris@87: \t\t\tgoto capi_fail;\\ Chris@87: \t} Chris@87: """ Chris@87: Chris@87: cppmacros['FAILNULL']="""\\ Chris@87: #define FAILNULL(p) do { \\ Chris@87: if ((p) == NULL) { \\ Chris@87: PyErr_SetString(PyExc_MemoryError, "NULL pointer found"); \\ Chris@87: goto capi_fail; \\ Chris@87: } \\ Chris@87: } while (0) Chris@87: """ Chris@87: needs['MEMCOPY']=['string.h', 'FAILNULL'] Chris@87: cppmacros['MEMCOPY']="""\ Chris@87: #define MEMCOPY(to,from,n)\\ Chris@87: do { FAILNULL(to); FAILNULL(from); (void)memcpy(to,from,n); } while (0) Chris@87: """ Chris@87: cppmacros['STRINGMALLOC']="""\ Chris@87: #define STRINGMALLOC(str,len)\\ Chris@87: \tif ((str = (string)malloc(sizeof(char)*(len+1))) == NULL) {\\ Chris@87: \t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");\\ Chris@87: \t\tgoto capi_fail;\\ Chris@87: \t} else {\\ Chris@87: \t\t(str)[len] = '\\0';\\ Chris@87: \t} Chris@87: """ Chris@87: cppmacros['STRINGFREE']="""\ Chris@87: #define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0) Chris@87: """ Chris@87: needs['STRINGCOPYN']=['string.h', 'FAILNULL'] Chris@87: cppmacros['STRINGCOPYN']="""\ Chris@87: #define STRINGCOPYN(to,from,buf_size) \\ Chris@87: do { \\ Chris@87: int _m = (buf_size); \\ Chris@87: char *_to = (to); \\ Chris@87: char *_from = (from); \\ Chris@87: FAILNULL(_to); FAILNULL(_from); \\ Chris@87: (void)strncpy(_to, _from, sizeof(char)*_m); \\ Chris@87: _to[_m-1] = '\\0'; \\ Chris@87: /* Padding with spaces instead of nulls */ \\ Chris@87: for (_m -= 2; _m >= 0 && _to[_m] == '\\0'; _m--) { \\ Chris@87: _to[_m] = ' '; \\ Chris@87: } \\ Chris@87: } while (0) Chris@87: """ Chris@87: needs['STRINGCOPY']=['string.h', 'FAILNULL'] Chris@87: cppmacros['STRINGCOPY']="""\ Chris@87: #define STRINGCOPY(to,from)\\ Chris@87: do { FAILNULL(to); FAILNULL(from); (void)strcpy(to,from); } while (0) Chris@87: """ Chris@87: cppmacros['CHECKGENERIC']="""\ Chris@87: #define CHECKGENERIC(check,tcheck,name) \\ Chris@87: \tif (!(check)) {\\ Chris@87: \t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ Chris@87: \t\t/*goto capi_fail;*/\\ Chris@87: \t} else """ Chris@87: cppmacros['CHECKARRAY']="""\ Chris@87: #define CHECKARRAY(check,tcheck,name) \\ Chris@87: \tif (!(check)) {\\ Chris@87: \t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ Chris@87: \t\t/*goto capi_fail;*/\\ Chris@87: \t} else """ Chris@87: cppmacros['CHECKSTRING']="""\ Chris@87: #define CHECKSTRING(check,tcheck,name,show,var)\\ Chris@87: \tif (!(check)) {\\ Chris@87: \t\tchar errstring[256];\\ Chris@87: \t\tsprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, slen(var), var);\\ Chris@87: \t\tPyErr_SetString(#modulename#_error, errstring);\\ Chris@87: \t\t/*goto capi_fail;*/\\ Chris@87: \t} else """ Chris@87: cppmacros['CHECKSCALAR']="""\ Chris@87: #define CHECKSCALAR(check,tcheck,name,show,var)\\ Chris@87: \tif (!(check)) {\\ Chris@87: \t\tchar errstring[256];\\ Chris@87: \t\tsprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, var);\\ Chris@87: \t\tPyErr_SetString(#modulename#_error,errstring);\\ Chris@87: \t\t/*goto capi_fail;*/\\ Chris@87: \t} else """ Chris@87: ## cppmacros['CHECKDIMS']="""\ Chris@87: ## #define CHECKDIMS(dims,rank) \\ Chris@87: ## \tfor (int i=0;i<(rank);i++)\\ Chris@87: ## \t\tif (dims[i]<0) {\\ Chris@87: ## \t\t\tfprintf(stderr,\"Unspecified array argument requires a complete dimension specification.\\n\");\\ Chris@87: ## \t\t\tgoto capi_fail;\\ Chris@87: ## \t\t} Chris@87: ## """ Chris@87: cppmacros['ARRSIZE']='#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))' Chris@87: cppmacros['OLDPYNUM']="""\ Chris@87: #ifdef OLDPYNUM Chris@87: #error You need to intall Numeric Python version 13 or higher. Get it from http:/sourceforge.net/project/?group_id=1369 Chris@87: #endif Chris@87: """ Chris@87: ################# C functions ############### Chris@87: Chris@87: cfuncs['calcarrindex']="""\ Chris@87: static int calcarrindex(int *i,PyArrayObject *arr) { Chris@87: \tint k,ii = i[0]; Chris@87: \tfor (k=1; k < arr->nd; k++) Chris@87: \t\tii += (ii*(arr->dimensions[k] - 1)+i[k]); /* assuming contiguous arr */ Chris@87: \treturn ii; Chris@87: }""" Chris@87: cfuncs['calcarrindextr']="""\ Chris@87: static int calcarrindextr(int *i,PyArrayObject *arr) { Chris@87: \tint k,ii = i[arr->nd-1]; Chris@87: \tfor (k=1; k < arr->nd; k++) Chris@87: \t\tii += (ii*(arr->dimensions[arr->nd-k-1] - 1)+i[arr->nd-k-1]); /* assuming contiguous arr */ Chris@87: \treturn ii; Chris@87: }""" Chris@87: cfuncs['forcomb']="""\ Chris@87: static struct { int nd;npy_intp *d;int *i,*i_tr,tr; } forcombcache; Chris@87: static int initforcomb(npy_intp *dims,int nd,int tr) { Chris@87: int k; Chris@87: if (dims==NULL) return 0; Chris@87: if (nd<0) return 0; Chris@87: forcombcache.nd = nd; Chris@87: forcombcache.d = dims; Chris@87: forcombcache.tr = tr; Chris@87: if ((forcombcache.i = (int *)malloc(sizeof(int)*nd))==NULL) return 0; Chris@87: if ((forcombcache.i_tr = (int *)malloc(sizeof(int)*nd))==NULL) return 0; Chris@87: for (k=1;kdata,str,PyArray_NBYTES(arr)); } Chris@87: \treturn 1; Chris@87: capi_fail: Chris@87: \tPRINTPYOBJERR(obj); Chris@87: \tPyErr_SetString(#modulename#_error,\"try_pyarr_from_string failed\"); Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['string_from_pyobj']=['string', 'STRINGMALLOC', 'STRINGCOPYN'] Chris@87: cfuncs['string_from_pyobj']="""\ Chris@87: static int string_from_pyobj(string *str,int *len,const string inistr,PyObject *obj,const char *errmess) { Chris@87: \tPyArrayObject *arr = NULL; Chris@87: \tPyObject *tmp = NULL; Chris@87: #ifdef DEBUGCFUNCS Chris@87: fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",(char*)str,*len,(char *)inistr,obj); Chris@87: #endif Chris@87: \tif (obj == Py_None) { Chris@87: \t\tif (*len == -1) Chris@87: \t\t\t*len = strlen(inistr); /* Will this cause problems? */ Chris@87: \t\tSTRINGMALLOC(*str,*len); Chris@87: \t\tSTRINGCOPYN(*str,inistr,*len+1); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyArray_Check(obj)) { Chris@87: \t\tif ((arr = (PyArrayObject *)obj) == NULL) Chris@87: \t\t\tgoto capi_fail; Chris@87: \t\tif (!ISCONTIGUOUS(arr)) { Chris@87: \t\t\tPyErr_SetString(PyExc_ValueError,\"array object is non-contiguous.\"); Chris@87: \t\t\tgoto capi_fail; Chris@87: \t\t} Chris@87: \t\tif (*len == -1) Chris@87: \t\t\t*len = (arr->descr->elsize)*PyArray_SIZE(arr); Chris@87: \t\tSTRINGMALLOC(*str,*len); Chris@87: \t\tSTRINGCOPYN(*str,arr->data,*len+1); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyString_Check(obj)) { Chris@87: \t\ttmp = obj; Chris@87: \t\tPy_INCREF(tmp); Chris@87: \t} Chris@87: #if PY_VERSION_HEX >= 0x03000000 Chris@87: \telse if (PyUnicode_Check(obj)) { Chris@87: \t\ttmp = PyUnicode_AsASCIIString(obj); Chris@87: \t} Chris@87: \telse { Chris@87: \t\tPyObject *tmp2; Chris@87: \t\ttmp2 = PyObject_Str(obj); Chris@87: \t\tif (tmp2) { Chris@87: \t\t\ttmp = PyUnicode_AsASCIIString(tmp2); Chris@87: \t\t\tPy_DECREF(tmp2); Chris@87: \t\t} Chris@87: \t\telse { Chris@87: \t\t\ttmp = NULL; Chris@87: \t\t} Chris@87: \t} Chris@87: #else Chris@87: \telse { Chris@87: \t\ttmp = PyObject_Str(obj); Chris@87: \t} Chris@87: #endif Chris@87: \tif (tmp == NULL) goto capi_fail; Chris@87: \tif (*len == -1) Chris@87: \t\t*len = PyString_GET_SIZE(tmp); Chris@87: \tSTRINGMALLOC(*str,*len); Chris@87: \tSTRINGCOPYN(*str,PyString_AS_STRING(tmp),*len+1); Chris@87: \tPy_DECREF(tmp); Chris@87: \treturn 1; Chris@87: capi_fail: Chris@87: \tPy_XDECREF(tmp); Chris@87: \t{ Chris@87: \t\tPyObject* err = PyErr_Occurred(); Chris@87: \t\tif (err==NULL) err = #modulename#_error; Chris@87: \t\tPyErr_SetString(err,errmess); Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['char_from_pyobj']=['int_from_pyobj'] Chris@87: cfuncs['char_from_pyobj']="""\ Chris@87: static int char_from_pyobj(char* v,PyObject *obj,const char *errmess) { Chris@87: \tint i=0; Chris@87: \tif (int_from_pyobj(&i,obj,errmess)) { Chris@87: \t\t*v = (char)i; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['signed_char_from_pyobj']=['int_from_pyobj', 'signed_char'] Chris@87: cfuncs['signed_char_from_pyobj']="""\ Chris@87: static int signed_char_from_pyobj(signed_char* v,PyObject *obj,const char *errmess) { Chris@87: \tint i=0; Chris@87: \tif (int_from_pyobj(&i,obj,errmess)) { Chris@87: \t\t*v = (signed_char)i; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['short_from_pyobj']=['int_from_pyobj'] Chris@87: cfuncs['short_from_pyobj']="""\ Chris@87: static int short_from_pyobj(short* v,PyObject *obj,const char *errmess) { Chris@87: \tint i=0; Chris@87: \tif (int_from_pyobj(&i,obj,errmess)) { Chris@87: \t\t*v = (short)i; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: cfuncs['int_from_pyobj']="""\ Chris@87: static int int_from_pyobj(int* v,PyObject *obj,const char *errmess) { Chris@87: \tPyObject* tmp = NULL; Chris@87: \tif (PyInt_Check(obj)) { Chris@87: \t\t*v = (int)PyInt_AS_LONG(obj); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \ttmp = PyNumber_Int(obj); Chris@87: \tif (tmp) { Chris@87: \t\t*v = PyInt_AS_LONG(tmp); Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyComplex_Check(obj)) Chris@87: \t\ttmp = PyObject_GetAttrString(obj,\"real\"); Chris@87: \telse if (PyString_Check(obj) || PyUnicode_Check(obj)) Chris@87: \t\t/*pass*/; Chris@87: \telse if (PySequence_Check(obj)) Chris@87: \t\ttmp = PySequence_GetItem(obj,0); Chris@87: \tif (tmp) { Chris@87: \t\tPyErr_Clear(); Chris@87: \t\tif (int_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t} Chris@87: \t{ Chris@87: \t\tPyObject* err = PyErr_Occurred(); Chris@87: \t\tif (err==NULL) err = #modulename#_error; Chris@87: \t\tPyErr_SetString(err,errmess); Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: cfuncs['long_from_pyobj']="""\ Chris@87: static int long_from_pyobj(long* v,PyObject *obj,const char *errmess) { Chris@87: \tPyObject* tmp = NULL; Chris@87: \tif (PyInt_Check(obj)) { Chris@87: \t\t*v = PyInt_AS_LONG(obj); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \ttmp = PyNumber_Int(obj); Chris@87: \tif (tmp) { Chris@87: \t\t*v = PyInt_AS_LONG(tmp); Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyComplex_Check(obj)) Chris@87: \t\ttmp = PyObject_GetAttrString(obj,\"real\"); Chris@87: \telse if (PyString_Check(obj) || PyUnicode_Check(obj)) Chris@87: \t\t/*pass*/; Chris@87: \telse if (PySequence_Check(obj)) Chris@87: \t\ttmp = PySequence_GetItem(obj,0); Chris@87: \tif (tmp) { Chris@87: \t\tPyErr_Clear(); Chris@87: \t\tif (long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t} Chris@87: \t{ Chris@87: \t\tPyObject* err = PyErr_Occurred(); Chris@87: \t\tif (err==NULL) err = #modulename#_error; Chris@87: \t\tPyErr_SetString(err,errmess); Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['long_long_from_pyobj']=['long_long'] Chris@87: cfuncs['long_long_from_pyobj']="""\ Chris@87: static int long_long_from_pyobj(long_long* v,PyObject *obj,const char *errmess) { Chris@87: \tPyObject* tmp = NULL; Chris@87: \tif (PyLong_Check(obj)) { Chris@87: \t\t*v = PyLong_AsLongLong(obj); Chris@87: \t\treturn (!PyErr_Occurred()); Chris@87: \t} Chris@87: \tif (PyInt_Check(obj)) { Chris@87: \t\t*v = (long_long)PyInt_AS_LONG(obj); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \ttmp = PyNumber_Long(obj); Chris@87: \tif (tmp) { Chris@87: \t\t*v = PyLong_AsLongLong(tmp); Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t\treturn (!PyErr_Occurred()); Chris@87: \t} Chris@87: \tif (PyComplex_Check(obj)) Chris@87: \t\ttmp = PyObject_GetAttrString(obj,\"real\"); Chris@87: \telse if (PyString_Check(obj) || PyUnicode_Check(obj)) Chris@87: \t\t/*pass*/; Chris@87: \telse if (PySequence_Check(obj)) Chris@87: \t\ttmp = PySequence_GetItem(obj,0); Chris@87: \tif (tmp) { Chris@87: \t\tPyErr_Clear(); Chris@87: \t\tif (long_long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t} Chris@87: \t{ Chris@87: \t\tPyObject* err = PyErr_Occurred(); Chris@87: \t\tif (err==NULL) err = #modulename#_error; Chris@87: \t\tPyErr_SetString(err,errmess); Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['long_double_from_pyobj']=['double_from_pyobj', 'long_double'] Chris@87: cfuncs['long_double_from_pyobj']="""\ Chris@87: static int long_double_from_pyobj(long_double* v,PyObject *obj,const char *errmess) { Chris@87: \tdouble d=0; Chris@87: \tif (PyArray_CheckScalar(obj)){ Chris@87: \t\tif PyArray_IsScalar(obj, LongDouble) { Chris@87: \t\t\tPyArray_ScalarAsCtype(obj, v); Chris@87: \t\t\treturn 1; Chris@87: \t\t} Chris@87: \t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==NPY_LONGDOUBLE) { Chris@87: \t\t\t(*v) = *((npy_longdouble *)PyArray_DATA(obj)); Chris@87: \t\t\treturn 1; Chris@87: \t\t} Chris@87: \t} Chris@87: \tif (double_from_pyobj(&d,obj,errmess)) { Chris@87: \t\t*v = (long_double)d; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: cfuncs['double_from_pyobj']="""\ Chris@87: static int double_from_pyobj(double* v,PyObject *obj,const char *errmess) { Chris@87: \tPyObject* tmp = NULL; Chris@87: \tif (PyFloat_Check(obj)) { Chris@87: #ifdef __sgi Chris@87: \t\t*v = PyFloat_AsDouble(obj); Chris@87: #else Chris@87: \t\t*v = PyFloat_AS_DOUBLE(obj); Chris@87: #endif Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \ttmp = PyNumber_Float(obj); Chris@87: \tif (tmp) { Chris@87: #ifdef __sgi Chris@87: \t\t*v = PyFloat_AsDouble(tmp); Chris@87: #else Chris@87: \t\t*v = PyFloat_AS_DOUBLE(tmp); Chris@87: #endif Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyComplex_Check(obj)) Chris@87: \t\ttmp = PyObject_GetAttrString(obj,\"real\"); Chris@87: \telse if (PyString_Check(obj) || PyUnicode_Check(obj)) Chris@87: \t\t/*pass*/; Chris@87: \telse if (PySequence_Check(obj)) Chris@87: \t\ttmp = PySequence_GetItem(obj,0); Chris@87: \tif (tmp) { Chris@87: \t\tPyErr_Clear(); Chris@87: \t\tif (double_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;} Chris@87: \t\tPy_DECREF(tmp); Chris@87: \t} Chris@87: \t{ Chris@87: \t\tPyObject* err = PyErr_Occurred(); Chris@87: \t\tif (err==NULL) err = #modulename#_error; Chris@87: \t\tPyErr_SetString(err,errmess); Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['float_from_pyobj']=['double_from_pyobj'] Chris@87: cfuncs['float_from_pyobj']="""\ Chris@87: static int float_from_pyobj(float* v,PyObject *obj,const char *errmess) { Chris@87: \tdouble d=0.0; Chris@87: \tif (double_from_pyobj(&d,obj,errmess)) { Chris@87: \t\t*v = (float)d; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['complex_long_double_from_pyobj']=['complex_long_double', 'long_double', Chris@87: 'complex_double_from_pyobj'] Chris@87: cfuncs['complex_long_double_from_pyobj']="""\ Chris@87: static int complex_long_double_from_pyobj(complex_long_double* v,PyObject *obj,const char *errmess) { Chris@87: \tcomplex_double cd={0.0,0.0}; Chris@87: \tif (PyArray_CheckScalar(obj)){ Chris@87: \t\tif PyArray_IsScalar(obj, CLongDouble) { Chris@87: \t\t\tPyArray_ScalarAsCtype(obj, v); Chris@87: \t\t\treturn 1; Chris@87: \t\t} Chris@87: \t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==NPY_CLONGDOUBLE) { Chris@87: \t\t\t(*v).r = ((npy_clongdouble *)PyArray_DATA(obj))->real; Chris@87: \t\t\t(*v).i = ((npy_clongdouble *)PyArray_DATA(obj))->imag; Chris@87: \t\t\treturn 1; Chris@87: \t\t} Chris@87: \t} Chris@87: \tif (complex_double_from_pyobj(&cd,obj,errmess)) { Chris@87: \t\t(*v).r = (long_double)cd.r; Chris@87: \t\t(*v).i = (long_double)cd.i; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['complex_double_from_pyobj']=['complex_double'] Chris@87: cfuncs['complex_double_from_pyobj']="""\ Chris@87: static int complex_double_from_pyobj(complex_double* v,PyObject *obj,const char *errmess) { Chris@87: \tPy_complex c; Chris@87: \tif (PyComplex_Check(obj)) { Chris@87: \t\tc=PyComplex_AsCComplex(obj); Chris@87: \t\t(*v).r=c.real, (*v).i=c.imag; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyArray_IsScalar(obj, ComplexFloating)) { Chris@87: \t\tif (PyArray_IsScalar(obj, CFloat)) { Chris@87: \t\t\tnpy_cfloat new; Chris@87: \t\t\tPyArray_ScalarAsCtype(obj, &new); Chris@87: \t\t\t(*v).r = (double)new.real; Chris@87: \t\t\t(*v).i = (double)new.imag; Chris@87: \t\t} Chris@87: \t\telse if (PyArray_IsScalar(obj, CLongDouble)) { Chris@87: \t\t\tnpy_clongdouble new; Chris@87: \t\t\tPyArray_ScalarAsCtype(obj, &new); Chris@87: \t\t\t(*v).r = (double)new.real; Chris@87: \t\t\t(*v).i = (double)new.imag; Chris@87: \t\t} Chris@87: \t\telse { /* if (PyArray_IsScalar(obj, CDouble)) */ Chris@87: \t\t\tPyArray_ScalarAsCtype(obj, v); Chris@87: \t\t} Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */ Chris@87: \t\tPyObject *arr; Chris@87: \t\tif (PyArray_Check(obj)) { Chris@87: \t\t\tarr = PyArray_Cast((PyArrayObject *)obj, NPY_CDOUBLE); Chris@87: \t\t} Chris@87: \t\telse { Chris@87: \t\t\tarr = PyArray_FromScalar(obj, PyArray_DescrFromType(NPY_CDOUBLE)); Chris@87: \t\t} Chris@87: \t\tif (arr==NULL) return 0; Chris@87: \t\t(*v).r = ((npy_cdouble *)PyArray_DATA(arr))->real; Chris@87: \t\t(*v).i = ((npy_cdouble *)PyArray_DATA(arr))->imag; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \t/* Python does not provide PyNumber_Complex function :-( */ Chris@87: \t(*v).i=0.0; Chris@87: \tif (PyFloat_Check(obj)) { Chris@87: #ifdef __sgi Chris@87: \t\t(*v).r = PyFloat_AsDouble(obj); Chris@87: #else Chris@87: \t\t(*v).r = PyFloat_AS_DOUBLE(obj); Chris@87: #endif Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyInt_Check(obj)) { Chris@87: \t\t(*v).r = (double)PyInt_AS_LONG(obj); Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \tif (PyLong_Check(obj)) { Chris@87: \t\t(*v).r = PyLong_AsDouble(obj); Chris@87: \t\treturn (!PyErr_Occurred()); Chris@87: \t} Chris@87: \tif (PySequence_Check(obj) && !(PyString_Check(obj) || PyUnicode_Check(obj))) { Chris@87: \t\tPyObject *tmp = PySequence_GetItem(obj,0); Chris@87: \t\tif (tmp) { Chris@87: \t\t\tif (complex_double_from_pyobj(v,tmp,errmess)) { Chris@87: \t\t\t\tPy_DECREF(tmp); Chris@87: \t\t\t\treturn 1; Chris@87: \t\t\t} Chris@87: \t\t\tPy_DECREF(tmp); Chris@87: \t\t} Chris@87: \t} Chris@87: \t{ Chris@87: \t\tPyObject* err = PyErr_Occurred(); Chris@87: \t\tif (err==NULL) Chris@87: \t\t\terr = PyExc_TypeError; Chris@87: \t\tPyErr_SetString(err,errmess); Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['complex_float_from_pyobj']=['complex_float', 'complex_double_from_pyobj'] Chris@87: cfuncs['complex_float_from_pyobj']="""\ Chris@87: static int complex_float_from_pyobj(complex_float* v,PyObject *obj,const char *errmess) { Chris@87: \tcomplex_double cd={0.0,0.0}; Chris@87: \tif (complex_double_from_pyobj(&cd,obj,errmess)) { Chris@87: \t\t(*v).r = (float)cd.r; Chris@87: \t\t(*v).i = (float)cd.i; Chris@87: \t\treturn 1; Chris@87: \t} Chris@87: \treturn 0; Chris@87: } Chris@87: """ Chris@87: needs['try_pyarr_from_char']=['pyobj_from_char1', 'TRYPYARRAYTEMPLATE'] Chris@87: cfuncs['try_pyarr_from_char']='static int try_pyarr_from_char(PyObject* obj,char* v) {\n\tTRYPYARRAYTEMPLATE(char,\'c\');\n}\n' Chris@87: needs['try_pyarr_from_signed_char']=['TRYPYARRAYTEMPLATE', 'unsigned_char'] Chris@87: cfuncs['try_pyarr_from_unsigned_char']='static int try_pyarr_from_unsigned_char(PyObject* obj,unsigned_char* v) {\n\tTRYPYARRAYTEMPLATE(unsigned_char,\'b\');\n}\n' Chris@87: needs['try_pyarr_from_signed_char']=['TRYPYARRAYTEMPLATE', 'signed_char'] Chris@87: cfuncs['try_pyarr_from_signed_char']='static int try_pyarr_from_signed_char(PyObject* obj,signed_char* v) {\n\tTRYPYARRAYTEMPLATE(signed_char,\'1\');\n}\n' Chris@87: needs['try_pyarr_from_short']=['pyobj_from_short1', 'TRYPYARRAYTEMPLATE'] Chris@87: cfuncs['try_pyarr_from_short']='static int try_pyarr_from_short(PyObject* obj,short* v) {\n\tTRYPYARRAYTEMPLATE(short,\'s\');\n}\n' Chris@87: needs['try_pyarr_from_int']=['pyobj_from_int1', 'TRYPYARRAYTEMPLATE'] Chris@87: cfuncs['try_pyarr_from_int']='static int try_pyarr_from_int(PyObject* obj,int* v) {\n\tTRYPYARRAYTEMPLATE(int,\'i\');\n}\n' Chris@87: needs['try_pyarr_from_long']=['pyobj_from_long1', 'TRYPYARRAYTEMPLATE'] Chris@87: cfuncs['try_pyarr_from_long']='static int try_pyarr_from_long(PyObject* obj,long* v) {\n\tTRYPYARRAYTEMPLATE(long,\'l\');\n}\n' Chris@87: needs['try_pyarr_from_long_long']=['pyobj_from_long_long1', 'TRYPYARRAYTEMPLATE', 'long_long'] Chris@87: cfuncs['try_pyarr_from_long_long']='static int try_pyarr_from_long_long(PyObject* obj,long_long* v) {\n\tTRYPYARRAYTEMPLATE(long_long,\'L\');\n}\n' Chris@87: needs['try_pyarr_from_float']=['pyobj_from_float1', 'TRYPYARRAYTEMPLATE'] Chris@87: cfuncs['try_pyarr_from_float']='static int try_pyarr_from_float(PyObject* obj,float* v) {\n\tTRYPYARRAYTEMPLATE(float,\'f\');\n}\n' Chris@87: needs['try_pyarr_from_double']=['pyobj_from_double1', 'TRYPYARRAYTEMPLATE'] Chris@87: cfuncs['try_pyarr_from_double']='static int try_pyarr_from_double(PyObject* obj,double* v) {\n\tTRYPYARRAYTEMPLATE(double,\'d\');\n}\n' Chris@87: needs['try_pyarr_from_complex_float']=['pyobj_from_complex_float1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_float'] Chris@87: cfuncs['try_pyarr_from_complex_float']='static int try_pyarr_from_complex_float(PyObject* obj,complex_float* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(float,\'F\');\n}\n' Chris@87: needs['try_pyarr_from_complex_double']=['pyobj_from_complex_double1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_double'] Chris@87: cfuncs['try_pyarr_from_complex_double']='static int try_pyarr_from_complex_double(PyObject* obj,complex_double* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(double,\'D\');\n}\n' Chris@87: Chris@87: needs['create_cb_arglist']=['CFUNCSMESS', 'PRINTPYOBJERR', 'MINMAX'] Chris@87: cfuncs['create_cb_arglist']="""\ Chris@87: static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofargs,const int nofoptargs,int *nofargs,PyTupleObject **args,const char *errmess) { Chris@87: \tPyObject *tmp = NULL; Chris@87: \tPyObject *tmp_fun = NULL; Chris@87: \tint tot,opt,ext,siz,i,di=0; Chris@87: \tCFUNCSMESS(\"create_cb_arglist\\n\"); Chris@87: \ttot=opt=ext=siz=0; Chris@87: \t/* Get the total number of arguments */ Chris@87: \tif (PyFunction_Check(fun)) Chris@87: \t\ttmp_fun = fun; Chris@87: \telse { Chris@87: \t\tdi = 1; Chris@87: \t\tif (PyObject_HasAttrString(fun,\"im_func\")) { Chris@87: \t\t\ttmp_fun = PyObject_GetAttrString(fun,\"im_func\"); Chris@87: \t\t} Chris@87: \t\telse if (PyObject_HasAttrString(fun,\"__call__\")) { Chris@87: \t\t\ttmp = PyObject_GetAttrString(fun,\"__call__\"); Chris@87: \t\t\tif (PyObject_HasAttrString(tmp,\"im_func\")) Chris@87: \t\t\t\ttmp_fun = PyObject_GetAttrString(tmp,\"im_func\"); Chris@87: \t\t\telse { Chris@87: \t\t\t\ttmp_fun = fun; /* built-in function */ Chris@87: \t\t\t\ttot = maxnofargs; Chris@87: \t\t\t\tif (xa != NULL) Chris@87: \t\t\t\t\ttot += PyTuple_Size((PyObject *)xa); Chris@87: \t\t\t} Chris@87: \t\t\tPy_XDECREF(tmp); Chris@87: \t\t} Chris@87: \t\telse if (PyFortran_Check(fun) || PyFortran_Check1(fun)) { Chris@87: \t\t\ttot = maxnofargs; Chris@87: \t\t\tif (xa != NULL) Chris@87: \t\t\t\ttot += PyTuple_Size((PyObject *)xa); Chris@87: \t\t\ttmp_fun = fun; Chris@87: \t\t} Chris@87: \t\telse if (F2PyCapsule_Check(fun)) { Chris@87: \t\t\ttot = maxnofargs; Chris@87: \t\t\tif (xa != NULL) Chris@87: \t\t\t\text = PyTuple_Size((PyObject *)xa); Chris@87: \t\t\tif(ext>0) { Chris@87: \t\t\t\tfprintf(stderr,\"extra arguments tuple cannot be used with CObject call-back\\n\"); Chris@87: \t\t\t\tgoto capi_fail; Chris@87: \t\t\t} Chris@87: \t\t\ttmp_fun = fun; Chris@87: \t\t} Chris@87: \t} Chris@87: if (tmp_fun==NULL) { Chris@87: 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)); Chris@87: goto capi_fail; Chris@87: } Chris@87: #if PY_VERSION_HEX >= 0x03000000 Chris@87: \tif (PyObject_HasAttrString(tmp_fun,\"__code__\")) { Chris@87: \t\tif (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"__code__\"),\"co_argcount\")) Chris@87: #else Chris@87: \tif (PyObject_HasAttrString(tmp_fun,\"func_code\")) { Chris@87: \t\tif (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"func_code\"),\"co_argcount\")) Chris@87: #endif Chris@87: \t\t\ttot = PyInt_AsLong(PyObject_GetAttrString(tmp,\"co_argcount\")) - di; Chris@87: \t\tPy_XDECREF(tmp); Chris@87: \t} Chris@87: \t/* Get the number of optional arguments */ Chris@87: #if PY_VERSION_HEX >= 0x03000000 Chris@87: \tif (PyObject_HasAttrString(tmp_fun,\"__defaults__\")) { Chris@87: \t\tif (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"__defaults__\"))) Chris@87: #else Chris@87: \tif (PyObject_HasAttrString(tmp_fun,\"func_defaults\")) { Chris@87: \t\tif (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"func_defaults\"))) Chris@87: #endif Chris@87: \t\t\topt = PyTuple_Size(tmp); Chris@87: \t\tPy_XDECREF(tmp); Chris@87: \t} Chris@87: \t/* Get the number of extra arguments */ Chris@87: \tif (xa != NULL) Chris@87: \t\text = PyTuple_Size((PyObject *)xa); Chris@87: \t/* Calculate the size of call-backs argument list */ Chris@87: \tsiz = MIN(maxnofargs+ext,tot); Chris@87: \t*nofargs = MAX(0,siz-ext); Chris@87: #ifdef DEBUGCFUNCS Chris@87: \tfprintf(stderr,\"debug-capi:create_cb_arglist:maxnofargs(-nofoptargs),tot,opt,ext,siz,nofargs=%d(-%d),%d,%d,%d,%d,%d\\n\",maxnofargs,nofoptargs,tot,opt,ext,siz,*nofargs); Chris@87: #endif Chris@87: \tif (siz0: Chris@87: if outneeds[n][0] not in needs: Chris@87: out.append(outneeds[n][0]) Chris@87: del outneeds[n][0] Chris@87: else: Chris@87: flag=0 Chris@87: for k in outneeds[n][1:]: Chris@87: if k in needs[outneeds[n][0]]: Chris@87: flag=1 Chris@87: break Chris@87: if flag: Chris@87: outneeds[n]=outneeds[n][1:]+[outneeds[n][0]] Chris@87: else: Chris@87: out.append(outneeds[n][0]) Chris@87: del outneeds[n][0] Chris@87: if saveout and (0 not in map(lambda x, y:x==y, saveout, outneeds[n])) \ Chris@87: and outneeds[n] != []: Chris@87: print(n, saveout) Chris@87: errmess('get_needs: no progress in sorting needs, probably circular dependence, skipping.\n') Chris@87: out=out+saveout Chris@87: break Chris@87: saveout=copy.copy(outneeds[n]) Chris@87: if out==[]: Chris@87: out=[n] Chris@87: res[n]=out Chris@87: return res