xref: /freebsd/lib/libc/tests/string/ffs_test.c (revision 559a218c9b257775fb249b67945fe4a05b7a6b9f)
1*49390697SRobert Clausecker /*-
2*49390697SRobert Clausecker  * Copyright (c) 2023 The FreeBSD Foundation
3*49390697SRobert Clausecker  *
4*49390697SRobert Clausecker  * This software was developed by Robert Clausecker <fuz@FreeBSD.org>
5*49390697SRobert Clausecker  * under sponsorship from the FreeBSD Foundation.
6*49390697SRobert Clausecker  *
7*49390697SRobert Clausecker  * Redistribution and use in source and binary forms, with or without
8*49390697SRobert Clausecker  * modification, are permitted provided that the following conditions
9*49390697SRobert Clausecker  * are met:
10*49390697SRobert Clausecker  * 1. Redistributions of source code must retain the above copyright
11*49390697SRobert Clausecker  *    notice, this list of conditions and the following disclaimer.
12*49390697SRobert Clausecker  * 2. Redistributions in binary form must reproduce the above copyright
13*49390697SRobert Clausecker  *    notice, this list of conditions and the following disclaimer in the
14*49390697SRobert Clausecker  *    documentation and/or other materials provided with the distribution.
15*49390697SRobert Clausecker  *
16*49390697SRobert Clausecker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ''AS IS'' AND
17*49390697SRobert Clausecker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*49390697SRobert Clausecker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*49390697SRobert Clausecker  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*49390697SRobert Clausecker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*49390697SRobert Clausecker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*49390697SRobert Clausecker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*49390697SRobert Clausecker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*49390697SRobert Clausecker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*49390697SRobert Clausecker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*49390697SRobert Clausecker  * SUCH DAMAGE
27*49390697SRobert Clausecker  */
28*49390697SRobert Clausecker 
29*49390697SRobert Clausecker #include <atf-c.h>
30*49390697SRobert Clausecker #include <limits.h>
31*49390697SRobert Clausecker #include <stdint.h>
32*49390697SRobert Clausecker #include <strings.h>
33*49390697SRobert Clausecker 
34*49390697SRobert Clausecker #ifndef FFS
35*49390697SRobert Clausecker # define FFS ffs
36*49390697SRobert Clausecker # define TYPE int
37*49390697SRobert Clausecker # define TYPE_MIN INT_MIN
38*49390697SRobert Clausecker #endif
39*49390697SRobert Clausecker 
40*49390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(zero);
ATF_TC_BODY(zero,tc)41*49390697SRobert Clausecker ATF_TC_BODY(zero, tc)
42*49390697SRobert Clausecker {
43*49390697SRobert Clausecker 	ATF_CHECK_EQ((TYPE)0, FFS(0));
44*49390697SRobert Clausecker }
45*49390697SRobert Clausecker 
46*49390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(twobit);
ATF_TC_BODY(twobit,tc)47*49390697SRobert Clausecker ATF_TC_BODY(twobit, tc)
48*49390697SRobert Clausecker {
49*49390697SRobert Clausecker 	const TYPE one = 1;
50*49390697SRobert Clausecker 	TYPE x;
51*49390697SRobert Clausecker 	const int n = sizeof(TYPE) * CHAR_BIT;
52*49390697SRobert Clausecker 	int i, j;
53*49390697SRobert Clausecker 
54*49390697SRobert Clausecker 	for (i = 0; i < n - 1; i++)
55*49390697SRobert Clausecker 		for (j = 0; j <= i; j++) {
56*49390697SRobert Clausecker 			x = one << i | one << j;
57*49390697SRobert Clausecker 			ATF_CHECK_EQ_MSG(j + 1, FFS(x),
58*49390697SRobert Clausecker 			    "%s(%#jx) == %d != %d", __STRING(FFS), (intmax_t)x, FFS(x), j + 1);
59*49390697SRobert Clausecker 		}
60*49390697SRobert Clausecker }
61*49390697SRobert Clausecker 
62*49390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(twobitneg);
ATF_TC_BODY(twobitneg,tc)63*49390697SRobert Clausecker ATF_TC_BODY(twobitneg, tc)
64*49390697SRobert Clausecker {
65*49390697SRobert Clausecker 	const TYPE one = 1;
66*49390697SRobert Clausecker 	TYPE x;
67*49390697SRobert Clausecker 	const int n = sizeof(TYPE) * CHAR_BIT;
68*49390697SRobert Clausecker 	int i, j;
69*49390697SRobert Clausecker 
70*49390697SRobert Clausecker 	for (i = 0; i < n - 1; i++)
71*49390697SRobert Clausecker 		for (j = 0; j <= i; j++) {
72*49390697SRobert Clausecker 			x = one << i | one << j | TYPE_MIN;
73*49390697SRobert Clausecker 			ATF_CHECK_EQ_MSG(j + 1, FFS(x),
74*49390697SRobert Clausecker 			    "%s(%#jx) == %d != %d", __STRING(FFS), (intmax_t)x, FFS(x), j + 1);
75*49390697SRobert Clausecker 		}
76*49390697SRobert Clausecker }
77*49390697SRobert Clausecker 
78*49390697SRobert Clausecker 
ATF_TP_ADD_TCS(tp)79*49390697SRobert Clausecker ATF_TP_ADD_TCS(tp)
80*49390697SRobert Clausecker {
81*49390697SRobert Clausecker 
82*49390697SRobert Clausecker 	ATF_TP_ADD_TC(tp, zero);
83*49390697SRobert Clausecker 	ATF_TP_ADD_TC(tp, twobit);
84*49390697SRobert Clausecker 	ATF_TP_ADD_TC(tp, twobitneg);
85*49390697SRobert Clausecker 
86*49390697SRobert Clausecker 	return (atf_no_error());
87*49390697SRobert Clausecker }
88