From: Lennart Poettering Date: Fri, 26 Aug 2016 17:18:15 +0000 (+0200) Subject: strv: fix STRV_FOREACH_BACKWARDS() to be a single statement only X-Git-Tag: v232~114^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a39c774196f1a694477432f845e8bd62efee245;p=thirdparty%2Fsystemd.git strv: fix STRV_FOREACH_BACKWARDS() to be a single statement only Let's make sure people invoking STRV_FOREACH_BACKWARDS() as a single statement of an if statement don't fall into a trap, and find the tail for the list via strv_length(). --- diff --git a/src/basic/strv.h b/src/basic/strv.h index fec2597db0b..385ad17779b 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -96,10 +96,13 @@ bool strv_overlap(char **a, char **b) _pure_; #define STRV_FOREACH(s, l) \ for ((s) = (l); (s) && *(s); (s)++) -#define STRV_FOREACH_BACKWARDS(s, l) \ - STRV_FOREACH(s, l) \ - ; \ - for ((s)--; (l) && ((s) >= (l)); (s)--) +#define STRV_FOREACH_BACKWARDS(s, l) \ + for (s = ({ \ + char **_l = l; \ + _l ? _l + strv_length(_l) - 1U : NULL; \ + }); \ + (l) && ((s) >= (l)); \ + (s)--) #define STRV_FOREACH_PAIR(x, y, l) \ for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1)) diff --git a/src/test/test-strv.c b/src/test/test-strv.c index ce20f2dd5b6..88da69e2d7d 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -453,9 +453,14 @@ static void test_strv_foreach_backwards(void) { assert_se(a); - STRV_FOREACH_BACKWARDS(check, a) { + STRV_FOREACH_BACKWARDS(check, a) assert_se(streq_ptr(*check, input_table_multiple[i--])); - } + + STRV_FOREACH_BACKWARDS(check, (char**) NULL) + assert_not_reached("Let's see that we check empty strv right, too."); + + STRV_FOREACH_BACKWARDS(check, (char**) { NULL }) + assert_not_reached("Let's see that we check empty strv right, too."); } static void test_strv_foreach_pair(void) {