t_hsearch.c revision 1.4 1 1.4 christos /* $NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $ */
2 1.1 pgoyette
3 1.1 pgoyette /*-
4 1.1 pgoyette * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 1.1 pgoyette * All rights reserved.
6 1.1 pgoyette *
7 1.1 pgoyette * Redistribution and use in source and binary forms, with or without
8 1.1 pgoyette * modification, are permitted provided that the following conditions
9 1.1 pgoyette * are met:
10 1.1 pgoyette * 1. Redistributions of source code must retain the above copyright
11 1.1 pgoyette * notice, this list of conditions and the following disclaimer.
12 1.1 pgoyette * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 pgoyette * notice, this list of conditions and the following disclaimer in the
14 1.1 pgoyette * documentation and/or other materials provided with the distribution.
15 1.1 pgoyette *
16 1.1 pgoyette * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 pgoyette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 pgoyette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 pgoyette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 pgoyette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 pgoyette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 pgoyette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 pgoyette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 pgoyette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 pgoyette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 pgoyette * POSSIBILITY OF SUCH DAMAGE.
27 1.1 pgoyette */
28 1.1 pgoyette
29 1.1 pgoyette /*
30 1.1 pgoyette * Copyright (c) 2001 Christopher G. Demetriou
31 1.1 pgoyette * All rights reserved.
32 1.2 jruoho *
33 1.1 pgoyette * Redistribution and use in source and binary forms, with or without
34 1.1 pgoyette * modification, are permitted provided that the following conditions
35 1.1 pgoyette * are met:
36 1.1 pgoyette * 1. Redistributions of source code must retain the above copyright
37 1.1 pgoyette * notice, this list of conditions and the following disclaimer.
38 1.1 pgoyette * 2. Redistributions in binary form must reproduce the above copyright
39 1.1 pgoyette * notice, this list of conditions and the following disclaimer in the
40 1.1 pgoyette * documentation and/or other materials provided with the distribution.
41 1.1 pgoyette * 3. All advertising materials mentioning features or use of this software
42 1.1 pgoyette * must display the following acknowledgement:
43 1.1 pgoyette * This product includes software developed for the
44 1.1 pgoyette * NetBSD Project. See http://www.NetBSD.org/ for
45 1.1 pgoyette * information about NetBSD.
46 1.1 pgoyette * 4. The name of the author may not be used to endorse or promote products
47 1.1 pgoyette * derived from this software without specific prior written permission.
48 1.2 jruoho *
49 1.1 pgoyette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50 1.1 pgoyette * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51 1.1 pgoyette * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52 1.1 pgoyette * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
53 1.1 pgoyette * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54 1.1 pgoyette * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55 1.1 pgoyette * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56 1.1 pgoyette * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57 1.1 pgoyette * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58 1.1 pgoyette * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 1.2 jruoho *
60 1.1 pgoyette * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
61 1.1 pgoyette */
62 1.1 pgoyette
63 1.1 pgoyette #include <sys/cdefs.h>
64 1.1 pgoyette __COPYRIGHT("@(#) Copyright (c) 2008\
65 1.1 pgoyette The NetBSD Foundation, inc. All rights reserved.");
66 1.4 christos __RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $");
67 1.1 pgoyette
68 1.1 pgoyette #include <errno.h>
69 1.1 pgoyette #include <search.h>
70 1.1 pgoyette #include <string.h>
71 1.1 pgoyette #include <stdio.h>
72 1.4 christos #include <stdlib.h>
73 1.1 pgoyette
74 1.1 pgoyette #include <atf-c.h>
75 1.1 pgoyette
76 1.1 pgoyette #define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno))
77 1.1 pgoyette
78 1.2 jruoho ATF_TC(hsearch_basic);
79 1.2 jruoho ATF_TC_HEAD(hsearch_basic, tc)
80 1.1 pgoyette {
81 1.1 pgoyette
82 1.1 pgoyette atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching");
83 1.1 pgoyette }
84 1.1 pgoyette
85 1.2 jruoho ATF_TC_BODY(hsearch_basic, tc)
86 1.1 pgoyette {
87 1.1 pgoyette ENTRY e, *ep;
88 1.1 pgoyette char ch[2];
89 1.1 pgoyette int i;
90 1.1 pgoyette
91 1.1 pgoyette REQUIRE_ERRNO(hcreate(16) != 0);
92 1.1 pgoyette
93 1.1 pgoyette /* ch[1] should be constant from here on down. */
94 1.1 pgoyette ch[1] = '\0';
95 1.1 pgoyette
96 1.1 pgoyette /* Basic insertions. Check enough that there'll be collisions. */
97 1.1 pgoyette for (i = 0; i < 26; i++) {
98 1.1 pgoyette ch[0] = 'a' + i;
99 1.1 pgoyette e.key = strdup(ch); /* ptr to provided key is kept! */
100 1.1 pgoyette ATF_REQUIRE(e.key != NULL);
101 1.4 christos e.data = (void *)(intptr_t)i;
102 1.1 pgoyette
103 1.1 pgoyette ep = hsearch(e, ENTER);
104 1.1 pgoyette
105 1.1 pgoyette ATF_REQUIRE(ep != NULL);
106 1.1 pgoyette ATF_REQUIRE_STREQ(ep->key, ch);
107 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, i);
108 1.1 pgoyette }
109 1.1 pgoyette
110 1.1 pgoyette /* e.key should be constant from here on down. */
111 1.1 pgoyette e.key = ch;
112 1.1 pgoyette
113 1.1 pgoyette /* Basic lookups. */
114 1.1 pgoyette for (i = 0; i < 26; i++) {
115 1.1 pgoyette ch[0] = 'a' + i;
116 1.1 pgoyette
117 1.1 pgoyette ep = hsearch(e, FIND);
118 1.1 pgoyette
119 1.1 pgoyette ATF_REQUIRE(ep != NULL);
120 1.1 pgoyette ATF_REQUIRE_STREQ(ep->key, ch);
121 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, i);
122 1.1 pgoyette }
123 1.1 pgoyette
124 1.4 christos hdestroy1(free, NULL);
125 1.1 pgoyette }
126 1.1 pgoyette
127 1.2 jruoho ATF_TC(hsearch_duplicate);
128 1.2 jruoho ATF_TC_HEAD(hsearch_duplicate, tc)
129 1.1 pgoyette {
130 1.1 pgoyette
131 1.1 pgoyette atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate "
132 1.1 pgoyette "doesn't overwrite existing data");
133 1.1 pgoyette }
134 1.1 pgoyette
135 1.2 jruoho ATF_TC_BODY(hsearch_duplicate, tc)
136 1.1 pgoyette {
137 1.1 pgoyette ENTRY e, *ep;
138 1.1 pgoyette
139 1.1 pgoyette REQUIRE_ERRNO(hcreate(16));
140 1.1 pgoyette
141 1.4 christos e.key = __UNCONST("a");
142 1.4 christos e.data = (void *)(intptr_t) 0;
143 1.1 pgoyette
144 1.1 pgoyette ep = hsearch(e, ENTER);
145 1.1 pgoyette
146 1.1 pgoyette ATF_REQUIRE(ep != NULL);
147 1.1 pgoyette ATF_REQUIRE_STREQ(ep->key, "a");
148 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
149 1.1 pgoyette
150 1.4 christos e.data = (void *)(intptr_t)12345;
151 1.1 pgoyette
152 1.1 pgoyette ep = hsearch(e, ENTER);
153 1.1 pgoyette ep = hsearch(e, FIND);
154 1.1 pgoyette
155 1.1 pgoyette ATF_REQUIRE(ep != NULL);
156 1.1 pgoyette ATF_REQUIRE_STREQ(ep->key, "a");
157 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
158 1.1 pgoyette
159 1.1 pgoyette hdestroy();
160 1.1 pgoyette }
161 1.1 pgoyette
162 1.2 jruoho ATF_TC(hsearch_nonexistent);
163 1.2 jruoho ATF_TC_HEAD(hsearch_nonexistent, tc)
164 1.1 pgoyette {
165 1.1 pgoyette
166 1.1 pgoyette atf_tc_set_md_var(tc, "descr",
167 1.1 pgoyette "Checks searching for non-existent entry");
168 1.1 pgoyette }
169 1.1 pgoyette
170 1.2 jruoho ATF_TC_BODY(hsearch_nonexistent, tc)
171 1.1 pgoyette {
172 1.1 pgoyette ENTRY e, *ep;
173 1.1 pgoyette
174 1.1 pgoyette REQUIRE_ERRNO(hcreate(16));
175 1.1 pgoyette
176 1.4 christos e.key = __UNCONST("A");
177 1.1 pgoyette ep = hsearch(e, FIND);
178 1.1 pgoyette ATF_REQUIRE_EQ(ep, NULL);
179 1.1 pgoyette
180 1.1 pgoyette hdestroy();
181 1.1 pgoyette }
182 1.1 pgoyette
183 1.2 jruoho ATF_TC(hsearch_two);
184 1.2 jruoho ATF_TC_HEAD(hsearch_two, tc)
185 1.1 pgoyette {
186 1.1 pgoyette
187 1.1 pgoyette atf_tc_set_md_var(tc, "descr",
188 1.1 pgoyette "Checks that searching doesn't overwrite previous search results");
189 1.1 pgoyette }
190 1.1 pgoyette
191 1.2 jruoho ATF_TC_BODY(hsearch_two, tc)
192 1.1 pgoyette {
193 1.1 pgoyette ENTRY e, *ep, *ep2;
194 1.1 pgoyette
195 1.1 pgoyette REQUIRE_ERRNO(hcreate(16));
196 1.1 pgoyette
197 1.4 christos e.key = __UNCONST("a");
198 1.4 christos e.data = (void*)(intptr_t)0;
199 1.1 pgoyette
200 1.1 pgoyette ep = hsearch(e, ENTER);
201 1.1 pgoyette
202 1.1 pgoyette ATF_REQUIRE(ep != NULL);
203 1.1 pgoyette ATF_REQUIRE_STREQ(ep->key, "a");
204 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
205 1.1 pgoyette
206 1.4 christos e.key = __UNCONST("b");
207 1.4 christos e.data = (void*)(intptr_t)1;
208 1.1 pgoyette
209 1.1 pgoyette ep = hsearch(e, ENTER);
210 1.2 jruoho
211 1.1 pgoyette ATF_REQUIRE(ep != NULL);
212 1.1 pgoyette ATF_REQUIRE_STREQ(ep->key, "b");
213 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 1);
214 1.1 pgoyette
215 1.4 christos e.key = __UNCONST("a");
216 1.1 pgoyette ep = hsearch(e, FIND);
217 1.1 pgoyette
218 1.4 christos e.key = __UNCONST("b");
219 1.1 pgoyette ep2 = hsearch(e, FIND);
220 1.1 pgoyette
221 1.1 pgoyette ATF_REQUIRE(ep != NULL);
222 1.1 pgoyette ATF_REQUIRE_STREQ(ep->key, "a");
223 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
224 1.1 pgoyette
225 1.1 pgoyette ATF_REQUIRE(ep2 != NULL);
226 1.1 pgoyette ATF_REQUIRE_STREQ(ep2->key, "b");
227 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep2->data, 1);
228 1.2 jruoho
229 1.1 pgoyette hdestroy();
230 1.1 pgoyette }
231 1.1 pgoyette
232 1.3 christos ATF_TC(hsearch_r_basic);
233 1.3 christos ATF_TC_HEAD(hsearch_r_basic, tc)
234 1.3 christos {
235 1.3 christos
236 1.3 christos atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching");
237 1.3 christos }
238 1.3 christos
239 1.3 christos ATF_TC_BODY(hsearch_r_basic, tc)
240 1.3 christos {
241 1.3 christos ENTRY e, *ep;
242 1.3 christos char ch[2];
243 1.3 christos int i;
244 1.3 christos struct hsearch_data t;
245 1.3 christos
246 1.3 christos REQUIRE_ERRNO(hcreate_r(16, &t) != 0);
247 1.3 christos
248 1.3 christos /* ch[1] should be constant from here on down. */
249 1.3 christos ch[1] = '\0';
250 1.3 christos
251 1.3 christos /* Basic insertions. Check enough that there'll be collisions. */
252 1.3 christos for (i = 0; i < 26; i++) {
253 1.3 christos ch[0] = 'a' + i;
254 1.3 christos e.key = strdup(ch); /* ptr to provided key is kept! */
255 1.3 christos ATF_REQUIRE(e.key != NULL);
256 1.4 christos e.data = (void *)(intptr_t)i;
257 1.3 christos
258 1.3 christos ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
259 1.3 christos ATF_REQUIRE(ep != NULL);
260 1.3 christos ATF_REQUIRE_STREQ(ep->key, ch);
261 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, i);
262 1.3 christos }
263 1.3 christos
264 1.3 christos /* e.key should be constant from here on down. */
265 1.3 christos e.key = ch;
266 1.3 christos
267 1.3 christos /* Basic lookups. */
268 1.3 christos for (i = 0; i < 26; i++) {
269 1.3 christos ch[0] = 'a' + i;
270 1.3 christos
271 1.3 christos ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
272 1.3 christos ATF_REQUIRE(ep != NULL);
273 1.3 christos ATF_REQUIRE_STREQ(ep->key, ch);
274 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, i);
275 1.3 christos }
276 1.3 christos
277 1.4 christos hdestroy1_r(&t, free, NULL);
278 1.3 christos }
279 1.3 christos
280 1.3 christos ATF_TC(hsearch_r_duplicate);
281 1.3 christos ATF_TC_HEAD(hsearch_r_duplicate, tc)
282 1.3 christos {
283 1.3 christos
284 1.3 christos atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate "
285 1.3 christos "doesn't overwrite existing data");
286 1.3 christos }
287 1.3 christos
288 1.3 christos ATF_TC_BODY(hsearch_r_duplicate, tc)
289 1.3 christos {
290 1.3 christos ENTRY e, *ep;
291 1.3 christos struct hsearch_data t;
292 1.3 christos
293 1.3 christos REQUIRE_ERRNO(hcreate_r(16, &t));
294 1.3 christos
295 1.4 christos e.key = __UNCONST("a");
296 1.4 christos e.data = (void *)(intptr_t) 0;
297 1.3 christos
298 1.3 christos ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
299 1.3 christos ATF_REQUIRE(ep != NULL);
300 1.3 christos ATF_REQUIRE_STREQ(ep->key, "a");
301 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
302 1.3 christos
303 1.4 christos e.data = (void *)(intptr_t)12345;
304 1.3 christos
305 1.3 christos ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
306 1.3 christos ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
307 1.3 christos
308 1.3 christos ATF_REQUIRE(ep != NULL);
309 1.3 christos ATF_REQUIRE_STREQ(ep->key, "a");
310 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
311 1.3 christos
312 1.3 christos hdestroy_r(&t);
313 1.3 christos }
314 1.3 christos
315 1.3 christos ATF_TC(hsearch_r_nonexistent);
316 1.3 christos ATF_TC_HEAD(hsearch_r_nonexistent, tc)
317 1.3 christos {
318 1.3 christos
319 1.3 christos atf_tc_set_md_var(tc, "descr",
320 1.3 christos "Checks searching for non-existent entry");
321 1.3 christos }
322 1.3 christos
323 1.3 christos ATF_TC_BODY(hsearch_r_nonexistent, tc)
324 1.3 christos {
325 1.3 christos ENTRY e, *ep;
326 1.3 christos struct hsearch_data t;
327 1.3 christos
328 1.3 christos REQUIRE_ERRNO(hcreate_r(16, &t));
329 1.3 christos
330 1.4 christos e.key = __UNCONST("A");
331 1.3 christos ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
332 1.3 christos ATF_REQUIRE_EQ(ep, NULL);
333 1.3 christos
334 1.3 christos hdestroy_r(&t);
335 1.3 christos }
336 1.3 christos
337 1.3 christos ATF_TC(hsearch_r_two);
338 1.3 christos ATF_TC_HEAD(hsearch_r_two, tc)
339 1.3 christos {
340 1.3 christos
341 1.3 christos atf_tc_set_md_var(tc, "descr",
342 1.3 christos "Checks that searching doesn't overwrite previous search results");
343 1.3 christos }
344 1.3 christos
345 1.3 christos ATF_TC_BODY(hsearch_r_two, tc)
346 1.3 christos {
347 1.3 christos ENTRY e, *ep, *ep2;
348 1.3 christos struct hsearch_data t;
349 1.3 christos
350 1.3 christos REQUIRE_ERRNO(hcreate_r(16, &t));
351 1.3 christos
352 1.4 christos e.key = __UNCONST("a");
353 1.4 christos e.data = (void*)(intptr_t)0;
354 1.3 christos
355 1.3 christos ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
356 1.3 christos ATF_REQUIRE(ep != NULL);
357 1.3 christos ATF_REQUIRE_STREQ(ep->key, "a");
358 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
359 1.3 christos
360 1.4 christos e.key = __UNCONST("b");
361 1.4 christos e.data = (void*)(intptr_t)1;
362 1.3 christos
363 1.3 christos ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
364 1.3 christos ATF_REQUIRE(ep != NULL);
365 1.3 christos ATF_REQUIRE_STREQ(ep->key, "b");
366 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 1);
367 1.3 christos
368 1.4 christos e.key = __UNCONST("a");
369 1.3 christos ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
370 1.3 christos
371 1.4 christos e.key = __UNCONST("b");
372 1.3 christos ATF_REQUIRE(hsearch_r(e, FIND, &ep2, &t) == 1);
373 1.3 christos
374 1.3 christos ATF_REQUIRE(ep != NULL);
375 1.3 christos ATF_REQUIRE_STREQ(ep->key, "a");
376 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
377 1.3 christos
378 1.3 christos ATF_REQUIRE(ep2 != NULL);
379 1.3 christos ATF_REQUIRE_STREQ(ep2->key, "b");
380 1.4 christos ATF_REQUIRE_EQ((intptr_t)ep2->data, 1);
381 1.3 christos
382 1.3 christos hdestroy_r(&t);
383 1.3 christos }
384 1.3 christos
385 1.1 pgoyette ATF_TP_ADD_TCS(tp)
386 1.1 pgoyette {
387 1.1 pgoyette
388 1.2 jruoho ATF_TP_ADD_TC(tp, hsearch_basic);
389 1.2 jruoho ATF_TP_ADD_TC(tp, hsearch_duplicate);
390 1.2 jruoho ATF_TP_ADD_TC(tp, hsearch_nonexistent);
391 1.2 jruoho ATF_TP_ADD_TC(tp, hsearch_two);
392 1.1 pgoyette
393 1.3 christos ATF_TP_ADD_TC(tp, hsearch_r_basic);
394 1.3 christos ATF_TP_ADD_TC(tp, hsearch_r_duplicate);
395 1.3 christos ATF_TP_ADD_TC(tp, hsearch_r_nonexistent);
396 1.3 christos ATF_TP_ADD_TC(tp, hsearch_r_two);
397 1.3 christos
398 1.1 pgoyette return atf_no_error();
399 1.1 pgoyette }
400