From 43ce32ab6917c90c21a89f93a5bf1faa5724ab4d Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Sat, 4 Mar 2017 18:46:33 +0100 Subject: [PATCH] Add test for bitset logic Add bitset_set_str Add bitset_xor Fix bugs --- m-bitset.h | 43 +++++++++++++++++++++++++++++++++++ tests/test-mbitset.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/m-bitset.h b/m-bitset.h index 8d0f61a7..2044f628 100644 --- a/m-bitset.h +++ b/m-bitset.h @@ -434,6 +434,25 @@ bitset_in_str(bitset_t set, FILE *file) return c == ']'; } +static inline bool +bitset_set_str(bitset_t set, const char str[]) +{ + BITSETI_CONTRACT (set); + assert(str != NULL); + bitset_clean(set); + char c = *str++; + if (c != '[') return false; + c = *str++; + do { + if (c != '0' && c != '1') return false; + bool b = (c == '1'); + bitset_push_back (set, b); + c = *str++; + } while (c != ']' && c != 0); + BITSETI_CONTRACT (set); + return c == ']'; +} + static inline void bitset_get_str(string_t str, const bitset_t set, bool append) { @@ -462,6 +481,8 @@ bitset_and(bitset_t dest, const bitset_t src) size_t mask = (1UL << m) - 1; dest->ptr[n] = (dest->ptr[n] & src->ptr[n]) & mask; } + dest->size = s; + BITSETI_CONTRACT(dest); } static inline void @@ -477,7 +498,27 @@ bitset_or(bitset_t dest, const bitset_t src) if (m) { size_t mask = (1UL << m) - 1; dest->ptr[n] = (dest->ptr[n] | src->ptr[n]) & mask; + } + dest->size = s; + BITSETI_CONTRACT(dest); } + +static inline void +bitset_xor(bitset_t dest, const bitset_t src) +{ + BITSETI_CONTRACT(dest); + BITSETI_CONTRACT(src); + size_t s = M_MIN(dest->size, src->size); + size_t n = s / CHAR_BIT; + size_t m = s % CHAR_BIT; + for(size_t i = 0 ; i < n; i++) + dest->ptr[i] ^= src->ptr[i]; + if (m) { + size_t mask = (1UL << m) - 1; + dest->ptr[n] = (dest->ptr[n] ^ src->ptr[n]) & mask; + } + dest->size = s; + BITSETI_CONTRACT(dest); } static inline void @@ -493,6 +534,8 @@ bitset_not(bitset_t dest) size_t mask = (1UL << m) - 1; dest->ptr[n] = (~ dest->ptr[n]) & mask; } + dest->size = s; + BITSETI_CONTRACT(dest); } #define BITSET_OPLIST \ diff --git a/tests/test-mbitset.c b/tests/test-mbitset.c index 5540a0be..5f0a6e35 100644 --- a/tests/test-mbitset.c +++ b/tests/test-mbitset.c @@ -149,9 +149,63 @@ static void test_str(void) bitset_clear(set2); } +static void test_logic(void) +{ + M_LET(s1, s2, BITSET_OPLIST) { + bitset_set_str(s1, "[1010]"); + bitset_set_str(s2, "[1100]"); + bitset_and (s1, s2); + bitset_set_str(s2, "[1000]"); + assert(bitset_equal_p(s1, s2)); + + bitset_set_str(s1, "[1010]"); + bitset_set_str(s2, "[1100]"); + bitset_or (s1, s2); + bitset_set_str(s2, "[1110]"); + assert(bitset_equal_p(s1, s2)); + + bitset_set_str(s1, "[1010]"); + bitset_set_str(s2, "[1100]"); + bitset_xor (s1, s2); + bitset_set_str(s2, "[0110]"); + assert(bitset_equal_p(s1, s2)); + + bitset_set_str(s1, "[1010]"); + bitset_not (s1); + bitset_set_str(s2, "[0101]"); + assert(bitset_equal_p(s1, s2)); + + // Bigger set + bitset_set_str(s1, "[10101010101010101010]"); + bitset_set_str(s2, "[110000000000000000000]"); + bitset_and (s1, s2); + bitset_set_str(s2, "[10000000000000000000]"); + assert(bitset_equal_p(s1, s2)); + + bitset_set_str(s1, "[1010000000000000000001]"); + bitset_set_str(s2, "[110000000000000000000]"); + bitset_or (s1, s2); + bitset_set_str(s2, "[111000000000000000000]"); + assert(bitset_equal_p(s1, s2)); + + bitset_set_str(s1, "[1010000000000000000001111111111110]"); + bitset_set_str(s2, "[1100000000000000000111111111111111]"); + bitset_xor (s1, s2); + bitset_set_str(s2, "[0110000000000000000110000000000001]"); + assert(bitset_equal_p(s1, s2)); + + bitset_set_str(s1, "[1010000000000000000000000000000000000]"); + bitset_not (s1); + bitset_set_str(s2, "[0101111111111111111111111111111111111]"); + assert(bitset_equal_p(s1, s2)); + + } +} + int main(void) { test1(); test_str(); + test_logic(); exit(0); }