1272343Sngie/* $NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 2008 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * Redistribution and use in source and binary forms, with or without 8272343Sngie * modification, are permitted provided that the following conditions 9272343Sngie * are met: 10272343Sngie * 1. Redistributions of source code must retain the above copyright 11272343Sngie * notice, this list of conditions and the following disclaimer. 12272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 13272343Sngie * notice, this list of conditions and the following disclaimer in the 14272343Sngie * documentation and/or other materials provided with the distribution. 15272343Sngie * 16272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26272343Sngie * POSSIBILITY OF SUCH DAMAGE. 27272343Sngie */ 28272343Sngie 29272343Sngie/* 30272343Sngie * Copyright (c) 2001 Christopher G. Demetriou 31272343Sngie * All rights reserved. 32272343Sngie * 33272343Sngie * Redistribution and use in source and binary forms, with or without 34272343Sngie * modification, are permitted provided that the following conditions 35272343Sngie * are met: 36272343Sngie * 1. Redistributions of source code must retain the above copyright 37272343Sngie * notice, this list of conditions and the following disclaimer. 38272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 39272343Sngie * notice, this list of conditions and the following disclaimer in the 40272343Sngie * documentation and/or other materials provided with the distribution. 41272343Sngie * 3. All advertising materials mentioning features or use of this software 42272343Sngie * must display the following acknowledgement: 43272343Sngie * This product includes software developed for the 44272343Sngie * NetBSD Project. See http://www.NetBSD.org/ for 45272343Sngie * information about NetBSD. 46272343Sngie * 4. The name of the author may not be used to endorse or promote products 47272343Sngie * derived from this software without specific prior written permission. 48272343Sngie * 49272343Sngie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 50272343Sngie * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 51272343Sngie * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52272343Sngie * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 53272343Sngie * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 54272343Sngie * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 55272343Sngie * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 56272343Sngie * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 57272343Sngie * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 58272343Sngie * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59272343Sngie * 60272343Sngie * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> 61272343Sngie */ 62272343Sngie 63272343Sngie#include <sys/cdefs.h> 64272343Sngie__COPYRIGHT("@(#) Copyright (c) 2008\ 65272343Sngie The NetBSD Foundation, inc. All rights reserved."); 66272343Sngie__RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $"); 67272343Sngie 68272343Sngie#include <errno.h> 69272343Sngie#include <search.h> 70272343Sngie#include <string.h> 71272343Sngie#include <stdio.h> 72272343Sngie#include <stdlib.h> 73272343Sngie 74272343Sngie#include <atf-c.h> 75272343Sngie 76272343Sngie#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) 77272343Sngie 78272343SngieATF_TC(hsearch_basic); 79272343SngieATF_TC_HEAD(hsearch_basic, tc) 80272343Sngie{ 81272343Sngie 82272343Sngie atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); 83272343Sngie} 84272343Sngie 85272343SngieATF_TC_BODY(hsearch_basic, tc) 86272343Sngie{ 87272343Sngie ENTRY e, *ep; 88272343Sngie char ch[2]; 89272343Sngie int i; 90272343Sngie 91272343Sngie REQUIRE_ERRNO(hcreate(16) != 0); 92272343Sngie 93272343Sngie /* ch[1] should be constant from here on down. */ 94272343Sngie ch[1] = '\0'; 95272343Sngie 96272343Sngie /* Basic insertions. Check enough that there'll be collisions. */ 97272343Sngie for (i = 0; i < 26; i++) { 98272343Sngie ch[0] = 'a' + i; 99272343Sngie e.key = strdup(ch); /* ptr to provided key is kept! */ 100272343Sngie ATF_REQUIRE(e.key != NULL); 101272343Sngie e.data = (void *)(intptr_t)i; 102272343Sngie 103272343Sngie ep = hsearch(e, ENTER); 104272343Sngie 105272343Sngie ATF_REQUIRE(ep != NULL); 106272343Sngie ATF_REQUIRE_STREQ(ep->key, ch); 107272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, i); 108272343Sngie } 109272343Sngie 110272343Sngie /* e.key should be constant from here on down. */ 111272343Sngie e.key = ch; 112272343Sngie 113272343Sngie /* Basic lookups. */ 114272343Sngie for (i = 0; i < 26; i++) { 115272343Sngie ch[0] = 'a' + i; 116272343Sngie 117272343Sngie ep = hsearch(e, FIND); 118272343Sngie 119272343Sngie ATF_REQUIRE(ep != NULL); 120272343Sngie ATF_REQUIRE_STREQ(ep->key, ch); 121272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, i); 122272343Sngie } 123272343Sngie 124314818Sngie#ifdef __NetBSD__ 125272343Sngie hdestroy1(free, NULL); 126314818Sngie#else 127314818Sngie hdestroy(); 128314818Sngie#endif 129272343Sngie} 130272343Sngie 131272343SngieATF_TC(hsearch_duplicate); 132272343SngieATF_TC_HEAD(hsearch_duplicate, tc) 133272343Sngie{ 134272343Sngie 135272343Sngie atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " 136272343Sngie "doesn't overwrite existing data"); 137272343Sngie} 138272343Sngie 139272343SngieATF_TC_BODY(hsearch_duplicate, tc) 140272343Sngie{ 141272343Sngie ENTRY e, *ep; 142272343Sngie 143272343Sngie REQUIRE_ERRNO(hcreate(16)); 144272343Sngie 145272343Sngie e.key = __UNCONST("a"); 146272343Sngie e.data = (void *)(intptr_t) 0; 147272343Sngie 148272343Sngie ep = hsearch(e, ENTER); 149272343Sngie 150272343Sngie ATF_REQUIRE(ep != NULL); 151272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 152272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 153272343Sngie 154272343Sngie e.data = (void *)(intptr_t)12345; 155272343Sngie 156272343Sngie ep = hsearch(e, ENTER); 157272343Sngie ep = hsearch(e, FIND); 158272343Sngie 159272343Sngie ATF_REQUIRE(ep != NULL); 160272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 161272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 162272343Sngie 163272343Sngie hdestroy(); 164272343Sngie} 165272343Sngie 166272343SngieATF_TC(hsearch_nonexistent); 167272343SngieATF_TC_HEAD(hsearch_nonexistent, tc) 168272343Sngie{ 169272343Sngie 170272343Sngie atf_tc_set_md_var(tc, "descr", 171272343Sngie "Checks searching for non-existent entry"); 172272343Sngie} 173272343Sngie 174272343SngieATF_TC_BODY(hsearch_nonexistent, tc) 175272343Sngie{ 176272343Sngie ENTRY e, *ep; 177272343Sngie 178272343Sngie REQUIRE_ERRNO(hcreate(16)); 179272343Sngie 180272343Sngie e.key = __UNCONST("A"); 181272343Sngie ep = hsearch(e, FIND); 182272343Sngie ATF_REQUIRE_EQ(ep, NULL); 183272343Sngie 184272343Sngie hdestroy(); 185272343Sngie} 186272343Sngie 187272343SngieATF_TC(hsearch_two); 188272343SngieATF_TC_HEAD(hsearch_two, tc) 189272343Sngie{ 190272343Sngie 191272343Sngie atf_tc_set_md_var(tc, "descr", 192272343Sngie "Checks that searching doesn't overwrite previous search results"); 193272343Sngie} 194272343Sngie 195272343SngieATF_TC_BODY(hsearch_two, tc) 196272343Sngie{ 197272343Sngie ENTRY e, *ep, *ep2; 198272343Sngie 199272343Sngie REQUIRE_ERRNO(hcreate(16)); 200272343Sngie 201272343Sngie e.key = __UNCONST("a"); 202272343Sngie e.data = (void*)(intptr_t)0; 203272343Sngie 204272343Sngie ep = hsearch(e, ENTER); 205272343Sngie 206272343Sngie ATF_REQUIRE(ep != NULL); 207272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 208272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 209272343Sngie 210272343Sngie e.key = __UNCONST("b"); 211272343Sngie e.data = (void*)(intptr_t)1; 212272343Sngie 213272343Sngie ep = hsearch(e, ENTER); 214272343Sngie 215272343Sngie ATF_REQUIRE(ep != NULL); 216272343Sngie ATF_REQUIRE_STREQ(ep->key, "b"); 217272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 1); 218272343Sngie 219272343Sngie e.key = __UNCONST("a"); 220272343Sngie ep = hsearch(e, FIND); 221272343Sngie 222272343Sngie e.key = __UNCONST("b"); 223272343Sngie ep2 = hsearch(e, FIND); 224272343Sngie 225272343Sngie ATF_REQUIRE(ep != NULL); 226272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 227272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 228272343Sngie 229272343Sngie ATF_REQUIRE(ep2 != NULL); 230272343Sngie ATF_REQUIRE_STREQ(ep2->key, "b"); 231272343Sngie ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); 232272343Sngie 233272343Sngie hdestroy(); 234272343Sngie} 235272343Sngie 236276046Sngie#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version 237272343SngieATF_TC(hsearch_r_basic); 238272343SngieATF_TC_HEAD(hsearch_r_basic, tc) 239272343Sngie{ 240272343Sngie 241272343Sngie atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); 242272343Sngie} 243272343Sngie 244272343SngieATF_TC_BODY(hsearch_r_basic, tc) 245272343Sngie{ 246272343Sngie ENTRY e, *ep; 247272343Sngie char ch[2]; 248272343Sngie int i; 249272343Sngie struct hsearch_data t; 250272343Sngie 251272343Sngie REQUIRE_ERRNO(hcreate_r(16, &t) != 0); 252272343Sngie 253272343Sngie /* ch[1] should be constant from here on down. */ 254272343Sngie ch[1] = '\0'; 255272343Sngie 256272343Sngie /* Basic insertions. Check enough that there'll be collisions. */ 257272343Sngie for (i = 0; i < 26; i++) { 258272343Sngie ch[0] = 'a' + i; 259272343Sngie e.key = strdup(ch); /* ptr to provided key is kept! */ 260272343Sngie ATF_REQUIRE(e.key != NULL); 261272343Sngie e.data = (void *)(intptr_t)i; 262272343Sngie 263272343Sngie ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); 264272343Sngie ATF_REQUIRE(ep != NULL); 265272343Sngie ATF_REQUIRE_STREQ(ep->key, ch); 266272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, i); 267272343Sngie } 268272343Sngie 269272343Sngie /* e.key should be constant from here on down. */ 270272343Sngie e.key = ch; 271272343Sngie 272272343Sngie /* Basic lookups. */ 273272343Sngie for (i = 0; i < 26; i++) { 274272343Sngie ch[0] = 'a' + i; 275272343Sngie 276272343Sngie ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); 277272343Sngie ATF_REQUIRE(ep != NULL); 278272343Sngie ATF_REQUIRE_STREQ(ep->key, ch); 279272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, i); 280272343Sngie } 281272343Sngie 282314818Sngie#ifdef __NetBSD__ 283272343Sngie hdestroy1_r(&t, free, NULL); 284314818Sngie#else 285314818Sngie hdestroy_r(&t); 286314818Sngie#endif 287272343Sngie} 288272890Sngie#endif 289272343Sngie 290314818Sngie#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version 291272343SngieATF_TC(hsearch_r_duplicate); 292272343SngieATF_TC_HEAD(hsearch_r_duplicate, tc) 293272343Sngie{ 294272343Sngie 295272343Sngie atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " 296272343Sngie "doesn't overwrite existing data"); 297272343Sngie} 298272343Sngie 299272343SngieATF_TC_BODY(hsearch_r_duplicate, tc) 300272343Sngie{ 301272343Sngie ENTRY e, *ep; 302272343Sngie struct hsearch_data t; 303272343Sngie 304272343Sngie REQUIRE_ERRNO(hcreate_r(16, &t)); 305272343Sngie 306272343Sngie e.key = __UNCONST("a"); 307272343Sngie e.data = (void *)(intptr_t) 0; 308272343Sngie 309272343Sngie ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); 310272343Sngie ATF_REQUIRE(ep != NULL); 311272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 312272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 313272343Sngie 314272343Sngie e.data = (void *)(intptr_t)12345; 315272343Sngie 316272343Sngie ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); 317272343Sngie ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); 318272343Sngie 319272343Sngie ATF_REQUIRE(ep != NULL); 320272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 321272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 322272343Sngie 323272343Sngie hdestroy_r(&t); 324272343Sngie} 325272343Sngie 326272343SngieATF_TC(hsearch_r_nonexistent); 327272343SngieATF_TC_HEAD(hsearch_r_nonexistent, tc) 328272343Sngie{ 329272343Sngie 330272343Sngie atf_tc_set_md_var(tc, "descr", 331272343Sngie "Checks searching for non-existent entry"); 332272343Sngie} 333272343Sngie 334272343SngieATF_TC_BODY(hsearch_r_nonexistent, tc) 335272343Sngie{ 336272343Sngie ENTRY e, *ep; 337272343Sngie struct hsearch_data t; 338272343Sngie 339272343Sngie REQUIRE_ERRNO(hcreate_r(16, &t)); 340272343Sngie 341314818Sngie#ifdef __FreeBSD__ 342314818Sngie atf_tc_expect_fail("behavior doesn't match docs; see bug # 216872"); 343314818Sngie#endif 344272343Sngie e.key = __UNCONST("A"); 345272343Sngie ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); 346272343Sngie ATF_REQUIRE_EQ(ep, NULL); 347272343Sngie 348272343Sngie hdestroy_r(&t); 349272343Sngie} 350272343Sngie 351272343SngieATF_TC(hsearch_r_two); 352272343SngieATF_TC_HEAD(hsearch_r_two, tc) 353272343Sngie{ 354272343Sngie 355272343Sngie atf_tc_set_md_var(tc, "descr", 356272343Sngie "Checks that searching doesn't overwrite previous search results"); 357272343Sngie} 358272343Sngie 359272343SngieATF_TC_BODY(hsearch_r_two, tc) 360272343Sngie{ 361272343Sngie ENTRY e, *ep, *ep2; 362272343Sngie struct hsearch_data t; 363272343Sngie 364272343Sngie REQUIRE_ERRNO(hcreate_r(16, &t)); 365272343Sngie 366272343Sngie e.key = __UNCONST("a"); 367272343Sngie e.data = (void*)(intptr_t)0; 368272343Sngie 369272343Sngie ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); 370272343Sngie ATF_REQUIRE(ep != NULL); 371272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 372272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 373272343Sngie 374272343Sngie e.key = __UNCONST("b"); 375272343Sngie e.data = (void*)(intptr_t)1; 376272343Sngie 377272343Sngie ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); 378272343Sngie ATF_REQUIRE(ep != NULL); 379272343Sngie ATF_REQUIRE_STREQ(ep->key, "b"); 380272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 1); 381272343Sngie 382272343Sngie e.key = __UNCONST("a"); 383272343Sngie ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); 384272343Sngie 385272343Sngie e.key = __UNCONST("b"); 386272343Sngie ATF_REQUIRE(hsearch_r(e, FIND, &ep2, &t) == 1); 387272343Sngie 388272343Sngie ATF_REQUIRE(ep != NULL); 389272343Sngie ATF_REQUIRE_STREQ(ep->key, "a"); 390272343Sngie ATF_REQUIRE_EQ((intptr_t)ep->data, 0); 391272343Sngie 392272343Sngie ATF_REQUIRE(ep2 != NULL); 393272343Sngie ATF_REQUIRE_STREQ(ep2->key, "b"); 394272343Sngie ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); 395272343Sngie 396272343Sngie hdestroy_r(&t); 397272343Sngie} 398276046Sngie#endif 399272343Sngie 400272343SngieATF_TP_ADD_TCS(tp) 401272343Sngie{ 402272343Sngie 403272343Sngie ATF_TP_ADD_TC(tp, hsearch_basic); 404272343Sngie ATF_TP_ADD_TC(tp, hsearch_duplicate); 405272343Sngie ATF_TP_ADD_TC(tp, hsearch_nonexistent); 406272343Sngie ATF_TP_ADD_TC(tp, hsearch_two); 407314818Sngie 408276046Sngie#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version 409272343Sngie ATF_TP_ADD_TC(tp, hsearch_r_basic); 410272343Sngie ATF_TP_ADD_TC(tp, hsearch_r_duplicate); 411272343Sngie ATF_TP_ADD_TC(tp, hsearch_r_nonexistent); 412272343Sngie ATF_TP_ADD_TC(tp, hsearch_r_two); 413276046Sngie#endif 414272343Sngie 415272343Sngie return atf_no_error(); 416272343Sngie} 417