#include <pygsl/error_helpers.h>
#include <pygsl/utils.h>
#include <gsl/gsl_errno.h>
#include <compile.h>
#include <frameobject.h>
static const char error_module[] = "pygsl.errors";
static PyObject *gsl_error_dict = NULL;
static int
PyGSL_error_flag(long flag)
{
if(DEBUG > 2){
fprintf(stderr,"I got an Error of %ld\n", flag);
}
if(PyErr_Occurred())
return GSL_FAILURE;
if(flag>0){
/* How can I end here without an Python error? */
gsl_error("Unknown Reason. It was not set by GSL.", __FILE__,
__LINE__, flag);
return GSL_FAILURE;
}
return GSL_SUCCESS;
}
static PyObject *
PyGSL_error_flag_to_pyint(long flag)
{
PyObject * result = NULL;
if(GSL_FAILURE == PyGSL_error_flag(flag)){
return NULL;
}
result = PyInt_FromLong((long) flag);
return result;
}
static void
PyGSL_add_traceback(PyObject *module, const char *filename, const char *funcname, int lineno)
{
PyObject *py_srcfile = NULL, *py_funcname = NULL, *py_globals = NULL,
*empty_tuple = NULL, *empty_string = NULL;
PyCodeObject *py_code = NULL;
PyFrameObject *py_frame = NULL;
FUNC_MESS_BEGIN();
if(filename == NULL)
filename = "file ???";
py_srcfile = PyString_FromString(filename);
if (py_srcfile == NULL)
goto fail;
if(funcname == NULL)
funcname = "function ???";
py_funcname = PyString_FromString(funcname);
if (py_funcname == NULL)
goto fail;
/* Use the module if provided */
if(module == NULL){
py_globals = PyDict_New();
} else {
py_globals = PyModule_GetDict(module);
}
if (py_globals == NULL)
goto fail;
empty_tuple = PyTuple_New(0);
if (empty_tuple == NULL)
goto fail;
empty_string = PyString_FromString("");
if (empty_string == NULL)
goto fail;
py_code = PyCode_New(
0, /*int argcount,*/
0, /*int nlocals,*/
0, /*int stacksize,*/
0, /*int flags,*/
empty_string, /*PyObject *code,*/
empty_tuple, /*PyObject *consts,*/
empty_tuple, /*PyObject *names,*/
empty_tuple, /*PyObject *varnames,*/
empty_tuple, /*PyObject *freevars,*/
empty_tuple, /*PyObject *cellvars,*/
py_srcfile, /*PyObject *filename,*/
py_funcname, /*PyObject *name,*/
lineno, /*int firstlineno,*/
empty_string /*PyObject *lnotab*/
);
if (py_code == NULL)
goto fail;
py_frame = PyFrame_New(
PyThreadState_Get(), /*PyThreadState *tstate,*/
py_code, /*PyCodeObject *code,*/
py_globals, /*PyObject *globals,*/
0 /*PyObject *locals*/
);
if (py_frame == NULL)
goto fail;
py_frame->f_lineno = lineno;
PyTraceBack_Here(py_frame);
FUNC_MESS_END();
return;
fail:
FUNC_MESS("Handling failure");
Py_XDECREF(py_srcfile);
Py_XDECREF(py_funcname);
Py_XDECREF(empty_tuple);
Py_XDECREF(empty_string);
Py_XDECREF(py_code);
Py_XDECREF(py_frame);
}
static const char *
PyGSL_get_error_object_name(int gsl_error)
{
const char *default_err_str="gsl_Error", *err_str;
switch(gsl_error)
{
case GSL_FAILURE : err_str = "gsl_Error"; break;
case GSL_CONTINUE: err_str = NULL; break;
case GSL_EDOM : err_str = "gsl_DomainError"; break;
case GSL_ERANGE : err_str = "gsl_RangeError"; break;
case GSL_EFAULT : err_str = "gsl_PointerError"; break;
case GSL_EINVAL : err_str = "gsl_InvalidArgumentError"; break;
case GSL_EFAILED : err_str = "gsl_GenericError"; break;
case GSL_EFACTOR : err_str = "gsl_FactorizationError"; break;
case GSL_ESANITY : err_str = "gsl_SanityCheckError"; break;
case GSL_ENOMEM : err_str = NULL; break;
case GSL_EBADFUNC: err_str = "gsl_BadFuncError"; break;
case GSL_ERUNAWAY: err_str = "gsl_RunAwayError"; break;
case GSL_EMAXITER: err_str = "gsl_MaximumIterationError"; break;
case GSL_EZERODIV: err_str = "gsl_ZeroDivisionError"; break;
case GSL_EBADTOL : err_str = "gsl_BadToleranceError"; break;
case GSL_ETOL : err_str = "gsl_ToleranceError"; break;
case GSL_EUNDRFLW: err_str = "gsl_UnderflowError"; break;
case GSL_EOVRFLW : err_str = "gsl_OverflowError"; break;
case GSL_ELOSS : err_str = "gsl_AccuracyLossError"; break;
case GSL_EROUND : err_str = "gsl_RoundOffError"; break;
case GSL_EBADLEN : err_str = "gsl_BadLength"; break;
case GSL_ENOTSQR : err_str = "gsl_MatrixNotSquare"; break;
case GSL_ESING : err_str = "gsl_SingularityError"; break;
case GSL_EDIVERGE: err_str = "gsl_DivergeError"; break;
case GSL_EUNSUP : err_str = "gsl_NoHardwareSupportError"; break;
case GSL_EUNIMPL : err_str = "gsl_NotImplementedError"; break;
case GSL_ECACHE : err_str = "gsl_CacheLimitError"; break;
case GSL_ETABLE : err_str = "gsl_TableLimitError"; break;
case GSL_ENOPROG : err_str = "gsl_NoProgressError"; break;
case GSL_ENOPROGJ: err_str = "gsl_JacobianEvaluationError"; break;
case GSL_ETOLF : err_str = "gsl_ToleranceFError"; break;
case GSL_ETOLX : err_str = "gsl_ToleranceXError"; break;
case GSL_ETOLG : err_str = "gsl_ToleranceGradientError"; break;
case GSL_EOF : err_str = "gsl_EOFError"; break;
case PyGSL_ESTRIDE : err_str = "pygsl_StrideError"; break;
default:
err_str = default_err_str;
} /* switch(gsl_errno) */
return err_str;
}
static const char *
PyGSL_get_warning_object_name(int gsl_error)
{
const char *default_err_str="gsl_Warning", *err_str;
switch(gsl_error)
{
case GSL_FAILURE : err_str = "gsl_Warning"; break;
case GSL_CONTINUE: err_str = NULL; break;
case GSL_EDOM : err_str = "gsl_DomainWarning"; break;
case GSL_ERANGE : err_str = "gsl_RangeWarning"; break;
case GSL_EFAULT : err_str = "gsl_PointerWarning"; break;
case GSL_EINVAL : err_str = "gsl_InvalidArgumentWarning"; break;
case GSL_EFAILED : err_str = "gsl_GenericWarning"; break;
case GSL_EFACTOR : err_str = "gsl_FactorizationWarning"; break;
case GSL_ESANITY : err_str = "gsl_SanityCheckWarning"; break;
case GSL_ENOMEM : err_str = NULL; break;
case GSL_EBADFUNC: err_str = "gsl_BadFuncWarning"; break;
case GSL_ERUNAWAY: err_str = "gsl_RunAwayWarning"; break;
case GSL_EMAXITER: err_str = "gsl_MaximumIterationWarning"; break;
case GSL_EZERODIV: err_str = "gsl_ZeroDivisionWarning"; break;
case GSL_EBADTOL : err_str = "gsl_BadToleranceWarning"; break;
case GSL_ETOL : err_str = "gsl_ToleranceWarning"; break;
case GSL_EUNDRFLW: err_str = "gsl_UnderflowWarning"; break;
case GSL_EOVRFLW : err_str = "gsl_OverflowWarning"; break;
case GSL_ELOSS : err_str = "gsl_AccuracyLossWarning"; break;
case GSL_EROUND : err_str = "gsl_RoundOffWarning"; break;
case GSL_EBADLEN : err_str = "gsl_BadLength"; break;
case GSL_ENOTSQR : err_str = "gsl_MatrixNotSquare"; break;
case GSL_ESING : err_str = "gsl_SingularityWarning"; break;
case GSL_EDIVERGE: err_str = "gsl_DivergeWarning"; break;
case GSL_EUNSUP : err_str = "gsl_NoHardwareSupportWarning"; break;
case GSL_EUNIMPL : err_str = "gsl_NotImplementedWarning"; break;
case GSL_ECACHE : err_str = "gsl_CacheLimitWarning"; break;
case GSL_ETABLE : err_str = "gsl_TableLimitWarning"; break;
case GSL_ENOPROG : err_str = "gsl_NoProgressWarning"; break;
case GSL_ENOPROGJ: err_str = "gsl_JacobianEvaluationWarning"; break;
case GSL_ETOLF : err_str = "gsl_ToleranceFWarning"; break;
case GSL_ETOLX : err_str = "gsl_ToleranceXWarning"; break;
case GSL_ETOLG : err_str = "gsl_ToleranceGradientWarning"; break;
case GSL_EOF : err_str = "gsl_EOFWarning"; break;
case PyGSL_ESTRIDE : err_str = "pygsl_StrideWarning"; break;
default:
err_str = default_err_str;
} /* switch(gsl_errno) */
return err_str;
}
enum handleflag {
HANDLE_ERROR = 0,
HANDLE_WARNING
};
static PyObject *
PyGSL_get_object_error_module(int gsl_error, enum handleflag flag)
{
PyObject *gsl_error_module=NULL, *gsl_error_object=NULL;
const char *err_str = NULL;
FUNC_MESS_BEGIN();
if(!gsl_error_dict){
gsl_error_module=PyImport_ImportModule((char *) error_module);
if(!gsl_error_module){
fprintf(stderr, "I could not get module %s!\n", error_module);
Py_XDECREF(gsl_error_module);
gsl_error_module = NULL;
return NULL;
}
gsl_error_dict=PyModule_GetDict(gsl_error_module);
}
if(!gsl_error_dict){
fprintf(stderr, "I could not get the dictionary of the module %s!\n",
error_module);
goto fail;
}
switch(flag){
case HANDLE_ERROR:
err_str = PyGSL_get_error_object_name(gsl_error);
break;
case HANDLE_WARNING:
err_str = PyGSL_get_warning_object_name(gsl_error);
break;
default:
fprintf(stderr, "Unknown handle flag %d\n", flag);
}
if (err_str == NULL) {
fprintf(stderr, "Pygsl Internal Error. I got an error number of %d. "
"For this errno no approbriate Exception was found!", gsl_error);
} else {
gsl_error_object=PyDict_GetItemString(gsl_error_dict, err_str);
}
FUNC_MESS_END();
return gsl_error_object;
fail:
return NULL;
}
/*
* Warnings return a flag, so one can see if the warning raises an exception
* or not.
*/
static int
PyGSL_internal_error_handler(const char *reason, /* name of function*/
const char *file, /*from CPP*/
int line, /*from CPP*/
int gsl_error,
enum handleflag flag)
{
const char* error_explanation;
char error_text[255];
PyObject* gsl_error_object;
FUNC_MESS_BEGIN();
/*
* GSL_ENOMEM is special. I am out of memory. No fancy tricks here.
*/
if (GSL_ENOMEM == gsl_error){
PyErr_NoMemory();
return -1;
}
error_explanation = gsl_strerror(gsl_error);
if (error_explanation==NULL)
if (reason==NULL)
snprintf(error_text,sizeof(error_text),
"unknown error %d, no reason given",
gsl_error);
else
snprintf(error_text,sizeof(error_text),
"unknown error %d: %s",
gsl_error,reason);
else
if (reason==NULL)
snprintf(error_text,sizeof(error_text),
"%s",
error_explanation);
else
snprintf(error_text,sizeof(error_text),
"%s: %s",
error_explanation,reason);
/*
* some functions call error handler more than once before returning
* report only the first (most specific) error
*/
/* test, if exception is already set */
if (PyErr_Occurred()) {
if(PyGSL_DEBUG_LEVEL() > 0)
fprintf(stderr, "Another error occured: %s\n",error_text);
return -1;
}
/* error handler for gsl routines, sets exception */
gsl_error_object=PyGSL_get_object_error_module(gsl_error, flag);
if(!gsl_error_object){
fprintf(stderr, "%s. In Function %s. I could not get object gsl_Error!\n",
error_module, __FUNCTION__);
return -1;
}
Py_INCREF(gsl_error_object);
switch(flag){
case HANDLE_ERROR:
PyErr_SetObject(gsl_error_object, PyString_FromString(error_text));
return -1;
break;
case HANDLE_WARNING:
return PyErr_Warn(gsl_error_object, error_text);
break;
default:
fprintf(stderr, "Unknown handle %d\n", flag);
}
FUNC_MESS("Should not end here!");
return -1;
}
/*
* sets the right exception, but does not return to python!
*/
static void
PyGSL_module_error_handler(const char *reason, /* name of function*/
const char *file, /*from CPP*/
int line, /*from CPP*/
int gsl_error) /* real "reason" */
{
FUNC_MESS_BEGIN();
PyGSL_internal_error_handler(reason, file, line, gsl_error, HANDLE_ERROR);
FUNC_MESS_END();
}
static int
PyGSL_warning(const char *reason, /* name of function*/
const char *file, /*from CPP*/
int line, /*from CPP*/
int gsl_error) /* real "reason" */
{
int tmp;
FUNC_MESS_BEGIN();
tmp = PyGSL_internal_error_handler(reason, file, line, gsl_error, HANDLE_WARNING);
FUNC_MESS_END();
return tmp;
}
syntax highlighted by Code2HTML, v. 0.9.1