#if (PYGSL_GSL_MAJOR_VERSION == 1) && (PYGSL_GSL_MINOR_VERSION < 5)
#define _PYGSL_HAS_DERIV 0
#else
#define _PYGSL_HAS_DERIV 1
#endif
#ifdef _PYGSL_HAS_DERIV
#include <gsl/gsl_deriv.h>
#endif
#ifdef PyGSL_DERIV_MODULE
#ifndef _PYGSL_HAS_DERIV
#error "The deriv module was only introduced by GSL 1.5. You seem to compile against an older verion!"
#endif
#endif /* PyGSL_DERIV_MODULE */
#include <gsl/gsl_diff.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include <Python.h>
#include <pygsl/error_helpers.h>
#include <pygsl/function_helpers.h>
#include <setjmp.h>
/*
* callback functions
* - python function passed by user
* - actual C callback
* - GSL wrapper struct
*/
/* Used for traceback */
static PyObject *module = NULL;
typedef struct{
PyObject * callback;
PyObject * args;
jmp_buf buffer;
}pygsl_diff_args;
static double
diff_callback(double x, void *p)
{
double value;
int flag;
pygsl_diff_args *pargs = NULL;
pargs = (pygsl_diff_args *) p;
assert(pargs->callback);
assert(pargs->args);
flag = PyGSL_function_wrap_helper(x, &value, NULL, pargs->callback,
pargs->args, (char *)__FUNCTION__);
if(GSL_SUCCESS != flag){
longjmp(pargs->buffer, flag);
return gsl_nan();
}
return value;
}
/* wrapper function */
typedef int pygsl_deriv_func(const gsl_function *, double, double, double *, double *);
typedef int pygsl_diff_func(const gsl_function *, double, double *, double *);
static PyObject *
PyGSL_diff_generic(PyObject *self, PyObject *args,
#ifndef PyGSL_DIFF_MODULE
pygsl_deriv_func func
#else
pygsl_diff_func func
#endif
)
{
PyObject *result=NULL, *myargs=NULL;
PyObject *cb=NULL;
pygsl_diff_args pargs = {NULL, NULL};
/* Changed to compile using Sun's Compiler */
gsl_function diff_gsl_callback = {NULL, NULL};
double x, value, abserr;
int flag;
#ifndef PyGSL_DIFF_MODULE
double h;
if(! PyArg_ParseTuple(args, "Odd|O", &cb, &x, &h, &myargs)){
return NULL;
}
#else
if(! PyArg_ParseTuple(args, "Od|O", &cb, &x, &myargs)){
return NULL;
}
#endif
/* Changed to compile using Sun's Compiler */
diff_gsl_callback.function = diff_callback;
diff_gsl_callback.params = (void *) &pargs;
if(! PyCallable_Check(cb)) {
PyErr_SetString(PyExc_TypeError,
"The first parameter must be callable");
return NULL;
}
Py_INCREF(cb); /* Add a reference to new callback */
pargs.callback = cb; /* Remember new callback */
/* Did I get arguments? If so handle them */
if(NULL == myargs){
Py_INCREF(Py_None);
pargs.args= Py_None;
}else{
Py_INCREF(myargs);
pargs.args= myargs;
}
if((flag=setjmp(pargs.buffer)) == 0){
/* Jmp buffer set, call the function */
#ifndef PyGSL_DIFF_MODULE
flag = func(&diff_gsl_callback, x, h, &value, &abserr);
#else
flag = func(&diff_gsl_callback, x, &value, &abserr);
#endif
}else{
DEBUG_MESS(2, "CALLBACK called longjmp!", 0);
}
/* Arguments no longer used */
Py_DECREF(pargs.args);
/* Dispose of callback */
Py_DECREF(pargs.callback);
if(flag != GSL_SUCCESS){
PyGSL_ERROR_FLAG(flag);
return NULL;
}
result = Py_BuildValue("(dd)", value, abserr);
return result;
}
syntax highlighted by Code2HTML, v. 0.9.1