home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / sources / misc / 4250 / except.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-11  |  7.4 KB  |  255 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 class 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 class 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. #ifdef __GNUC__
  134.    virtual ~Janitor();                          // to stop warning messages
  135. #else
  136.    ~Janitor();
  137. #endif
  138. };
  139.  
  140.  
  141.  
  142.  
  143. #ifdef DO_FREE_CHECK
  144. // Routines for tracing whether new and delete calls are balanced
  145.  
  146. class FreeCheck;
  147.  
  148. class FreeCheckLink
  149. {
  150. protected:
  151.    FreeCheckLink* next;
  152.    void* ClassStore;
  153.    FreeCheckLink();
  154.    virtual void Report()=0;                   // print details of link
  155.    friend class FreeCheck;
  156. };
  157.  
  158. class FCLClass : public FreeCheckLink         // for registering objects
  159. {
  160.    char* ClassName;
  161.    FCLClass(void* t, char* name);
  162.    void Report();
  163.    friend class FreeCheck;
  164. };
  165.  
  166. class FCLRealArray : public FreeCheckLink     // for registering real arrays
  167. {
  168.    char* Operation;
  169.    int size;
  170.    FCLRealArray(void* t, char* o, int s);
  171.    void Report();
  172.    friend class FreeCheck;
  173. };
  174.  
  175. class FCLIntArray : public FreeCheckLink     // for registering int arrays
  176. {
  177.    char* Operation;
  178.    int size;
  179.    FCLIntArray(void* t, char* o, int s);
  180.    void Report();
  181.    friend class FreeCheck;
  182. };
  183.  
  184.  
  185. class FreeCheck
  186. {
  187.    static FreeCheckLink* next;
  188. public:
  189.    static void Register(void*, char*);
  190.    static void DeRegister(void*, char*);
  191.    static void RegisterR(void*, char*, int);
  192.    static void DeRegisterR(void*, char*, int);
  193.    static void RegisterI(void*, char*, int);
  194.    static void DeRegisterI(void*, char*, int);
  195.    static void Status();
  196.    friend class FreeCheckLink;
  197.    friend class FCLClass;
  198.    friend class FCLRealArray;
  199.    friend class FCLIntArray;
  200. };
  201.  
  202. #define FREE_CHECK(Class)                                                  \
  203. public:                                                                    \
  204.    void* operator new(size_t size)                                         \
  205.    {                                                                       \
  206.       void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  207.       return t;                                                            \
  208.    }                                                                       \
  209.    void operator delete(void* t)                                           \
  210.    { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  211.  
  212. #define NEW_DELETE(Class)                                                  \
  213. public:                                                                    \
  214.    void* operator new(size_t size)                                         \
  215.    {                                                                       \
  216.       do_not_link=TRUE;                                                    \
  217.       void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  218.       return t;                                                            \
  219.    }                                                                       \
  220.    void operator delete(void* t)                                           \
  221.    { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  222.  
  223. #define MONITOR_REAL_NEW(Operation, Size, Pointer)                         \
  224.    FreeCheck::RegisterR(Pointer, Operation, Size);
  225. #define MONITOR_INT_NEW(Operation, Size, Pointer)                          \
  226.    FreeCheck::RegisterI(Pointer, Operation, Size);
  227. #define MONITOR_REAL_DELETE(Operation, Size, Pointer)                      \
  228.    FreeCheck::DeRegisterR(Pointer, Operation, Size);
  229. #define MONITOR_INT_DELETE(Operation, Size, Pointer)                       \
  230.    FreeCheck::DeRegisterI(Pointer, Operation, Size);
  231. #else
  232. #define FREE_CHECK(Class) public:
  233. #define MONITOR_REAL_NEW(Operation, Size, Pointer) {}
  234. #define MONITOR_INT_NEW(Operation, Size, Pointer) {}
  235. #define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}
  236. #define MONITOR_INT_DELETE(Operation, Size, Pointer) {}
  237.  
  238.  
  239. #define NEW_DELETE(Class)                                                  \
  240. public:                                                                    \
  241.    void* operator new(size_t size)                                         \
  242.    { do_not_link=TRUE; void* t = ::operator new(size); return t; }         \
  243.    void operator delete(void* t) { ::operator delete(t); }
  244.  
  245. #endif
  246.  
  247.  
  248.  
  249.  
  250. #endif
  251.  
  252.  
  253.  
  254.  
  255.