]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
macro: introduce FOREACH_ARRAY() macro
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 5 Mar 2023 05:56:15 +0000 (14:56 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 7 Mar 2023 04:27:16 +0000 (13:27 +0900)
The pattern that runs all array element is quite common.
But, sometimes, the number of element may be in a signed integer, or the
array may be NULL.

src/basic/macro.h
src/test/test-macro.c

index 2425d27819a35e0b6ef40eb01610815223b12c5b..3de319d880f95a8c3e1b367b8abbcae4d908ee18 100644 (file)
@@ -297,6 +297,13 @@ static inline int __coverity_check_and_return__(int condition) {
              p != (typeof(p)) POINTER_MAX;                                               \
              p = *(++_l))
 
+#define _FOREACH_ARRAY(i, array, num, m, s)                             \
+        for (typeof(num) m = (num); m > 0; m = 0)                       \
+                for (typeof(array[0]) *s = (array), *i = s; s && i < s + m; i++)
+
+#define FOREACH_ARRAY(i, array, num)                                    \
+        _FOREACH_ARRAY(i, array, num, UNIQ_T(m, UNIQ), UNIQ_T(s, UNIQ))
+
 #define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func)             \
         static inline void name(type *p) {                      \
                 func(p);                                        \
index aec1f1ecd42656fa625368f0e9c483f1d3ba6645..ef74b8273edb558a6f9ae8d1a2b396b7e7126eb2 100644 (file)
@@ -584,4 +584,54 @@ TEST(ALIGNED) {
 #endif
 }
 
+TEST(FOREACH_ARRAY) {
+        int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+        int b[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+        int x, n;
+
+        x = n = 0;
+        FOREACH_ARRAY(i, a, 10) {
+                x += *i;
+                n++;
+        }
+        assert_se(x == 45);
+        assert_se(n == 10);
+
+        x = n = 0;
+        FOREACH_ARRAY(i, a, 10)
+                FOREACH_ARRAY(j, b, 10) {
+                        x += (*i) * (*j);
+                        n++;
+                }
+        assert_se(x == 45 * 45);
+        assert_se(n == 10 * 10);
+
+        x = n = 0;
+        FOREACH_ARRAY(i, a, 5)
+                FOREACH_ARRAY(j, b, 5) {
+                        x += (*i) * (*j);
+                        n++;
+                }
+        assert_se(x == 10 * 35);
+        assert_se(n == 5 * 5);
+
+        x = n = 0;
+        FOREACH_ARRAY(i, a, 0)
+                FOREACH_ARRAY(j, b, 0) {
+                        x += (*i) * (*j);
+                        n++;
+                }
+        assert_se(x == 0);
+        assert_se(n == 0);
+
+        x = n = 0;
+        FOREACH_ARRAY(i, a, -1)
+                FOREACH_ARRAY(j, b, -1) {
+                        x += (*i) * (*j);
+                        n++;
+                }
+        assert_se(x == 0);
+        assert_se(n == 0);
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);