lib: Introduce macros for bit operations
authorAustin Clements <aclements@csail.mit.edu>
Fri, 24 Oct 2014 12:49:15 +0000 (08:49 -0400)
committerDavid Bremner <david@tethera.net>
Sat, 25 Oct 2014 17:26:43 +0000 (19:26 +0200)
These macros help clarify basic bit-twiddling code and are written to
be robust against C undefined behavior of shift operators.

lib/message.cc
lib/notmuch-private.h

index 38bc92914163bc92441ee05f8aede64a65d3efca..55d2ff69fff4c479c2dfa4e430bb88bcfe441025 100644 (file)
@@ -869,7 +869,7 @@ notmuch_bool_t
 notmuch_message_get_flag (notmuch_message_t *message,
                          notmuch_message_flag_t flag)
 {
-    return message->flags & (1 << flag);
+    return NOTMUCH_TEST_BIT (message->flags, flag);
 }
 
 void
@@ -877,9 +877,9 @@ notmuch_message_set_flag (notmuch_message_t *message,
                          notmuch_message_flag_t flag, notmuch_bool_t enable)
 {
     if (enable)
-       message->flags |= (1 << flag);
+       NOTMUCH_SET_BIT (&message->flags, flag);
     else
-       message->flags &= ~(1 << flag);
+       NOTMUCH_CLEAR_BIT (&message->flags, flag);
 }
 
 time_t
index 36cc12b0df123c7a0eb79c0d81f8b40db9650d79..b86897c2031195a6bfa9d85ab4a5602204335315 100644 (file)
@@ -63,6 +63,17 @@ NOTMUCH_BEGIN_DECLS
 #define STRNCMP_LITERAL(var, literal) \
     strncmp ((var), (literal), sizeof (literal) - 1)
 
+/* Robust bit test/set/reset macros */
+#define NOTMUCH_TEST_BIT(val, bit) \
+    (((bit) < 0 || (bit) >= CHAR_BIT * sizeof (unsigned long long)) ? 0        \
+     : !!((val) & (1ull << (bit))))
+#define NOTMUCH_SET_BIT(valp, bit) \
+    (((bit) < 0 || (bit) >= CHAR_BIT * sizeof (unsigned long long)) ? *(valp) \
+     : (*(valp) |= (1ull << (bit))))
+#define NOTMUCH_CLEAR_BIT(valp,  bit) \
+    (((bit) < 0 || (bit) >= CHAR_BIT * sizeof (unsigned long long)) ? *(valp) \
+     : (*(valp) &= ~(1ull << (bit))))
+
 #define unused(x) x __attribute__ ((unused))
 
 #ifdef __cplusplus