chiark / gitweb /
Commit 2.4.5-5 as unpacked
[inn-innduct.git] / tests / lib / hashtab-t.c
1 /* $Id: hashtab-t.c 6026 2002-12-24 05:02:51Z rra $ */
2 /* Test suite for lib/hashtab.c. */
3
4 #include "config.h"
5 #include "clibrary.h"
6 #include <sys/stat.h>
7
8 #include "inn/hashtab.h"
9 #include "inn/messages.h"
10 #include "libinn.h"
11 #include "libtest.h"
12
13 struct wordref {
14     const char *word;
15     int count;
16 };
17
18 static const void *
19 string_key(const void *entry)
20 {
21     return entry;
22 }
23
24 static bool
25 string_equal(const void *key, const void *entry)
26 {
27     const char *p, *q;
28
29     p = key;
30     q = entry;
31     return !strcmp(p, q);
32 }
33
34 static void
35 string_delete(void *entry)
36 {
37     free(entry);
38 }
39
40 static void
41 string_traverse(void *entry, void *data)
42 {
43     int i;
44     struct wordref *wordrefs = data;
45
46     for (i = 0; wordrefs[i].word != NULL; i++)
47         if (!strcmp(entry, wordrefs[i].word)) {
48             wordrefs[i].count++;
49             return;
50         }
51     wordrefs[3].count++;
52 }
53
54 int
55 main(void)
56 {
57     struct hash *hash;
58     FILE *words;
59     int reported, i;
60     char buffer[1024];
61     char *word;
62     char *test, *testing, *strange, *change, *foo, *bar;
63
64     struct wordref wordrefs[4] = {
65         { "test", 0 }, { "testing", 0 }, { "change", 0 }, { NULL, 0 }
66     };
67
68     test = xstrdup("test");
69     testing = xstrdup("testing");
70     strange = xstrdup("strange");
71     change = xstrdup("change");
72
73     puts("38");
74     hash = hash_create(4, hash_string, string_key, string_equal,
75                        string_delete);
76     ok(1, hash != NULL);
77     if (hash == NULL)
78         die("Unable to create hash, cannot continue");
79
80     ok(2, hash_insert(hash, "test", test));
81     ok(3, hash_collisions(hash) == 0);
82     ok(4, hash_expansions(hash) == 0);
83     ok(5, hash_searches(hash) == 1);
84     ok(6, hash_count(hash) == 1);
85     word = hash_lookup(hash, "test");
86     ok(7, word != NULL && !strcmp("test", word));
87     ok(8, hash_delete(hash, "test"));
88     test = xstrdup("test");
89     ok(9, hash_lookup(hash, "test") == NULL);
90     ok(10, !hash_delete(hash, "test"));
91     ok(11, !hash_replace(hash, "test", testing));
92     ok(12, hash_count(hash) == 0);
93     ok(13, hash_insert(hash, "test", test));
94     ok(14, hash_insert(hash, "testing", testing));
95     ok(15, hash_insert(hash, "strange", strange));
96     ok(16, hash_expansions(hash) == 0);
97     ok(17, hash_insert(hash, "change", change));
98     ok(18, hash_expansions(hash) == 1);
99     ok(19, hash_count(hash) == 4);
100     word = hash_lookup(hash, "testing");
101     ok(20, word != NULL && !strcmp("testing", word));
102     word = hash_lookup(hash, "strange");
103     ok(21, word != NULL && !strcmp("strange", word));
104     ok(22, hash_lookup(hash, "thingie") == NULL);
105     ok(23, !hash_delete(hash, "thingie"));
106     ok(24, hash_delete(hash, "strange"));
107     ok(25, hash_lookup(hash, "strange") == NULL);
108     ok(26, hash_count(hash) == 3);
109
110     hash_traverse(hash, string_traverse, &wordrefs[0]);
111     reported = 0;
112     for (i = 0; wordrefs[i].word != NULL; i++)
113         if (wordrefs[i].count != 1 && !reported) {
114             printf("not ");
115             reported = 1;
116         }
117     puts("ok 27");
118     ok(28, wordrefs[3].count == 0);
119
120     hash_free(hash);
121
122     /* Test hash creation with an odd size.  This previously could result
123        in the wrong table size being allocated. */
124     test = xstrdup("test");
125     testing = xstrdup("testing");
126     strange = xstrdup("strange");
127     change = xstrdup("change");
128     foo = xstrdup("foo");
129     bar = xstrdup("bar");
130     hash = hash_create(5, hash_string, string_key, string_equal,
131                        string_delete);
132     ok(29, hash != NULL);
133     if (hash == NULL)
134         die("Unable to create hash, cannot continue");
135     ok(30, hash_insert(hash, "test", test));
136     ok(31, hash_insert(hash, "testing", testing));
137     ok(32, hash_insert(hash, "strange", strange));
138     ok(33, hash_insert(hash, "change", change));
139     ok(34, hash_insert(hash, "foo", foo));
140     ok(35, hash_insert(hash, "bar", bar));
141     ok(36, hash_count(hash) == 6);
142     hash_free(hash);
143
144     words = fopen("/usr/dict/words", "r");
145     if (words == NULL)
146         words = fopen("/usr/share/dict/words", "r");
147     if (words == NULL) {
148         puts("ok 37 # skip\nok 38 # skip");
149         exit(0);
150     }
151
152     hash = hash_create(4, hash_string, string_key, string_equal,
153                        string_delete);
154     reported = 0;
155     if (hash == NULL)
156         printf("not ");
157     else {
158         while (fgets(buffer, sizeof(buffer), words)) {
159             buffer[strlen(buffer) - 1] = '\0';
160             word = xstrdup(buffer);
161             if (!hash_insert(hash, word, word)) {
162                 if (!reported)
163                     printf("not ");
164                 reported = 1;
165             }
166         }
167     }
168     puts("ok 37");
169
170     if (fseek(words, 0, SEEK_SET) < 0)
171         sysdie("Unable to rewind words file");
172     reported = 0;
173     if (hash == NULL)
174         printf("not ");
175     else {
176         while (fgets(buffer, sizeof(buffer), words)) {
177             buffer[strlen(buffer) - 1] = '\0';
178             word = hash_lookup(hash, buffer);
179             if (!word || strcmp(word, buffer) != 0) {
180                 if (!reported)
181                     printf("not ");
182                 reported = 1;
183             }
184         }
185     }
186     puts("ok 38");
187
188     hash_free(hash);
189
190     return 0;
191 }