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