diff options
author | Robert de Bath <rdebath@poboxes.com> | 2002-07-28 22:10:50 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:48:47 +0200 |
commit | e6248da18100235ae33468d058e5b71fcefeff3b (patch) | |
tree | 4e3833ed515d03d2366c27f71ef0fe349a2dee12 /cpp/hash.c | |
parent | 2060b4f4cc1c13975e495d088344825f7700181b (diff) | |
download | dev86-e6248da18100235ae33468d058e5b71fcefeff3b.tar.gz |
Import Dev86src-0.16.6.tar.gzv0.16.6
Diffstat (limited to 'cpp/hash.c')
-rw-r--r-- | cpp/hash.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/cpp/hash.c b/cpp/hash.c new file mode 100644 index 0000000..3d340e8 --- /dev/null +++ b/cpp/hash.c @@ -0,0 +1,114 @@ + +#include <stdio.h> +#include <malloc.h> +#include "cc.h" + +/* + * Two functions: + * char * set_entry(int namespace, char * name, void * value); + * returns a pointer to the copy of the name; + * + * void * read_entry(int namespace, char * name); + * returns the value; + */ + +struct hashentry +{ + struct hashentry * next; + void * value; + int namespace; + char word[1]; +}; + +struct hashentry ** hashtable; +int hashsize = 0xFF; /* 2^X -1 */ +int hashcount = 0; +static int hashvalue(); + +void * +read_entry(namespace, word) +int namespace; +char * word; +{ + int hash_val; + struct hashentry * hashline; + if( hashtable == 0 ) return 0; + hash_val = hashvalue(namespace, word); + + hashline = hashtable[hash_val]; + + for(; hashline; hashline = hashline->next) + { + if(namespace != hashline->namespace) continue; + if(word[0] != hashline->word[0]) continue; + if(strcmp(word, hashline->word) ) continue; + return hashline->value; + } + return 0; +} + +char * +set_entry(namespace, word, value) +int namespace; +char * word; +void * value; +{ + int hash_val, i; + struct hashentry * hashline, *prev; + hash_val = hashvalue(namespace, word); + + if( hashtable ) + { + hashline = hashtable[hash_val]; + + for(prev=0; hashline; prev=hashline, hashline = hashline->next) + { + if(namespace != hashline->namespace) continue; + if(word[0] != hashline->word[0]) continue; + if(strcmp(word, hashline->word) ) continue; + if( value ) hashline->value = value; + else + { + if( prev == 0 ) hashtable[hash_val] = hashline->next; + else prev->next = hashline->next; + free(hashline); + return 0; + } + return hashline->word; + } + } + if( value == 0 ) return 0; + if( hashtable == 0 ) + { + hashtable = malloc((hashsize+1)*sizeof(char*)); + if( hashtable == 0 ) cfatal("Out of memory"); + for(i=0; i<=hashsize; i++) hashtable[i] = 0; + } + /* Add record */ + hashline = malloc(sizeof(struct hashentry)+strlen(word)); + if( hashline == 0 ) cfatal("Out of memory"); + else + { + hashline->next = hashtable[hash_val]; + hashline->namespace = namespace; + hashline->value = value; + strcpy(hashline->word, word); + hashtable[hash_val] = hashline; + } + return hashline->word; +} + +static int hashvalue(namespace, word) +int namespace; +char * word; +{ + int val = namespace; + char *p = word; + + while(*p) + { + val = ((val<<4)^((val>>12)&0xF)^((*p++)&0xFF)); + } + val &= hashsize; + return val; +} |