CppAD: A C++ Algorithmic Differentiation Package 20110419
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_ERROR_HANDLER_INCLUDED 00003 # define CPPAD_ERROR_HANDLER_INCLUDED 00004 /* -------------------------------------------------------------------------- 00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-10 Bradley M. Bell 00006 00007 CppAD is distributed under multiple licenses. This distribution is under 00008 the terms of the 00009 Common Public License Version 1.0. 00010 00011 A copy of this license is included in the COPYING file of this distribution. 00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00013 -------------------------------------------------------------------------- */ 00014 00015 /* 00016 $begin ErrorHandler$$ 00017 $spell 00018 cppad.hpp 00019 CppAD 00020 exp 00021 bool 00022 const 00023 $$ 00024 00025 $section Replacing the CppAD Error Handler$$ 00026 $index error, handler$$ 00027 $index handler, error$$ 00028 $index replace, error handler$$ 00029 $index assert, error handler$$ 00030 $index exception, error handler$$ 00031 00032 $head Syntax$$ 00033 $syntax%ErrorHandler %info%(%handler%)%$$ 00034 $pre 00035 $$ 00036 $syntax%ErrorHandler::Call(%known%, %line%, %file%, %exp%, %msg%)%$$ 00037 00038 00039 $head Constructor$$ 00040 When you construct a $code ErrorHandler$$ object, 00041 the current CppAD error handler is replaced by $italic handler$$. 00042 When the object is destructed, the previous CppAD error handler is restored. 00043 00044 $head Call$$ 00045 When $code ErrorHandler::Call$$ is called, 00046 the current CppAD error handler is used to report an error. 00047 This starts out as a default error handler and can be replaced 00048 using the $code ErrorHandler$$ constructor. 00049 00050 $head info$$ 00051 The object $italic info$$ is used to store information 00052 that is necessary to restore the previous CppAD error handler. 00053 This is done when the destructor for $italic info$$ is called. 00054 00055 00056 $head handler$$ 00057 The argument $italic handler$$ has prototype 00058 $syntax% 00059 void (*%handler%) 00060 (bool, int, const char *, const char *, const char *); 00061 %$$ 00062 When an error is detected, 00063 it is called with the syntax 00064 $syntax% 00065 %handler% (%known%, %line%, %file%, %exp%, %msg%) 00066 %$$ 00067 This routine should not return; i.e., upon detection of the error, 00068 the routine calling $italic handler$$ does not know how to proceed. 00069 00070 $head known$$ 00071 The $italic handler$$ argument $italic known$$ has prototype 00072 $syntax% 00073 bool %known% 00074 %$$ 00075 If it is true, the error being reported is from a know problem. 00076 00077 $head line$$ 00078 The $italic handler$$ argument $italic line$$ has prototype 00079 $syntax% 00080 int %line% 00081 %$$ 00082 It reports the source code line number where the error is detected. 00083 00084 $head file$$ 00085 The $italic handler$$ argument $italic file$$ has prototype 00086 $syntax% 00087 const char *%file% 00088 %$$ 00089 and is a $code '\0'$$ terminated character vector. 00090 It reports the source code file where the error is detected. 00091 00092 $head exp$$ 00093 The $italic handler$$ argument $italic exp$$ has prototype 00094 $syntax% 00095 const char *%exp% 00096 %$$ 00097 and is a $code '\0'$$ terminated character vector. 00098 It is a source code boolean expression that should have been true, 00099 but is false, 00100 and thereby causes this call to $italic handler$$. 00101 00102 $head msg$$ 00103 The $italic handler$$ argument $italic msg$$ has prototype 00104 $syntax% 00105 const char *%msg% 00106 %$$ 00107 and is a $code '\0'$$ terminated character vector. 00108 It reports the meaning of the error from the C++ programmers point of view. 00109 00110 $children% 00111 example/error_handler.cpp% 00112 cppad/local/cppad_assert.hpp 00113 %$$ 00114 $head Example$$ 00115 The file 00116 $xref/ErrorHandler.cpp/$$ 00117 contains an example and test a test of using this routine. 00118 It returns true if it succeeds and false otherwise. 00119 00120 $end 00121 --------------------------------------------------------------------------- 00122 */ 00123 00124 # include <iostream> 00125 00126 # ifdef _OPENMP 00127 # include <omp.h> 00128 # endif 00129 00130 # include <cppad/configure.hpp> 00131 # include <cassert> 00132 # include <cstdlib> 00133 00134 namespace CppAD { // BEGIN CppAD namespace 00135 00136 class ErrorHandler { 00137 public: 00138 typedef void (*Handler) 00139 (bool, int, const char *, const char *, const char *); 00140 00141 00142 // construct an handler 00143 ErrorHandler(Handler handler) : previous( Current() ) 00144 { Current() = handler; } 00145 00146 // destructor for an error handler 00147 ~ErrorHandler(void) 00148 { Current() = previous; } 00149 00150 // report an error 00151 static void Call( 00152 bool known, 00153 int line , 00154 const char *file , 00155 const char *exp , 00156 const char *msg ) 00157 { Handler handler = Current(); 00158 handler(known, line, file, exp, msg); 00159 } 00160 00161 private: 00162 const Handler previous; 00163 00164 // The default error handler 00165 static void Default( 00166 bool known, 00167 int line , 00168 const char *file , 00169 const char *exp , 00170 const char *msg ) 00171 { using std::cerr; 00172 using std::endl; 00173 00174 # ifdef _OPENMP 00175 int thread_num = omp_get_thread_num(); 00176 # endif 00177 00178 // if OpenMP multi-threading, only run output on master thread 00179 # ifdef _OPENMP 00180 # pragma omp master 00181 # endif 00182 { 00183 cerr << CPPAD_PACKAGE_STRING; 00184 if( known ) 00185 cerr << " error from a known source:" << endl; 00186 else cerr << " error from unknown source" << endl; 00187 if( msg[0] != '\0' ) 00188 cerr << msg << endl; 00189 cerr << "Error detected by false result for" << endl; 00190 cerr << " " << exp << endl; 00191 cerr << "at line " << line << " in the file " << endl; 00192 cerr << " " << file << endl; 00193 # ifdef _OPENMP 00194 cerr << "OpenMP: thread_num = " << thread_num << endl; 00195 # endif 00196 00197 // terminate program execution 00198 assert(false); 00199 00200 // termination when NDEBUG is defined 00201 std::exit(1); 00202 } 00203 // pragma omp master 00204 } 00205 00206 // current error handler 00207 static Handler &Current(void) 00208 { static Handler current = Default; 00209 return current; 00210 } 00211 }; 00212 00213 } // END CppAD namespace 00214 00215 00216 00217 # endif