/* 
 * POSTGRES Data Base Management System
 * 
 * Copyright (c) 1989 Regents of the University of California
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for educational, research, and non-profit purposes and
 * without fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation, and that
 * the name of the University of California not be used in advertising
 * or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Permission to incorporate this
 * software into commercial products can be obtained from the Campus
 * Software Office, 295 Evans Hall, University of California, Berkeley,
 * Ca., 94720.  The University of California makes no representations
 * about the suitability of this software for any purpose.  It is
 * provided "as is" without express or implied warranty.
 */ 
/*
 * exc.h --
 *	POSTGRES exception handling definitions.
 */

#ifndef	ExcIncluded		/* Include this file only once */
#define ExcIncluded	1

/*
 * Identification:
 */
#define EXC_H	"$Header: RCS/exc.h,v 1.6 89/09/25 11:26:49 cimarron Exp $"

#ifndef	C_H
#include "c.h"
#endif

#include <setjmp.h>

/*
 * EnableExceptionHandling --
 *	Enables/disables the exception handling system.
 *
 * Note:
 *	This must be called before any exceptions occur.  I.e., call this first!
 *	This routine will not return if an error is detected.
 *	This does not follow the usual Enable... protocol.
 *	This should be merged more closely with the error logging and tracing
 *	packages.
 *
 * Exceptions:
 *	none
 */
extern
void
EnableExceptionHandling ARGS((
	pgbool	on
));

/* START HERE */

/*
 * ExcMessage and Exception are now defined in c.h
 */
#if	0
typedef char*		ExcMessage;

typedef struct Exception {
	ExcMessage	message;
} Exception;
#endif	/* 0 */

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;
	ExcMessage	message;
} 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, message) \
	ExcRaise(&(x), (ExcDetail)(t), (ExcData)(d), (ExcMessage)(message))

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

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

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

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

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

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

/*
 * ExcAbort --
 *	Handler for uncaught exception.
 *
 * Note:
 *	Define this yourself if you don't want the default action (dump core).
 */
extern
void
ExcAbort ARGS((
	Exception*	exceptionP,
	ExcDetail	detail,
	ExcData		data,
	ExcMessage	message
));

#endif	/* !defined(ExcIncluded) */
