Listing 1 Header for exception handling classes and functions

////////////////////////////////////////////////////////////
// UNWIND.H
// Copyright 1994 Gregory Colvin.
// May be distributed free with this notice.
#include <stdlib.h>
#include <setjmp.h>

// These macros emulate the corresponding C++ keywords.
#define try                              \
   int eh_err=0;                        \
   { Handler Handler;                   \
      eh_err = setjmp(Handler.buf);    \
      if (!eh_err)
#define catch(dcl)                       \
   }                                    \
   dcl = eh_err;                        \
   if (eh_err)
#define throw(err) Handler::Throw(err)

// Entry on stack of exception handlers.
struct Handler {
   friend struct Pusher;
   friend struct Unwindable;
   Handler() : prev(handler), link(0) { handler = this; }
   ~Handler() { handler = handler->prev; }
   static void Throw(int);          // throw an exception
   jmp_buf buf;                     // for use by try macro
private:
   Handler* prey;                   // stack of handlers
   Unwindable* link;                // stack of catchables
   static Handler* handler;         // current handler
   static void push(Unwindable*,size_t);
};

// Pusher is used by the UNWINDABLE macro to make objects
// catchable when their constructor is finished.
struct Pusher {
   friend struct Unwindable;
   Pusher(Unwindable* p,size_t s) : pushed(p), size(s) {}
   ~Pusher() { Handler::push(pushed,size); }
private:
   Unwindable* pushed;
   size_t size;
};
#define UNWINDABLE Pusher pusher(this,sizeof *this)

// Unwindables can be destroyed when an exception is thrown.
struct Unwindable {
   friend Handler;
   Unwindable() { UNWINDABLE; count++; }
   Unwindable(const Unwindable&) { UNWINDABLE; count++; }
   Unwindable& operator=(const Unwindable&) {
      UNWINDABLE;
      return *this;
   }
   virtual ~Unwindable() { --count; }
   void* operator new(size_t);
   void operator delete(void* p) { ::operator delete(p); }
   static unsigned Count() { return count; }
private:
   Unwindable* link;       // next object on stack
   size_t size;            // size of complete object
   static unsigned count;  // number of objects
   int within(Unwindable*);
};

/* End of File */