130fdf1140b8d1ce93f3821d986fa165552023440lgao/*
230fdf1140b8d1ce93f3821d986fa165552023440lgao * Simple symbol table manager using coalesced chaining to resolve collisions
330fdf1140b8d1ce93f3821d986fa165552023440lgao *
430fdf1140b8d1ce93f3821d986fa165552023440lgao * Doubly-linked lists are used for fast removal of entries.
530fdf1140b8d1ce93f3821d986fa165552023440lgao *
630fdf1140b8d1ce93f3821d986fa165552023440lgao * 'sym.h' must have a definition for typedef "Sym".  Sym must include at
730fdf1140b8d1ce93f3821d986fa165552023440lgao * minimum the following fields:
830fdf1140b8d1ce93f3821d986fa165552023440lgao *
930fdf1140b8d1ce93f3821d986fa165552023440lgao *		...
1030fdf1140b8d1ce93f3821d986fa165552023440lgao *		char *symbol;
1130fdf1140b8d1ce93f3821d986fa165552023440lgao *		struct ... *next, *prev, **head, *scope;
1230fdf1140b8d1ce93f3821d986fa165552023440lgao *		unsigned int hash;
1330fdf1140b8d1ce93f3821d986fa165552023440lgao *		...
1430fdf1140b8d1ce93f3821d986fa165552023440lgao *
1530fdf1140b8d1ce93f3821d986fa165552023440lgao * 'template.h' can be used as a template to create a 'sym.h'.
1630fdf1140b8d1ce93f3821d986fa165552023440lgao *
1730fdf1140b8d1ce93f3821d986fa165552023440lgao * 'head' is &(table[hash(itself)]).
1830fdf1140b8d1ce93f3821d986fa165552023440lgao * The hash table is not resizable at run-time.
1930fdf1140b8d1ce93f3821d986fa165552023440lgao * The scope field is used to link all symbols of a current scope together.
2030fdf1140b8d1ce93f3821d986fa165552023440lgao * Scope() sets the current scope (linked list) to add symbols to.
2130fdf1140b8d1ce93f3821d986fa165552023440lgao * Any number of scopes can be handled.  The user passes the address of
2230fdf1140b8d1ce93f3821d986fa165552023440lgao * a pointer to a symbol table
2330fdf1140b8d1ce93f3821d986fa165552023440lgao * entry (INITIALIZED TO NULL first time).
2430fdf1140b8d1ce93f3821d986fa165552023440lgao *
2530fdf1140b8d1ce93f3821d986fa165552023440lgao * Available Functions:
2630fdf1140b8d1ce93f3821d986fa165552023440lgao *
2730fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_init(s1,s2)	--	Create hash table with size s1, string table size s2.
2830fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_done()		--	Free hash and string table created with zzs_init().
2930fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_add(key,rec)--	Add 'rec' with key 'key' to the symbol table.
3030fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_newadd(key)	--	create entry; add using 'key' to the symbol table.
3130fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_get(key)	--	Return pointer to last record entered under 'key'
3230fdf1140b8d1ce93f3821d986fa165552023440lgao *						Else return NULL
3330fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_del(p)		--	Unlink the entry associated with p.  This does
3430fdf1140b8d1ce93f3821d986fa165552023440lgao *						NOT free 'p' and DOES NOT remove it from a scope
3530fdf1140b8d1ce93f3821d986fa165552023440lgao *						list.  If it was a part of your intermediate code
3630fdf1140b8d1ce93f3821d986fa165552023440lgao *						tree or another structure.  It will still be there.
3730fdf1140b8d1ce93f3821d986fa165552023440lgao *			  			It is only removed from further consideration
3830fdf1140b8d1ce93f3821d986fa165552023440lgao *						by the symbol table.
3930fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_keydel(s)	--	Unlink the entry associated with key s.
4030fdf1140b8d1ce93f3821d986fa165552023440lgao *						Calls zzs_del(p) to unlink.
4130fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_scope(sc)	--	Specifies that everything added to the symbol
4230fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			table with zzs_add() is added to the list (scope)
4330fdf1140b8d1ce93f3821d986fa165552023440lgao *						'sc'.  'sc' is of 'Sym **sc' type and must be
4430fdf1140b8d1ce93f3821d986fa165552023440lgao *						initialized to NULL before trying to add anything
4530fdf1140b8d1ce93f3821d986fa165552023440lgao *						to it (passing it to zzs_scope()).  Scopes can be
4630fdf1140b8d1ce93f3821d986fa165552023440lgao *					    switched at any time and merely links a set of
4730fdf1140b8d1ce93f3821d986fa165552023440lgao *						symbol table entries.  If a NULL pointer is
4830fdf1140b8d1ce93f3821d986fa165552023440lgao *						passed, the current scope is returned.
4930fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_rmscope(sc)	--	Remove (zzs_del()) all elements of scope 'sc'
5030fdf1140b8d1ce93f3821d986fa165552023440lgao *						from the symbol table.  The entries are NOT
5130fdf1140b8d1ce93f3821d986fa165552023440lgao *						free()'d.  A pointer to the first
5230fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			element in the "scope" is returned.  The user
5330fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			can then manipulate the list as he/she chooses
5430fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			(such as freeing them all). NOTE that this
5530fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			function sets your scope pointer to NULL,
5630fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			but returns a pointer to the list for you to use.
5730fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_stat()		--	Print out the symbol table and some relevant stats.
5830fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_new(key)	--	Create a new record with calloc() of type Sym.
5930fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			Add 'key' to the string table and make the new
6030fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			records 'symbol' pointer point to it.
6130fdf1140b8d1ce93f3821d986fa165552023440lgao *	zzs_strdup(s)	--	Add s to the string table and return a pointer
6230fdf1140b8d1ce93f3821d986fa165552023440lgao *			   			to it.  Very fast allocation routine
6330fdf1140b8d1ce93f3821d986fa165552023440lgao *						and does not require strlen() nor calloc().
6430fdf1140b8d1ce93f3821d986fa165552023440lgao *
6530fdf1140b8d1ce93f3821d986fa165552023440lgao * Example:
6630fdf1140b8d1ce93f3821d986fa165552023440lgao *
6730fdf1140b8d1ce93f3821d986fa165552023440lgao *	#include <stdio.h>
6830fdf1140b8d1ce93f3821d986fa165552023440lgao *	#include "sym.h"
6930fdf1140b8d1ce93f3821d986fa165552023440lgao *
7030fdf1140b8d1ce93f3821d986fa165552023440lgao *	main()
7130fdf1140b8d1ce93f3821d986fa165552023440lgao *	{
7230fdf1140b8d1ce93f3821d986fa165552023440lgao *	    Sym *scope1=NULL, *scope2=NULL, *a, *p;
7330fdf1140b8d1ce93f3821d986fa165552023440lgao *
7430fdf1140b8d1ce93f3821d986fa165552023440lgao *	    zzs_init(101, 100);
7530fdf1140b8d1ce93f3821d986fa165552023440lgao *
7630fdf1140b8d1ce93f3821d986fa165552023440lgao *	    a = zzs_new("Apple");	zzs_add(a->symbol, a);	-- No scope
7730fdf1140b8d1ce93f3821d986fa165552023440lgao *	    zzs_scope( &scope1 );	-- enter scope 1
7830fdf1140b8d1ce93f3821d986fa165552023440lgao *	    a = zzs_new("Plum");	zzs_add(a->symbol, a);
7930fdf1140b8d1ce93f3821d986fa165552023440lgao *	    zzs_scope( &scope2 );	-- enter scope 2
8030fdf1140b8d1ce93f3821d986fa165552023440lgao *	    a = zzs_new("Truck");	zzs_add(a->symbol, a);
8130fdf1140b8d1ce93f3821d986fa165552023440lgao *
8230fdf1140b8d1ce93f3821d986fa165552023440lgao *    	p = zzs_get("Plum");
8330fdf1140b8d1ce93f3821d986fa165552023440lgao *    	if ( p == NULL ) fprintf(stderr, "Hmmm...Can't find 'Plum'\n");
8430fdf1140b8d1ce93f3821d986fa165552023440lgao *
8530fdf1140b8d1ce93f3821d986fa165552023440lgao *    	p = zzs_rmscope(&scope1)
8630fdf1140b8d1ce93f3821d986fa165552023440lgao *    	for (; p!=NULL; p=p->scope) {printf("Scope1:  %s\n", p->symbol);}
8730fdf1140b8d1ce93f3821d986fa165552023440lgao *    	p = zzs_rmscope(&scope2)
8830fdf1140b8d1ce93f3821d986fa165552023440lgao *    	for (; p!=NULL; p=p->scope) {printf("Scope2:  %s\n", p->symbol);}
8930fdf1140b8d1ce93f3821d986fa165552023440lgao * }
9030fdf1140b8d1ce93f3821d986fa165552023440lgao *
9130fdf1140b8d1ce93f3821d986fa165552023440lgao * Terence Parr
9230fdf1140b8d1ce93f3821d986fa165552023440lgao * Purdue University
9330fdf1140b8d1ce93f3821d986fa165552023440lgao * February 1990
9430fdf1140b8d1ce93f3821d986fa165552023440lgao *
9530fdf1140b8d1ce93f3821d986fa165552023440lgao * CHANGES
9630fdf1140b8d1ce93f3821d986fa165552023440lgao *
9730fdf1140b8d1ce93f3821d986fa165552023440lgao *	Terence Parr
9830fdf1140b8d1ce93f3821d986fa165552023440lgao *	May 1991
9930fdf1140b8d1ce93f3821d986fa165552023440lgao *		Renamed functions to be consistent with ANTLR
10030fdf1140b8d1ce93f3821d986fa165552023440lgao *		Made HASH macro
10130fdf1140b8d1ce93f3821d986fa165552023440lgao *		Added zzs_keydel()
10230fdf1140b8d1ce93f3821d986fa165552023440lgao *		Added zzs_newadd()
10330fdf1140b8d1ce93f3821d986fa165552023440lgao *		Fixed up zzs_stat()
10430fdf1140b8d1ce93f3821d986fa165552023440lgao *
10530fdf1140b8d1ce93f3821d986fa165552023440lgao *	July 1991
10630fdf1140b8d1ce93f3821d986fa165552023440lgao *		Made symbol table entry save its hash code for fast comparison
10730fdf1140b8d1ce93f3821d986fa165552023440lgao *			during searching etc...
10830fdf1140b8d1ce93f3821d986fa165552023440lgao */
10930fdf1140b8d1ce93f3821d986fa165552023440lgao
11030fdf1140b8d1ce93f3821d986fa165552023440lgao#include <stdio.h>
11130fdf1140b8d1ce93f3821d986fa165552023440lgao#if defined(__STDC__) || defined(__USE_PROTOS)
11230fdf1140b8d1ce93f3821d986fa165552023440lgao#include <string.h>
11330fdf1140b8d1ce93f3821d986fa165552023440lgao#include <stdlib.h>
11430fdf1140b8d1ce93f3821d986fa165552023440lgao#else
11530fdf1140b8d1ce93f3821d986fa165552023440lgao#include <malloc.h>
11630fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
11730fdf1140b8d1ce93f3821d986fa165552023440lgao#include "sym.h"
11830fdf1140b8d1ce93f3821d986fa165552023440lgao
11930fdf1140b8d1ce93f3821d986fa165552023440lgao#define StrSame		0
12030fdf1140b8d1ce93f3821d986fa165552023440lgao
12130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic Sym **CurScope = NULL;
12230fdf1140b8d1ce93f3821d986fa165552023440lgaostatic unsigned size = 0;
12330fdf1140b8d1ce93f3821d986fa165552023440lgaostatic Sym **table=NULL;
12430fdf1140b8d1ce93f3821d986fa165552023440lgaostatic char *strings;
12530fdf1140b8d1ce93f3821d986fa165552023440lgaostatic char *strp;
12630fdf1140b8d1ce93f3821d986fa165552023440lgaostatic int strsize = 0;
12730fdf1140b8d1ce93f3821d986fa165552023440lgao
12830fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
12930fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_init(int sz,int strs)
13030fdf1140b8d1ce93f3821d986fa165552023440lgao#else
13130fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_init(sz, strs)
13230fdf1140b8d1ce93f3821d986fa165552023440lgaoint sz, strs;
13330fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
13430fdf1140b8d1ce93f3821d986fa165552023440lgao{
13530fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( sz <= 0 || strs <= 0 ) return;
13630fdf1140b8d1ce93f3821d986fa165552023440lgao	table = (Sym **) calloc(sz, sizeof(Sym *));
13730fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( table == NULL )
13830fdf1140b8d1ce93f3821d986fa165552023440lgao	{
13930fdf1140b8d1ce93f3821d986fa165552023440lgao		fprintf(stderr, "Cannot allocate table of size %d\n", sz);
14030fdf1140b8d1ce93f3821d986fa165552023440lgao		exit(1);
14130fdf1140b8d1ce93f3821d986fa165552023440lgao	}
14230fdf1140b8d1ce93f3821d986fa165552023440lgao	strings = (char *) calloc(strs, sizeof(char));
14330fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( strings == NULL )
14430fdf1140b8d1ce93f3821d986fa165552023440lgao	{
14530fdf1140b8d1ce93f3821d986fa165552023440lgao		fprintf(stderr, "Cannot allocate string table of size %d\n", strs);
14630fdf1140b8d1ce93f3821d986fa165552023440lgao		exit(1);
14730fdf1140b8d1ce93f3821d986fa165552023440lgao	}
14830fdf1140b8d1ce93f3821d986fa165552023440lgao	size = sz;
14930fdf1140b8d1ce93f3821d986fa165552023440lgao	strsize = strs;
15030fdf1140b8d1ce93f3821d986fa165552023440lgao	strp = strings;
15130fdf1140b8d1ce93f3821d986fa165552023440lgao}
15230fdf1140b8d1ce93f3821d986fa165552023440lgao
15330fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
15430fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_done(void)
15530fdf1140b8d1ce93f3821d986fa165552023440lgao#else
15630fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_done()
15730fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
15830fdf1140b8d1ce93f3821d986fa165552023440lgao{
15930fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( table != NULL ) free( table );
16030fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( strings != NULL ) free( strings );
16130fdf1140b8d1ce93f3821d986fa165552023440lgao}
16230fdf1140b8d1ce93f3821d986fa165552023440lgao
16330fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
16430fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_add(char *key,Sym rec)
16530fdf1140b8d1ce93f3821d986fa165552023440lgao#else
16630fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_add(key, rec)
16730fdf1140b8d1ce93f3821d986fa165552023440lgaochar *key;
16830fdf1140b8d1ce93f3821d986fa165552023440lgaoregister Sym *rec;
16930fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
17030fdf1140b8d1ce93f3821d986fa165552023440lgao{
17130fdf1140b8d1ce93f3821d986fa165552023440lgao	register unsigned int h=0;
17230fdf1140b8d1ce93f3821d986fa165552023440lgao	register char *p=key;
17330fdf1140b8d1ce93f3821d986fa165552023440lgao
17430fdf1140b8d1ce93f3821d986fa165552023440lgao	HASH(p, h);
17530fdf1140b8d1ce93f3821d986fa165552023440lgao	rec->hash = h;					/* save hash code for fast comp later */
17630fdf1140b8d1ce93f3821d986fa165552023440lgao	h %= size;
17730fdf1140b8d1ce93f3821d986fa165552023440lgao
17830fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( CurScope != NULL ) {rec->scope = *CurScope; *CurScope = rec;}
17930fdf1140b8d1ce93f3821d986fa165552023440lgao	rec->next = table[h];			/* Add to doubly-linked list */
18030fdf1140b8d1ce93f3821d986fa165552023440lgao	rec->prev = NULL;
18130fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( rec->next != NULL ) (rec->next)->prev = rec;
18230fdf1140b8d1ce93f3821d986fa165552023440lgao	table[h] = rec;
18330fdf1140b8d1ce93f3821d986fa165552023440lgao	rec->head = &(table[h]);
18430fdf1140b8d1ce93f3821d986fa165552023440lgao}
18530fdf1140b8d1ce93f3821d986fa165552023440lgao
18630fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
18730fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_get(char *key)
18830fdf1140b8d1ce93f3821d986fa165552023440lgao#else
18930fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_get(key)
19030fdf1140b8d1ce93f3821d986fa165552023440lgaochar *key;
19130fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
19230fdf1140b8d1ce93f3821d986fa165552023440lgao{
19330fdf1140b8d1ce93f3821d986fa165552023440lgao	register unsigned int h=0;
19430fdf1140b8d1ce93f3821d986fa165552023440lgao	register char *p=key;
19530fdf1140b8d1ce93f3821d986fa165552023440lgao	register Sym *q;
19630fdf1140b8d1ce93f3821d986fa165552023440lgao
19730fdf1140b8d1ce93f3821d986fa165552023440lgao	HASH(p, h);
19830fdf1140b8d1ce93f3821d986fa165552023440lgao
19930fdf1140b8d1ce93f3821d986fa165552023440lgao	for (q = table[h%size]; q != NULL; q = q->next)
20030fdf1140b8d1ce93f3821d986fa165552023440lgao	{
20130fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( q->hash == h )		/* do we even have a chance of matching? */
20230fdf1140b8d1ce93f3821d986fa165552023440lgao			if ( strcmp(key, q->symbol) == StrSame ) return( q );
20330fdf1140b8d1ce93f3821d986fa165552023440lgao	}
20430fdf1140b8d1ce93f3821d986fa165552023440lgao	return( NULL );
20530fdf1140b8d1ce93f3821d986fa165552023440lgao}
20630fdf1140b8d1ce93f3821d986fa165552023440lgao
20730fdf1140b8d1ce93f3821d986fa165552023440lgao/*
20830fdf1140b8d1ce93f3821d986fa165552023440lgao * Unlink p from the symbol table.  Hopefully, it's actually in the
20930fdf1140b8d1ce93f3821d986fa165552023440lgao * symbol table.
21030fdf1140b8d1ce93f3821d986fa165552023440lgao *
21130fdf1140b8d1ce93f3821d986fa165552023440lgao * If p is not part of a bucket chain of the symbol table, bad things
21230fdf1140b8d1ce93f3821d986fa165552023440lgao * will happen.
21330fdf1140b8d1ce93f3821d986fa165552023440lgao *
21430fdf1140b8d1ce93f3821d986fa165552023440lgao * Will do nothing if all list pointers are NULL
21530fdf1140b8d1ce93f3821d986fa165552023440lgao */
21630fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
21730fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_del(Sym *p)
21830fdf1140b8d1ce93f3821d986fa165552023440lgao#else
21930fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_del(p)
22030fdf1140b8d1ce93f3821d986fa165552023440lgaoregister Sym *p;
22130fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
22230fdf1140b8d1ce93f3821d986fa165552023440lgao{
22330fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( p == NULL ) {fprintf(stderr, "zzs_del(NULL)\n"); exit(1);}
22430fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( p->prev == NULL )	/* Head of list */
22530fdf1140b8d1ce93f3821d986fa165552023440lgao	{
22630fdf1140b8d1ce93f3821d986fa165552023440lgao		register Sym **t = p->head;
22730fdf1140b8d1ce93f3821d986fa165552023440lgao
22830fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( t == NULL ) return;	/* not part of symbol table */
22930fdf1140b8d1ce93f3821d986fa165552023440lgao		(*t) = p->next;
23030fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( (*t) != NULL ) (*t)->prev = NULL;
23130fdf1140b8d1ce93f3821d986fa165552023440lgao	}
23230fdf1140b8d1ce93f3821d986fa165552023440lgao	else
23330fdf1140b8d1ce93f3821d986fa165552023440lgao	{
23430fdf1140b8d1ce93f3821d986fa165552023440lgao		(p->prev)->next = p->next;
23530fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( p->next != NULL ) (p->next)->prev = p->prev;
23630fdf1140b8d1ce93f3821d986fa165552023440lgao	}
23730fdf1140b8d1ce93f3821d986fa165552023440lgao	p->next = p->prev = NULL;	/* not part of symbol table anymore */
23830fdf1140b8d1ce93f3821d986fa165552023440lgao	p->head = NULL;
23930fdf1140b8d1ce93f3821d986fa165552023440lgao}
24030fdf1140b8d1ce93f3821d986fa165552023440lgao
24130fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
24230fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_keydel(char *key)
24330fdf1140b8d1ce93f3821d986fa165552023440lgao#else
24430fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_keydel(key)
24530fdf1140b8d1ce93f3821d986fa165552023440lgaochar *key;
24630fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
24730fdf1140b8d1ce93f3821d986fa165552023440lgao{
24830fdf1140b8d1ce93f3821d986fa165552023440lgao	Sym *p = zzs_get(key);
24930fdf1140b8d1ce93f3821d986fa165552023440lgao
25030fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( p != NULL ) zzs_del( p );
25130fdf1140b8d1ce93f3821d986fa165552023440lgao}
25230fdf1140b8d1ce93f3821d986fa165552023440lgao
25330fdf1140b8d1ce93f3821d986fa165552023440lgao/* S c o p e  S t u f f */
25430fdf1140b8d1ce93f3821d986fa165552023440lgao
25530fdf1140b8d1ce93f3821d986fa165552023440lgao/* Set current scope to 'scope'; return current scope if 'scope' == NULL */
25630fdf1140b8d1ce93f3821d986fa165552023440lgao
25730fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
25830fdf1140b8d1ce93f3821d986fa165552023440lgaoSym ** zzs_scope(Sym **scope)
25930fdf1140b8d1ce93f3821d986fa165552023440lgao#else
26030fdf1140b8d1ce93f3821d986fa165552023440lgaoSym ** zzs_scope(scope)
26130fdf1140b8d1ce93f3821d986fa165552023440lgaoSym **scope;
26230fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
26330fdf1140b8d1ce93f3821d986fa165552023440lgao{
26430fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( scope == NULL ) return( CurScope );
26530fdf1140b8d1ce93f3821d986fa165552023440lgao	CurScope = scope;
26630fdf1140b8d1ce93f3821d986fa165552023440lgao	return( scope );
26730fdf1140b8d1ce93f3821d986fa165552023440lgao}
26830fdf1140b8d1ce93f3821d986fa165552023440lgao
26930fdf1140b8d1ce93f3821d986fa165552023440lgao/* Remove a scope described by 'scope'.  Return pointer to 1st element in scope */
27030fdf1140b8d1ce93f3821d986fa165552023440lgao
27130fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
27230fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_rmscope(Sym **scope)
27330fdf1140b8d1ce93f3821d986fa165552023440lgao#else
27430fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_rmscope(scope)
27530fdf1140b8d1ce93f3821d986fa165552023440lgaoregister Sym **scope;
27630fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
27730fdf1140b8d1ce93f3821d986fa165552023440lgao{
27830fdf1140b8d1ce93f3821d986fa165552023440lgao	register Sym *p;
27930fdf1140b8d1ce93f3821d986fa165552023440lgao	Sym *start;
28030fdf1140b8d1ce93f3821d986fa165552023440lgao
28130fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( scope == NULL ) return(NULL);
28230fdf1140b8d1ce93f3821d986fa165552023440lgao	start = p = *scope;
28330fdf1140b8d1ce93f3821d986fa165552023440lgao	for (; p != NULL; p=p->scope) { zzs_del( p ); }
28430fdf1140b8d1ce93f3821d986fa165552023440lgao	*scope = NULL;
28530fdf1140b8d1ce93f3821d986fa165552023440lgao	return( start );
28630fdf1140b8d1ce93f3821d986fa165552023440lgao}
28730fdf1140b8d1ce93f3821d986fa165552023440lgao
28830fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
28930fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_stat(void)
29030fdf1140b8d1ce93f3821d986fa165552023440lgao#else
29130fdf1140b8d1ce93f3821d986fa165552023440lgaovoid zzs_stat()
29230fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
29330fdf1140b8d1ce93f3821d986fa165552023440lgao{
29430fdf1140b8d1ce93f3821d986fa165552023440lgao	static unsigned short count[20];
29530fdf1140b8d1ce93f3821d986fa165552023440lgao	unsigned int i,n=0,low=0, hi=0;
29630fdf1140b8d1ce93f3821d986fa165552023440lgao	register Sym **p;
29730fdf1140b8d1ce93f3821d986fa165552023440lgao	float avg=0.0;
29830fdf1140b8d1ce93f3821d986fa165552023440lgao
29930fdf1140b8d1ce93f3821d986fa165552023440lgao	for (i=0; i<20; i++) count[i] = 0;
30030fdf1140b8d1ce93f3821d986fa165552023440lgao	for (p=table; p<&(table[size]); p++)
30130fdf1140b8d1ce93f3821d986fa165552023440lgao	{
30230fdf1140b8d1ce93f3821d986fa165552023440lgao		register Sym *q = *p;
30330fdf1140b8d1ce93f3821d986fa165552023440lgao		unsigned int len;
30430fdf1140b8d1ce93f3821d986fa165552023440lgao
30530fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( q != NULL && low==0 ) low = p-table;
30630fdf1140b8d1ce93f3821d986fa165552023440lgao		len = 0;
30730fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( q != NULL ) printf("[%d]", p-table);
30830fdf1140b8d1ce93f3821d986fa165552023440lgao		while ( q != NULL )
30930fdf1140b8d1ce93f3821d986fa165552023440lgao		{
31030fdf1140b8d1ce93f3821d986fa165552023440lgao			len++;
31130fdf1140b8d1ce93f3821d986fa165552023440lgao			n++;
31230fdf1140b8d1ce93f3821d986fa165552023440lgao			printf(" %s", q->symbol);
31330fdf1140b8d1ce93f3821d986fa165552023440lgao			q = q->next;
31430fdf1140b8d1ce93f3821d986fa165552023440lgao			if ( q == NULL ) printf("\n");
31530fdf1140b8d1ce93f3821d986fa165552023440lgao		}
31630fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( len>=20 ) printf("zzs_stat: count table too small\n");
31730fdf1140b8d1ce93f3821d986fa165552023440lgao		else count[len]++;
31830fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( *p != NULL ) hi = p-table;
31930fdf1140b8d1ce93f3821d986fa165552023440lgao	}
32030fdf1140b8d1ce93f3821d986fa165552023440lgao
32130fdf1140b8d1ce93f3821d986fa165552023440lgao	printf("Storing %d recs used %d hash positions out of %d\n",
32230fdf1140b8d1ce93f3821d986fa165552023440lgao			n, size-count[0], size);
32330fdf1140b8d1ce93f3821d986fa165552023440lgao	printf("%f %% utilization\n",
32430fdf1140b8d1ce93f3821d986fa165552023440lgao			((float)(size-count[0]))/((float)size));
32530fdf1140b8d1ce93f3821d986fa165552023440lgao	for (i=0; i<20; i++)
32630fdf1140b8d1ce93f3821d986fa165552023440lgao	{
32730fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( count[i] != 0 )
32830fdf1140b8d1ce93f3821d986fa165552023440lgao		{
32930fdf1140b8d1ce93f3821d986fa165552023440lgao			avg += (((float)(i*count[i]))/((float)n)) * i;
33030fdf1140b8d1ce93f3821d986fa165552023440lgao			printf("Buckets of len %d == %d (%f %% of recs)\n",
33130fdf1140b8d1ce93f3821d986fa165552023440lgao					i, count[i], 100.0*((float)(i*count[i]))/((float)n));
33230fdf1140b8d1ce93f3821d986fa165552023440lgao		}
33330fdf1140b8d1ce93f3821d986fa165552023440lgao	}
33430fdf1140b8d1ce93f3821d986fa165552023440lgao	printf("Avg bucket length %f\n", avg);
33530fdf1140b8d1ce93f3821d986fa165552023440lgao	printf("Range of hash function: %d..%d\n", low, hi);
33630fdf1140b8d1ce93f3821d986fa165552023440lgao}
33730fdf1140b8d1ce93f3821d986fa165552023440lgao
33830fdf1140b8d1ce93f3821d986fa165552023440lgao/*
33930fdf1140b8d1ce93f3821d986fa165552023440lgao * Given a string, this function allocates and returns a pointer to a
34030fdf1140b8d1ce93f3821d986fa165552023440lgao * symbol table record whose "symbol" pointer is reset to a position
34130fdf1140b8d1ce93f3821d986fa165552023440lgao * in the string table.
34230fdf1140b8d1ce93f3821d986fa165552023440lgao */
34330fdf1140b8d1ce93f3821d986fa165552023440lgao
34430fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
34530fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_new(char *text)
34630fdf1140b8d1ce93f3821d986fa165552023440lgao#else
34730fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_new(text)
34830fdf1140b8d1ce93f3821d986fa165552023440lgaochar *text;
34930fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
35030fdf1140b8d1ce93f3821d986fa165552023440lgao{
35130fdf1140b8d1ce93f3821d986fa165552023440lgao	Sym *p;
35230fdf1140b8d1ce93f3821d986fa165552023440lgao
35330fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( (p = (Sym *) calloc(1,sizeof(Sym))) == 0 )
35430fdf1140b8d1ce93f3821d986fa165552023440lgao	{
35530fdf1140b8d1ce93f3821d986fa165552023440lgao		fprintf(stderr,"Out of memory\n");
35630fdf1140b8d1ce93f3821d986fa165552023440lgao		exit(1);
35730fdf1140b8d1ce93f3821d986fa165552023440lgao	}
35830fdf1140b8d1ce93f3821d986fa165552023440lgao	p->symbol = zzs_strdup(text);
35930fdf1140b8d1ce93f3821d986fa165552023440lgao
36030fdf1140b8d1ce93f3821d986fa165552023440lgao	return p;
36130fdf1140b8d1ce93f3821d986fa165552023440lgao}
36230fdf1140b8d1ce93f3821d986fa165552023440lgao
36330fdf1140b8d1ce93f3821d986fa165552023440lgao/* create a new symbol table entry and add it to the symbol table */
36430fdf1140b8d1ce93f3821d986fa165552023440lgao
36530fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
36630fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_newadd(char *text)
36730fdf1140b8d1ce93f3821d986fa165552023440lgao#else
36830fdf1140b8d1ce93f3821d986fa165552023440lgaoSym * zzs_newadd(text)
36930fdf1140b8d1ce93f3821d986fa165552023440lgaochar *text;
37030fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
37130fdf1140b8d1ce93f3821d986fa165552023440lgao{
37230fdf1140b8d1ce93f3821d986fa165552023440lgao	Sym *p = zzs_new(text);
37330fdf1140b8d1ce93f3821d986fa165552023440lgao	if ( p != NULL ) zzs_add(text, p);
37430fdf1140b8d1ce93f3821d986fa165552023440lgao	return p;
37530fdf1140b8d1ce93f3821d986fa165552023440lgao}
37630fdf1140b8d1ce93f3821d986fa165552023440lgao
37730fdf1140b8d1ce93f3821d986fa165552023440lgao/* Add a string to the string table and return a pointer to it.
37830fdf1140b8d1ce93f3821d986fa165552023440lgao * Bump the pointer into the string table to next avail position.
37930fdf1140b8d1ce93f3821d986fa165552023440lgao */
38030fdf1140b8d1ce93f3821d986fa165552023440lgao
38130fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef __USE_PROTOS
38230fdf1140b8d1ce93f3821d986fa165552023440lgaochar * zzs_strdup(char *s)
38330fdf1140b8d1ce93f3821d986fa165552023440lgao#else
38430fdf1140b8d1ce93f3821d986fa165552023440lgaochar * zzs_strdup(s)
38530fdf1140b8d1ce93f3821d986fa165552023440lgaoregister char *s;
38630fdf1140b8d1ce93f3821d986fa165552023440lgao#endif
38730fdf1140b8d1ce93f3821d986fa165552023440lgao{
38830fdf1140b8d1ce93f3821d986fa165552023440lgao	register char *start=strp;
38930fdf1140b8d1ce93f3821d986fa165552023440lgao
39030fdf1140b8d1ce93f3821d986fa165552023440lgao	while ( *s != '\0' )
39130fdf1140b8d1ce93f3821d986fa165552023440lgao	{
39230fdf1140b8d1ce93f3821d986fa165552023440lgao		if ( strp >= &(strings[strsize-2]) )
39330fdf1140b8d1ce93f3821d986fa165552023440lgao		{
39430fdf1140b8d1ce93f3821d986fa165552023440lgao			fprintf(stderr, "sym: string table overflow (%d chars)\n", strsize);
39530fdf1140b8d1ce93f3821d986fa165552023440lgao			exit(-1);
39630fdf1140b8d1ce93f3821d986fa165552023440lgao		}
39730fdf1140b8d1ce93f3821d986fa165552023440lgao		*strp++ = *s++;
39830fdf1140b8d1ce93f3821d986fa165552023440lgao	}
39930fdf1140b8d1ce93f3821d986fa165552023440lgao	*strp++ = '\0';
40030fdf1140b8d1ce93f3821d986fa165552023440lgao
40130fdf1140b8d1ce93f3821d986fa165552023440lgao	return( start );
40230fdf1140b8d1ce93f3821d986fa165552023440lgao}
403