
/*
 * 
 * POSTGRES Data Base Management System
 * 
 * Copyright (c) 1988 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 provided only that the the requestor give the University
 * of California a free licence to any derived software for educational
 * and research purposes.  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.
 * 
 */



/*LINTLIBRARY*/
#include <stdio.h>

#include "exception.h"

#ifndef lint
#ifdef	SCCS
static char sccsid[] = "%W% (serge) %G%";
#endif	/* defined(SCCS) */
#ifdef	RCS
static char rcsid[] = "$Header: exception.c,v 1.1 89/01/17 05:55:16 cimarron Exp $";
#endif	/* defined(RCS) */
#endif	/* !defined(lint) */

ExcFrame		*ExcCurFrameP;

static	ExcProc		*ExcUnCaughtP;

void
ExcPrint(excP, detail, data, msg)
	Exception	*excP;
	ExcDetail	detail;
	ExcData		data;
	ExcMsg		msg;
{
	extern	int	errno;
	extern	int	sys_nerr;
	extern	char	*sys_errlist[];

#ifdef	lint
	data = data;
#endif

	(void) fflush(stdout);	/* In case stderr is buffered */

#if	0
	if (ProgramName != NULL && *ProgramName != '\0')
		(void) fprintf(stderr, "%s: ", ProgramName);
#endif

	if (msg != NULL)
		(void) fprintf(stderr, "%s", msg);
	else if (excP->msg != NULL)
		(void) fprintf(stderr, "%s", excP->msg);
	else
#ifdef	lint
		(void) fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", excP);
#else
		(void) fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", (long)excP);
#endif

	(void) fprintf(stderr, " (%ld)", detail);

	if (errno > 0 && errno < sys_nerr &&
	    sys_errlist[errno] != NULL && sys_errlist[errno][0] != '\0')
		(void) fprintf(stderr, " [%s]", sys_errlist[errno]);
	else if (errno != 0)
		(void) fprintf(stderr, " [Error %d]", errno);

	(void) fprintf(stderr, "\n");

	(void) fflush(stderr);
}

/*ARGSUSED*/
void
ExcAbort(excP, detail, data, msg)
	Exception	*excP;
	ExcDetail	detail;
	ExcData		data;
	ExcMsg		msg;
{
	extern	char	*getenv();
	char		*excAbort;

	excAbort = getenv("EXCABORT");
	if (excAbort != NULL && excAbort[0] != '\0')
		abort();
	else
		exit(127);
}

ExcProc *
ExcGetUnCaught()
{
	return (ExcUnCaughtP);
}

ExcProc *
ExcSetUnCaught(newP)
	ExcProc	*newP;
{
	ExcProc	*oldP = ExcUnCaughtP;

	ExcUnCaughtP = newP;

	return (oldP);
}

void
ExcUnCaught(excP, detail, data, msg)
	Exception	*excP;
	ExcDetail	detail;
	ExcData		data;
	ExcMsg		msg;
{
	ExcPrint(excP, detail, data, msg);

	ExcAbort(excP, detail, data, msg);
	/*NOTREACHED*/
}

void
ExcRaise(excP, detail, data, msg)
	Exception	*excP;
	ExcDetail	detail;
	ExcData		data;
	ExcMsg		msg;
{
	register ExcFrame	*efp;

	efp = ExcCurFrameP;
	if (efp == NULL) {
		if (ExcUnCaughtP != NULL)
			(*ExcUnCaughtP)(excP, detail, data, msg);

		ExcUnCaught(excP, detail, data, msg);
		/*NOTREACHED*/
	} else {
		efp->id		= excP;
		efp->detail	= detail;
		efp->data	= data;
		efp->msg	= msg;

		ExcCurFrameP = efp->link;

		longjmp(efp->context, 1);
		/*NOTREACHED*/
	}
	/*NOTREACHED*/
}
