mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 05:38:26 +00:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1676 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			222 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * hash.c
 | 
						|
 *
 | 
						|
 * Manage hash tables.
 | 
						|
 *
 | 
						|
 * The following functions are visible:
 | 
						|
 *
 | 
						|
 *		char	*mystrdup(char *);		Make space and copy string
 | 
						|
 *		Entry 	**newHashTable();		Create and return initialized hash table
 | 
						|
 *		Entry	*hash_add(Entry **, char *, Entry *)
 | 
						|
 *		Entry	*hash_get(Entry **, char *)
 | 
						|
 *
 | 
						|
 * SOFTWARE RIGHTS
 | 
						|
 *
 | 
						|
 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
 | 
						|
 * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
 | 
						|
 * company may do whatever they wish with source code distributed with
 | 
						|
 * PCCTS or the code generated by PCCTS, including the incorporation of
 | 
						|
 * PCCTS, or its output, into commerical software.
 | 
						|
 *
 | 
						|
 * We encourage users to develop software with PCCTS.  However, we do ask
 | 
						|
 * that credit is given to us for developing PCCTS.  By "credit",
 | 
						|
 * we mean that if you incorporate our source code into one of your
 | 
						|
 * programs (commercial product, research project, or otherwise) that you
 | 
						|
 * acknowledge this fact somewhere in the documentation, research report,
 | 
						|
 * etc...  If you like PCCTS and have developed a nice tool with the
 | 
						|
 * output, please mention that you developed it using PCCTS.  In
 | 
						|
 * addition, we ask that this header remain intact in our source code.
 | 
						|
 * As long as these guidelines are kept, we expect to continue enhancing
 | 
						|
 * this system and expect to make other tools available as they are
 | 
						|
 * completed.
 | 
						|
 *
 | 
						|
 * ANTLR 1.33
 | 
						|
 * Terence Parr
 | 
						|
 * Parr Research Corporation
 | 
						|
 * with Purdue University and AHPCRC, University of Minnesota
 | 
						|
 * 1989-2001
 | 
						|
 */
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include "pcctscfg.h"
 | 
						|
#include "hash.h"
 | 
						|
 | 
						|
#ifdef __USE_PROTOS
 | 
						|
#include <stdlib.h>
 | 
						|
#else
 | 
						|
#ifdef VAXC
 | 
						|
#include <stdlib.h>
 | 
						|
#else
 | 
						|
#include <malloc.h>
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#define StrSame		0
 | 
						|
 | 
						|
#define fatal(err)															\
 | 
						|
			{fprintf(stderr, "%s(%d):", __FILE__, __LINE__);				\
 | 
						|
			fprintf(stderr, " %s\n", err); exit(PCCTS_EXIT_FAILURE);}
 | 
						|
#define require(expr, err) {if ( !(expr) ) fatal(err);}
 | 
						|
 | 
						|
static unsigned size = HashTableSize;
 | 
						|
static char *strings = NULL;
 | 
						|
static char *strp;
 | 
						|
static unsigned strsize = StrTableSize;
 | 
						|
 | 
						|
/* create the hash table and string table for terminals (string table only once) */
 | 
						|
Entry **
 | 
						|
#ifdef __USE_PROTOS
 | 
						|
newHashTable( void )
 | 
						|
#else
 | 
						|
newHashTable( )
 | 
						|
#endif
 | 
						|
{
 | 
						|
	Entry **table;
 | 
						|
	
 | 
						|
	table = (Entry **) calloc(size, sizeof(Entry *));
 | 
						|
	require( table != NULL, "cannot allocate hash table");
 | 
						|
	if ( strings == NULL )
 | 
						|
	{
 | 
						|
		strings = (char *) calloc(strsize, sizeof(char));
 | 
						|
		require( strings != NULL, "cannot allocate string table");
 | 
						|
		strp = strings;
 | 
						|
	}
 | 
						|
	return table;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
#ifdef __USE_PROTOS
 | 
						|
killHashTable( Entry **table )
 | 
						|
#else
 | 
						|
killHashTable( table )
 | 
						|
Entry **table;
 | 
						|
#endif
 | 
						|
{
 | 
						|
	/* for now, just free table, forget entries */
 | 
						|
	free( (char *) table );     /* MR10 cast */
 | 
						|
}
 | 
						|
 | 
						|
/* Given a table, add 'rec' with key 'key' (add to front of list). return ptr to entry */
 | 
						|
Entry *
 | 
						|
#ifdef __USE_PROTOS
 | 
						|
hash_add( Entry **table, char *key, Entry *rec )
 | 
						|
#else
 | 
						|
hash_add( table, key, rec )
 | 
						|
Entry **table;
 | 
						|
char *key;
 | 
						|
Entry *rec;
 | 
						|
#endif
 | 
						|
{
 | 
						|
	unsigned h=0;
 | 
						|
	char *p=key;
 | 
						|
	require(table!=NULL && key!=NULL && rec!=NULL, "add: invalid addition");
 | 
						|
	
 | 
						|
	Hash(p,h,size);
 | 
						|
	rec->next = table[h];			/* Add to singly-linked list */
 | 
						|
	table[h] = rec;
 | 
						|
	return rec;
 | 
						|
}
 | 
						|
 | 
						|
/* Return ptr to 1st entry found in table under key (return NULL if none found) */
 | 
						|
Entry *
 | 
						|
#ifdef __USE_PROTOS
 | 
						|
hash_get( Entry **table, char *key )
 | 
						|
#else
 | 
						|
hash_get( table, key )
 | 
						|
Entry **table;
 | 
						|
char *key;
 | 
						|
#endif
 | 
						|
{
 | 
						|
	unsigned h=0;
 | 
						|
	char *p=key;
 | 
						|
	Entry *q;
 | 
						|
/*	require(table!=NULL && key!=NULL, "get: invalid table and/or key");*/
 | 
						|
	if ( !(table!=NULL && key!=NULL) ) *((char *) 34) = 3;
 | 
						|
	
 | 
						|
	Hash(p,h,size);
 | 
						|
	for (q = table[h]; q != NULL; q = q->next)
 | 
						|
	{
 | 
						|
		if ( strcmp(key, q->str) == StrSame ) return( q );
 | 
						|
	}
 | 
						|
	return( NULL );
 | 
						|
}
 | 
						|
 | 
						|
#ifdef DEBUG_HASH
 | 
						|
void
 | 
						|
#ifdef __USE_PROTOS
 | 
						|
hashStat( Entry **table )
 | 
						|
#else
 | 
						|
hashStat( table )
 | 
						|
Entry **table;
 | 
						|
#endif
 | 
						|
{
 | 
						|
	static unsigned short count[20];
 | 
						|
	int i,n=0,low=0, hi=0;
 | 
						|
	Entry **p;
 | 
						|
	float avg=0.0;
 | 
						|
	
 | 
						|
	for (i=0; i<20; i++) count[i] = 0;
 | 
						|
	for (p=table; p<&(table[size]); p++)
 | 
						|
	{
 | 
						|
		Entry *q = *p;
 | 
						|
		int len;
 | 
						|
		
 | 
						|
		if ( q != NULL && low==0 ) low = p-table;
 | 
						|
		len = 0;
 | 
						|
		if ( q != NULL ) fprintf(stderr, "[%d]", p-table);
 | 
						|
		while ( q != NULL )
 | 
						|
		{
 | 
						|
			len++;
 | 
						|
			n++;
 | 
						|
			fprintf(stderr, " %s", q->str);
 | 
						|
			q = q->next;
 | 
						|
			if ( q == NULL ) fprintf(stderr, "\n");
 | 
						|
		}
 | 
						|
		count[len]++;
 | 
						|
		if ( *p != NULL ) hi = p-table;
 | 
						|
	}
 | 
						|
 | 
						|
	fprintf(stderr, "Storing %d recs used %d hash positions out of %d\n",
 | 
						|
					n, size-count[0], size);
 | 
						|
	fprintf(stderr, "%f %% utilization\n",
 | 
						|
					((float)(size-count[0]))/((float)size));
 | 
						|
	for (i=0; i<20; i++)
 | 
						|
	{
 | 
						|
		if ( count[i] != 0 )
 | 
						|
		{
 | 
						|
			avg += (((float)(i*count[i]))/((float)n)) * i;
 | 
						|
			fprintf(stderr, "Bucket len %d == %d (%f %% of recs)\n",
 | 
						|
							i, count[i], ((float)(i*count[i]))/((float)n));
 | 
						|
		}
 | 
						|
	}
 | 
						|
	fprintf(stderr, "Avg bucket length %f\n", avg);
 | 
						|
	fprintf(stderr, "Range of hash function: %d..%d\n", low, hi);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/* Add a string to the string table and return a pointer to it.
 | 
						|
 * Bump the pointer into the string table to next avail position.
 | 
						|
 */
 | 
						|
char *
 | 
						|
#ifdef __USE_PROTOS
 | 
						|
mystrdup( char *s )
 | 
						|
#else
 | 
						|
mystrdup( s )
 | 
						|
char *s;
 | 
						|
#endif
 | 
						|
{
 | 
						|
	char *start=strp;
 | 
						|
	require(s!=NULL, "mystrdup: NULL string");
 | 
						|
 | 
						|
	while ( *s != '\0' )
 | 
						|
	{
 | 
						|
		require( strp <= &(strings[strsize-2]),
 | 
						|
				 "string table overflow\nIncrease StrTableSize in hash.h and recompile hash.c\n");
 | 
						|
		*strp++ = *s++;
 | 
						|
	}
 | 
						|
	*strp++ = '\0';
 | 
						|
 | 
						|
	return( start );
 | 
						|
}
 |