xref: /netbsd-src/tests/lib/libc/stdlib/t_hsearch.c (revision 88fcb00c0357f2d7c1774f86a352637bfda96184)
1 /* $NetBSD: t_hsearch.c,v 1.1 2011/01/13 14:32:35 pgoyette 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.1 2011/01/13 14:32:35 pgoyette Exp $");
67 
68 #include <errno.h>
69 #include <search.h>
70 #include <string.h>
71 #include <stdio.h>
72 
73 #include <atf-c.h>
74 
75 #define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno))
76 
77 ATF_TC(basic);
78 
79 ATF_TC_HEAD(basic, tc)
80 {
81 
82 	atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching");
83 }
84 
85 ATF_TC_BODY(basic, tc)
86 {
87 	ENTRY e, *ep;
88 	char ch[2];
89 	int i;
90 
91 	REQUIRE_ERRNO(hcreate(16) != 0);
92 
93 	/* ch[1] should be constant from here on down. */
94 	ch[1] = '\0';
95 
96 	/* Basic insertions.  Check enough that there'll be collisions. */
97 	for (i = 0; i < 26; i++) {
98 		ch[0] = 'a' + i;
99 		e.key = strdup(ch);	/* ptr to provided key is kept! */
100 		ATF_REQUIRE(e.key != NULL);
101 		e.data = (void *)(long)i;
102 
103 		ep = hsearch(e, ENTER);
104 
105 		ATF_REQUIRE(ep != NULL);
106 		ATF_REQUIRE_STREQ(ep->key, ch);
107 		ATF_REQUIRE_EQ((long)ep->data, i);
108 	}
109 
110 	/* e.key should be constant from here on down. */
111 	e.key = ch;
112 
113 	/* Basic lookups. */
114 	for (i = 0; i < 26; i++) {
115 		ch[0] = 'a' + i;
116 
117 		ep = hsearch(e, FIND);
118 
119 		ATF_REQUIRE(ep != NULL);
120 		ATF_REQUIRE_STREQ(ep->key, ch);
121 		ATF_REQUIRE_EQ((long)ep->data, i);
122 	}
123 
124 	hdestroy();
125 }
126 
127 ATF_TC(duplicate);
128 
129 ATF_TC_HEAD(duplicate, tc)
130 {
131 
132 	atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate "
133 	    "doesn't overwrite existing data");
134 }
135 
136 ATF_TC_BODY(duplicate, tc)
137 {
138 	ENTRY e, *ep;
139 
140 	REQUIRE_ERRNO(hcreate(16));
141 
142 	e.key = strdup("a");
143 	ATF_REQUIRE(e.key != NULL);
144 	e.data = (void *)(long) 0;
145 
146 	ep = hsearch(e, ENTER);
147 
148 	ATF_REQUIRE(ep != NULL);
149 	ATF_REQUIRE_STREQ(ep->key, "a");
150 	ATF_REQUIRE_EQ((long)ep->data, 0);
151 
152 	e.data = (void *)(long)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((long)ep->data, 0);
160 
161 	hdestroy();
162 }
163 
164 ATF_TC(nonexistent);
165 
166 ATF_TC_HEAD(nonexistent, tc)
167 {
168 
169 	atf_tc_set_md_var(tc, "descr",
170 	    "Checks searching for non-existent entry");
171 }
172 
173 ATF_TC_BODY(nonexistent, tc)
174 {
175 	ENTRY e, *ep;
176 
177 	REQUIRE_ERRNO(hcreate(16));
178 
179 	e.key = strdup("A");
180 	ep = hsearch(e, FIND);
181 	ATF_REQUIRE_EQ(ep, NULL);
182 
183 	hdestroy();
184 }
185 
186 ATF_TC(two);
187 
188 ATF_TC_HEAD(two, tc)
189 {
190 
191 	atf_tc_set_md_var(tc, "descr",
192 	    "Checks that searching doesn't overwrite previous search results");
193 }
194 
195 ATF_TC_BODY(two, tc)
196 {
197 	ENTRY e, *ep, *ep2;
198 	char *sa, *sb;
199 
200 	ATF_REQUIRE((sa = strdup("a")) != NULL);
201 	ATF_REQUIRE((sb = strdup("b")) != NULL);
202 
203 	REQUIRE_ERRNO(hcreate(16));
204 
205 	e.key = sa;
206 	e.data = (void*)(long)0;
207 
208 	ep = hsearch(e, ENTER);
209 
210 	ATF_REQUIRE(ep != NULL);
211 	ATF_REQUIRE_STREQ(ep->key, "a");
212 	ATF_REQUIRE_EQ((long)ep->data, 0);
213 
214 	e.key = sb;
215 	e.data = (void*)(long)1;
216 
217 	ep = hsearch(e, ENTER);
218 
219 	ATF_REQUIRE(ep != NULL);
220 	ATF_REQUIRE_STREQ(ep->key, "b");
221 	ATF_REQUIRE_EQ((long)ep->data, 1);
222 
223 	e.key = sa;
224 	ep = hsearch(e, FIND);
225 
226 	e.key = sb;
227 	ep2 = hsearch(e, FIND);
228 
229 	ATF_REQUIRE(ep != NULL);
230 	ATF_REQUIRE_STREQ(ep->key, "a");
231 	ATF_REQUIRE_EQ((long)ep->data, 0);
232 
233 	ATF_REQUIRE(ep2 != NULL);
234 	ATF_REQUIRE_STREQ(ep2->key, "b");
235 	ATF_REQUIRE_EQ((long)ep2->data, 1);
236 
237 	hdestroy();
238 }
239 
240 ATF_TP_ADD_TCS(tp)
241 {
242 
243 	ATF_TP_ADD_TC(tp, basic);
244 	ATF_TP_ADD_TC(tp, duplicate);
245 	ATF_TP_ADD_TC(tp, nonexistent);
246 	ATF_TP_ADD_TC(tp, two);
247 
248 	return atf_no_error();
249 }
250