1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
import os
import genapi
h_template = r"""
#ifdef _UMATHMODULE
static PyTypeObject PyUFunc_Type;
%s
#else
#if defined(PY_UFUNC_UNIQUE_SYMBOL)
#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
#endif
#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
extern void **PyUFunc_API;
#else
#if defined(PY_UFUNC_UNIQUE_SYMBOL)
void **PyUFunc_API;
#else
static void **PyUFunc_API=NULL;
#endif
#endif
#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0])
%s
static int
_import_umath(void)
{
PyObject *numpy = PyImport_ImportModule("numpy.core.umath");
PyObject *c_api = NULL;
if (numpy == NULL) return -1;
c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
if (c_api == NULL) {Py_DECREF(numpy); return -1;}
if (PyCObject_Check(c_api)) {
PyUFunc_API = (void **)PyCObject_AsVoidPtr(c_api);
}
Py_DECREF(c_api);
Py_DECREF(numpy);
if (PyUFunc_API == NULL) return -1;
return 0;
}
#define import_umath() { UFUNC_NOFPE if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import"); return; }}
#define import_umath1(ret) { UFUNC_NOFPE if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import"); return ret; }}
#define import_umath2(msg, ret) { UFUNC_NOFPE if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; }}
#define import_ufunc() { UFUNC_NOFPE if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import"); }}
#endif
"""
c_template = r"""
/* These pointers will be stored in the C-object for use in other
extension modules
*/
void *PyUFunc_API[] = {
(void *) &PyUFunc_Type,
%s
};
"""
def generate_api(output_dir, force=False):
basename = 'ufunc_api'
h_file = os.path.join(output_dir, '__%s.h' % basename)
c_file = os.path.join(output_dir, '__%s.c' % basename)
d_file = os.path.join(output_dir, '%s.txt' % basename)
targets = (h_file, c_file, d_file)
sources = ['ufunc_api_order.txt']
if (not force and not genapi.should_rebuild(targets, sources + [__file__])):
return targets
else:
do_generate_api(targets, sources)
return targets
def do_generate_api(targets, sources):
header_file = targets[0]
c_file = targets[1]
doc_file = targets[2]
ufunc_api_list = genapi.get_api_functions('UFUNC_API', sources[0])
# API fixes for __arrayobject_api.h
fixed = 1
nummulti = len(ufunc_api_list)
numtotal = fixed + nummulti
module_list = []
extension_list = []
init_list = []
# set up object API
genapi.add_api_list(fixed, 'PyUFunc_API', ufunc_api_list,
module_list, extension_list, init_list)
# Write to header
fid = open(header_file, 'w')
s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
fid.write(s)
fid.close()
# Write to c-code
fid = open(c_file, 'w')
s = c_template % '\n'.join(init_list)
fid.write(s)
fid.close()
# Write to documentation
fid = open(doc_file, 'w')
fid.write('''
=================
Numpy Ufunc C-API
=================
''')
for func in ufunc_api_list:
fid.write(func.to_ReST())
fid.write('\n\n')
fid.close()
return targets
|