xref: /freebsd/lib/libc/tests/string/memrchr_test.c (revision 691ff1832e09a6ccbc8f5b04c88cafc7452b3ce6)
1*691ff183SRobert Clausecker /*-
2*691ff183SRobert Clausecker  * SPDX-License-Identifier: BSD-2-Clause
3*691ff183SRobert Clausecker  *
4*691ff183SRobert Clausecker  * Copyright (c) 2023 Robert Clausecker
5*691ff183SRobert Clausecker  */
6*691ff183SRobert Clausecker 
7*691ff183SRobert Clausecker #include <sys/cdefs.h>
8*691ff183SRobert Clausecker 
9*691ff183SRobert Clausecker #include <dlfcn.h>
10*691ff183SRobert Clausecker #include <limits.h>
11*691ff183SRobert Clausecker #include <string.h>
12*691ff183SRobert Clausecker 
13*691ff183SRobert Clausecker #include <atf-c.h>
14*691ff183SRobert Clausecker 
15*691ff183SRobert Clausecker static void *(*memrchr_fn)(const void *, int, size_t);
16*691ff183SRobert Clausecker 
17*691ff183SRobert Clausecker ATF_TC_WITHOUT_HEAD(null);
ATF_TC_BODY(null,tc)18*691ff183SRobert Clausecker ATF_TC_BODY(null, tc)
19*691ff183SRobert Clausecker {
20*691ff183SRobert Clausecker 	ATF_CHECK_EQ(memrchr_fn(NULL, 42, 0), NULL);
21*691ff183SRobert Clausecker }
22*691ff183SRobert Clausecker 
23*691ff183SRobert Clausecker ATF_TC_WITHOUT_HEAD(not_found);
ATF_TC_BODY(not_found,tc)24*691ff183SRobert Clausecker ATF_TC_BODY(not_found, tc)
25*691ff183SRobert Clausecker {
26*691ff183SRobert Clausecker 	size_t i, j;
27*691ff183SRobert Clausecker 	char buf[1+15+64+1]; /* offset [0..15] + 64 buffer bytes + sentinels */
28*691ff183SRobert Clausecker 
29*691ff183SRobert Clausecker 	buf[0] = 'X';
30*691ff183SRobert Clausecker 	memset(buf + 1, '-', sizeof(buf) - 1);
31*691ff183SRobert Clausecker 
32*691ff183SRobert Clausecker 	for (i = 0; i < 16; i++)
33*691ff183SRobert Clausecker 		for (j = 0; j < 64; j++) {
34*691ff183SRobert Clausecker 			buf[i + j + 1] = 'X';
35*691ff183SRobert Clausecker 			ATF_CHECK_EQ(memrchr_fn(buf + i + 1, 'X', j), NULL);
36*691ff183SRobert Clausecker 			buf[i + j + 1] = '-';
37*691ff183SRobert Clausecker 		}
38*691ff183SRobert Clausecker }
39*691ff183SRobert Clausecker 
40*691ff183SRobert Clausecker static void
do_found_test(char buf[],size_t len,size_t first,size_t second)41*691ff183SRobert Clausecker do_found_test(char buf[], size_t len, size_t first, size_t second)
42*691ff183SRobert Clausecker {
43*691ff183SRobert Clausecker 	/* invariant: first <= second */
44*691ff183SRobert Clausecker 
45*691ff183SRobert Clausecker 	buf[first] = 'X';
46*691ff183SRobert Clausecker 	buf[second] = 'X';
47*691ff183SRobert Clausecker 	ATF_CHECK_EQ(memrchr_fn(buf, 'X', len), buf + second);
48*691ff183SRobert Clausecker 	buf[first] = '-';
49*691ff183SRobert Clausecker 	buf[second] = '-';
50*691ff183SRobert Clausecker }
51*691ff183SRobert Clausecker 
52*691ff183SRobert Clausecker ATF_TC_WITHOUT_HEAD(found);
ATF_TC_BODY(found,tc)53*691ff183SRobert Clausecker ATF_TC_BODY(found, tc)
54*691ff183SRobert Clausecker {
55*691ff183SRobert Clausecker 	size_t i, j, k, l;
56*691ff183SRobert Clausecker 	char buf[1+15+64+1];
57*691ff183SRobert Clausecker 
58*691ff183SRobert Clausecker 	buf[0] = 'X';
59*691ff183SRobert Clausecker 	memset(buf + 1, '-', sizeof(buf) - 1);
60*691ff183SRobert Clausecker 
61*691ff183SRobert Clausecker 	for (i = 0; i < 16; i++)
62*691ff183SRobert Clausecker 		for (j = 0; j < 64; j++)
63*691ff183SRobert Clausecker 			for (k = 0; k < j; k++)
64*691ff183SRobert Clausecker 				for (l = 0; l <= k; l++) {
65*691ff183SRobert Clausecker 					buf[i + j + 1] = 'X';
66*691ff183SRobert Clausecker 					do_found_test(buf + i + 1, j, l, k);
67*691ff183SRobert Clausecker 					buf[i + j + 1] = '-';
68*691ff183SRobert Clausecker 				}
69*691ff183SRobert Clausecker }
70*691ff183SRobert Clausecker 
71*691ff183SRobert Clausecker /* check that the right character is found */
72*691ff183SRobert Clausecker static void
do_values_test(unsigned char buf[],size_t len,size_t i,int c)73*691ff183SRobert Clausecker do_values_test(unsigned char buf[], size_t len, size_t i, int c)
74*691ff183SRobert Clausecker {
75*691ff183SRobert Clausecker 	/* sentinels */
76*691ff183SRobert Clausecker 	buf[-1] = c;
77*691ff183SRobert Clausecker 	buf[len] = c;
78*691ff183SRobert Clausecker 	memset(buf, c + 1, len);
79*691ff183SRobert Clausecker 
80*691ff183SRobert Clausecker 	if (i < len) {
81*691ff183SRobert Clausecker 		buf[i] = c;
82*691ff183SRobert Clausecker 		ATF_CHECK_EQ(memrchr_fn(buf, c, len), buf + i);
83*691ff183SRobert Clausecker 	} else
84*691ff183SRobert Clausecker 		ATF_CHECK_EQ(memrchr_fn(buf, c, len), NULL);
85*691ff183SRobert Clausecker }
86*691ff183SRobert Clausecker 
87*691ff183SRobert Clausecker ATF_TC_WITHOUT_HEAD(values);
ATF_TC_BODY(values,tc)88*691ff183SRobert Clausecker ATF_TC_BODY(values, tc)
89*691ff183SRobert Clausecker {
90*691ff183SRobert Clausecker 	size_t i, j, k;
91*691ff183SRobert Clausecker 	int c;
92*691ff183SRobert Clausecker 	unsigned char buf[1+15+64+1];
93*691ff183SRobert Clausecker 
94*691ff183SRobert Clausecker 	for (i = 0; i < 16; i++)
95*691ff183SRobert Clausecker 		for (j = 0; j < 64; j++)
96*691ff183SRobert Clausecker 			for (k = 0; k <= j; k++)
97*691ff183SRobert Clausecker 				for (c = 0; c <= UCHAR_MAX; c++)
98*691ff183SRobert Clausecker 					do_values_test(buf + i + 1, j, k, c);
99*691ff183SRobert Clausecker }
100*691ff183SRobert Clausecker 
ATF_TP_ADD_TCS(tp)101*691ff183SRobert Clausecker ATF_TP_ADD_TCS(tp)
102*691ff183SRobert Clausecker {
103*691ff183SRobert Clausecker 	void *dl_handle;
104*691ff183SRobert Clausecker 
105*691ff183SRobert Clausecker 	dl_handle = dlopen(NULL, RTLD_LAZY);
106*691ff183SRobert Clausecker 	memrchr_fn = dlsym(dl_handle, "test_memrchr");
107*691ff183SRobert Clausecker 	if (memrchr_fn == NULL)
108*691ff183SRobert Clausecker 		memrchr_fn = memrchr;
109*691ff183SRobert Clausecker 
110*691ff183SRobert Clausecker 	ATF_TP_ADD_TC(tp, null);
111*691ff183SRobert Clausecker 	ATF_TP_ADD_TC(tp, not_found);
112*691ff183SRobert Clausecker 	ATF_TP_ADD_TC(tp, found);
113*691ff183SRobert Clausecker 	ATF_TP_ADD_TC(tp, values);
114*691ff183SRobert Clausecker 
115*691ff183SRobert Clausecker 	return (atf_no_error());
116*691ff183SRobert Clausecker }
117