#include #include #include #include #include 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; }