4.4BSD/usr/src/contrib/calc-1.26.4/calc.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright (c) 1993 David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 *
 * Arbitrary precision calculator.
 */

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

#include "calc.h"
#include "hist.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 */

char *calcpath;		/* $CALCPATH or default */
char *calcrc;		/* $CALCRC or default */
char *calcbindings;	/* $CALCBINDINGS or default */
char *home;		/* $HOME or default */
static char *pager;	/* $PAGER or default */
char *shell;		/* $SHELL or default */

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

#if defined(__STDC__)
#include <unistd.h>
#include <stdlib.h>
#else
extern struct passwd *getpwuid();
#if defined (UID_T)
typedef unsigned short uid_t;
#endif
extern char *getenv();
extern uid_t geteuid();
#endif


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

	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;
		printf("C-style arbitrary precision calculator.\n");
		version(stdout);
		printf("[Type \"exit\" to exit, or \"help\" for help.]\n\n");

		switch (hist_init(calcbindings)) {
		case HIST_NOFILE:
			fprintf(stderr,
				"Cannot open key bindings file \"%s\", fancy editing disabled.\n",
				calcbindings);
			break;

		case HIST_NOTTY:
			fprintf(stderr,
				"Cannot set terminal modes, fancy editing disabled.\n");
			break;
		}
	}
	if (setjmp(jmpbuf) == 0) {
		initmasks();
		inittokens();
		initglobals();
		initfunctions();
		initstack();
		resetinput();
		cleardiversions();
		setfp(stdout);
		set_mode(MODE_INITIAL);
		setdigits((long)DISPLAY_DEFAULT);
		maxprint = MAXPRINT_DEFAULT;
		_epsilon_ = atoq(EPSILON_DEFAULT);
		_epsilonprec_ = qprecision(_epsilon_);
		if (str) {
			if (q_flag == FALSE) {
				runrcfiles();
				q_flag = TRUE;
			}
			(void) openstring(str);
			getcommands();
			exit(0);
		}
	}
	if (str)
		exit(1);
	abortlevel = 0;
	_math_abort_ = FALSE;
	inputwait = FALSE;
	(void) signal(SIGINT, intint);
	cleardiversions();
	setfp(stdout);
	resetinput();
	if (q_flag == FALSE) {
		runrcfiles();
		q_flag = TRUE;
	}
	(void) openterminal();
	getcommands();
	exit(0);
	/*NOTREACHED*/
}


/*
 * initenv - obtain $CALCPATH, $CALCRC, $CALCBINDINGS, $HOME, $PAGER
 * and $SHELL values
 *
 * If $CALCPATH, $CALCRC, $CALCBINDINGS, $PAGER or $SHELL do not exist,
 * use the default values.  If $PAGER or $SHELL is an empty string, also
 * use a default value. If $HOME does not exist, or is empty, use the home
 * directory information from the password file.
 */
static void
initenv()
{
	struct passwd *ent;		/* our password entry */

	/* 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 $CALCBINDINGS value */
	calcbindings = getenv(CALCBINDINGS);
	if (calcbindings == NULL) {
		calcbindings = DEFAULTCALCBINDINGS;
	}

	/* determine the $HOME value */
	home = getenv(HOME);
	if (home == NULL || home[0] == '\0') {
		ent = getpwuid(geteuid());
		if (ent == NULL) {
			/* just assume . is home if all else fails */
			home = ".";
		}
		home = (char *)malloc(strlen(ent->pw_dir)+1);
		strcpy(home, ent->pw_dir);
	}

	/* determine the $PAGER value */
	pager = getenv(PAGER);
	if (pager == NULL || *pager == '\0') {
		pager = DEFAULTCALCPAGER;
	}

	/* determine the $SHELL value */
	shell = getenv(SHELL);
	if (shell == NULL)
		shell = DEFAULTSHELL;
}


void
givehelp(type)
	char *type;		/* the type of help to give, NULL => index */
{
	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 */
	}

	/* form the help command name */
	helpcmd = (char *)malloc(
		sizeof("if [ ! -d \"")+sizeof(HELPDIR)+1+strlen(type)+
		sizeof("\" ];then ")+
		strlen(pager)+1+1+sizeof(HELPDIR)+1+strlen(type)+1+1+
		sizeof(";else echo no such help;fi"));
	sprintf(helpcmd, 
	    "if [ -r \"%s/%s\" ];then %s \"%s/%s\";else echo no such help;fi", 
	    HELPDIR, type, pager, HELPDIR, type);

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


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

/* END CODE */