myexcept.h

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

Generated on 6 Apr 2011 for Slicer3 by  doxygen 1.6.1