![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
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
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).