home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / n / newmat06.zip / EXCEPT.H < prev    next >
C/C++ Source or Header  |  1992-12-03  |  8KB  |  251 lines

  1. //$$ except.h                          Exception handling classes
  2.  
  3. // A set of classes to simulate exceptions in C++
  4. //
  5. //   Partially copied from Carlos Vidal's article in the C users' journal
  6. //   September 1992, pp 19-28
  7. //
  8. //   Operations defined
  9. //      Try {     }
  10. //      Throw ( exception object )
  11. //      Catch ( exception class ) {      }
  12. //      CatchAll {      }
  13. //      CatchAndThrow
  14. //
  15. //   All catch lists must end with a CatchAll or CatchAndThrow statement
  16. //   but not both.
  17. //
  18. //   When exceptions are finally implemented replace Try, Throw, Catch,
  19. //   CatchAll, CatchAndThrow by try, throw, catch, catch(...), and {}.
  20. //
  21. //   All exception classes must be derived from Exception, have no non-static
  22. //   variables and must include functions
  23. //
  24. //      static long st_type()  { return 2; }
  25. //      long type() const { return 2; }
  26. //
  27. //   where 2 is replaced by a prime number unique to the exception class.
  28. //   See notes for use with levels of exceptions.
  29. //
  30.  
  31. #ifndef EXCEPTION_LIB
  32. #define EXCEPTION_LIB
  33.  
  34. #include <setjmp.h>
  35.  
  36. void Terminate();
  37.  
  38. /*********** classes for setting up exceptions and reporting ***************/
  39.  
  40. class Exception;
  41.  
  42. class Tracer                                    // linked list showing how
  43. {                                               // we got here
  44.    char* entry;
  45.    Tracer* previous;
  46. public:
  47.    Tracer(char*);
  48.    ~Tracer();
  49.    void ReName(char*);
  50.    friend Exception;
  51. };
  52.  
  53.  
  54. class Exception                                 // The base exception class
  55. {
  56. public:
  57.    static Tracer* last;                         // points to Tracer list
  58.    static long st_type() { return 1; }
  59.    virtual long type() const { return 1; }
  60.    static void PrintTrace(Boolean=FALSE);       // for printing trace
  61.    friend Tracer;
  62.    Exception(int action);
  63. };
  64.  
  65.  
  66. inline Tracer::Tracer(char* e)
  67.    : entry(e), previous(Exception::last) { Exception::last = this; }
  68.  
  69. inline Tracer::~Tracer() { Exception::last = previous; }
  70.  
  71. inline void Tracer::ReName(char* e) { entry=e; }
  72.  
  73.  
  74.  
  75.  
  76.  
  77. /************** the definitions of Try, Throw and Catch *******************/
  78.  
  79.  
  80. class JumpItem;
  81. class Janitor;
  82.  
  83. class JumpBase         // pointer to a linked list of jmp_buf s
  84. {
  85. public:
  86.    static JumpItem *jl;
  87.    static long type;                    // type id. of last exception
  88.    static jmp_buf env;
  89. };
  90.  
  91. class JumpItem         // an item in a linked list of jmp_buf s
  92. {
  93. public:
  94.    JumpItem *ji;
  95.    jmp_buf env;
  96.    Tracer* trace;                     // to keep check on Tracer items
  97.    Janitor* janitor;                  // list of items for cleanup
  98.    JumpItem() : trace(0), janitor(0), ji(JumpBase::jl)
  99.       { JumpBase::jl = this; }
  100.    ~JumpItem() { JumpBase::jl = ji; }
  101. };
  102.  
  103. void Throw(const Exception& exc);
  104.  
  105. void Throw();
  106.  
  107. #define Try                                             \
  108.       if (!setjmp( JumpBase::jl->env )) {               \
  109.       JumpBase::jl->trace = Exception::last;            \
  110.       JumpItem JI387256156;
  111.  
  112. #define Catch(EXCEPTION)                                \
  113.    } else if (JumpBase::type % EXCEPTION::st_type() == 0) {
  114.  
  115.  
  116. #define CatchAll } else
  117.  
  118. #define CatchAndThrow  } else Throw();
  119.  
  120.  
  121.  
  122. /******************* cleanup heap following Throw ************************/
  123.  
  124. class Janitor
  125. {
  126. protected:
  127.    static Boolean do_not_link;                  // set when new is called
  128.    Boolean OnStack;                             // false if created by new
  129. public:
  130.    Janitor* NextJanitor;
  131.    virtual void CleanUp() {}
  132.    Janitor();
  133.    ~Janitor();
  134. };
  135.  
  136.  
  137.  
  138.  
  139. #ifdef DO_FREE_CHECK
  140. // Routines for tracing whether new and delete calls are balanced
  141.  
  142. class FreeCheck;
  143.  
  144. class FreeCheckLink
  145. {
  146. protected:
  147.    FreeCheckLink* next;
  148.    void* ClassStore;
  149.    FreeCheckLink();
  150.    virtual void Report()=0;                   // print details of link
  151.    friend FreeCheck;
  152. };
  153.  
  154. class FCLClass : public FreeCheckLink         // for registering objects
  155. {
  156.    char* ClassName;
  157.    FCLClass(void* t, char* name);
  158.    void Report();
  159.    friend FreeCheck;
  160. };
  161.  
  162. class FCLRealArray : public FreeCheckLink     // for registering real arrays
  163. {
  164.    char* Operation;
  165.    int size;
  166.    FCLRealArray(void* t, char* o, int s);
  167.    void Report();
  168.    friend FreeCheck;
  169. };
  170.  
  171. class FCLIntArray : public FreeCheckLink     // for registering int arrays
  172. {
  173.    char* Operation;
  174.    int size;
  175.    FCLIntArray(void* t, char* o, int s);
  176.    void Report();
  177.    friend FreeCheck;
  178. };
  179.  
  180.  
  181. class FreeCheck
  182. {
  183.    static FreeCheckLink* next;
  184. public:
  185.    static void Register(void*, char*);
  186.    static void DeRegister(void*, char*);
  187.    static void RegisterR(void*, char*, int);
  188.    static void DeRegisterR(void*, char*, int);
  189.    static void RegisterI(void*, char*, int);
  190.    static void DeRegisterI(void*, char*, int);
  191.    static void Status();
  192.    friend FreeCheckLink;
  193.    friend FCLClass;
  194.    friend FCLRealArray;
  195.    friend FCLIntArray;
  196. };
  197.  
  198. #define FREE_CHECK(Class)                                                  \
  199. public:                                                                    \
  200.    void* operator new(size_t size)                                         \
  201.    {                                                                       \
  202.       void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  203.       return t;                                                            \
  204.    }                                                                       \
  205.    void operator delete(void* t)                                           \
  206.    { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  207.  
  208. #define NEW_DELETE(Class)                                                  \
  209. public:                                                                    \
  210.    void* operator new(size_t size)                                         \
  211.    {                                                                       \
  212.       do_not_link=TRUE;                                                    \
  213.       void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  214.       return t;                                                            \
  215.    }                                                                       \
  216.    void operator delete(void* t)                                           \
  217.    { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  218.  
  219. #define MONITOR_REAL_NEW(Operation, Size, Pointer)                         \
  220.    FreeCheck::RegisterR(Pointer, Operation, Size);
  221. #define MONITOR_INT_NEW(Operation, Size, Pointer)                          \
  222.    FreeCheck::RegisterI(Pointer, Operation, Size);
  223. #define MONITOR_REAL_DELETE(Operation, Size, Pointer)                      \
  224.    FreeCheck::DeRegisterR(Pointer, Operation, Size);
  225. #define MONITOR_INT_DELETE(Operation, Size, Pointer)                       \
  226.    FreeCheck::DeRegisterI(Pointer, Operation, Size);
  227. #else
  228. #define FREE_CHECK(Class) public:
  229. #define MONITOR_REAL_NEW(Operation, Size, Pointer) {}
  230. #define MONITOR_INT_NEW(Operation, Size, Pointer) {}
  231. #define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}
  232. #define MONITOR_INT_DELETE(Operation, Size, Pointer) {}
  233.  
  234.  
  235. #define NEW_DELETE(Class)                                                  \
  236. public:                                                                    \
  237.    void* operator new(size_t size)                                         \
  238.    { do_not_link=TRUE; void* t = ::operator new(size); return t; }         \
  239.    void operator delete(void* t) { ::operator delete(t); }
  240.  
  241. #endif
  242.  
  243.  
  244.  
  245.  
  246. #endif
  247.  
  248.  
  249.  
  250.  
  251.