Blob Blame History Raw
From edc8c0565efe09c404e0588fcdb1027b1c61faa8 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 2 Dec 2013 23:08:25 +0100
Subject: [PATCH] macro: add a macro to test whether a value is in a specified
 list

Introduce IN_SET() macro to nicely check whether a value a is one of a
few listed values.

This makes writing this:

        if (a == 1 || a == 7 || a == 8 || a == 9)

nicer, by allowing this:

        if (IN_SET(a, 1, 7, 8, 9))

This is particularly useful for state machine enums.

(cherry picked from commit cabb78068899232c152f4585f19d023e373aa73d)
---
 src/shared/macro.h   | 13 +++++++++++++
 src/test/test-util.c | 11 +++++++++++
 2 files changed, 24 insertions(+)

diff --git a/src/shared/macro.h b/src/shared/macro.h
index bc5b3c1de8..5f3e52294b 100644
--- a/src/shared/macro.h
+++ b/src/shared/macro.h
@@ -294,4 +294,17 @@ do {                                                                    \
 #define SET_FLAG(v, flag, b) \
         (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
 
+#define IN_SET(x, ...) ({                                               \
+        typeof(x) _x = (x);                                             \
+        unsigned _i;                                                    \
+        bool _found = false;                                            \
+        for (_i = 0; _i < sizeof((typeof(_x)[]) { __VA_ARGS__ })/sizeof(typeof(_x)); _i++) \
+                if (((typeof(_x)[]) { __VA_ARGS__ })[_i] == _x) {       \
+                        _found = true;                                  \
+                        break;                                          \
+                }                                                       \
+        _found;                                                         \
+        })
+
+
 #include "log.h"
diff --git a/src/test/test-util.c b/src/test/test-util.c
index c5762ede4b..7566adcc2f 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -591,6 +591,16 @@ static void test_get_files_in_directory(void) {
         assert_se(get_files_in_directory(".", NULL) >= 0);
 }
 
+static void test_in_set(void) {
+        assert_se(IN_SET(1, 1));
+        assert_se(IN_SET(1, 1, 2, 3, 4));
+        assert_se(IN_SET(2, 1, 2, 3, 4));
+        assert_se(IN_SET(3, 1, 2, 3, 4));
+        assert_se(IN_SET(4, 1, 2, 3, 4));
+        assert_se(!IN_SET(0, 1));
+        assert_se(!IN_SET(0, 1, 2, 3, 4));
+}
+
 int main(int argc, char *argv[]) {
         test_streq_ptr();
         test_first_word();
@@ -628,6 +638,7 @@ int main(int argc, char *argv[]) {
         test_split_pair();
         test_fstab_node_to_udev_node();
         test_get_files_in_directory();
+        test_in_set();
 
         return 0;
 }