joe-3.1jupp31.tgz (die zweite Klappe…)
[alioth/jupp.git] / hash.c
1 /* $MirOS: contrib/code/jupp/hash.c,v 1.3 2017/01/10 19:16:27 tg Exp $ */
2 /*
3  *      Simple hash table
4  *      Copyright
5  *              (C) 1992 Joseph H. Allen
6  *
7  *      This file is part of JOE (Joe's Own Editor)
8  */
9 #include "config.h"
10 #include "types.h"
11
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "hash.h"
16 #include "utils.h"
17
18 #define hnext(accu, c) (((accu) << 4) + ((accu) >> 28) + (c))
19
20 static HENTRY *freentry = NULL;
21
22 unsigned long hash(unsigned char *s)
23 {
24         unsigned long accu = 0;
25
26         while (*s) {
27                 accu = hnext(accu, *s++);
28         }
29         return accu;
30 }
31
32 HASH *htmk(int len)
33 {
34         HASH *t = (HASH *) joe_malloc(sizeof(HASH));
35
36         t->len = len - 1;
37         t->tab = (HENTRY **) joe_calloc(sizeof(HENTRY *), len);
38         return t;
39 }
40
41 void htrm(HASH *ht)
42 {
43         joe_free(ht->tab);
44         joe_free(ht);
45 }
46
47 void *htadd(HASH *ht, unsigned char *name, void *val)
48 {
49         int idx = hash(name) & ht->len;
50         HENTRY *entry;
51         int x;
52
53         if (!freentry) {
54                 entry = (HENTRY *) joe_malloc(sizeof(HENTRY) *64);
55                 for (x = 0; x != 64; ++x) {
56                         entry[x].next = freentry;
57                         freentry = entry + x;
58                 }
59         }
60         entry = freentry;
61         freentry = entry->next;
62         entry->next = ht->tab[idx];
63         ht->tab[idx] = entry;
64         entry->name = name;
65         return entry->val = val;
66 }
67
68 void *htfind(HASH *ht, unsigned char *name)
69 {
70         HENTRY *e;
71
72         for (e = ht->tab[hash(name) & ht->len]; e; e = e->next) {
73                 if (!strcmp(e->name, name)) {
74                         return e->val;
75                 }
76         }
77         return NULL;
78 }