* <tr><td> <usual/statlist.h> </td><td> List with stats </td></tr>
* <tr><td> <usual/strpool.h> </td><td> Refcounted strings </td></tr>
* <tr><th colspan=2> Data Processing </th></tr>
+ * <tr><td> <usual/bits.h> </td><td> Bit arithmetic </td></tr>
* <tr><td> <usual/cfparser.h> </td><td> Config parser </td></tr>
* <tr><td> <usual/crc32.h> </td><td> CRC32 </td></tr>
* <tr><td> <usual/endian.h> </td><td> Endianess conversion </td></tr>
OBJS = test_string.o test_crypto.o test_aatree.o test_heap.o \
test_common.o test_list.o tinytest.o test_cbtree.o \
test_utf8.o test_strpool.o test_pgutil.o test_regex.o \
- test_cxalloc.o
+ test_cxalloc.o test_bits.o
test-all: regtest
--- /dev/null
+
+#include <usual/bits.h>
+
+#include "test_common.h"
+
+/*
+ * is_power_of_2
+ */
+
+static void test_pow2(void *p)
+{
+ int_check(is_power_of_2(0), 0);
+ int_check(is_power_of_2(1), 1);
+ int_check(is_power_of_2(2), 1);
+ int_check(is_power_of_2(3), 0);
+end:;
+}
+
+/*
+ * rol
+ */
+
+static void test_rol(void *p)
+{
+ /* rol16 */
+ int_check(rol16(1, 1), 2);
+ int_check(rol16(1, 15), 32768);
+ int_check(rol16(0x8000, 1), 1);
+
+ /* rol32 */
+ int_check(rol32(1, 1), 2);
+ int_check(rol32(0x80000000, 1), 1);
+
+ /* rol64 */
+ ull_check(rol64(1, 1), 2);
+ ull_check(rol64(1, 63), 0x8000000000000000);
+end:;
+}
+
+/*
+ * ror
+ */
+
+static void test_ror(void *p)
+{
+ /* ror16 */
+ int_check(ror16(1, 1), 0x8000);
+ /* ror32 */
+ int_check(ror32(1, 1), 0x80000000);
+ /* ror64 */
+ int_check(ror64(1, 1), 0x8000000000000000);
+end:;
+}
+
+/*
+ * fls
+ */
+
+static void test_fls(void *p)
+{
+ /* fls */
+ int_check(fls(0), 0);
+ int_check(fls(1), 1);
+ int_check(fls(3), 2);
+ int_check(fls((int)-1), 32);
+
+ /* flsl */
+ int_check(flsl(0), 0);
+ int_check(flsl(1), 1);
+ int_check(flsl(3), 2);
+ if (sizeof(long) == 4)
+ int_check(flsl((long)-1), 32);
+ else
+ int_check(flsl((long)-1), 64);
+
+ /* flsll */
+ int_check(flsll(0), 0);
+ int_check(flsll(1), 1);
+ int_check(flsll(3), 2);
+ int_check(flsll((long long)-1), 64);
+end:;
+}
+
+/*
+ * ffs
+ */
+
+static void test_ffs(void *p)
+{
+ /* ffs */
+ int_check(ffs(0), 0);
+ int_check(ffs(1), 1);
+ int_check(ffs(3), 1);
+ int_check(ffs((int)-1), 1);
+ int_check(ffs(ror32(1,1)), 32);
+
+ /* flsl */
+ int_check(ffsl(0), 0);
+ int_check(ffsl(1), 1);
+ int_check(ffsl(3), 1);
+ int_check(ffsl((long)-1), 1);
+ if (sizeof(long) == 4)
+ int_check(ffsl(ror32(1,1)), 32);
+ else
+ int_check(ffsl(ror64(1,1)), 64);
+
+ /* ffsll */
+ int_check(ffsll(0), 0);
+ int_check(ffsll(1), 1);
+ int_check(ffsll(3), 1);
+ int_check(ffsll((long long)-1), 1);
+ int_check(ffsll(ror64(1,1)), 64);
+end:;
+}
+
+
+/*
+ * Describe
+ */
+
+struct testcase_t bits_tests[] = {
+ { "is_power_of_2", test_pow2 },
+ { "rol", test_rol },
+ { "ror", test_ror },
+ { "ffs", test_ffs },
+ { "fls", test_fls },
+ END_OF_TESTCASES
+};
+
struct testgroup_t groups[] = {
{ "aatree/", aatree_tests },
+ { "bits/", bits_tests },
{ "cxalloc/", cxalloc_tests },
{ "cbtree/", cbtree_tests },
{ "crypto/", crypto_tests },
#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")
extern struct testcase_t aatree_tests[];
extern struct testcase_t cbtree_tests[];
extern struct testcase_t pgutil_tests[];
extern struct testcase_t regex_tests[];
extern struct testcase_t cxalloc_tests[];
+extern struct testcase_t bits_tests[];
end:;
}
-/*
- * fls
- */
-
-static void test_fls(void *p)
-{
- int_check(fls(0), 0);
- int_check(fls(1), 1);
- int_check(fls(3), 2);
- int_check(fls((int)-1), 32);
-end:;
-}
-
-static void test_flsl(void *p)
-{
- int_check(flsl(0), 0);
- int_check(flsl(1), 1);
- int_check(flsl(3), 2);
- if (sizeof(long) == 4)
- int_check(flsl((long)-1), 32);
- else
- int_check(flsl((long)-1), 64);
-end:;
-}
-
-static void test_flsll(void *p)
-{
- int_check(flsll(0), 0);
- int_check(flsll(1), 1);
- int_check(flsll(3), 2);
- int_check(flsll((long long)-1), 64);
-end:;
-}
-
/*
* memrchr
*/
{ "strlcpy", test_strlcpy },
{ "strlcat", test_strlcat },
{ "strerror_r", test_strerror_r },
- { "fls", test_fls },
- { "flsl", test_flsl },
- { "flsll", test_flsll },
{ "memrchr", test_memrchr },
{ "basename", test_basename },
{ "dirname", test_dirname },
--- /dev/null
+/*
+ * Copyright (c) 2009 Marko Kreen
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/** @file
+ * Bit arithmetics.
+ *
+ * - is_power_of_2
+ * - ffs, ffsl, ffsll
+ * - fls, flsl, flsll
+ * - rol16, rol32, rol64
+ * - ror16, ror32, ror64
+ */
+#ifndef _USUAL_MISC_H_
+#define _USUAL_MISC_H_
+
+#include <usual/base.h>
+
+#include <string.h>
+
+/** Checks if integer has only one bit set */
+static inline int is_power_of_2(int n)
+{
+ return (n > 0) && !(n & (n - 1));
+}
+
+/*
+ * Single-eval and type-safe rol/ror
+ */
+
+/** Rotate 16-bit int to left */
+static inline uint16_t rol16(uint16_t v, int s)
+{
+ return (v << s) | (v >> (16 - s));
+}
+/** Rotate 32-bit int to left */
+static inline uint32_t rol32(uint32_t v, int s)
+{
+ return (v << s) | (v >> (32 - s));
+}
+/** Rotate 64-bit int to left */
+static inline uint64_t rol64(uint64_t v, int s)
+{
+ return (v << s) | (v >> (64 - s));
+}
+
+/** Rotate 16-bit int to right */
+static inline uint16_t ror16(uint16_t v, int s) { return rol16(v, 16 - s); }
+
+/** Rotate 32-bit int to right */
+static inline uint32_t ror32(uint32_t v, int s) { return rol32(v, 32 - s); }
+
+/** Rotate 64-bit int to right */
+static inline uint64_t ror64(uint64_t v, int s) { return rol64(v, 64 - s); }
+
+/*
+ * fls(int)
+ * flsl(long)
+ * flsll(long long)
+ *
+ * find MSB bit set, 1-based ofs, 0 if arg == 0
+ */
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#define _FLS(sfx, type) \
+ return (x == 0) ? 0 : ((8*sizeof(type)) - __builtin_clz ## sfx(x))
+#else
+#define _FLS(sfx, type) \
+ unsigned int bit; \
+ if (x == 0) return 0; \
+ /* count from smallest bit, assuming small values */ \
+ for (bit = 1; x > 1; bit++) x >>= 1; \
+ return bit
+#endif
+
+#ifndef HAVE_FLS
+/** 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
+/** 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
+/** 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
+
+#endif
+
#include <usual/cbtree.h>
-#include <usual/string.h>
+#include <usual/bits.h>
/*
* - Childs are either other nodes or user pointers.
#include <usual/md5.h>
#include <usual/endian.h>
-#include <usual/misc.h>
-#include <string.h>
+#include <usual/bits.h>
/*
* Support functions.
| ((unsigned int)(unsigned char)(d) << 24))
#endif
-/** Checks if integer has only one bit set */
-static inline int is_power_of_2(int n)
-{
- return (n > 0) && !(n & (n - 1));
-}
-
#if defined(__i386__) || defined(__x86_64__)
#define mb() asm volatile("mfence":::"memory")
#define rmb() asm volatile("lfence":::"memory")
#define wmb() asm volatile("sfence":::"memory")
#endif
-/*
- * Single-eval and type-safe rol/ror
- */
-
-/** Rotate 16-bit int to left */
-static inline uint16_t rol16(uint16_t v, int s)
-{
- return (v << s) | (v >> (16 - s));
-}
-/** Rotate 32-bit int to left */
-static inline uint32_t rol32(uint32_t v, int s)
-{
- return (v << s) | (v >> (32 - s));
-}
-/** Rotate 64-bit int to left */
-static inline uint64_t rol64(uint64_t v, int s)
-{
- return (v << s) | (v >> (64 - s));
-}
-/** Rotate 16-bit int to right */
-static inline uint16_t ror16(uint16_t v, int s) { return rol16(v, 16 - s); }
-/** Rotate 32-bit int to right */
-static inline uint32_t ror32(uint32_t v, int s) { return rol32(v, 32 - s); }
-/** Rotate 64-bit int to right */
-static inline uint64_t ror64(uint64_t v, int s) { return rol64(v, 64 - s); }
-
#endif
#include <usual/sha1.h>
#include <usual/endian.h>
-#include <usual/misc.h>
+#include <usual/bits.h>
#define bufpos(ctx) ((ctx)->nbytes & (SHA1_BLOCK_SIZE - 1))
size_t strlcat(char *dst, const char *src, size_t n);
#endif
-/*
- * fls(int)
- * flsl(long)
- * flsll(long long)
- *
- * find MSB bit set, 1-based ofs, 0 if arg == 0
- */
-
-#if defined(__GNUC__) && (__GNUC__ >= 4)
-#define _FLS(sfx, type) \
- return (x == 0) ? 0 : ((8*sizeof(type)) - __builtin_clz ## sfx(x))
-#else
-#define _FLS(sfx, type) \
- unsigned int bit; \
- if (x == 0) return 0; \
- /* count from smallest bit, assuming small values */ \
- for (bit = 1; x > 1; bit++) x >>= 1; \
- return bit
-#endif
-
-#ifndef HAVE_FLS
-/** 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
-/** 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
-/** 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
-
-
#ifndef HAVE_MEMRCHR
#define memrchr(a,b,c) usual_memrchr(a,b,c)
/** Compat: find byte in reverse direction */