⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbol.c

📁 Calc Software Package for Number Calc
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * symbol - global and local symbol routines * * Copyright (C) 1999-2006  David I. Bell and Ernest Bowen * * 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.6 $ * @(#) $Id: symbol.c,v 29.6 2006/06/20 10:28:06 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/symbol.c,v $ * * Under source code control:	1990/02/15 01:48:23 * File existed as early as:	before 1990 * * Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/ */#include <stdio.h>#include "calc.h"#include "token.h"#include "symbol.h"#include "string.h"#include "opcodes.h"#include "func.h"#define HASHSIZE	37	/* size of hash table */extern FILE *f_open(char *name, char *mode);static int filescope;		/* file scope level for static variables */static int funcscope;		/* function scope level for static variables */static STRINGHEAD localnames;	/* list of local variable names */static STRINGHEAD globalnames;	/* list of global variable names */static STRINGHEAD paramnames;	/* list of parameter variable names */static GLOBAL *globalhash[HASHSIZE];	/* hash table for globals */static void printtype(VALUE *);static void unscope(void);static void addstatic(GLOBAL *);static long staticcount = 0;static long staticavail = 0;static GLOBAL **statictable;/* * Hash a symbol name so we can find it in the hash table. * Args are the symbol name and the symbol name size. */#define HASHSYM(n, s) ((unsigned)((n)[0]*123 + (n)[s-1]*135 + (s)*157) % HASHSIZE)/* * Initialize the global symbol table. */voidinitglobals(void){	int i;		/* index counter */	for (i = 0; i < HASHSIZE; i++)		globalhash[i] = NULL;	initstr(&globalnames);	filescope = SCOPE_STATIC;	funcscope = 0;}/* * Define a possibly new global variable which may or may not be static. * If it did not already exist, it is created with a value of zero. * The address of the global symbol structure is returned. * * given: *	name		name of global variable *	isstatic	TRUE if symbol is static */GLOBAL *addglobal(char *name, BOOL isstatic){	GLOBAL *sp;		/* current symbol pointer */	GLOBAL **hp;		/* hash table head address */	size_t len;		/* length of string */	int newfilescope;	/* file scope being looked for */	int newfuncscope;	/* function scope being looked for */	newfilescope = SCOPE_GLOBAL;	newfuncscope = 0;	if (isstatic) {		newfilescope = filescope;		newfuncscope = funcscope;	}	len = strlen(name);	if (len <= 0)		return NULL;	hp = &globalhash[HASHSYM(name, len)];	for (sp = *hp; sp; sp = sp->g_next) {		if ((sp->g_len == len) && (strcmp(sp->g_name, name) == 0)			&& (sp->g_filescope == newfilescope)			&& (sp->g_funcscope == newfuncscope))				return sp;	}	sp = (GLOBAL *) malloc(sizeof(GLOBAL));	if (sp == NULL)		return sp;	sp->g_name = addstr(&globalnames, name);	sp->g_len = len;	sp->g_filescope = newfilescope;	sp->g_funcscope = newfuncscope;	sp->g_value.v_num = qlink(&_qzero_);	sp->g_value.v_type = V_NUM;	sp->g_value.v_subtype = V_NOSUBTYPE;	sp->g_next = *hp;	*hp = sp;	return sp;}/* * Look for the highest-scope global variable with a specified name. * Returns the address of the variable or NULL according as the search * succeeds or fails. */GLOBAL *findglobal(char *name){	GLOBAL *sp;		/* current symbol pointer */	GLOBAL *bestsp;		/* found symbol with highest scope */	size_t len;		/* length of string */	bestsp = NULL;	len = strlen(name);	for (sp = globalhash[HASHSYM(name, len)]; sp; sp = sp->g_next) {		if ((sp->g_len == len) && !strcmp(sp->g_name, name)) {			if ((bestsp == NULL) ||				(sp->g_filescope > bestsp->g_filescope) ||				 (sp->g_funcscope > bestsp->g_funcscope))				bestsp = sp;		}	}	return bestsp;}/* * Return the name of a global variable given its address. * * given: *	sp		address of global pointer */char *globalname(GLOBAL *sp){	if (sp)		return sp->g_name;	return "";}/* * Show the value of all real-number valued global variables, displaying * only the head and tail of very large numerators and denominators. * Static variables are not included. */voidshowglobals(void){	GLOBAL **hp;			/* hash table head address */	register GLOBAL *sp;		/* current global symbol pointer */	long count;			/* number of global variables shown */	count = 0;	for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {		for (sp = *hp; sp; sp = sp->g_next) {			if (sp->g_value.v_type != V_NUM)				continue;			if (count++ == 0) {				printf("\nName	  Digits	   Value\n");				printf(	 "----	  ------	   -----\n");			}			printf("%-8s", sp->g_name);			if (sp->g_filescope != SCOPE_GLOBAL)				printf(" (s)");			fitprint(sp->g_value.v_num, 50);			printf("\n");		}	}	if (count == 0) {		printf("No real-valued global variables\n");	}	putchar('\n');}voidshowallglobals(void){	GLOBAL **hp;			/* hash table head address */	register GLOBAL *sp;		/* current global symbol pointer */	long count;			/* number of global variables shown */	count = 0;	for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {		for (sp = *hp; sp; sp = sp->g_next) {			if (count++ == 0) {				printf("\nName	  Level	   Type\n");				printf(	 "----	  -----	   -----\n");			}			printf("%-8s%4d	    ", sp->g_name, sp->g_filescope);			printtype(&sp->g_value);			printf("\n");		}	}	if (count > 0)		printf("\nNumber: %ld\n", count);	else		printf("No global variables\n");}static voidprinttype(VALUE *vp){	int	type;	char	*s;	type = vp->v_type;	if (type < 0) {		printf("Error %d", -type);		return;	}	switch (type) {	case V_NUM:		printf("real = ");		fitprint(vp->v_num, 32);		return;	case V_COM:		printf("complex = ");		fitprint(vp->v_com->real, 8);		if (!vp->v_com->imag->num.sign)			printf("+");		fitprint(vp->v_com->imag, 8);		printf("i");		return;	case V_STR:		printf("string = \"");		fitstring(vp->v_str->s_str, vp->v_str->s_len, 50);		printf("\"");		return;	case V_NULL:		s = "null";		break;	case V_MAT:		s = "matrix";		break;	case V_LIST:		s = "list";		break;	case V_ASSOC:		s = "association";		break;	case V_OBJ:		printf("%s ", objtypename(			vp->v_obj->o_actions->oa_index));		s = "object";		break;	case V_FILE:		s = "file id";		break;	case V_RAND:		s = "additive 55 random state";		break;	case V_RANDOM:		s = "Blum random state";		break;	case V_CONFIG:		s = "config state";		break;	case V_HASH:		s = "hash state";		break;	case V_BLOCK:		s = "unnamed block";		break;	case V_NBLOCK:		s = "named block";		break;	case V_VPTR:		s = "value pointer";		break;	case V_OPTR:		s = "octet pointer";		break;	case V_SPTR:		s = "string pointer";		break;	case V_NPTR:		s = "number pointer";		break;	default:		s = "???";		break;	}	printf("%s", s);}/* * Write all normal global variables to an output file. * Note: Currently only simple types are saved. * Returns nonzero on error. */intwriteglobals(char *name){	FILE *fp;	GLOBAL **hp;			/* hash table head address */	register GLOBAL *sp;		/* current global symbol pointer */	int savemode;			/* saved output mode */	extern void math_setfp(FILE *fp);	fp = f_open(name, "w");	if (fp == NULL)		return 1;	math_setfp(fp);	for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {		for (sp = *hp; sp; sp = sp->g_next) {			switch (sp->g_value.v_type) {			case V_NUM:			case V_COM:			case V_STR:				break;			default:				continue;			}			math_fmt("%s = ", sp->g_name);			savemode = math_setmode(MODE_HEX);			printvalue(&sp->g_value, PRINT_UNAMBIG);			math_setmode(savemode);			math_str(";\n");		}	}	math_setfp(stdout);	if (fclose(fp))		return 1;	return 0;}/* * Free all non-null global and visible static variables */voidfreeglobals(void){	GLOBAL **hp;		/* hash table head address */	GLOBAL *sp;		/* current global symbol pointer */	long count;		/* number of global variables freed */	/*	 * We prevent the hp pointer from walking behind globalhash	 * by stopping one short of the end and running the loop one	 * more time.	 *	 * We could stop the loop with just hp >= globalhash, but stopping	 * short and running the loop one last time manually helps make	 * code checkers such as insure happy.	 */	count = 0;	for (hp = &globalhash[HASHSIZE-1]; hp > globalhash; hp--) {		for (sp = *hp; sp; sp = sp->g_next) {			if (sp->g_value.v_type != V_NULL) {				freevalue(&sp->g_value);				count++;

⌨️ 快捷键说明

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