// LISTING 4

#ifndef EXH_H
#define EXH_H

#include <mem.h>
#include <string.h>
#include "JmpStack.h"
#include "Exception.h"

typedef void(*PFV)();
extern void terminate();
extern PFV set_terminate(PFV);
extern void unexpected();
extern PFV set_unexpected(PFV);

class ExH {
public:
	enum {BUFSIZE=2024};

private:
	friend PFV set_terminate(PFV);
	friend PFV set_unexpected(PFV);
	friend void terminate();
	friend void unexpected();
	static PFV terminate;
	static PFV unexpected;

	static char safeSpace[BUFSIZE];

public:
	static Exception* lastEx;	// Pointer to safeSpace
	static JmpStack stk;
	static void throw(Exception&);
};

inline void ExH::throw (Exception& ex)
{
	// Copy exception to a safe place
	if(ExH::lastEx != &ex)
		memcpy(ExH::safeSpace, &ex, ex.size());

	// longjmp to last try
	longjmp(ExH::stk--, ex.type());
}

#endif
