macros: add NM_IN_STRSET()
authorThomas Haller <thaller@redhat.com>
Thu, 11 Feb 2016 15:53:06 +0000 (16:53 +0100)
committerThomas Haller <thaller@redhat.com>
Thu, 11 Feb 2016 16:54:38 +0000 (17:54 +0100)
Add macro similar to NM_IN_SET() that checks for C strings.
NULL values are allowed and handled as one would expect.

libnm-core/tests/test-general.c
shared/nm-macros-internal.h

index 48a8b7c..0ed2af7 100644 (file)
@@ -4899,6 +4899,132 @@ test_nm_in_set (void)
 
 /******************************************************************************/
 
+static const char *
+_test_nm_in_set_getstr (int *call_counter, gboolean allow_called, const char *value)
+{
+       g_assert (call_counter);
+       *call_counter += 1;
+       if (!allow_called)
+               g_assert_not_reached ();
+       return value;
+}
+
+static void
+test_nm_in_strset (void)
+{
+       int call_counter = 0;
+
+#define G(x) _test_nm_in_set_getstr (&call_counter, TRUE,  x)
+#define N(x) _test_nm_in_set_getstr (&call_counter, FALSE,  x)
+#define _ASSERT(expected, expr) \
+       G_STMT_START { \
+               _test_nm_in_set_assert (&call_counter, 0); \
+               g_assert (expr); \
+               _test_nm_in_set_assert (&call_counter, (expected)); \
+       } G_STMT_END
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL)));
+       _ASSERT (1, !NM_IN_STRSET ("a",  G(NULL)));
+       _ASSERT (1, !NM_IN_STRSET (NULL, G("a")));
+
+       _ASSERT (1,  NM_IN_STRSET_SE (NULL, G(NULL)));
+       _ASSERT (1, !NM_IN_STRSET_SE ("a",  G(NULL)));
+       _ASSERT (1, !NM_IN_STRSET_SE (NULL, G("a")));
+
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N(NULL)));
+       _ASSERT (2, !NM_IN_STRSET ("a",  G(NULL), G(NULL)));
+       _ASSERT (2,  NM_IN_STRSET (NULL, G("a"),  G(NULL)));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("a")));
+       _ASSERT (2,  NM_IN_STRSET ("a",  G(NULL), G("a")));
+       _ASSERT (2, !NM_IN_STRSET (NULL, G("a"),  G("a")));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("b")));
+       _ASSERT (2, !NM_IN_STRSET ("a",  G(NULL), G("b")));
+       _ASSERT (2, !NM_IN_STRSET (NULL, G("a"),  G("b")));
+
+       _ASSERT (2,  NM_IN_STRSET_SE (NULL, G(NULL), G(NULL)));
+       _ASSERT (2, !NM_IN_STRSET_SE ("a",  G(NULL), G(NULL)));
+       _ASSERT (2,  NM_IN_STRSET_SE (NULL, G("a"),  G(NULL)));
+       _ASSERT (2,  NM_IN_STRSET_SE (NULL, G(NULL), G("a")));
+       _ASSERT (2,  NM_IN_STRSET_SE ("a",  G(NULL), G("a")));
+       _ASSERT (2, !NM_IN_STRSET_SE (NULL, G("a"),  G("a")));
+       _ASSERT (2,  NM_IN_STRSET_SE (NULL, G(NULL), G("b")));
+       _ASSERT (2, !NM_IN_STRSET_SE ("a",  G(NULL), G("b")));
+       _ASSERT (2, !NM_IN_STRSET_SE (NULL, G("a"),  G("b")));
+
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N(NULL), N(NULL)));
+       _ASSERT (3, !NM_IN_STRSET ("a",  G(NULL), G(NULL), G(NULL)));
+       _ASSERT (2,  NM_IN_STRSET (NULL, G("a"),  G(NULL), N(NULL)));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("a"),  N(NULL)));
+       _ASSERT (2,  NM_IN_STRSET ("a",  G(NULL), G("a"),  N(NULL)));
+       _ASSERT (3,  NM_IN_STRSET (NULL, G("a"),  G("a"),  G(NULL)));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("b"),  N(NULL)));
+       _ASSERT (3, !NM_IN_STRSET ("a",  G(NULL), G("b"),  G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET (NULL, G("a"),  G("b"),  G(NULL)));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N(NULL), N("a")));
+       _ASSERT (3,  NM_IN_STRSET ("a",  G(NULL), G(NULL), G("a")));
+       _ASSERT (2,  NM_IN_STRSET (NULL, G("a"),  G(NULL), N("a")));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("a"),  N("a")));
+       _ASSERT (2,  NM_IN_STRSET ("a",  G(NULL), G("a"),  N("a")));
+       _ASSERT (3, !NM_IN_STRSET (NULL, G("a"),  G("a"),  G("a")));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("b"),  N("a")));
+       _ASSERT (3,  NM_IN_STRSET ("a",  G(NULL), G("b"),  G("a")));
+       _ASSERT (3, !NM_IN_STRSET (NULL, G("a"),  G("b"),  G("a")));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N(NULL), N("b")));
+       _ASSERT (3, !NM_IN_STRSET ("a",  G(NULL), G(NULL), G("b")));
+       _ASSERT (2,  NM_IN_STRSET (NULL, G("a"),  G(NULL), N("b")));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("a"),  N("b")));
+       _ASSERT (2,  NM_IN_STRSET ("a",  G(NULL), G("a"),  N("b")));
+       _ASSERT (3, !NM_IN_STRSET (NULL, G("a"),  G("a"),  G("b")));
+       _ASSERT (1,  NM_IN_STRSET (NULL, G(NULL), N("b"),  N("b")));
+       _ASSERT (3, !NM_IN_STRSET ("a",  G(NULL), G("b"),  G("b")));
+       _ASSERT (3, !NM_IN_STRSET (NULL, G("a"),  G("b"),  G("b")));
+
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G(NULL), G(NULL)));
+       _ASSERT (3, !NM_IN_STRSET_SE ("a",  G(NULL), G(NULL), G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G("a"),  G(NULL), G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G("a"),  G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET_SE ("a",  G(NULL), G("a"),  G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G("a"),  G("a"),  G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G("b"),  G(NULL)));
+       _ASSERT (3, !NM_IN_STRSET_SE ("a",  G(NULL), G("b"),  G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G("a"),  G("b"),  G(NULL)));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G(NULL), G("a")));
+       _ASSERT (3,  NM_IN_STRSET_SE ("a",  G(NULL), G(NULL), G("a")));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G("a"),  G(NULL), G("a")));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G("a"),  G("a")));
+       _ASSERT (3,  NM_IN_STRSET_SE ("a",  G(NULL), G("a"),  G("a")));
+       _ASSERT (3, !NM_IN_STRSET_SE (NULL, G("a"),  G("a"),  G("a")));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G("b"),  G("a")));
+       _ASSERT (3,  NM_IN_STRSET_SE ("a",  G(NULL), G("b"),  G("a")));
+       _ASSERT (3, !NM_IN_STRSET_SE (NULL, G("a"),  G("b"),  G("a")));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G(NULL), G("b")));
+       _ASSERT (3, !NM_IN_STRSET_SE ("a",  G(NULL), G(NULL), G("b")));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G("a"),  G(NULL), G("b")));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G("a"),  G("b")));
+       _ASSERT (3,  NM_IN_STRSET_SE ("a",  G(NULL), G("a"),  G("b")));
+       _ASSERT (3, !NM_IN_STRSET_SE (NULL, G("a"),  G("a"),  G("b")));
+       _ASSERT (3,  NM_IN_STRSET_SE (NULL, G(NULL), G("b"),  G("b")));
+       _ASSERT (3, !NM_IN_STRSET_SE ("a",  G(NULL), G("b"),  G("b")));
+       _ASSERT (3, !NM_IN_STRSET_SE (NULL, G("a"),  G("b"),  G("b")));
+
+
+       _ASSERT (3,  NM_IN_STRSET ("a",  G(NULL), G("b"),  G("a"),  N("a")));
+       _ASSERT (4,  NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("a")));
+       _ASSERT (4, !NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("d")));
+
+       _ASSERT (4,  NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("a"),  N("a")));
+       _ASSERT (5,  NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("d"),  G("a")));
+       _ASSERT (5, !NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("d"),  G("e")));
+
+       _ASSERT (5,  NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("d"),  G("a"),  N("a")));
+       _ASSERT (6,  NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("d"),  G("e"),  G("a")));
+       _ASSERT (6, !NM_IN_STRSET ("a",  G(NULL), G("b"),  G("c"),  G("d"),  G("e"),  G("f")));
+#undef G
+#undef N
+#undef _ASSERT
+}
+
+/******************************************************************************/
+
 NMTST_DEFINE ();
 
 int main (int argc, char **argv)
@@ -4907,6 +5033,7 @@ int main (int argc, char **argv)
 
        /* The tests */
        g_test_add_func ("/core/general/test_nm_in_set", test_nm_in_set);
+       g_test_add_func ("/core/general/test_nm_in_strset", test_nm_in_strset);
        g_test_add_func ("/core/general/test_setting_vpn_items", test_setting_vpn_items);
        g_test_add_func ("/core/general/test_setting_vpn_update_secrets", test_setting_vpn_update_secrets);
        g_test_add_func ("/core/general/test_setting_vpn_modify_during_foreach", test_setting_vpn_modify_during_foreach);
index c70c6e2..4b43b58 100644 (file)
  * side-effects. */
 #define NM_IN_SET_SE(x, ...)            _NM_IN_SET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
 
+/********************************************************/
+
+static inline gboolean
+_NM_IN_STRSET_streq (const char *x, const char *s)
+{
+       return s && strcmp (x, s) == 0;
+}
+
+#define _NM_IN_STRSET_EVAL_1(op, _x, y1)                            \
+    _NM_IN_STRSET_streq (_x, y1)
+
+#define _NM_IN_STRSET_EVAL_2(op, _x, y1, y2)                        \
+    (   _NM_IN_STRSET_streq (_x, y1)                                \
+     op _NM_IN_STRSET_streq (_x, y2)                                \
+    )
+
+#define _NM_IN_STRSET_EVAL_3(op, _x, y1, y2, y3)                    \
+    (   _NM_IN_STRSET_streq (_x, y1)                                \
+     op _NM_IN_STRSET_streq (_x, y2)                                \
+     op _NM_IN_STRSET_streq (_x, y3)                                \
+    )
+
+#define _NM_IN_STRSET_EVAL_4(op, _x, y1, y2, y3, y4)                \
+    (   _NM_IN_STRSET_streq (_x, y1)                                \
+     op _NM_IN_STRSET_streq (_x, y2)                                \
+     op _NM_IN_STRSET_streq (_x, y3)                                \
+     op _NM_IN_STRSET_streq (_x, y4)                                \
+    )
+
+#define _NM_IN_STRSET_EVAL_5(op, _x, y1, y2, y3, y4, y5)            \
+    (   _NM_IN_STRSET_streq (_x, y1)                                \
+     op _NM_IN_STRSET_streq (_x, y2)                                \
+     op _NM_IN_STRSET_streq (_x, y3)                                \
+     op _NM_IN_STRSET_streq (_x, y4)                                \
+     op _NM_IN_STRSET_streq (_x, y5)                                \
+    )
+
+#define _NM_IN_STRSET_EVAL_6(op, _x, y1, y2, y3, y4, y5, y6)        \
+    (   _NM_IN_STRSET_streq (_x, y1)                                \
+     op _NM_IN_STRSET_streq (_x, y2)                                \
+     op _NM_IN_STRSET_streq (_x, y3)                                \
+     op _NM_IN_STRSET_streq (_x, y4)                                \
+     op _NM_IN_STRSET_streq (_x, y5)                                \
+     op _NM_IN_STRSET_streq (_x, y6)                                \
+    )
+
+#define _NM_IN_STRSET_EVAL_N2(op, _x, n, ...) _NM_IN_STRSET_EVAL_##n(op, _x, __VA_ARGS__)
+#define _NM_IN_STRSET_EVAL_N(op, x, n, ...)                       \
+    ({                                                            \
+        const char *_x = (x);                                     \
+        (   ((_x == NULL) && _NM_IN_SET_EVAL_N2    (op, (const char *) NULL, n, __VA_ARGS__)) \
+         || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x,                  n, __VA_ARGS__)) \
+        ); \
+    })
+
+/* Beware that this does short-circuit evaluation (use "||" instead of "|")
+ * which has a possibly unexpected non-function-like behavior.
+ * Use NM_IN_STRSET_SE if you need all arguments to be evaluted. */
+#define NM_IN_STRSET(x, ...)               _NM_IN_STRSET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+
+/* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do
+ * short-circuit evaluation, which can make a difference if the arguments have
+ * side-effects. */
+#define NM_IN_STRSET_SE(x, ...)            _NM_IN_STRSET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+
 /*****************************************************************************/
 
 #define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \