1 /* GNU Thales - IRC to Relational Database Gateway
2 * Copyright (C) 2002 Lucas Nussbaum <lucas@lucas-nussbaum.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include "hashlist.h"
20 #include "log.h"
21
22 extern int verbose;
23
24 /* creates a new hashlist */
newhashlist()25 hashlist newhashlist()
26 {
27 hashlist h = (hashlist) malloc(sizeof(struct item *) * 256);
28 memset(h, 0, sizeof(struct item *) * 256);
29 return h;
30 }
31
32 /* returns an hashcode for the given string */
33 #define HASHSHIFT 5
hash(char * s,int keytype)34 int hash(char *s, int keytype)
35 {
36 int h = 0;
37 if (verbose)
38 /* dont use the # if chan */
39 if (keytype == KEYCHAN)
40 s++;
41 while (*s)
42 {
43 /* imported from ispell and modified */
44 h = (h << HASHSHIFT)
45 | ((h >> (8 - HASHSHIFT)) & ((1 << HASHSHIFT) - 1));
46 h ^= *s++;
47 }
48 return h & ((1 << 8) - 1);
49 }
50
51 /* adds an element to the hashlist */
hash_add(hashlist h,char * str,int n,int keytype)52 void hash_add(hashlist h, char *str, int n, int keytype)
53 {
54 struct item *pio;
55 struct item *pin;
56 int key = hash(str, keytype);
57 if (verbose)
58 mylog("HASH : hash_add %d, %s, %d, %d", (int) h, str, n, keytype);
59 pio = h[key];
60 pin = (struct item *) malloc(sizeof(struct item));
61 pin->str = strdup(str);
62 pin->n = n;
63 pin->next = pio;
64 h[key] = pin;
65 }
66
67 /* deletes an element from the hashlist */
hash_del(hashlist h,char * str,int keytype)68 void hash_del(hashlist h, char *str, int keytype)
69 {
70 struct item *pi, **piold;
71 if (verbose)
72 mylog("HASH : hash_del %d, %s, %d", (int) h, str, keytype);
73 for (piold = &h[hash(str, keytype)], pi = *piold; pi; pi = pi->next)
74 {
75 if (!strcmp(str, pi->str))
76 {
77 *piold = pi->next;
78 free(pi->str);
79 free(pi);
80 if (hash_find_unsure(h, str, keytype) != -1)
81 fatal("deleted %s but still present !", str);
82 return;
83 }
84 piold = &(pi->next);
85 }
86 fatal("hashlist element %s not found !", str);
87 }
88
89 /* finds an element in the hashlist - crash if not found */
hash_find(hashlist h,char * str,int keytype)90 int hash_find(hashlist h, char *str, int keytype)
91 {
92 int res;
93 if (verbose)
94 mylog("HASH : hash_find %d, %s, %d", (int) h, str, keytype);
95 res = hash_find_unsure(h, str, keytype);
96 if (res != -1)
97 return res;
98 fatal("hashlist element %s not found !", str);
99 return 0; /* prevents compiler warnings */
100 }
101
102 /* finds an element in the hashlist - returns -1 if not found */
hash_find_unsure(hashlist h,char * str,int keytype)103 int hash_find_unsure(hashlist h, char *str, int keytype)
104 {
105 struct item *pi;
106 if (verbose)
107 mylog("HASH : hash_find_unsure %d, %s, %d", (int) h, str, keytype);
108 for (pi = h[hash(str, keytype)]; pi; pi = pi->next)
109 if (!strcmp(str, pi->str))
110 return pi->n;
111 return -1;
112 }
113
114 /* finds an element in the hashlist, then remove it */
115 /* Findel, Luxembourg - where I worked when I wrote this :) */
hash_findel(hashlist h,char * str,int keytype)116 int hash_findel(hashlist h, char *str, int keytype)
117 {
118 int n;
119 struct item *pi, **piold;
120 if (verbose)
121 mylog("HASH : hash_findel %d, %s, %d", (int) h, str, keytype);
122
123 for (piold = &h[hash(str, keytype)], pi = *piold; pi; pi = pi->next)
124 {
125 if (!strcmp(str, pi->str))
126 {
127 n = pi->n;
128 *piold = pi->next;
129 free(pi->str);
130 free(pi);
131 return n;
132 }
133 piold = &(pi->next);
134 }
135 fatal("hashlist element %s not found !", str);
136 return 0; /* to prevent compiler warnings */
137 }
138
139 /* update an item */
hash_update(hashlist h,char * newinfo,char * str,int keytype)140 void hash_update(hashlist h, char *newinfo, char *str, int keytype)
141 {
142 int key;
143 int key2;
144 if (verbose)
145 mylog("HASH : hash_update %d, %s, %s, %d", (int) h, newinfo, str,
146 keytype);
147 if ((key = hash(str, keytype)) == (key2 = hash(newinfo, keytype)))
148 {
149 struct item *pi;
150
151 for (pi = h[key]; pi; pi = pi->next)
152 if (!strcmp(str, pi->str))
153 {
154 free(pi->str);
155 pi->str = strdup(newinfo);
156 return;
157 }
158 fatal("hashlist element %s not found !", str);
159 }
160 else
161 {
162 /* find and delete the old, create the new */
163 int n;
164 struct item *pi, **piold;
165 struct item *pio;
166
167 for (piold = &h[key], pi = *piold; pi; pi = pi->next)
168 {
169 if (!strcmp(str, pi->str))
170 {
171 /* save and delete the old entry */
172 n = pi->n;
173 *piold = pi->next;
174 free(pi->str);
175 /* create the new */
176 pio = h[key2];
177 pi->str = strdup(newinfo);
178 pi->n = n;
179 pi->next = pio;
180 h[key2] = pi;
181 return;
182 }
183 piold = &(pi->next);
184 }
185 fatal("hashlist element %s not found !", str);
186 }
187 }
188