From: Alejandro Colomar Date: Sat, 6 Jan 2024 01:17:38 +0000 (+0100) Subject: lib/, tests/: addsl(): Add addsl(), a variadic macro X-Git-Tag: 4.15.0-rc1~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e56af190222f2f3c3d26a58f2f085f55c98dd3c;p=thirdparty%2Fshadow.git lib/, tests/: addsl(): Add addsl(), a variadic macro Add a variadic macro addsl() that accepts an arbitrary number of addends, instead of having specific versions like addsl2() or addsl3(). It is internally implemented by the addslN() function, which itself calls addsl2(). addsl3() is now obsolete and thus removed. Code should just call addsl(). Link: Cc: Serge Hallyn Signed-off-by: Alejandro Colomar --- diff --git a/lib/adds.c b/lib/adds.c index b5ea3bb66..5d8c1537f 100644 --- a/lib/adds.c +++ b/lib/adds.c @@ -6,8 +6,10 @@ #include "adds.h" +#include + extern inline long addsl2(long a, long b); -extern inline long addsl3(long a, long b, long c); +extern inline long addslN(size_t n, long addend[n]); extern inline int cmpl(const void *p1, const void *p2); diff --git a/lib/adds.h b/lib/adds.h index 107e64e24..6544ce5fe 100644 --- a/lib/adds.h +++ b/lib/adds.h @@ -10,13 +10,22 @@ #include #include +#include #include #include "sizeof.h" +#define addsl(a, b, ...) \ +({ \ + long addend_[] = {a, b, __VA_ARGS__}; \ + \ + addslN(NITEMS(addend_), addend_); \ +}) + + inline long addsl2(long a, long b); -inline long addsl3(long a, long b, long c); +inline long addslN(size_t n, long addend[n]); inline int cmpl(const void *p1, const void *p2); @@ -37,21 +46,26 @@ addsl2(long a, long b) inline long -addsl3(long a, long b, long c) +addslN(size_t n, long addend[n]) { int e; - long sum; - long n[3] = {a, b, c}; + + if (n == 0) { + errno = EDOM; + return 0; + } e = errno; - qsort(n, NITEMS(n), sizeof(n[0]), cmpl); + while (n > 1) { + qsort(addend, n, sizeof(addend[0]), cmpl); - errno = 0; - sum = addsl(n[0], n[2]); - if (errno == EOVERFLOW) - return sum; + errno = 0; + addend[0] = addsl2(addend[0], addend[--n]); + if (errno == EOVERFLOW) + return addend[0]; + } errno = e; - return addsl(sum, n[1]); + return addend[0]; } diff --git a/tests/unit/test_adds.c b/tests/unit/test_adds.c index 72790a593..fdc671f5c 100644 --- a/tests/unit/test_adds.c +++ b/tests/unit/test_adds.c @@ -19,6 +19,7 @@ static void test_addsl_2_overflow(void **state); static void test_addsl_3_ok(void **state); static void test_addsl_3_underflow(void **state); static void test_addsl_3_overflow(void **state); +static void test_addsl_5_ok(void **state); int @@ -31,6 +32,7 @@ main(void) cmocka_unit_test(test_addsl_3_ok), cmocka_unit_test(test_addsl_3_underflow), cmocka_unit_test(test_addsl_3_overflow), + cmocka_unit_test(test_addsl_5_ok), }; return cmocka_run_group_tests(tests, NULL, NULL); @@ -40,41 +42,41 @@ main(void) static void test_addsl_2_ok(void **state) { - assert_true(addsl2(1, 3) == 1 + 3); - assert_true(addsl2(-4321, 7) == -4321 + 7); - assert_true(addsl2(1, 1) == 1 + 1); - assert_true(addsl2(-1, -2) == -1 - 2); - assert_true(addsl2(LONG_MAX, -1) == LONG_MAX - 1); - assert_true(addsl2(LONG_MIN, 1) == LONG_MIN + 1); - assert_true(addsl2(LONG_MIN, LONG_MAX) == LONG_MIN + LONG_MAX); - assert_true(addsl2(0, 0) == 0); + assert_true(addsl(1, 3) == 1 + 3); + assert_true(addsl(-4321, 7) == -4321 + 7); + assert_true(addsl(1, 1) == 1 + 1); + assert_true(addsl(-1, -2) == -1 - 2); + assert_true(addsl(LONG_MAX, -1) == LONG_MAX - 1); + assert_true(addsl(LONG_MIN, 1) == LONG_MIN + 1); + assert_true(addsl(LONG_MIN, LONG_MAX) == LONG_MIN + LONG_MAX); + assert_true(addsl(0, 0) == 0); } static void test_addsl_2_underflow(void **state) { - assert_true(addsl2(LONG_MIN, -1) == LONG_MIN); - assert_true(addsl2(LONG_MIN + 3, -7) == LONG_MIN); - assert_true(addsl2(LONG_MIN, LONG_MIN) == LONG_MIN); + assert_true(addsl(LONG_MIN, -1) == LONG_MIN); + assert_true(addsl(LONG_MIN + 3, -7) == LONG_MIN); + assert_true(addsl(LONG_MIN, LONG_MIN) == LONG_MIN); } static void test_addsl_2_overflow(void **state) { - assert_true(addsl2(LONG_MAX, 1) == LONG_MAX); - assert_true(addsl2(LONG_MAX - 3, 7) == LONG_MAX); - assert_true(addsl2(LONG_MAX, LONG_MAX) == LONG_MAX); + assert_true(addsl(LONG_MAX, 1) == LONG_MAX); + assert_true(addsl(LONG_MAX - 3, 7) == LONG_MAX); + assert_true(addsl(LONG_MAX, LONG_MAX) == LONG_MAX); } static void test_addsl_3_ok(void **state) { - assert_true(addsl3(1, 2, 3) == 1 + 2 + 3); - assert_true(addsl3(LONG_MIN, -3, 4) == LONG_MIN + 4 - 3); - assert_true(addsl3(LONG_MAX, LONG_MAX, LONG_MIN) + assert_true(addsl(1, 2, 3) == 1 + 2 + 3); + assert_true(addsl(LONG_MIN, -3, 4) == LONG_MIN + 4 - 3); + assert_true(addsl(LONG_MAX, LONG_MAX, LONG_MIN) == LONG_MAX + LONG_MIN + LONG_MAX); } @@ -82,15 +84,22 @@ test_addsl_3_ok(void **state) static void test_addsl_3_underflow(void **state) { - assert_true(addsl3(LONG_MIN, 2, -3) == LONG_MIN); - assert_true(addsl3(LONG_MIN, -1, 0) == LONG_MIN); + assert_true(addsl(LONG_MIN, 2, -3) == LONG_MIN); + assert_true(addsl(LONG_MIN, -1, 0) == LONG_MIN); } static void test_addsl_3_overflow(void **state) { - assert_true(addsl3(LONG_MAX, -1, 2) == LONG_MAX); - assert_true(addsl3(LONG_MAX, +1, 0) == LONG_MAX); - assert_true(addsl3(LONG_MAX, LONG_MAX, 0)== LONG_MAX); + assert_true(addsl(LONG_MAX, -1, 2) == LONG_MAX); + assert_true(addsl(LONG_MAX, +1, 0) == LONG_MAX); + assert_true(addsl(LONG_MAX, LONG_MAX, 0)== LONG_MAX); +} + + +static void +test_addsl_5_ok(void **state) +{ + assert_true(addsl(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN, 44) == 42); }