summaryrefslogtreecommitdiff
path: root/cpp/hash.c
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2002-07-28 22:10:50 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:48:47 +0200
commite6248da18100235ae33468d058e5b71fcefeff3b (patch)
tree4e3833ed515d03d2366c27f71ef0fe349a2dee12 /cpp/hash.c
parent2060b4f4cc1c13975e495d088344825f7700181b (diff)
downloaddev86-e6248da18100235ae33468d058e5b71fcefeff3b.tar.gz
Import Dev86src-0.16.6.tar.gzv0.16.6
Diffstat (limited to 'cpp/hash.c')
-rw-r--r--cpp/hash.c114
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;
+}