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