lib_calc.c

来自「Calc Software Package for Number Calc」· C语言 代码 · 共 890 行 · 第 1/2 页

C
890
字号
/* * lib_calc - calc link library initialization and shutdown routines * * Copyright (C) 1999-2006  Landon Curt Noll * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL.  You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA. * * @(#) $Revision: 29.14 $ * @(#) $Id: lib_calc.c,v 29.14 2006/05/21 07:28:54 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/lib_calc.c,v $ * * Under source code control:	1996/06/17 18:06:19 * File existed as early as:	1996 * * chongo <was here> /\oo/\	http://www.isthe.com/chongo/ * Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/ */#include <stdio.h>#include <setjmp.h>#include <signal.h>#if !defined(_WIN32)# include <pwd.h>#endif#include "calc.h"#include "zmath.h"#include "zrandom.h"#include "conf.h"#include "token.h"#include "symbol.h"#include "func.h"#include "have_strdup.h"#if !defined(HAVE_STRDUP)# define strdup(x) calc_strdup((CONST char *)(x))#endif /* HAVE_STRDUP */#include "have_unistd.h"#if defined(HAVE_UNISTD_H)#include <unistd.h>#endif#include "have_stdlib.h"#if defined(HAVE_STDLIB_H)#include <stdlib.h>#endif#include "terminal.h"#if defined(USE_TERMIOS)# include <termios.h>typedef struct termios ttystruct;#elif defined(USE_TERMIO)# include <termio.h>typedef struct termio ttystruct;#elif defined(USE_SGTTY)# include <sys/ioctl.h>typedef struct sgttyb ttystruct;#elsetypedef struct {int fd;} ttystruct;#endif#if !defined(_WIN32)# if !defined(USE_SGTTY) && !defined (USE_TERMIOS) && !defined(USE_TERMIO)-=*#*=- A Windoz free system without termio, termios or sgtty!!! -=*#*=--=*#*=- We do not know how to compile for such a host, sorry!!!! -=*#*=-# endif#endif /* Windoz *//* * in case we do not have certain .h files */#if !defined(HAVE_STDLIB_H) && !defined(HAVE_UNISTD_H)#if !defined(HAVE_UID_T) && !defined(_UID_T)typedef unsigned short uid_t;#endifextern char *getenv();extern uid_t geteuid();#endif/* * Common definitions */int use_old_std = FALSE;	/* TRUE => use old classic configuration */int abortlevel;			/* current level of aborts */BOOL inputwait;			/* TRUE if in a terminal input wait */jmp_buf jmpbuf;			/* for errors */char *program = "calc";		/* our name */char *base_name = "calc";	/* basename of our name */char cmdbuf[MAXCMD+1+1+1];	/* command line expression + "\n\0" + guard */run run_state = RUN_ZERO;	/* calc startup run state *//* * global permissions */int allow_read = TRUE;	/* FALSE => may not open any files for reading */int allow_write = TRUE; /* FALSE => may not open any files for writing */int allow_exec = TRUE;	/* FALSE => may not execute any commands *//* * global flags */int p_flag = FALSE;	/* TRUE => pipe mode */int q_flag = FALSE;	/* TRUE => don't execute rc files */int u_flag = FALSE;	/* TRUE => unbuffer stdin and stdout */int d_flag = FALSE;	/* TRUE => disable heading, resource_debug == 0 */int c_flag = FALSE;	/* TRUE => continue on error if permitted */int i_flag = FALSE;	/* TRUE => go interactive if permitted */int s_flag = FALSE;	/* TRUE => keep args as strings for argv() *//* * global values */char *calcpath = NULL;		/* $CALCPATH or default */char *calcrc = NULL;		/* $CALCRC or default */char *calcbindings = NULL;	/* $CALCBINDINGS or default */char *home = NULL;		/* $HOME or default */char *pager = NULL;		/* $PAGER or default */char *shell = NULL;		/* $SHELL or default */int stdin_tty = FALSE;		/* TRUE if stdin is a tty */int havecommands = FALSE;	/* TRUE if have one or more cmd args */long stoponerror = 0;		/* >0 => stop, <0 => continue, ==0 => use -c */int post_init = FALSE;		/* TRUE setjmp for math_error is ready */BOOL abort_now = FALSE;		/* TRUE => go interactive now, if permitted */int argc_value = 0;		/* count of argv[] strings for argv() builtin */char **argv_value = NULL;	/* argv[] strings for argv() builtin */int no_env = FALSE;		/* TRUE (-e) => ignore env vars on startup */long errmax = ERRMAX;		/* if >= 0,  maximum value for errcount */NUMBER *epsilon_default;	/* default allowed error for float calcs */char *calc_debug = NULL;	/* !=NULL => value of config("calc_debug") */char *resource_debug = NULL;	/* !=NULL => config("resource_debug") value */char *user_debug = NULL;	/* !=NULL => value of config("user_debug") *//* * initialization functions */extern void math_setfp(FILE *fp);extern void file_init(void);extern void zio_init(void);extern void initialize(void);extern void reinitialize(void);/* * static declarations */static int init_done = 0;		/* 1 => we already initialized */static int *fd_setup = NULL;		/* fd's setup for interaction or -1 */static int fd_setup_len = 0;		/* number of fd's in fd_setup */static ttystruct *fd_orig = NULL;	/* fd original state */static ttystruct *fd_cur = NULL;	/* fd current state */static void initenv(void);		/* setup calc environment */static int find_tty_state(int fd);	/* find slot for saved tty state *//* * libcalc_call_me_first - users of libcalc.a must call this function first! * * Anything that uses libcalc.a MUST call this function first before doing * any other libcalc.a processing. */voidlibcalc_call_me_first(void){	char *p;	/*	 * do nothing if we are initialized already	 */	if (init_done) {		return;	}	/*	 * Disable SIGPIPE so that the pipe to the help file pager will	 * not stop calc.	 */#if !defined(_WIN32)	(void) signal(SIGPIPE, SIG_IGN);#endif	/*	 * determine the basename	 */	if (program != NULL) {		p = strrchr(program, '/');#if defined(_WIN32) || defined(__MSDOS__)		if (p == NULL) {			p = strrchr(program, '\\');		}#endif		if (p == NULL) {			base_name = program;		} else {			base_name = p+1;		}	}	/*	 * initialize old and new configuration values	 */	newstd.epsilon = &_qonesqbase_; /* magic to fake early str2q() */	newstd.program = strdup(program);	newstd.base_name = strdup(base_name);	newstd.version = strdup(version());	conf = config_copy(&newstd); /* more magic to fake early str2q() */	conf->tab_ok = FALSE;	newstd.epsilon = str2q(EPSILON_DEFAULT);	oldstd.epsilon = str2q(EPSILON_DEFAULT);	/*	 * make newstd our default config, unless -O	 */	config_free(conf);	if (use_old_std) {		conf = config_copy(&oldstd);	} else {		conf = config_copy(&newstd);	}	/*	 * -d turns off resource_debug and tilde	 */	if (d_flag) {		conf->resource_debug = 0;		conf->tilde_ok = 0;	}	/*	 * -p turns off tab	 */	if (p_flag) {		conf->tab_ok = 0;	}	/*	 * -D flags can change calc_debug, resource_debug of user_debug	 */	if (calc_debug) {		conf->calc_debug = strtol(calc_debug, NULL, 0);	}	if (resource_debug) {		conf->resource_debug = strtol(resource_debug, NULL, 0);	}	if (user_debug) {		conf->user_debug = strtol(user_debug, NULL, 0);	}	/*	 * initialize	 */	initialize();	/*	 * ready to rock & roll ..	 */	if (conf->calc_debug & CALCDBG_RUNSTATE) {		printf("libcalc_call_me_first: run_state from %s to %s\n",		    run_state_name(run_state),		    run_state_name(RUN_BEGIN));	}	run_state = RUN_BEGIN;	init_done = 1;	return;}/* * initialize - perform the required calc initializations */voidinitialize(void){	/*	 * ZVALUE io initialization	 */	zio_init();	/*	 * process the environment	 */	initenv();	/*	 * initialize I/O	 */	file_init();	/*	 * initialize file I/O	 */	resetinput();	/*	 * initialize calc internal data structures	 */	inittokens();	initglobals();	initfunctions();	initstack();	/*	 * initialize calc math	 */	math_cleardiversions();	math_setfp(stdout);	math_setmode(MODE_INITIAL);	math_setdigits(DISPLAY_DEFAULT);	conf->maxprint = MAXPRINT_DEFAULT;}/* * reinitialize - reinitialize after a longjmp */voidreinitialize(void){	/*	 * process commands (from stdin, not the command line)	 */	abortlevel = 0;	_math_abort_ = FALSE;	inputwait = FALSE;	math_cleardiversions();	math_setfp(stdout);	resetscopes();	resetinput();	inittokens();	(void) openterminal();}/* * cvmalloc_error - for users of the SGI Workshop Debugger * * usage: *	message - error message passed along via libmalloc_cv.a */voidcvmalloc_error(char *message){	/* firewall */	if (message == NULL) {		fprintf(stderr, "cvmalloc_error message is NULL\n");		return;	}	/* print message and return */	fprintf(stderr, "cvmalloc_error: %s\n", message);	return;}/* * 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 voidinitenv(void){#if !defined(_WIN32)	struct passwd *ent;		/* our password entry */#endif	char *c;	/* determine the $CALCPATH value */	c = (no_env ? NULL : getenv(CALCPATH));	calcpath = (c ? strdup(c) : NULL);	if (calcpath == NULL)		calcpath = DEFAULTCALCPATH;	/* determine the $CALCRC value */	c = (no_env ? NULL : getenv(CALCRC));	calcrc = (c ? strdup(c) : NULL);	if (calcrc == NULL)		calcrc = DEFAULTCALCRC;	if (strlen(calcrc) > MAX_CALCRC) {		math_error("The $CALCRC variable is longer than %d chars",			   MAX_CALCRC);		/*NOTREACHED*/	}	/* determine the $CALCBINDINGS value */	c = (no_env ? NULL : getenv(CALCBINDINGS));	calcbindings = (c ? strdup(c) : NULL);	if (calcbindings == NULL)		calcbindings = DEFAULTCALCBINDINGS;	/* determine the $HOME value */	c = (no_env ? NULL : getenv(HOME));	home = (c ? strdup(c) : NULL);#if defined(_WIN32)	if (home == NULL || home[0] == '\0') {		/* just assume . is home if all else fails */		home = ".";	}#else /* Windoz free systems */	if (home == NULL || home[0] == '\0') {		size_t pw_dir_len;		ent = (struct passwd *)getpwuid(geteuid());		if (ent == NULL) {			/* just assume . is home if all else fails */			home = ".";		}		pw_dir_len = strlen(ent->pw_dir);		home = (char *)malloc(pw_dir_len+1);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?