diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-08-26 19:18:15 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-10-07 20:14:38 +0200 |
commit | 4a39c774196f1a694477432f845e8bd62efee245 (patch) | |
tree | 7ebdfbdab40660fcf8087b967eaa5d6598d85584 | |
parent | f767d3de652ec18c84ff0b99b1c4430269501e51 (diff) |
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().
-rw-r--r-- | src/basic/strv.h | 11 | ||||
-rw-r--r-- | src/test/test-strv.c | 9 |
2 files changed, 14 insertions, 6 deletions
diff --git a/src/basic/strv.h b/src/basic/strv.h index fec2597db0..385ad17779 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 ce20f2dd5b..88da69e2d7 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) { |