MOOS 0.2375
|
00001 //$$ myexcept.h Exception handling classes 00002 00003 00004 // A set of classes to simulate exceptions in C++ 00005 // 00006 // Partially copied from Carlos Vidal s article in the C users journal 00007 // September 1992, pp 19-28 00008 // 00009 // Operations defined 00010 // Try { } 00011 // Throw ( exception object ) 00012 // ReThrow 00013 // Catch ( exception class ) { } 00014 // CatchAll { } 00015 // CatchAndThrow 00016 // 00017 // All catch lists must end with a CatchAll or CatchAndThrow statement 00018 // but not both. 00019 // 00020 // When exceptions are finally implemented replace Try, Throw(E), Rethrow, 00021 // Catch, CatchAll, CatchAndThrow by try, throw E, throw, catch, 00022 // catch(...), and {}. 00023 // 00024 // All exception classes must be derived from Exception, have no non-static 00025 // variables and must include the statement 00026 // 00027 // static unsigned long Select; 00028 // 00029 // Any constructor in one of these exception classes must include 00030 // 00031 // Select = Exception::Select; 00032 // 00033 // For each exceptions class, EX_1, some .cpp file must include 00034 // 00035 // unsigned long EX_1::Select; 00036 // 00037 00038 00039 #ifndef EXCEPTION_LIB 00040 #define EXCEPTION_LIB 00041 00042 #ifdef use_namespace 00043 namespace RBD_COMMON { 00044 #endif 00045 00046 00047 void Terminate(); 00048 00049 00050 //********** classes for setting up exceptions and reporting ************// 00051 00052 class Exception; 00053 00054 class Tracer // linked list showing how 00055 { // we got here 00056 const char* entry; 00057 Tracer* previous; 00058 public: 00059 Tracer(const char*); 00060 ~Tracer(); 00061 void ReName(const char*); 00062 static void PrintTrace(); // for printing trace 00063 static void AddTrace(); // insert trace in exception record 00064 static Tracer* last; // points to Tracer list 00065 friend class Exception; 00066 }; 00067 00068 00069 class Exception // The base exception class 00070 { 00071 protected: 00072 static char* what_error; // error message 00073 static int SoFar; // no. characters already entered 00074 static int LastOne; // last location in error buffer 00075 public: 00076 static void AddMessage(const char* a_what); 00077 // messages about exception 00078 static void AddInt(int value); // integer to error message 00079 static unsigned long Select; // for identifying exception 00080 Exception(const char* a_what = 0); 00081 static const char* what() { return what_error; } 00082 // for getting error message 00083 }; 00084 00085 00086 inline Tracer::Tracer(const char* e) 00087 : entry(e), previous(last) { last = this; } 00088 00089 inline Tracer::~Tracer() { last = previous; } 00090 00091 inline void Tracer::ReName(const char* e) { entry=e; } 00092 00093 #ifdef SimulateExceptions // SimulateExceptions 00094 00095 #include <setjmp.h> 00096 00097 00098 //************* the definitions of Try, Throw and Catch *****************// 00099 00100 00101 class JumpItem; 00102 class Janitor; 00103 00104 class JumpBase // pointer to a linked list of jmp_buf s 00105 { 00106 public: 00107 static JumpItem *jl; 00108 static jmp_buf env; 00109 }; 00110 00111 class JumpItem // an item in a linked list of jmp_buf s 00112 { 00113 public: 00114 JumpItem *ji; 00115 jmp_buf env; 00116 Tracer* trace; // to keep check on Tracer items 00117 Janitor* janitor; // list of items for cleanup 00118 JumpItem() : ji(JumpBase::jl), trace(0), janitor(0) 00119 { JumpBase::jl = this; } 00120 ~JumpItem() { JumpBase::jl = ji; } 00121 }; 00122 00123 void Throw(); 00124 00125 inline void Throw(const Exception&) { Throw(); } 00126 00127 #define Try \ 00128 if (!setjmp( JumpBase::jl->env )) { \ 00129 JumpBase::jl->trace = Tracer::last; \ 00130 JumpItem JI387256156; 00131 00132 #define ReThrow Throw() 00133 00134 #define Catch(EXCEPTION) \ 00135 } else if (Exception::Select == EXCEPTION::Select) { 00136 00137 #define CatchAll } else 00138 00139 #define CatchAndThrow } else Throw(); 00140 00141 00142 //****************** cleanup heap following Throw ***********************// 00143 00144 class Janitor 00145 { 00146 protected: 00147 static bool do_not_link; // set when new is called 00148 bool OnStack; // false if created by new 00149 public: 00150 Janitor* NextJanitor; 00151 virtual void CleanUp() {} 00152 Janitor(); 00153 virtual ~Janitor(); 00154 }; 00155 00156 00157 // The tiresome old trick for initializing the Janitor class 00158 // this is needed for classes derived from Janitor which have objects 00159 // declared globally 00160 00161 class JanitorInitializer 00162 { 00163 public: 00164 JanitorInitializer(); 00165 private: 00166 static int ref_count; 00167 }; 00168 00169 static JanitorInitializer JanInit; 00170 00171 #endif // end of SimulateExceptions 00172 00173 #ifdef UseExceptions 00174 00175 #define Try try 00176 #define Throw(E) throw E 00177 #define ReThrow throw 00178 #define Catch catch 00179 #define CatchAll catch(...) 00180 #define CatchAndThrow {} 00181 00182 #endif // end of UseExceptions 00183 00184 00185 #ifdef DisableExceptions // Disable exceptions 00186 00187 #define Try { 00188 #define ReThrow Throw() 00189 #define Catch(EXCEPTION) } if (false) { 00190 #define CatchAll } if (false) 00191 #define CatchAndThrow } 00192 00193 inline void Throw() { Terminate(); } 00194 inline void Throw(const Exception&) { Terminate(); } 00195 00196 00197 #endif // end of DisableExceptions 00198 00199 #ifndef SimulateExceptions // ! SimulateExceptions 00200 00201 class Janitor // a dummy version 00202 { 00203 public: 00204 virtual void CleanUp() {} 00205 Janitor() {} 00206 virtual ~Janitor() {} 00207 }; 00208 00209 #endif // end of ! SimulateExceptions 00210 00211 00212 //******************** FREE_CHECK and NEW_DELETE ***********************// 00213 00214 #ifdef DO_FREE_CHECK // DO_FREE_CHECK 00215 // Routines for tracing whether new and delete calls are balanced 00216 00217 class FreeCheck; 00218 00219 class FreeCheckLink 00220 { 00221 protected: 00222 FreeCheckLink* next; 00223 void* ClassStore; 00224 FreeCheckLink(); 00225 virtual void Report()=0; // print details of link 00226 friend class FreeCheck; 00227 }; 00228 00229 class FCLClass : public FreeCheckLink // for registering objects 00230 { 00231 char* ClassName; 00232 FCLClass(void* t, char* name); 00233 void Report(); 00234 friend class FreeCheck; 00235 }; 00236 00237 class FCLRealArray : public FreeCheckLink // for registering real arrays 00238 { 00239 char* Operation; 00240 int size; 00241 FCLRealArray(void* t, char* o, int s); 00242 void Report(); 00243 friend class FreeCheck; 00244 }; 00245 00246 class FCLIntArray : public FreeCheckLink // for registering int arrays 00247 { 00248 char* Operation; 00249 int size; 00250 FCLIntArray(void* t, char* o, int s); 00251 void Report(); 00252 friend class FreeCheck; 00253 }; 00254 00255 00256 class FreeCheck 00257 { 00258 static FreeCheckLink* next; 00259 static int BadDelete; 00260 public: 00261 static void Register(void*, char*); 00262 static void DeRegister(void*, char*); 00263 static void RegisterR(void*, char*, int); 00264 static void DeRegisterR(void*, char*, int); 00265 static void RegisterI(void*, char*, int); 00266 static void DeRegisterI(void*, char*, int); 00267 static void Status(); 00268 friend class FreeCheckLink; 00269 friend class FCLClass; 00270 friend class FCLRealArray; 00271 friend class FCLIntArray; 00272 }; 00273 00274 #define FREE_CHECK(Class) \ 00275 public: \ 00276 void* operator new(size_t size) \ 00277 { \ 00278 void* t = ::operator new(size); FreeCheck::Register(t,#Class); \ 00279 return t; \ 00280 } \ 00281 void operator delete(void* t) \ 00282 { FreeCheck::DeRegister(t,#Class); ::operator delete(t); } 00283 00284 00285 #ifdef SimulateExceptions // SimulateExceptions 00286 00287 #define NEW_DELETE(Class) \ 00288 public: \ 00289 void* operator new(size_t size) \ 00290 { \ 00291 do_not_link=true; \ 00292 void* t = ::operator new(size); FreeCheck::Register(t,#Class); \ 00293 return t; \ 00294 } \ 00295 void operator delete(void* t) \ 00296 { FreeCheck::DeRegister(t,#Class); ::operator delete(t); } 00297 00298 00299 #endif // end of SimulateExceptions 00300 00301 00302 #define MONITOR_REAL_NEW(Operation, Size, Pointer) \ 00303 FreeCheck::RegisterR(Pointer, Operation, Size); 00304 #define MONITOR_INT_NEW(Operation, Size, Pointer) \ 00305 FreeCheck::RegisterI(Pointer, Operation, Size); 00306 #define MONITOR_REAL_DELETE(Operation, Size, Pointer) \ 00307 FreeCheck::DeRegisterR(Pointer, Operation, Size); 00308 #define MONITOR_INT_DELETE(Operation, Size, Pointer) \ 00309 FreeCheck::DeRegisterI(Pointer, Operation, Size); 00310 00311 #else // DO_FREE_CHECK not defined 00312 00313 #define FREE_CHECK(Class) public: 00314 #define MONITOR_REAL_NEW(Operation, Size, Pointer) {} 00315 #define MONITOR_INT_NEW(Operation, Size, Pointer) {} 00316 #define MONITOR_REAL_DELETE(Operation, Size, Pointer) {} 00317 #define MONITOR_INT_DELETE(Operation, Size, Pointer) {} 00318 00319 00320 #ifdef SimulateExceptions // SimulateExceptions 00321 00322 00323 #define NEW_DELETE(Class) \ 00324 public: \ 00325 void* operator new(size_t size) \ 00326 { do_not_link=true; void* t = ::operator new(size); return t; } \ 00327 void operator delete(void* t) { ::operator delete(t); } 00328 00329 #endif // end of SimulateExceptions 00330 00331 #endif // end of ! DO_FREE_CHECK 00332 00333 #ifndef SimulateExceptions // ! SimulateExceptions 00334 00335 #define NEW_DELETE(Class) FREE_CHECK(Class) 00336 00337 #endif // end of ! SimulateExceptions 00338 00339 00340 //********************* derived exceptions ******************************// 00341 00342 class Logic_error : public Exception 00343 { 00344 public: 00345 static unsigned long Select; 00346 Logic_error(const char* a_what = 0); 00347 }; 00348 00349 class Runtime_error : public Exception 00350 { 00351 public: 00352 static unsigned long Select; 00353 Runtime_error(const char* a_what = 0); 00354 }; 00355 00356 class Domain_error : public Logic_error 00357 { 00358 public: 00359 static unsigned long Select; 00360 Domain_error(const char* a_what = 0); 00361 }; 00362 00363 class Invalid_argument : public Logic_error 00364 { 00365 public: 00366 static unsigned long Select; 00367 Invalid_argument(const char* a_what = 0); 00368 }; 00369 00370 class Length_error : public Logic_error 00371 { 00372 public: 00373 static unsigned long Select; 00374 Length_error(const char* a_what = 0); 00375 }; 00376 00377 class Out_of_range : public Logic_error 00378 { 00379 public: 00380 static unsigned long Select; 00381 Out_of_range(const char* a_what = 0); 00382 }; 00383 00384 //class Bad_cast : public Logic_error 00385 //{ 00386 //public: 00387 // static unsigned long Select; 00388 // Bad_cast(const char* a_what = 0); 00389 //}; 00390 00391 //class Bad_typeid : public Logic_error 00392 //{ 00393 //public: 00394 // static unsigned long Select; 00395 // Bad_typeid(const char* a_what = 0); 00396 //}; 00397 00398 class Range_error : public Runtime_error 00399 { 00400 public: 00401 static unsigned long Select; 00402 Range_error(const char* a_what = 0); 00403 }; 00404 00405 class Overflow_error : public Runtime_error 00406 { 00407 public: 00408 static unsigned long Select; 00409 Overflow_error(const char* a_what = 0); 00410 }; 00411 00412 class Bad_alloc : public Exception 00413 { 00414 public: 00415 static unsigned long Select; 00416 Bad_alloc(const char* a_what = 0); 00417 }; 00418 00419 #ifdef use_namespace 00420 } 00421 #endif 00422 00423 00424 #endif // end of EXCEPTION_LIB 00425 00426 00427 // body file: myexcept.cpp 00428 00429 00430