/*
 * Copyright (1987) Jeff Elman.  University of California, San Diego
 * This software may be redistributed without charge; this notice
 * should be preserved.
 */

#include <stdio.h>
#include <signal.h>
#include <math.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/types.h>
#include "X/box.h"
#include "defs.h"
#include <signal.h>
#include <setjmp.h>

sigsetup()
{
	int	onintr();
	int	urp();
	extern	int debug;

	signal(SIGHUP, onintr);
	signal(SIGQUIT, onintr);
	signal(SIGKILL, onintr);
	if (!debug) {
#ifdef sun
#ifdef mc68000
		extern	int sigfpe_handler();
		signal(SIGFPE, sigfpe_handler);
#endif mc68000
#else
		signal(SIGFPE, urp);
#endif
		signal(SIGINT, onintr);
		signal(SIGBUS, urp);
		signal(SIGSEGV, urp);
		signal(SIGILL, urp);
	}
}

onintr(signo, code)
	int     signo;
	int	code;
{
	extern	char *sys_siglist[];
	extern	int array;
	extern	int interactive;
	extern	int val;
	extern	jmp_buf env;
	extern	char fileroot[];

	fprintf(stderr, "Signal %s", sys_siglist[signo]);
	if (code != 0)
		fprintf(stderr, "[code %d]\n", code);
	else
		fprintf(stderr, "\n");
	if (interactive) {
		longjmp(env, val);
	} else {
		if (array == 0)
			saveweights1(fileroot);
		else if (array == 1)
			saveweights2(fileroot);
		exit(signo);
	}
}

urp(signo, code)
	int     signo;
	int	code;
{
	extern	char *sys_siglist[];
	extern	int run, cur_token;
	extern	u_int cur_type;

	fprintf(stderr, "Signal %s", sys_siglist[signo]);
	if (code != 0)
		fpe_errors(code);
	fprintf(stderr, "\n");
	fprintf(stderr, " run #: %d\n", run);
	fprintf(stderr, " cur token: %d\n", cur_token);
	fprintf(stderr, " cur type: %u\n", cur_type);
	signal(SIGILL, SIG_DFL);
	abort();
}

struct fpe_ex {
	int code;
	char *desc;
};

struct fpe_ex fpe[] = {
#ifdef sun
#ifdef mc68000
	FPE_CHKINST_TRAP, "chk (chk2) instruction",
	FPE_TRAPV_TRAP, "trap instruction",
	FPE_FLTBSUN_TRAP, "branch or set on unordered condition",
	FPE_FLTNAN_TRAP, "floating NaN trap",
	FPE_FPA_ENABLE, "fpa not enabled",
	FPE_FPA_ERROR, "fpa arithmetic exception",
#endif 
	FPE_INTDIV_TRAP, "integer divide by zero",
	FPE_FLTINEX_TRAP, "floating inexact result",
	FPE_FLTDIV_TRAP, "floating divide by zero",
	FPE_FLTUND_TRAP, "floating underflow",
	FPE_FLTOPERR_TRAP, "floating operand error",
	FPE_FLTOVF_TRAP, "floating overflow",
#endif
#ifdef vax
	FPE_INTOVF_TRAP, "integer overflow",
	FPE_INTDIV_TRAP, "integer divide by zero",
	FPE_FLTOVF_TRAP, "floating overflow",
	FPE_FLTDIV_TRAP, "floating/decimal divide by zero",
	FPE_FLTUND_TRAP, "floating underflow",
	FPE_DECOVF_TRAP, "decimal overflow",
	FPE_SUBRNG_TRAP, "subscript out of range",
	FPE_FLTOVF_FAULT, "floating overflow fault",
	FPE_FLTDIV_FAULT, "divide by zero floating fault",
	FPE_FLTUND_FAULT, "floating underflow fault",
#endif
	0, 0,
};

fpe_errors(code)
	int	code;
{
	int	i;

	for (i=0; fpe[i].desc != 0; i++) {
		if (code == fpe[i].code) {
			fprintf(stderr, "; type is \"%s\"", fpe[i].desc);
			return;
		}
	}
	fprintf(stderr, "; code %x", code);
}
