#ifndef	ExcIncluded
#define ExcIncluded	1 /* %W% (serge) %G% */ /* $Header: /private/postgres/src/lib/H/utils/RCS/exception.h,v 1.2 1989/09/05 17:05:38 mao Version_2 $ */

#include <setjmp.h>

typedef char*		ExcMsg;

typedef struct {
	ExcMsg	msg;
} Exception;

typedef jmp_buf		ExcContext;
typedef Exception*	ExcId;
typedef long		ExcDetail;
typedef char*		ExcData;

typedef struct ExcFrame {
	struct ExcFrame	*link;
	ExcContext	context;
	ExcId		id;
	ExcDetail	detail;
	ExcData		data;
	ExcMsg		msg;
} ExcFrame;

extern	ExcFrame*	ExcCurFrameP;

#define	ExcBegin()							\
	{								\
		ExcFrame	exception;				\
									\
		exception.link = ExcCurFrameP; 				\
		if (setjmp(exception.context) == 0) {			\
			ExcCurFrameP = &exception;			\
			{
#define	ExcExcept()							\
			}						\
			ExcCurFrameP = exception.link;			\
		} else {						\
			{
#define	ExcEnd()							\
			}						\
		}							\
	}

#define raise(exception)	raise2((exception), 0)
#define raise2(x, detail)	raise3((x), (detail), 0)
#define raise3(x, t, data)	raise4((x), (t), (data), 0)

#define raise4(x, t, d, msg) \
	ExcRaise(&(x), (ExcDetail)(t), (ExcData)(d), (ExcMsg)(msg))

#define	reraise() \
	raise4(exception.id, exception.detail, exception.data, exception.msg)

typedef	void	ExcProc(/* Exception*, ExcDetail, ExcData, ExcMsg */);

extern	void	ExcRaise(/* Exception*, ExcDetail, ExcData, ExcMsg */);

extern	ExcProc	*ExcGetUnCaught();
extern	ExcProc	*ExcSetUnCaught(/* ExcProc * */);

extern	void	ExcUnCaught(/* Exception*, ExcDetail, ExcData, ExcMsg */);

extern	void	ExcPrint(/* Exception*, ExcDetail, ExcData, ExcMsg */);
extern	char*	ProgramName;

extern	void	ExcAbort(/* Exception*, ExcDetail, ExcData, ExcMsg */);

#endif	/* !defined(ExcIncluded) */
