bits: add ffs compat, minor test fixes
authorMarko Kreen <markokr@gmail.com>
Tue, 28 Sep 2010 18:50:43 +0000 (11:50 -0700)
committerMarko Kreen <markokr@gmail.com>
Tue, 28 Sep 2010 18:50:43 +0000 (11:50 -0700)
m4/usual.m4
test/force_compat.sed
test/test_bits.c
test/test_common.h
usual/bits.h

index 0519882f7edfd2352cf0872782e4b498183ff231..f381d723a855d9197e4c7697024261c7648ec9dd 100644 (file)
@@ -142,6 +142,7 @@ AC_CHECK_FUNCS(basename dirname strlcpy strlcat getpeereid sigaction)
 AC_CHECK_FUNCS(inet_ntop poll getline memrchr regcomp)
 AC_CHECK_FUNCS(err errx warn warnx getprogname setprogname)
 AC_CHECK_FUNCS(posix_memalign memalign valloc)
+AC_CHECK_FUNCS(fls flsl flsll ffs ffsl ffsll)
 ### Functions provided only on win32
 AC_CHECK_FUNCS(localtime_r recvmsg sendmsg usleep)
 ### Functions used by libusual itself
index 8549029ec78034feb965fa63d50e319bc0b165d3..61bac0fc0eaacf47bbbc12cf961787b8ddf19285 100644 (file)
@@ -1,3 +1,5 @@
+/FFS/s,^,//,
+/FLS/s,^,//,
 /STRLCPY/s,^,//,
 /STRLCAT/s,^,//,
 /BASENAME/s,^,//,
index 2a5f2ccbf59eb85e0531113c2892e2b2c196decf..1fb5ba2fea377b83c0a4586398aa71ca0e319441 100644 (file)
@@ -48,7 +48,7 @@ static void test_ror(void *p)
        /* ror32 */
        int_check(ror32(1, 1), 0x80000000);
        /* ror64 */
-       int_check(ror64(1, 1), 0x8000000000000000);
+       ull_check(ror64(1, 1), 0x8000000000000000ULL);
 end:;
 }
 
@@ -109,6 +109,8 @@ static void test_ffs(void *p)
        int_check(ffsll(1), 1);
        int_check(ffsll(3), 1);
        int_check(ffsll((long long)-1), 1);
+       ull_check((1ULL << 63), ror64(1,1));
+       int_check(ffsll(1ULL << 63), 64);
        int_check(ffsll(ror64(1,1)), 64);
 end:;
 }
index b034319d18cecc925653290ad07c534bd8a96469..6ba09f1734b8281141ca96095dac8f15b61fd030 100644 (file)
@@ -6,7 +6,7 @@
 
 #define str_check(a, b) tt_str_op(a, ==, b)
 #define int_check(a, b) tt_int_op(a, ==, b)
-#define ull_check(a, b) tt_assert_op_type(a, ==, b, unsigned long long, "%llu")
+#define ull_check(a, b) tt_assert_op_type(a, ==, b, uint64_t, "%" PRIu64)
 
 extern struct testcase_t aatree_tests[];
 extern struct testcase_t cbtree_tests[];
index 31a7033a69bac68353fda3b7a1a70efa5b598253..f05f2e3dbe098321001af3624f2dba37da292322 100644 (file)
@@ -87,18 +87,61 @@ static inline uint64_t ror64(uint64_t v, int s) { return rol64(v, 64 - s); }
 #endif
 
 #ifndef HAVE_FLS
+#define fls(x) usual_fls(x)
 /** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
 static inline int fls(int x) { _FLS(, int); }
 #endif
 #ifndef HAVE_FLSL
+#define flsl(x) usual_flsl(x)
 /** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
 static inline int flsl(long x) { _FLS(l, long); }
 #endif
 #ifndef HAVE_FLSLL
+#define flsll(x) usual_flsll(x)
 /** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
 static inline int flsll(long long x) { _FLS(ll, long long); }
 #endif
 #undef _FLS
 
+/*
+ * ffs(int)
+ * ffsl(long)
+ * ffsll(long long)
+ *
+ *   find LSB bit set, 1-based ofs, 0 if arg == 0
+ */
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#define _FFS(sfx, type) \
+       return __builtin_ffs ## sfx((unsigned type)(x))
+#else
+#define _FFS(sfx, type) \
+       unsigned int bit; \
+       unsigned type u = x; \
+       if (!x) return 0; \
+       /* count from smallest bit, assuming small values */ \
+       for (bit = 1; !(u & 1); bit++) { \
+               u >>= 1; \
+       } \
+       return bit
+#endif
+
+#ifndef HAVE_FFS
+#define ffs(x) usual_ffs(x)
+/** Compat: Find first (LSB) set bit, 1-based ofs, 0 if arg == 0 */
+static inline int ffs(int x) { _FFS(, int); }
+#endif
+#ifndef HAVE_FFSL
+#define ffsl(x) usual_ffsl(x)
+/** Compat: Find first (LSB) set bit, 1-based ofs, 0 if arg == 0 */
+static inline int ffsl(long x) { _FFS(l, long); }
+#endif
+#ifndef HAVE_FFSLL
+#define ffsll(x) usual_ffsll(x)
+/** Compat: Find first (LSB) set bit, 1-based ofs, 0 if arg == 0 */
+static inline int ffsll(long long x) { _FFS(ll, long long); }
+#endif
+#undef _FFS
+
 #endif