]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
macros: add CMP(a, b) macro.
authorFilipe Brandenburger <filbranden@google.com>
Thu, 2 Aug 2018 21:37:42 +0000 (14:37 -0700)
committerFilipe Brandenburger <filbranden@google.com>
Tue, 7 Aug 2018 02:19:05 +0000 (19:19 -0700)
Macro returns -1, 0, 1 depending on whether a < b, a == b or a > b.

It's safe to use on unsigned types.

Add tests to confirm corner cases are properly covered.

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

index de4716919be0ffb41dc7c9c5f650a904978205aa..24fcdc8400870bdd9224c141cab92847512492a7 100644 (file)
@@ -222,6 +222,15 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
                 UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) - UNIQ_T(B, bq) : 0; \
         })
 
+#define CMP(a, b) __CMP(UNIQ, (a), UNIQ, (b))
+#define __CMP(aq, a, bq, b)                             \
+        ({                                              \
+                const typeof(a) UNIQ_T(A, aq) = (a);    \
+                const typeof(b) UNIQ_T(B, bq) = (b);    \
+                UNIQ_T(A, aq) < UNIQ_T(B, bq) ? -1 :    \
+                UNIQ_T(A, aq) > UNIQ_T(B, bq) ? 1 : 0;  \
+        })
+
 #undef CLAMP
 #define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
 #define __CLAMP(xq, x, lowq, low, highq, high)                          \
index 4d3e5c5b94c9fec981de4ac4201b2f18f724ba4a..7c645d7742a51e3601de1d7cca350a864b799f06 100644 (file)
@@ -53,6 +53,12 @@ static void test_max(void) {
                 .a = CONST_MAX(10, 100),
         };
         int d = 0;
+        unsigned long x = 12345;
+        unsigned long y = 54321;
+        const char str[] = "a_string_constant";
+        const unsigned long long arr[] = {9999ULL, 10ULL, 0ULL, 3000ULL, 2000ULL, 1000ULL, 100ULL, 9999999ULL};
+        void *p = (void *)str;
+        void *q = (void *)&str[16];
 
         assert_cc(sizeof(val1.b) == sizeof(int) * 100);
 
@@ -80,6 +86,35 @@ static void test_max(void) {
         assert_se(LESS_BY(4, 8) == 0);
         assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
         assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
+        assert_se(CMP(-5, 5) == -1);
+        assert_se(CMP(5, -5) == 1);
+        assert_se(CMP(5, 5) == 0);
+        assert_se(CMP(x, y) == -1);
+        assert_se(CMP(y, x) == 1);
+        assert_se(CMP(x, x) == 0);
+        assert_se(CMP(y, y) == 0);
+        assert_se(CMP(UINT64_MAX, 0L) == 1);
+        assert_se(CMP(0L, UINT64_MAX) == -1);
+        assert_se(CMP(UINT64_MAX, UINT64_MAX) == 0);
+        assert_se(CMP(INT64_MIN, INT64_MAX) == -1);
+        assert_se(CMP(INT64_MAX, INT64_MIN) == 1);
+        assert_se(CMP(INT64_MAX, INT64_MAX) == 0);
+        assert_se(CMP(INT64_MIN, INT64_MIN) == 0);
+        assert_se(CMP(INT64_MAX, 0L) == 1);
+        assert_se(CMP(0L, INT64_MIN) == 1);
+        assert_se(CMP(INT64_MIN, 0L) == -1);
+        assert_se(CMP(0L, INT64_MAX) == -1);
+        assert_se(CMP(&str[2], &str[7]) == -1);
+        assert_se(CMP(&str[2], &str[2]) == 0);
+        assert_se(CMP(&str[7], (const char *)str) == 1);
+        assert_se(CMP(str[2], str[7]) == 1);
+        assert_se(CMP(str[7], *str) == 1);
+        assert_se(CMP((const unsigned long long *)arr, &arr[3]) == -1);
+        assert_se(CMP(*arr, arr[3]) == 1);
+        assert_se(CMP(p, q) == -1);
+        assert_se(CMP(q, p) == 1);
+        assert_se(CMP(p, p) == 0);
+        assert_se(CMP(q, q) == 0);
         assert_se(CLAMP(-5, 0, 1) == 0);
         assert_se(CLAMP(5, 0, 1) == 1);
         assert_se(CLAMP(5, -10, 1) == 1);