/*
 * machdep_bsd.c
 *
 * BSD dependencies
 *
 * In here, we do command line parsing, getting time of day, and
 * other things that BSD is nice for.
 *
 */

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

machdep_init(argc, argv)
	int	argc;
	char	**argv;
{
	extern	FILE *rootfile();
	extern	char *rindex();
	extern	char *progname;
	extern	int interactive;
	extern	long sweeps;
	extern	char fileroot[];
	extern	char loadfile[];
	extern	char onlyfile[];
	extern	char cmdfile[];
	extern	int extract;
	extern	int testall;
	extern	int only;
	extern	int *onlys;
	extern	int numtotal;
	extern	int dispout;
	extern	long seed;
	extern	FILE *cmdfp;
	extern	FILE *onlyfp;
	extern	FILE *loadfp;
	extern	int no_cmd;
	extern	int ndtokens;
	extern	int box;
	extern	int disphid;
	extern	int array;
	char	*bp;
	register int i;
	int	nread;

	progname = argv[0];
	if ((bp = rindex(argv[0], '/')) != 0)
		progname = bp+1;
	time(&seed);
	argvec(argc, argv);
	srandom(seed);
	exp_init();
	if (argc == 1 || fileroot[0] == 0)
		interactive++;
	if (testall > 0 && sweeps == 0L && fileroot[0] != 0)
		sweeps = -1L;
	if (sweeps == 0L && extract == 0)
		interactive++;
	/*
	 * save the command (but we need a fileroot for this)
	 */
	if (no_cmd == 0 && fileroot[0]) {
		cmdfp = rootfile(cmdfile, "cmd", "a");
		for (i = 1; i < argc; i++)
			fprintf(cmdfp, "%s ", argv[i]);
		fprintf(cmdfp, "\n");
		fflush(cmdfp);
	}
	/*
	 * if we have a fileroot, set up our filenames and configure
	 * the network; otherwise, we'll have to wait until we're
	 * in the command loop.  setup() does a lot of stuff and calls
	 * a number of other routines.
	 */
	if (fileroot[0] != 0)
		(void) setup(fileroot);
	if (testall > 0 && sweeps == -1L)
		sweeps = ndtokens;
	/*
	 * open up box stream (must follow setup())
	 */
#ifdef X
	if (box) {
		if (dispout == 1) {
			box_create(BOX_OUT);
		} else if (disphid == 1) {
			box_create(BOX_HID);
		}
	}
#endif
	/*
	 * if a loadfile is specified read it in
	 */
	if (loadfile[0] != 0) {
		if (array == 0)
			loadweights1(loadfile);
		if (array == 1)
			loadweights2(loadfile);
	}
	if (only == 1) {
		if (array != 1){
			perror("ERROR: .only requires -a");
			exit(1);
		}
		onlyfp = rootfile(onlyfile, "only", "r");
		nread = 0;
		for (i = 0; i < numtotal; i++){
			nread += fscanf(onlyfp, "%d", (onlys+i));
		}
		if (nread != numtotal)
			inputerr(onlyfile, "only data");
	}
	sigsetup();
}

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

	signal(SIGHUP, onintr);
	signal(SIGQUIT, onintr);
	signal(SIGKILL, onintr);
	if (!debug) {
		/*signal(SIGFPE, urp);*/
		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	long run;
	extern	int 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 #: %ld\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);
}
