/*
 * Copyright (c) 1994 David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 *
 * Modified for the Amiga by Steve Leblanc, Oct 1995
 *
 * Arbitrary precision calculator.
 */

#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>

#include "calc.h"
#include "func.h"
#include "opcodes.h"
#include "config.h"
#include "token.h"
#include "symbol.h"


/*
 * Common definitions
 */
long maxprint;		/* number of elements to print */
int abortlevel;		/* current level of aborts */
BOOL inputwait;		/* TRUE if in a terminal input wait */
jmp_buf jmpbuf;		/* for errors */

static int q_flag = FALSE;	/* TRUE => don't execute rc files */

/* AMIGA: got rid of the bindings path variable */
char *calcpath;		/* CALCPATH or default */
char *calcrc;		/* CALCRC or default */
char *helpdir;		/* CALCHELP or default */
char *home;		/* HOME or default */
static char *pager;	/* PAGER or default */
int stdin_tty = TRUE;	/* TRUE if stdin is a tty */

static void intint();	/* interrupt routine */
static void initenv();	/* initialize/default special environment vars */

#include <stdlib.h>

extern void file_init();
extern void zio_init();


/*
 * Top level calculator routine.
 */
main(int argc,char **argv)
{
	static char *str;	/* current option string or expression */
	char cmdbuf[MAXCMD+1];	/* command line expression */

	file_init();
	zio_init();
	initenv();
	argc--;
	argv++;
	while ((argc > 0) && (**argv == '-')) {
		for (str = &argv[0][1]; *str; str++) switch (*str) {
			case 'h':
				givehelp(DEFAULTCALCHELP);
				exit(0);
				break;
			case 'q':
				q_flag = TRUE;
				break;
			default:
				printf("Unknown option\n");
				exit(1);
		}
		argc--;
		argv++;
	}
	str = cmdbuf;
	*str = '\0';
	while (--argc >= 0) {
		*str++ = ' ';
		strcpy(str, *argv++);
		str += strlen(str);
		str[0] = '\n';
		str[1] = '\0';
	}
	str = cmdbuf;

	if (*str == '\0') {
		str = NULL;
		stdin_tty = 1;	/* AMIGA: assume a tty if no cmd_arg */

		if (stdin_tty) {
			version(stdout);
			printf("[Type \"exit\" to exit, or \"help\" for help.]\n\n");
		}
	}
	if (setjmp(jmpbuf) == 0) {
		initmasks();
		inittokens();
		initglobals();
		initfunctions();
		initstack();
		resetinput();
		math_cleardiversions();
		math_setfp(stdout);
		math_setmode(MODE_INITIAL);
		math_setdigits((long)DISPLAY_DEFAULT);
		maxprint = MAXPRINT_DEFAULT;
		_epsilon_ = atoq(EPSILON_DEFAULT);
		_epsilonprec_ = qprecision(_epsilon_);
		if (str || !stdin_tty) {
			if (q_flag == FALSE) {
				runrcfiles();
				q_flag = TRUE;
			}
			if (str)
				(void) openstring(str);
			else
				(void) openterminal();
			getcommands(FALSE);
			exit(0);
		}
	}
	if (str)
		exit(1);
	abortlevel = 0;
	_math_abort_ = FALSE;
	inputwait = FALSE;
	(void) signal(SIGINT, intint);
	math_cleardiversions();
	math_setfp(stdout);
	resetscopes();
	resetinput();
	if (q_flag == FALSE) {
		runrcfiles();
		q_flag = TRUE;
	}
	(void) openterminal();
	getcommands(TRUE);
	exit(0);
	/*NOTREACHED*/
}


/*
 * initenv - obtain CALCPATH, CALCRC, CALCHELP, HOME, and PAGER values
 *
 * If CALCPATH, CALCRC, CALCHELP, or PAGER do not exist,
 * use the default values.  If PAGER is an empty string, also
 * use a default value. If HOME does not exist, or is empty, use S:
 *
 * AMIGA: Heavily modified to use the environment variables I decided
 *        for the Amiga.
 */
static void
initenv()
{
	/* determine the CALCPATH value */
	calcpath = getenv("CALCPATH");
	if (calcpath == NULL)
		calcpath = DEFAULTCALCPATH;

	/* determine the CALCRC value */
	calcrc = getenv("CALCRC");
	if (calcrc == NULL)
		calcrc = DEFAULTCALCRC;

	/* determine the CALCHELP value */
	helpdir = getenv("CALCHELP");
	if(helpdir == NULL)
		helpdir = DEFAULTHELPDIR;

	/* determine the HOME value */
	home = getenv("HOME");
	if (home == NULL || home[0] == '\0')
		home = DEFAULTHOME;
  
	/* determine the PAGER value */
	pager = getenv("PAGER");
	if (pager == NULL || *pager == '\0')
		pager = DEFAULTCALCPAGER;
}

void
givehelp(char *type)
{
	char *helpcmd;		/* what to execute to print help */

	/* catch the case where we just print the index */
	if (type == NULL) {
		type = DEFAULTCALCHELP;		/* the help index file */
	}

	/* AMIGA: Command string modified to work on Amiga */
  /* form the help command name */
	helpcmd = (char *)malloc(strlen(pager)+1+strlen(helpdir)+1+strlen(type)+1);
	sprintf(helpcmd,"%s %s%s",pager,helpdir,type);

	/* execute the help command */
	system(helpcmd);
	free(helpcmd);
}

/*
 * Interrupt routine.
 */
/*ARGSUSED*/
static void
intint(int arg)
{
	(void)signal(SIGINT,intint);
	if (inputwait || (++abortlevel >= ABORT_NOW))
		math_error("\nABORT");
	if (abortlevel >= ABORT_MATH)
		_math_abort_ = TRUE;
	printf("\n[Abort level %d]\n", abortlevel);
}

/* END CODE */
