/* * BIRD Library -- Generic Bit Operations Tests * * (c) 2015 CZ.NIC z.s.p.o. * * Can be freely distributed and used under the terms of the GNU GPL. */ #include "test/birdtest.h" #include "bitops.h" #define MAX_NUM 1000 #define CHECK_BIT(var,pos) ((var) & (u32)(1<<(pos))) static int t_mkmask(void) { int i; u32 compute, expect; bt_assert(u32_mkmask(0) == 0x00000000); for (i = 1; i <= 32; i++) { compute = u32_mkmask(i); expect = (u32) (0xffffffff << (32-i)); bt_assert_msg(compute == expect, "u32_mkmask(%d) = 0x%08X, expected 0x%08X \n", i, compute, expect); } return BT_SUCCESS; } static int u32_masklen_expected(u32 mask) { int j, expect = 0; int valid = 0; for (j = 0; j <= 32; j++) if (mask == (0xffffffff << (32-j))) valid = 1; if (!valid && mask != 0) expect = -1; else for (j = 0; j <= 31; j++) if (CHECK_BIT(mask, (31-j))) expect = j+1; else break; return expect; } void static check_mask(u32 mask) { int compute, expect; compute = u32_masklen_expected(mask); expect = u32_masklen(mask); int ok = compute == expect; bt_debug("u32_masklen(Ox%08x) = %d, expected %d %s\n", mask, u32_masklen(mask), u32_masklen_expected(mask), ok ? "OK" : "FAIL!"); bt_assert(compute == expect); } static int t_masklen(void) { u32 i; check_mask(0x82828282); check_mask(0x00000000); for (i = 0; i <= 32; i++) check_mask(((u32) (0xffffffff << (32-i))) & 0xffffffff); for (i = 0; i <= MAX_NUM; i++) check_mask(bt_rand_num()); return BT_SUCCESS; } static u32 pow2(u32 exp) { u32 i, n, r; n = r = 2; if (exp == 0) return 1; for (i = 2; i <= exp; i++) r *= n; return r; } static void check_log2(u32 n) { u32 log = u32_log2(n); u32 low = pow2(log); u32 high = pow2(log+1); bt_debug("Test u32_log2(%u) = %u, %u should be in the range <%u, %u) \n", n, log, n, low, high); bt_assert(n >= low && n < high); } static int t_log2(void) { u32 i; struct in_out_data_ { u32 in; u32 out; } in_out_data[31]; for (i = 0; i < 31; i++) { in_out_data[i].in = pow2(i+1); in_out_data[i].out = i+1; } bt_assert_out_fn_in(u32_log2, in_out_data, "%u", "%u"); u32_log2(0); for (i = 1; i < MAX_NUM; i++) check_log2(i); for (i = 1; i < MAX_NUM; i++) check_log2(bt_rand_num()); return BT_SUCCESS; } int main(int argc, char *argv[]) { bt_init(argc, argv); bt_test_suite(t_mkmask, "u32_mkmask()"); bt_test_suite(t_masklen, "u32_masklen()"); bt_test_suite(t_log2, "u32_log2()"); return bt_end(); }