1 /*
2 * Copyright (c) 2026 Faraz Vahedi <kfv@FreeBSD.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7 /*
8 * Test for bsearch() routine.
9 */
10
11 #include <stdlib.h>
12
13 #include "test-search.h"
14
15 static const void *expected_key;
16 static const void *expected_base;
17 static size_t expected_nmemb;
18
19 static int
searchhelp_check(const void * a,const void * b)20 searchhelp_check(const void *a, const void *b)
21 {
22 const char *p, *base;
23
24 ATF_CHECK(a == expected_key);
25 p = b;
26 base = expected_base;
27 ATF_CHECK(((size_t)(p - base) % sizeof(int)) == 0);
28 ATF_CHECK(p >= base);
29 ATF_CHECK(p < base + expected_nmemb * sizeof(int));
30 return (searchhelp(a, b));
31 }
32
33 static int
searchhelp_never(const void * a __unused,const void * b __unused)34 searchhelp_never(const void *a __unused, const void *b __unused)
35 {
36 atf_tc_fail("comparison function invoked unexpectedly");
37 return (0);
38 }
39
40 static void *
do_bsearch(const int * key,const int * base,size_t n,void * ctx __unused)41 do_bsearch(const int *key, const int *base, size_t n, void *ctx __unused)
42 {
43 expected_key = key;
44 return (bsearch(key, base, n, sizeof(int), searchhelp_check));
45 }
46
47 ATF_TC_WITHOUT_HEAD(bsearch_test);
ATF_TC_BODY(bsearch_test,tc)48 ATF_TC_BODY(bsearch_test, tc)
49 {
50 int testvector[SVEC_LEN];
51 int key, j;
52
53 for (j = 0; j <= SVEC_LEN; j++) {
54 if (j == 0) {
55 key = 0;
56 ATF_CHECK(bsearch(&key, testvector, 0,
57 sizeof(testvector[0]), searchhelp_never) == NULL);
58 continue;
59 }
60 expected_base = testvector;
61 expected_nmemb = (size_t)j;
62 check_sorted_search(do_bsearch, NULL, testvector, (size_t)j);
63 }
64 }
65
66 ATF_TC_WITHOUT_HEAD(bsearch_duplicates);
ATF_TC_BODY(bsearch_duplicates,tc)67 ATF_TC_BODY(bsearch_duplicates, tc)
68 {
69 int d[] = { 1, 2, 2, 2, 3 };
70 int e[] = { 7, 7, 7 };
71 int key, *found;
72
73 key = 2;
74 found = bsearch(&key, d, nitems(d), sizeof(d[0]), searchhelp);
75 ATF_REQUIRE(found != NULL);
76 ATF_CHECK(found >= &d[1] && found <= &d[3]);
77 ATF_CHECK_EQ(*found, 2);
78
79 key = 7;
80 found = bsearch(&key, e, nitems(e), sizeof(e[0]), searchhelp);
81 ATF_REQUIRE(found != NULL);
82 ATF_CHECK(found >= &e[0] && found <= &e[2]);
83 ATF_CHECK_EQ(*found, 7);
84 }
85
ATF_TP_ADD_TCS(tp)86 ATF_TP_ADD_TCS(tp)
87 {
88 ATF_TP_ADD_TC(tp, bsearch_test);
89 ATF_TP_ADD_TC(tp, bsearch_duplicates);
90
91 return (atf_no_error());
92 }
93