err_hnd.h

Go to the documentation of this file.
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, Andrew W. Steiner
00005   
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 #ifndef O2SCL_ERR_HND_H
00024 #define O2SCL_ERR_HND_H
00025 
00026 #include <iostream>
00027 #include <string>
00028 #include <gsl/gsl_errno.h>
00029 
00030 /** \file err_hnd.h
00031     \brief File for definitions for err_class
00032 */
00033 
00034 #ifndef DOXYGENP
00035 namespace o2scl {
00036 #endif
00037 
00038   /** 
00039       \brief The error definitions from GSL
00040 
00041   */
00042   enum {
00043     /// Success
00044     gsl_success  = 0,
00045     /// Failure
00046     gsl_failure  = -1,
00047     /// iteration has not converged 
00048     gsl_continue = -2,  
00049     /// input domain error, e.g sqrt(-1) 
00050     gsl_edom     = 1,   
00051     /// output range error, e.g. exp(1e100) 
00052     gsl_erange   = 2,   
00053     /// invalid pointer 
00054     gsl_efault   = 3,   
00055     /// invalid argument supplied by user 
00056     gsl_einval   = 4,   
00057     /// generic failure 
00058     gsl_efailed  = 5,   
00059     /// factorization failed 
00060     gsl_efactor  = 6,   
00061     /// sanity check failed - shouldn't happen 
00062     gsl_esanity  = 7,   
00063     /// malloc failed 
00064     gsl_enomem   = 8,   
00065     /// problem with user-supplied function 
00066     gsl_ebadfunc = 9,   
00067     /// iterative process is out of control 
00068     gsl_erunaway = 10,  
00069     /// exceeded max number of iterations 
00070     gsl_emaxiter = 11,  
00071     /// tried to divide by zero 
00072     gsl_ezerodiv = 12,  
00073     /// user specified an invalid tolerance 
00074     gsl_ebadtol  = 13,  
00075     /// failed to reach the specified tolerance 
00076     gsl_etol     = 14,  
00077     /// underflow 
00078     gsl_eundrflw = 15,  
00079     /// overflow 
00080     gsl_eovrflw  = 16,  
00081     /// loss of accuracy 
00082     gsl_eloss    = 17,  
00083     /// failed because of roundoff error 
00084     gsl_eround   = 18,  
00085     /// matrix, vector lengths are not conformant 
00086     gsl_ebadlen  = 19,  
00087     /// matrix not square 
00088     gsl_enotsqr  = 20,  
00089     /// apparent singularity detected 
00090     gsl_esing    = 21,  
00091     /// integral or series is divergent 
00092     gsl_ediverge = 22,  
00093     /// requested feature is not supported by the hardware
00094     gsl_eunsup   = 23,  
00095     /// requested feature not (yet) implemented 
00096     gsl_eunimpl  = 24,  
00097     /// cache limit exceeded 
00098     gsl_ecache   = 25,  
00099     /// table limit exceeded 
00100     gsl_etable   = 26,  
00101     /// iteration is not making progress toward solution
00102     gsl_enoprog  = 27,  
00103     /// jacobian evaluations are not improving the solution 
00104     gsl_enoprogj = 28,  
00105     /// cannot reach the specified tolerance in f 
00106     gsl_etolf    = 29,  
00107     /// cannot reach the specified tolerance in x 
00108     gsl_etolx    = 30,  
00109     /// cannot reach the specified tolerance in gradient 
00110     gsl_etolg    = 31,  
00111     /// end of file 
00112     gsl_eof      = 32,  
00113     /// a blank method in a base class has been called
00114     gsl_nobase   = 33,
00115     /// Generic "not found" result
00116     gsl_notfound = 34,
00117     /// Incorrect type for memory object
00118     gsl_memtype = 35,
00119     /// File not found
00120     gsl_efilenotfound = 36,
00121     /// Invalid index for array or matrix
00122     gsl_index = 37
00123   };
00124   
00125   /** 
00126       \brief The error handler 
00127       
00128       An error handler for use in O2scl which replaces the GSL error handler
00129       
00130       Note that the string arguments to set() can refer to temporary
00131       storage, since they are copied when the function is called and
00132       an error is set.
00133 
00134   */
00135   class err_class {
00136 
00137   public:  
00138 
00139     err_class();
00140 
00141     /** 
00142         \brief Set an error 
00143     
00144         This is separate from set(), since the gsl error handler
00145         needs to be a static function.
00146      */
00147     static void gsl_hnd(const char *reason, const char *file, 
00148                         int line, int lerrno);
00149 
00150     /// Set an error 
00151     void set(const char *reason, const char *file, 
00152              int line, int lerrno);
00153 
00154     /// Add information to previous error
00155     void add(const char *reason, const char *file, 
00156              int line, int lerrno);
00157 
00158     /// Get the last error
00159     void get(const char *&reason, const char *&file,
00160              int &line, int &lerrno);
00161 
00162     /// Return the last error number
00163     int get_errno();
00164 
00165     /// Return the line number of the last error
00166     int get_line();
00167 
00168     /// Return the reason for the last error
00169     const char *get_reason();
00170 
00171     /// Return the file name of the last error
00172     const char *get_file();
00173 
00174     /// Return a string summarizing the last error
00175     const char *get_str();
00176 
00177     /// Remove last error information
00178     void reset();
00179 
00180     /// Force a hard exit if an error occurs
00181     void set_mode(int m) {
00182       if (m<0) mode=0;
00183       else if (m>2) mode=2;
00184       else mode=m;
00185     }
00186 
00187     /** \brief If true, call exit() when an array index error is set 
00188         (default true)
00189         
00190         This is ignored if \c O2SCL_ARRAY_ABORT is not defined.
00191     */
00192     bool array_abort;
00193 
00194   protected:
00195 
00196 #ifndef DOXYGEN_INTERNAL
00197 
00198     /// A pointer to the default error handler
00199     static err_class *ptr;
00200 
00201     /// The maximum size of error explanations
00202     static const int rsize=300;
00203     /// The maximum size of error explanations with the line and file info
00204     static const int fsize=400;
00205 
00206     /// The error number
00207     int a_errno;
00208     /// The line number
00209     int a_line;
00210     /// The mode of error handling
00211     int mode;
00212 
00213     /// The filename
00214     char *a_file;
00215     /// The error explanation
00216     char a_reason[rsize];
00217     /// A full string with explanation and line and file info
00218     char fullstr[fsize];
00219 
00220 #endif
00221 
00222   };
00223 
00224   /** \brief The global error handler pointer
00225   */      
00226   extern err_class *err_hnd;
00227 
00228   /** \brief The default error handler
00229   */      
00230   extern err_class def_err_hnd;
00231 
00232   /** \brief Set an error
00233   */
00234 #define set_err(d,n) o2scl::set_err_fn(d,__FILE__,__LINE__,n);
00235 
00236   /** \brief Set an error and return the error value
00237   */
00238 #define set_err_ret(d,n) \
00239 do { o2scl::set_err_fn(d,__FILE__,__LINE__,n); return n; } while (0)
00240   
00241   /** \brief Set an error and add the information from the last error
00242   */
00243 #define add_err(d,n) o2scl::add_err_fn(d,__FILE__,__LINE__,n);
00244   
00245   /** \brief Set an error, add the information from the last error,
00246       and return the error value
00247   */
00248 #define add_err_ret(d,n) \
00249 do { o2scl::add_err_fn(d,__FILE__,__LINE__,n); return n; } while(0)
00250   
00251   /** \brief Set an error
00252   */
00253   inline void set_err_fn(const char *desc, const char *file, int line,
00254                          int errnum) {
00255     err_hnd->set(desc,file,line,errnum);
00256     return;
00257   }
00258   
00259   /** \brief Set an error and add the information from the last error
00260   */
00261   inline void add_err_fn(const char *desc, const char *file, int line,
00262                          int errnum) {
00263     err_hnd->add(desc,file,line,errnum);
00264     return;
00265   }
00266   
00267   /// Desc
00268   inline void error_update(int &ret, int err) { if (ret==0) ret=err; }
00269   
00270   /** \brief Print out error information
00271    */
00272 #define err_print(ev)                                                   \
00273   do { if (ev!=0) std::cout << ev << " " << err_hnd->get_str() << std::endl; \
00274     else std::cout << "No error occured." << std::endl; } while (0)
00275   
00276   /** \brief Print out error information to \c cerr, do nothing 
00277       occured
00278   */
00279 #define cerr_print(ev)                                                  \
00280   do { if (ev!=0) std::cerr << ev << " " << err_hnd->get_str() << std::endl; \
00281   } while (0)
00282   
00283   /** \brief A version of \c assert, i.e. exit if the error value is non-zero
00284       and do nothing otherwise
00285 
00286       \todo Should make this consistent with assert() using NDEBUG
00287   */
00288 #define err_assert(ev)                                                  \
00289   do { if (ev!=0) { std::cout << "O2scl: Macro err_assert() causing exit" \
00290                               << " from error " << ev << " at "         \
00291                               << __LINE__ << " in file:\n  "            \
00292                               << __FILE__ << std::endl;                 \
00293          std::cout << "Error handler string:\n  " << err_hnd->get_str() \
00294                    << std::endl; exit(ev); } } while (0)
00295   
00296   /** \brief A version of \c assert for bool types. Exit if the argument
00297       is false
00298   */
00299 #define bool_assert(ev,str)                                             \
00300   do { if (ev==false) {                                                 \
00301       std::cout << "O2scl: Macro bool_assert() causing exit at line "   \
00302                 << __LINE__ << " in file:\n  "                          \
00303                 << __FILE__ << std::endl;                               \
00304       std::cout << "Given string: " << str                              \
00305                 << std::endl; exit(-1); } } while (0)
00306   
00307 #ifndef DOXYGENP
00308 }
00309 #endif
00310 
00311 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.