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