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 + -
显示快捷键?