Object-oriented Scientific Computing Library: Version 0.910
err_hnd.h
Go to the documentation of this file.
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006-2012, 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_hnd_type and err_hnd_gsl
00032 
00033     See also \ref exception.h .
00034 */
00035 
00036 #ifndef DOXYGENP
00037 namespace o2scl {
00038 #endif
00039 
00040   /** \brief The integer error definitions 
00041       
00042       The errors associated with the integers between -2 and 32
00043       are from GSL, the rest are specific to \o2 . 
00044   */
00045   enum {
00046     /// Success (GSL)
00047     gsl_success=0,
00048     /// Failure (GSL)
00049     gsl_failure=-1,
00050     /// iteration has not converged (GSL)
00051     gsl_continue=-2,  
00052     /// input domain error, e.g sqrt(-1) (GSL)
00053     gsl_edom=1,   
00054     /// output range error, e.g. exp(1e100) (GSL)
00055     gsl_erange=2,   
00056     /// invalid pointer (GSL)
00057     gsl_efault=3,   
00058     /// invalid argument supplied by user (GSL)
00059     gsl_einval=4,   
00060     /// generic failure (GSL)
00061     gsl_efailed=5,   
00062     /// factorization failed (GSL)
00063     gsl_efactor=6,   
00064     /// sanity check failed - shouldn't happen (GSL)
00065     gsl_esanity=7,   
00066     /// malloc failed (GSL)
00067     gsl_enomem=8,   
00068     /// problem with user-supplied function (GSL)
00069     gsl_ebadfunc=9,   
00070     /// iterative process is out of control (GSL)
00071     gsl_erunaway=10,  
00072     /// exceeded max number of iterations (GSL)
00073     gsl_emaxiter=11,  
00074     /// tried to divide by zero (GSL)
00075     gsl_ezerodiv=12,  
00076     /// user specified an invalid tolerance (GSL)
00077     gsl_ebadtol=13,  
00078     /// failed to reach the specified tolerance (GSL)
00079     gsl_etol=14,  
00080     /// underflow (GSL)
00081     gsl_eundrflw=15,  
00082     /// overflow (GSL)
00083     gsl_eovrflw=16,  
00084     /// loss of accuracy (GSL)
00085     gsl_eloss=17,  
00086     /// failed because of roundoff error (GSL)
00087     gsl_eround=18,  
00088     /// matrix, vector lengths are not conformant (GSL)
00089     gsl_ebadlen=19,  
00090     /// matrix not square (GSL)
00091     gsl_enotsqr=20,  
00092     /// apparent singularity detected (GSL)
00093     gsl_esing=21,  
00094     /// integral or series is divergent (GSL)
00095     gsl_ediverge=22,  
00096     /// requested feature is not supported by the hardware (GSL)
00097     gsl_eunsup=23,  
00098     /// requested feature not (yet) implemented (GSL)
00099     gsl_eunimpl=24,  
00100     /// cache limit exceeded (GSL)
00101     gsl_ecache=25,  
00102     /// \table limit exceeded (GSL)
00103     gsl_etable=26,  
00104     /// iteration is not making progress toward solution (GSL)
00105     gsl_enoprog=27,  
00106     /// \jacobian evaluations are not improving the solution (GSL)
00107     gsl_enoprogj=28,  
00108     /// cannot reach the specified tolerance in f (GSL)
00109     gsl_etolf=29,  
00110     /// cannot reach the specified tolerance in x (GSL)
00111     gsl_etolx=30,  
00112     /// cannot reach the specified tolerance in \gradient (GSL)
00113     gsl_etolg=31,  
00114     /// end of file (GSL)
00115     gsl_eof=32,  
00116     /// Generic "not found" result
00117     gsl_enotfound=33,
00118     /// Incorrect type for memory object
00119     gsl_ememtype=34,
00120     /// File not found
00121     gsl_efilenotfound=35,
00122     /// Invalid index for array or matrix
00123     gsl_eindex=36,
00124     /// Outside constraint region
00125     gsl_outsidecons=37
00126   };
00127 
00128   // Forward declaration
00129   class err_hnd_type;
00130 
00131   /** \brief The global error handler pointer
00132    */      
00133   extern err_hnd_type *err_hnd;
00134 
00135   /** \brief Class defining an error handler [abstract base]
00136 
00137       A global object of this type is defined, \ref err_hnd .
00138 
00139       \future There may be an issue associated with the string
00140       manipulations causing errors in the error handler.
00141    */
00142   class err_hnd_type {
00143     
00144   public:
00145 
00146     err_hnd_type() {}
00147 
00148     virtual ~err_hnd_type() {}
00149 
00150     /** \brief Set an error 
00151     
00152         This is separate from set(), since the gsl error handler
00153         needs to be a static function.
00154     */
00155     static void gsl_hnd(const char *reason, const char *file, 
00156                         int line, int lerrno) {
00157       err_hnd->set(reason,file,line,lerrno);
00158     }
00159 
00160     /// Set an error 
00161     virtual void set(const char *reason, const char *file, 
00162                      int line, int lerrno)=0;
00163     
00164     /// Get the last error
00165     virtual void get(const char *&reason, const char *&file,
00166                      int &line, int &lerrno)=0;
00167 
00168     /// Return the last error number
00169     virtual int get_errno() const=0;
00170 
00171     /// Return the line number of the last error
00172     virtual int get_line() const=0;
00173 
00174     /// Return the reason for the last error
00175     virtual const char *get_reason() const=0;
00176 
00177     /// Return the file name of the last error
00178     virtual const char *get_file() const=0;
00179 
00180     /// Return a string summarizing the last error
00181     virtual const char *get_str()=0;
00182 
00183     /// Remove last error information
00184     virtual void reset()=0;
00185 
00186     /// Return type
00187     virtual const char *type() const=0;
00188 
00189   };
00190   
00191   /** \brief The error handler 
00192       
00193       An error handler for use in \o2 which replaces the GSL error handler
00194       
00195       Note that the string arguments to set() can refer to temporary
00196       storage, since they are copied when the function is called and
00197       an error is set.
00198   */
00199   class err_hnd_gsl : public err_hnd_type {
00200 
00201   public:  
00202 
00203     err_hnd_gsl();
00204 
00205     virtual ~err_hnd_gsl() {}
00206 
00207     /// Set an error 
00208     virtual void set(const char *reason, const char *file, 
00209                      int line, int lerrno);
00210 
00211     /// Get the last error
00212     virtual void get(const char *&reason, const char *&file,
00213                      int &line, int &lerrno);
00214 
00215     /// Return the last error number
00216     virtual int get_errno() const;
00217 
00218     /// Return the line number of the last error
00219     virtual int get_line() const;
00220 
00221     /// Return the reason for the last error
00222     virtual const char *get_reason() const;
00223 
00224     /// Return the file name of the last error
00225     virtual const char *get_file() const;
00226 
00227     /// Return a string summarizing the last error
00228     virtual const char *get_str();
00229 
00230     /// Remove last error information
00231     virtual void reset();
00232 
00233     /** \brief Set error handling mode
00234 
00235         - 0 - Continue execution after an error occurs
00236         - 1 - Continue execution after an error occurs
00237         - 2 - Abort execution after an error occurs, and print
00238         out the error information (default)
00239      */
00240     void set_mode(int m) {
00241       if (m<0) mode=0;
00242       else if (m>2) mode=2;
00243       else mode=m;
00244     }
00245 
00246     /// Return the error handling mode
00247     int get_mode() const {
00248       return mode;
00249     }
00250 
00251     /** \brief If true, call exit() when an array index error is set 
00252         (default true)
00253     */
00254     bool array_abort;
00255 
00256     /// Number of characters from filename to print (default 28)
00257     size_t fname_size;
00258 
00259     /// Return type ("err_hnd_gsl")
00260     virtual const char *type() const { return "err_hnd_gsl"; }
00261 
00262   protected:
00263 
00264 #ifndef DOXYGEN_INTERNAL
00265 
00266     /// Convert an error number to a string
00267     std::string errno_to_string(int errnox);
00268 
00269     /// The maximum size of error explanations
00270     static const int rsize=300;
00271     /// The maximum size of error explanations with the line and file info
00272     static const int fsize=400;
00273 
00274     /// The error number
00275     int a_errno;
00276     /// The line number
00277     int a_line;
00278     /// The mode of error handling (default 2)
00279     int mode;
00280 
00281     /// The filename
00282     char *a_file;
00283     /// The error explanation
00284     char a_reason[rsize];
00285     /// A full string with explanation and line and file info
00286     char fullstr[fsize];
00287 
00288 #endif
00289 
00290   };
00291 
00292   /** \brief An alternate GSL-like error handler
00293    */      
00294   extern err_hnd_gsl alt_err_hnd;
00295 
00296   /** \brief Set an error with message \c d and code \c n
00297    */
00298 #define O2SCL_ERR(d,n) o2scl::set_err_fn(d,__FILE__,__LINE__,n);
00299   
00300   /** \brief Set a "convergence" error
00301    */
00302 #define O2SCL_CONV(d,n,b) {if (b) o2scl::set_err_fn(d,__FILE__,__LINE__,n);}
00303   
00304   /** \brief Set an error, two-string version
00305    */
00306 #define O2SCL_ERR2(d,d2,n) o2scl::set_err_fn((std::string(d)+d2).c_str(), \
00307                                              __FILE__,__LINE__,n);
00308   
00309   /** \brief Set a "convergence" error, two-string version
00310    */
00311 #define O2SCL_CONV2(d,d2,n,b) {if (b)                                   \
00312       o2scl::set_err_fn((std::string(d)+d2).c_str(),                    \
00313                         __FILE__,__LINE__,n);}
00314   
00315   /** \brief Set an error and return the error value
00316    */
00317 #define O2SCL_ERR_RET(d,n)                                              \
00318   do { o2scl::set_err_fn(d,__FILE__,__LINE__,n); return n; } while (0)
00319   
00320   /** \brief Set a "convergence" error and return the error value
00321    */
00322 #define O2SCL_CONV_RET(d,n,b)                                           \
00323   do { if (!b) { return 0; } else {                                     \
00324       o2scl::set_err_fn(d,__FILE__,__LINE__,n); return n; } } while (0)
00325   
00326   /** \brief Set an error and return the error value, two-string version
00327    */
00328 #define O2SCL_ERR2_RET(d,d2,n)                                          \
00329   do { o2scl::set_err_fn((std::string(d)+d2).c_str(),                   \
00330                          __FILE__,__LINE__,n); return n; } while (0)
00331   
00332   /** \brief Set an error and return the error value, two-string version
00333    */
00334 #define O2SCL_CONV2_RET(d,d2,n,b)                                       \
00335   do { if (!b) {return 0; } else {                                      \
00336       o2scl::set_err_fn((std::string(d)+d2).c_str(),                    \
00337                         __FILE__,__LINE__,n); return n; } } while (0)
00338   
00339   /** \brief Set an error
00340    */
00341   inline void set_err_fn(const char *desc, const char *file, int line,
00342                          int errnum) {
00343     err_hnd->set(desc,file,line,errnum);
00344     return;
00345   }
00346   
00347   /** \brief Update an error value \c err with the value in \c ret
00348 
00349       If \c ret is zero, this sets \c ret to the value \c err, and 
00350       if \c ret is nonzero this function does nothing.
00351    */
00352   inline void error_update(int &ret, int err) { if (ret==0) ret=err; }
00353   
00354   /** \brief A version of \c assert, i.e. exit if the error value is
00355       non-zero and do nothing otherwise
00356       
00357       \future Make this consistent with assert() using NDEBUG?
00358   */
00359 #define O2SCL_ASSERT(ev)                                                \
00360   do { if (ev!=0) { std::cout << "O2scl: Macro err_assert() causing exit" \
00361                               << " from error " << ev << " at "         \
00362                               << __LINE__ << " in file:\n "             \
00363                               << __FILE__ << std::endl;                 \
00364       std::cout << "Error handler string:\n " << err_hnd->get_str()     \
00365                 << std::endl; exit(ev); } } while (0)
00366   
00367   /** \brief A version of \c assert for bool types. Exit if the argument
00368       is false
00369   */
00370 #define O2SCL_BOOL_ASSERT(ev,str)                                       \
00371   do { if (ev==false) {                                                 \
00372       std::cout << "O2scl: Macro bool_assert() causing exit at line "   \
00373                 << __LINE__ << " in file:\n "                           \
00374                 << __FILE__ << std::endl;                               \
00375       std::cout << "Given string: " << str                              \
00376                 << std::endl; exit(-1); } } while (0)
00377   
00378 #ifndef DOXYGENP
00379 }
00380 #endif
00381 
00382 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.