myexcept.h

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