config.c

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

C
1,477
字号
/* * config - configuration routines * * Copyright (C) 1999-2006  David I. Bell and Landon Curt Noll * * Primary author:  David I. Bell * * 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.23 $ * @(#) $Id: config.c,v 29.23 2006/12/15 16:17:18 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/config.c,v $ * * Under source code control:	1991/07/20 00:21:56 * File existed as early as:	1991 * * Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/ */#include <stdio.h>#include "have_times.h"#if defined(HAVE_TIME_H)#include <time.h>#endif#if defined(HAVE_TIMES_H)#include <times.h>#endif#if defined(HAVE_SYS_TIME_H)#include <sys/time.h>#endif#if defined(HAVE_SYS_TIMES_H)#include <sys/times.h>#endif#include "calc.h"#include "token.h"#include "zrand.h"#include "block.h"#include "nametype.h"#include "config.h"#include "string.h"#include "custom.h"#include "have_strdup.h"#if !defined(HAVE_STRDUP)# define strdup(x) calc_strdup((CONST char *)(x))#endif /* HAVE_STRDUP *//* * deal with systems that lack a defined CLK_TCK */#if defined(CLK_TCK)# define CALC_HZ ((long)(CLK_TCK))#else# define CALC_HZ (0L)	/* no defined clock tick rate */#endif/* * Table of configuration types that can be set or read. */NAMETYPE configs[] = {	{"all",		CONFIG_ALL},	{"mode",	CONFIG_MODE},	{"mode2",	CONFIG_MODE2},	{"display",	CONFIG_DISPLAY},	{"epsilon",	CONFIG_EPSILON},	/*epsilonprec -- tied to epsilon not a configuration type*/	{"trace",	CONFIG_TRACE},	{"maxprint",	CONFIG_MAXPRINT},	{"mul2",	CONFIG_MUL2},	{"sq2",		CONFIG_SQ2},	{"pow2",	CONFIG_POW2},	{"redc2",	CONFIG_REDC2},	{"tilde",	CONFIG_TILDE},	{"tab",		CONFIG_TAB},	{"quomod",	CONFIG_QUOMOD},	{"quo",		CONFIG_QUO},	{"mod",		CONFIG_MOD},	{"sqrt",	CONFIG_SQRT},	{"appr",	CONFIG_APPR},	{"cfappr",	CONFIG_CFAPPR},	{"cfsim",	CONFIG_CFSIM},	{"outround",	CONFIG_OUTROUND},	{"round",	CONFIG_ROUND},	{"leadzero",	CONFIG_LEADZERO},	{"fullzero",	CONFIG_FULLZERO},	{"maxscan",	CONFIG_MAXSCAN},	    {"maxerr",	CONFIG_MAXSCAN},	/* old name for maxscan */	{"prompt",	CONFIG_PROMPT},	{"more",	CONFIG_MORE},	{"blkmaxprint", CONFIG_BLKMAXPRINT},	{"blkverbose",	CONFIG_BLKVERBOSE},	{"blkbase",	CONFIG_BLKBASE},	{"blkfmt",	CONFIG_BLKFMT},	{"resource_debug", CONFIG_RESOURCE_DEBUG},	{"lib_debug",	CONFIG_RESOURCE_DEBUG},	{"calc_debug",	CONFIG_CALC_DEBUG},	{"user_debug",	CONFIG_USER_DEBUG},	{"verbose_quit",CONFIG_VERBOSE_QUIT},	{"ctrl_d",	CONFIG_CTRL_D},	    {"ctrl-d",	CONFIG_CTRL_D},		/* alias for ctrl_d */	{"program",	CONFIG_PROGRAM},	{"basename",	CONFIG_BASENAME},	{"windows",	CONFIG_WINDOWS},	{"cygwin",	CONFIG_CYGWIN},	{"compile_custom",	CONFIG_COMPILE_CUSTOM},	{"allow_custom",	CONFIG_ALLOW_CUSTOM},	{"version",	CONFIG_VERSION},	{"baseb",	CONFIG_BASEB},	{"redecl_warn",	CONFIG_REDECL_WARN},	{"dupvar_warn",	CONFIG_DUPVAR_WARN},	{"hz",		CONFIG_HZ},	{NULL,		0}};/* * configurations */CONFIG oldstd = {	/* backward compatible standard configuration */	MODE_INITIAL,		/* current output mode */	MODE2_INITIAL,		/* current secondary output mode */	20,			/* current output digits for float or exp */	NULL,	/* loaded in at startup - default error for real functions */	EPSILONPREC_DEFAULT,	/* binary precision of epsilon */	FALSE,			/* tracing flags */	MAXPRINT_DEFAULT,	/* number of elements to print */	MUL_ALG2,		/* size of number to use multiply alg 2 */	SQ_ALG2,		/* size of number to use square alg 2 */	POW_ALG2,		/* size of modulus to use REDC for powers */	REDC_ALG2,		/* size of modulus to use REDC algorithm 2 */	TRUE,			/* ok to print a tilde on approximations */	TRUE,			/* ok to print tab before numeric values */	0,			/* quomod() default rounding mode */	2,			/* quotient // default rounding mode */	0,			/* mod % default rounding mode */	24,			/* sqrt() default rounding mode */	24,			/* appr() default rounding mode */	0,			/* cfappr() default rounding mode */	8,			/* cfsim() default rounding mode */	2,			/* output default rounding mode */	24,			/* round()/bround() default rounding mode */	FALSE,			/* ok to print leading 0 before decimal pt */	0,			/* ok to print trailing 0's */	MAXSCANCOUNT,		/* max scan errors before abort */	PROMPT1,		/* normal prompt */	PROMPT2,		/* prompt when inside multi-line input */	BLK_DEF_MAXPRINT,	/* number of octets of a block to print */	FALSE,			/* skip duplicate block output lines */	BLK_BASE_HEX,		/* block octet print base */	BLK_FMT_HD_STYLE,	/* block output format */	0,			/* internal calc debug level */	3,			/* calc resource file debug level */	0,			/* user defined debug level */	FALSE,			/* print Quit or abort executed messages */	CTRL_D_VIRGIN_EOF,	/* ^D only exits on virgin lines */	NULL,			/* our name */	NULL,			/* basename of our name */#if defined(_WIN32)	TRUE,			/* running under windows */#else	FALSE,			/* congrats, you are not using windows */#endif#if defined(__CYGWIN__)	TRUE,			/* compiled under cygwin */#else	FALSE,			/* not compiled with cygwin */#endif#if defined(CUSTOM)	TRUE,			/* compiled with -DCUSTOM */#else	FALSE,			/* compiled without -DCUSTOM */#endif	&allow_custom,		/* *TRUE=> custom functions are enabled */	NULL,			/* version */	BASEB,			/* base for calculations */	TRUE,			/* warn when redeclaring */	TRUE,			/* warn when variable names collide */};CONFIG newstd = {	/* new non-backward compatible configuration */	MODE_INITIAL,		/* current output mode */	MODE2_INITIAL,		/* current output mode */	20,			/* current output digits for float or exp */	NULL,	/* loaded in at startup - default error for real functions */	EPSILONPREC_DEFAULT,	/* binary precision of epsilon */	FALSE,			/* tracing flags */	MAXPRINT_DEFAULT,	/* number of elements to print */	MUL_ALG2,		/* size of number to use multiply alg 2 */	SQ_ALG2,		/* size of number to use square alg 2 */	POW_ALG2,		/* size of modulus to use REDC for powers */	REDC_ALG2,		/* size of modulus to use REDC algorithm 2 */	TRUE,			/* ok to print a tilde on approximations */	TRUE,			/* ok to print tab before numeric values */	0,			/* quomod() default rounding mode */	2,			/* quotient // default rounding mode */	0,			/* mod % default rounding mode */	24,			/* sqrt() default rounding mode */	24,			/* appr() default rounding mode */	0,			/* cfappr() default rounding mode */	8,			/* cfsim() default rounding mode */	24,			/* output default rounding mode */	24,			/* round()/bround() default rounding mode */	TRUE,			/* ok to print leading 0 before decimal pt */	0,			/* ok to print trailing 0's */	MAXSCANCOUNT,		/* max scan errors before abort */	"; ",			/* normal prompt */	";; ",			/* prompt when inside multi-line input */	BLK_DEF_MAXPRINT,	/* number of octets of a block to print */	FALSE,			/* skip duplicate block output lines */	BLK_BASE_HEX,		/* block octet print base */	BLK_FMT_HD_STYLE,	/* block output format */	0,			/* internal calc debug level */	3,			/* calc resource file debug level */	0,			/* user defined debug level */	FALSE,			/* print Quit or abort executed messages */	CTRL_D_VIRGIN_EOF,	/* ^D only exits on virgin lines */	NULL,			/* our name */	NULL,			/* basename of our name */#if defined(_WIN32)	TRUE,			/* running under windows */#else	FALSE,			/* congrats, you are not using windows */#endif#if defined(__CYGWIN__)	TRUE,			/* compiled under cygwin */#else	FALSE,			/* not compiled with cygwin */#endif#if defined(CUSTOM)	TRUE,			/* compiled with -DCUSTOM */#else	FALSE,			/* compiled without -DCUSTOM */#endif	&allow_custom,		/* *TRUE=> custom functions are enabled */	NULL,			/* version */	BASEB,			/* base for calculations */	TRUE,			/* warn when redeclaring */	TRUE,			/* warn when variable names collide */};CONFIG *conf = NULL;	/* loaded in at startup - current configuration *//* * Possible output modes. */static NAMETYPE modes[] = {	{"fraction",	MODE_FRAC},	{"frac",	MODE_FRAC},	{"integer",	MODE_INT},	{"int",		MODE_INT},	{"real",	MODE_REAL},	{"float",	MODE_REAL},	{"default",	MODE_INITIAL},	/* MODE_REAL */	{"scientific",	MODE_EXP},	{"sci",		MODE_EXP},	{"exp",		MODE_EXP},	{"hexadecimal", MODE_HEX},	{"hex",		MODE_HEX},	{"octal",	MODE_OCTAL},	{"oct",		MODE_OCTAL},	{"binary",	MODE_BINARY},	{"bin",		MODE_BINARY},	{"off",		MODE2_OFF},	{NULL,		0}};/* * Possible block base output modes */static NAMETYPE blk_base[] = {	{"hexadecimal", BLK_BASE_HEX},	{"hex",		BLK_BASE_HEX},	{"default",	BLK_BASE_HEX},	{"octal",	BLK_BASE_OCT},	{"oct",		BLK_BASE_OCT},	{"character",	BLK_BASE_CHAR},	{"char",	BLK_BASE_CHAR},	{"binary",	BLK_BASE_BINARY},	{"bin",		BLK_BASE_BINARY},	{"raw",		BLK_BASE_RAW},	{"none",	BLK_BASE_RAW},	{NULL,		0}};/* * Possible block output formats */static NAMETYPE blk_fmt[] = {	{"lines",	BLK_FMT_LINE},	{"line",	BLK_FMT_LINE},	{"strings",	BLK_FMT_STRING},	{"string",	BLK_FMT_STRING},	{"str",		BLK_FMT_STRING},	{"od_style",	BLK_FMT_OD_STYLE},	{"odstyle",	BLK_FMT_OD_STYLE},	{"od",		BLK_FMT_OD_STYLE},	{"hd_style",	BLK_FMT_HD_STYLE},	{"hdstyle",	BLK_FMT_HD_STYLE},	{"hd",		BLK_FMT_HD_STYLE},	{"default",	BLK_FMT_HD_STYLE},	{NULL,		0}};/* * Possible ctrl_d styles */static NAMETYPE ctrl_d[] = {	{"virgin_eof",	CTRL_D_VIRGIN_EOF},	{"virgineof",	CTRL_D_VIRGIN_EOF},	{"virgin",	CTRL_D_VIRGIN_EOF},	{"default",	CTRL_D_VIRGIN_EOF},	{"never_eof",	CTRL_D_NEVER_EOF},	{"nevereof",	CTRL_D_NEVER_EOF},	{"never",	CTRL_D_NEVER_EOF},	{"empty_eof",	CTRL_D_EMPTY_EOF},	{"emptyeof",	CTRL_D_EMPTY_EOF},	{"empty",	CTRL_D_EMPTY_EOF},	{NULL,		0}};/* * Possible binary config state values */#define TRUE_STRING	"true"#define FALSE_STRING	"false"static NAMETYPE truth[] = {	{TRUE_STRING,	TRUE},	{"t",		TRUE},	{"on",		TRUE},	{"yes",		TRUE},	{"y",		TRUE},	{"set",		TRUE},	{"1",		TRUE},	{FALSE_STRING,	FALSE},	{"f",		FALSE},	{"off",		FALSE},	{"no",		FALSE},	{"n",		FALSE},	{"unset",	FALSE},	{"0",		FALSE},	{NULL,		0}};/* * declare static functions */static long lookup_long(NAMETYPE *set, char *name);static char *lookup_name(NAMETYPE *set, long val);static int getlen(VALUE *vp, LEN *lp);/* * Given a string value which represents a configuration name, return * the configuration type for that string.  Returns negative type if * the string is unknown. * * given: *	name			configuration name */intconfigtype(char *name){	NAMETYPE *cp;		/* current config pointer */	for (cp = configs; cp->name; cp++) {		if (strcmp(cp->name, name) == 0)			return cp->type;	}	return -1;}/* * lookup_long - given a name and a NAMETYPE, return the int * * given: *	set		the NAMESET array of name/int pairs *	name		mode name * * returns: *	numeric value of the name or -1 if not found */static longlookup_long(NAMETYPE *set, char *name){	NAMETYPE *cp;		/* current config pointer */	for (cp = set; cp->name; cp++) {		if (strcmp(cp->name, name) == 0)			return cp->type;	}	return -1;}/* * lookup_name - given numeric value and a NAMETYPE, return the name * * given: *	set		the NAMESET array of name/int pairs *	val		numeric value to lookup * * returns: *	name of the value found of NULL */static char *lookup_name(NAMETYPE *set, long val){	NAMETYPE *cp;		/* current config pointer */	for (cp = set; cp->name; cp++) {		if (val == cp->type)			return cp->name;	}	return NULL;}/* * Check whether VALUE at vp is a LEN (32-bit signed integer) and if so, * copy that integer to lp. * * Return: 1 ==> not an integer, 2 ==> int > 2^31, 0 ==> OK, -1 ==> error */static intgetlen(VALUE *vp, LEN *lp){	if (vp->v_type != V_NUM || !qisint(vp->v_num))		return 1;	if (zge31b(vp->v_num->num))		return 2;	*lp = ztoi(vp->v_num->num);	if (*lp < 0)		return -1;	return 0;}/* * Set the specified configuration type to the specified value. * An error is generated if the type number or value is illegal. */voidsetconfig(int type, VALUE *vp){	NUMBER *q;	CONFIG *newconf;	/* new configuration to set */	long temp;	LEN len = 0;	char *p;	switch (type) {	case CONFIG_ALL:		newconf = NULL; /* firewall */		if (vp->v_type == V_STR) {			if (strcmp(vp->v_str->s_str, "oldstd") == 0) {				newconf = &oldstd;			} else if (strcmp(vp->v_str->s_str, "newstd") == 0) {				newconf = &newstd;			} else {				math_error("CONFIG alias not oldstd or newstd");				/*NOTREACHED*/			}		} else if (vp->v_type != V_CONFIG) {			math_error("non-CONFIG for all");			/*NOTREACHED*/		} else {			newconf = vp->v_config;		}

⌨️ 快捷键说明

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