]> jfr.im git - irc/thales.git/blame - src/hashlist.c
readmes added, contribs removed
[irc/thales.git] / src / hashlist.c
CommitLineData
2ace9480 1/* 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
22extern int verbose;
23
24/* creates a new hashlist */
25hashlist 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
34int 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 */
52void 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 log("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 */
68void hash_del(hashlist h, char *str, int keytype)
69{
70 struct item *pi, **piold;
71 if (verbose)
72 log("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 */
90int hash_find(hashlist h, char *str, int keytype)
91{
92 int res;
93 if (verbose)
94 log("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 */
103int hash_find_unsure(hashlist h, char *str, int keytype)
104{
105 struct item *pi;
106 if (verbose)
107 log("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 :) */
116int hash_findel(hashlist h, char *str, int keytype)
117{
118 int n;
119 struct item *pi, **piold;
120 if (verbose)
121 log("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 */
140void hash_update(hashlist h, char *newinfo, char *str, int keytype)
141{
142 int key;
143 int key2;
144 if (verbose)
145 log("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}