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