xref: /src/lib/libc/tests/string/ffs_test.c (revision 559a218c9b257775fb249b67945fe4a05b7a6b9f)
149390697SRobert Clausecker /*-
249390697SRobert Clausecker  * Copyright (c) 2023 The FreeBSD Foundation
349390697SRobert Clausecker  *
449390697SRobert Clausecker  * This software was developed by Robert Clausecker <fuz@FreeBSD.org>
549390697SRobert Clausecker  * under sponsorship from the FreeBSD Foundation.
649390697SRobert Clausecker  *
749390697SRobert Clausecker  * Redistribution and use in source and binary forms, with or without
849390697SRobert Clausecker  * modification, are permitted provided that the following conditions
949390697SRobert Clausecker  * are met:
1049390697SRobert Clausecker  * 1. Redistributions of source code must retain the above copyright
1149390697SRobert Clausecker  *    notice, this list of conditions and the following disclaimer.
1249390697SRobert Clausecker  * 2. Redistributions in binary form must reproduce the above copyright
1349390697SRobert Clausecker  *    notice, this list of conditions and the following disclaimer in the
1449390697SRobert Clausecker  *    documentation and/or other materials provided with the distribution.
1549390697SRobert Clausecker  *
1649390697SRobert Clausecker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ''AS IS'' AND
1749390697SRobert Clausecker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1849390697SRobert Clausecker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1949390697SRobert Clausecker  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2049390697SRobert Clausecker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2149390697SRobert Clausecker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2249390697SRobert Clausecker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2349390697SRobert Clausecker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2449390697SRobert Clausecker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2549390697SRobert Clausecker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2649390697SRobert Clausecker  * SUCH DAMAGE
2749390697SRobert Clausecker  */
2849390697SRobert Clausecker 
2949390697SRobert Clausecker #include <atf-c.h>
3049390697SRobert Clausecker #include <limits.h>
3149390697SRobert Clausecker #include <stdint.h>
3249390697SRobert Clausecker #include <strings.h>
3349390697SRobert Clausecker 
3449390697SRobert Clausecker #ifndef FFS
3549390697SRobert Clausecker # define FFS ffs
3649390697SRobert Clausecker # define TYPE int
3749390697SRobert Clausecker # define TYPE_MIN INT_MIN
3849390697SRobert Clausecker #endif
3949390697SRobert Clausecker 
4049390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(zero);
ATF_TC_BODY(zero,tc)4149390697SRobert Clausecker ATF_TC_BODY(zero, tc)
4249390697SRobert Clausecker {
4349390697SRobert Clausecker 	ATF_CHECK_EQ((TYPE)0, FFS(0));
4449390697SRobert Clausecker }
4549390697SRobert Clausecker 
4649390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(twobit);
ATF_TC_BODY(twobit,tc)4749390697SRobert Clausecker ATF_TC_BODY(twobit, tc)
4849390697SRobert Clausecker {
4949390697SRobert Clausecker 	const TYPE one = 1;
5049390697SRobert Clausecker 	TYPE x;
5149390697SRobert Clausecker 	const int n = sizeof(TYPE) * CHAR_BIT;
5249390697SRobert Clausecker 	int i, j;
5349390697SRobert Clausecker 
5449390697SRobert Clausecker 	for (i = 0; i < n - 1; i++)
5549390697SRobert Clausecker 		for (j = 0; j <= i; j++) {
5649390697SRobert Clausecker 			x = one << i | one << j;
5749390697SRobert Clausecker 			ATF_CHECK_EQ_MSG(j + 1, FFS(x),
5849390697SRobert Clausecker 			    "%s(%#jx) == %d != %d", __STRING(FFS), (intmax_t)x, FFS(x), j + 1);
5949390697SRobert Clausecker 		}
6049390697SRobert Clausecker }
6149390697SRobert Clausecker 
6249390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(twobitneg);
ATF_TC_BODY(twobitneg,tc)6349390697SRobert Clausecker ATF_TC_BODY(twobitneg, tc)
6449390697SRobert Clausecker {
6549390697SRobert Clausecker 	const TYPE one = 1;
6649390697SRobert Clausecker 	TYPE x;
6749390697SRobert Clausecker 	const int n = sizeof(TYPE) * CHAR_BIT;
6849390697SRobert Clausecker 	int i, j;
6949390697SRobert Clausecker 
7049390697SRobert Clausecker 	for (i = 0; i < n - 1; i++)
7149390697SRobert Clausecker 		for (j = 0; j <= i; j++) {
7249390697SRobert Clausecker 			x = one << i | one << j | TYPE_MIN;
7349390697SRobert Clausecker 			ATF_CHECK_EQ_MSG(j + 1, FFS(x),
7449390697SRobert Clausecker 			    "%s(%#jx) == %d != %d", __STRING(FFS), (intmax_t)x, FFS(x), j + 1);
7549390697SRobert Clausecker 		}
7649390697SRobert Clausecker }
7749390697SRobert Clausecker 
7849390697SRobert Clausecker 
ATF_TP_ADD_TCS(tp)7949390697SRobert Clausecker ATF_TP_ADD_TCS(tp)
8049390697SRobert Clausecker {
8149390697SRobert Clausecker 
8249390697SRobert Clausecker 	ATF_TP_ADD_TC(tp, zero);
8349390697SRobert Clausecker 	ATF_TP_ADD_TC(tp, twobit);
8449390697SRobert Clausecker 	ATF_TP_ADD_TC(tp, twobitneg);
8549390697SRobert Clausecker 
8649390697SRobert Clausecker 	return (atf_no_error());
8749390697SRobert Clausecker }
88