diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-03-05 01:29:57 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-03-05 01:29:57 +0100 |
commit | f385c447870e0783814b37cb11a38187533458db (patch) | |
tree | f7e8f12e618a407938fe97fd0a1db58527c89c22 | |
parent | copy: move sync_rights() to copy.c and rename copy_rights() (diff) | |
download | systemd-f385c447870e0783814b37cb11a38187533458db.tar.xz systemd-f385c447870e0783814b37cb11a38187533458db.zip |
strv: introduce strv_split_newlines_full()
-rw-r--r-- | src/basic/strv.c | 25 | ||||
-rw-r--r-- | src/basic/strv.h | 16 | ||||
-rw-r--r-- | src/test/test-device-nodes.c | 1 | ||||
-rw-r--r-- | src/test/test-strv.c | 34 |
4 files changed, 59 insertions, 17 deletions
diff --git a/src/basic/strv.c b/src/basic/strv.c index 492dfe4002..765da04a7b 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -240,27 +240,28 @@ int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) { return 0; } -char **strv_split_newlines(const char *s) { - char **l; +int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags) { + _cleanup_strv_free_ char **l = NULL; size_t n; + int r; assert(s); - /* Special version of strv_split() that splits on newlines and - * suppresses an empty string at the end */ + /* Special version of strv_split_full() that splits on newlines and + * suppresses an empty string at the end. */ - l = strv_split(s, NEWLINE); - if (!l) - return NULL; + r = strv_split_full(&l, s, NEWLINE, flags); + if (r < 0) + return r; n = strv_length(l); - if (n <= 0) - return l; - - if (isempty(l[n - 1])) + if (n > 0 && isempty(l[n - 1])) { l[n - 1] = mfree(l[n - 1]); + n--; + } - return l; + *ret = TAKE_PTR(l); + return n; } int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags) { diff --git a/src/basic/strv.h b/src/basic/strv.h index 6b3e8e7f86..911528fab4 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -73,15 +73,21 @@ static inline bool strv_isempty(char * const *l) { return !l || !*l; } -char **strv_split_newlines(const char *s); - int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags); static inline char **strv_split(const char *s, const char *separators) { char **ret; - int r; - r = strv_split_full(&ret, s, separators, 0); - if (r < 0) + if (strv_split_full(&ret, s, separators, 0) < 0) + return NULL; + + return ret; +} + +int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags); +static inline char **strv_split_newlines(const char *s) { + char **ret; + + if (strv_split_newlines_full(&ret, s, 0) < 0) return NULL; return ret; diff --git a/src/test/test-device-nodes.c b/src/test/test-device-nodes.c index 9efb3fe3b3..c914d78324 100644 --- a/src/test/test-device-nodes.c +++ b/src/test/test-device-nodes.c @@ -31,6 +31,7 @@ static void test_encode_devnode_name(void) { assert_se(expect_encoded_as("s/ash/ng", "s\\x2fash\\x2fng")); assert_se(expect_encoded_as("/", "\\x2f")); assert_se(expect_encoded_as("!", "\\x21")); + assert_se(expect_encoded_as("QEMU ", "QEMU\\x20\\x20\\x20\\x20")); } int main(int argc, char *argv[]) { diff --git a/src/test/test-strv.c b/src/test/test-strv.c index 6b5005f9fc..162d8bed95 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -118,6 +118,20 @@ static const char* const input_table_one_empty[] = { NULL, }; +static const char* const input_table_unescape[] = { + "ID_VENDOR=QEMU", + "ID_VENDOR_ENC=QEMUx20x20x20x20", + "ID_MODEL_ENC=QEMUx20HARDDISKx20x20x20", + NULL, +}; + +static const char* const input_table_retain_escape[] = { + "ID_VENDOR=QEMU", + "ID_VENDOR_ENC=QEMU\\x20\\x20\\x20\\x20", + "ID_MODEL_ENC=QEMU\\x20HARDDISK\\x20\\x20\\x20", + NULL, +}; + static void test_strv_find(void) { log_info("/* %s */", __func__); @@ -453,6 +467,25 @@ static void test_strv_split_newlines(void) { assert_se(streq(*s, input_table_multiple[i++])); } +static void test_strv_split_newlines_full(void) { + const char str[] = + "ID_VENDOR=QEMU\n" + "ID_VENDOR_ENC=QEMU\\x20\\x20\\x20\\x20\n" + "ID_MODEL_ENC=QEMU\\x20HARDDISK\\x20\\x20\\x20\n" + "\n\n\n"; + _cleanup_strv_free_ char **l = NULL; + + log_info("/* %s */", __func__); + + assert_se(strv_split_newlines_full(&l, str, 0) == 3); + assert_se(strv_equal(l, (char**) input_table_unescape)); + + l = strv_free(l); + + assert_se(strv_split_newlines_full(&l, str, EXTRACT_RETAIN_ESCAPE) == 3); + assert_se(strv_equal(l, (char**) input_table_retain_escape)); +} + static void test_strv_split_nulstr(void) { _cleanup_strv_free_ char **l = NULL; const char nulstr[] = "str0\0str1\0str2\0str3\0"; @@ -1031,6 +1064,7 @@ int main(int argc, char *argv[]) { test_strv_split_full(); test_strv_split_colon_pairs(); test_strv_split_newlines(); + test_strv_split_newlines_full(); test_strv_split_nulstr(); test_strv_parse_nulstr(); test_strv_overlap(); |