
/*	Copyright (c) 1984 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident "$Header: symtab.c 1.1 89/10/09 $@(#)nls:symtab.c	1.1 88/01/06 AT&T UEL"

/* Preprocessor Statements */
#include "colltbl.h"

/* External Variables */
extern int	yydebug;
extern int	regexp_flag;

/* Global Variables */
static SYMNODE *Hashtab[MAXHASH];

SYMNODE
*lookup(name, type, re_len)
char	*name;
int	type;
int	re_len;
{
	static SYMNODE *np;

	for (np = Hashtab[hash(name, re_len)]; np != NULL; np = np->next) {
		if (re_len && re_len == np->regexp_len && regexp_flag) {
			if (!np->delete_flag && !memcmp(name, np->name, re_len) && type == np->type)
				return(np);
			
		}
		if (!np->delete_flag && EQ(name, np->name) && type == np->type)
				return(np);
	}
	return(NULL);
}


SYMNODE
*insert(name, type, re_len)
char		*name;
int		type;
int		re_len;
{
	static SYMNODE	*np, *prev, *curr;
	static int	hashval;

	if ((np = lookup(name, type, re_len)) != NULL)
		return((SYMNODE * ) NULL);
	if ((np = (SYMNODE *) malloc(sizeof(SYMNODE))) == NULL)
		error(NO_SPACE, "symbol table");
	np->name = name;
	TURNOFF(np->delete_flag);
	np->type = type;
	np->regexp_len = re_len;
	if ((curr = Hashtab[(hashval=hash(np->name, np->regexp_len))]) == NULL) {
		Hashtab[hashval] = np;
		np->next = NULL;
		}
	else if (GE(curr->name, np->name)) {
		np->next = curr;
		Hashtab[hashval] = np;
	}
	else {
		prev = curr;
		for (curr = curr->next; curr != NULL; curr = curr->next) {
			if (GE(curr->name, np->name))
				break;
			prev = curr;
		}
		prev->next = np;
		np->next = curr;
	}
	return(np);
}


void
delete(name, type)
char	*name;
int	type;
{
	static SYMNODE *np;

	if ((np = lookup(name, type)) != NULL)
		TURNON(np->delete_flag);
}


int
hash(name, re_len)
unsigned char	*name;
int	re_len;
{
	register int	hashval;
	char	c;
	if (re_len && regexp_flag)
		c = 026;
	else
		c = '\0';

	for (hashval = 0; *name != c; name++)
		hashval += *name;
	if (re_len)
		hashval += 026;
	return(hashval % MAXHASH);
}
