mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
strv: convert strv_split_quotes into a generic strv_split_extract
strv_split_extract is to strv_split_quotes as extract_first_word was to unquote_first_word. Now there's extract_first_word for extracting a single argument, extract_many_words for extracting a bounded number of arguments, and strv_split_extract for extracting an arbitrary number of arguments.
This commit is contained in:
parent
ffcd3e89d5
commit
8adaf7bd23
2
TODO
2
TODO
@ -6,7 +6,7 @@ Bugfixes:
|
||||
automount points even when the original .automount file did not exist
|
||||
anymore. Only the .mount unit was still around.
|
||||
|
||||
* ExecStart with unicode characters fails in strv_split_quoted:
|
||||
* ExecStart with unicode characters fails in strv_split_extract:
|
||||
|
||||
[Service]
|
||||
Environment=ONE='one' "TWO='two two' too" THREE=
|
||||
|
@ -550,7 +550,7 @@ char **replace_env_argv(char **argv, char **env) {
|
||||
if (e) {
|
||||
int r;
|
||||
|
||||
r = strv_split_quoted(&m, e, EXTRACT_RELAX);
|
||||
r = strv_split_extract(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_QUOTES);
|
||||
if (r < 0) {
|
||||
ret[k] = NULL;
|
||||
strv_free(ret);
|
||||
|
@ -278,7 +278,7 @@ char **strv_split_newlines(const char *s) {
|
||||
return l;
|
||||
}
|
||||
|
||||
int strv_split_quoted(char ***t, const char *s, ExtractFlags flags) {
|
||||
int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
|
||||
size_t n = 0, allocated = 0;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
int r;
|
||||
@ -289,11 +289,12 @@ int strv_split_quoted(char ***t, const char *s, ExtractFlags flags) {
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&s, &word, NULL, flags|EXTRACT_QUOTES);
|
||||
r = extract_first_word(&s, &word, separators, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
if (r == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(l, allocated, n + 2))
|
||||
return -ENOMEM;
|
||||
|
@ -73,7 +73,7 @@ static inline bool strv_isempty(char * const *l) {
|
||||
char **strv_split(const char *s, const char *separator);
|
||||
char **strv_split_newlines(const char *s);
|
||||
|
||||
int strv_split_quoted(char ***t, const char *s, ExtractFlags flags);
|
||||
int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags);
|
||||
|
||||
char *strv_join(char **l, const char *separator);
|
||||
char *strv_join_quoted(char **l);
|
||||
|
@ -148,7 +148,7 @@ static int spawn_getter(const char *getter, const char *url) {
|
||||
_cleanup_strv_free_ char **words = NULL;
|
||||
|
||||
assert(getter);
|
||||
r = strv_split_quoted(&words, getter, 0);
|
||||
r = strv_split_extract(&words, getter, WHITESPACE, EXTRACT_QUOTES);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to split getter option: %m");
|
||||
|
||||
|
@ -222,7 +222,7 @@ static int x11_read_data(Context *c) {
|
||||
if (in_section && first_word(l, "Option")) {
|
||||
_cleanup_strv_free_ char **a = NULL;
|
||||
|
||||
r = strv_split_quoted(&a, l, 0);
|
||||
r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -245,7 +245,7 @@ static int x11_read_data(Context *c) {
|
||||
} else if (!in_section && first_word(l, "Section")) {
|
||||
_cleanup_strv_free_ char **a = NULL;
|
||||
|
||||
r = strv_split_quoted(&a, l, 0);
|
||||
r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -544,7 +544,7 @@ static int read_next_mapping(const char* filename,
|
||||
if (l[0] == 0 || l[0] == '#')
|
||||
continue;
|
||||
|
||||
r = strv_split_quoted(&b, l, 0);
|
||||
r = strv_split_extract(&b, l, WHITESPACE, EXTRACT_QUOTES);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -165,7 +165,7 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
|
||||
assert_se(p);
|
||||
assert_se(streq(p, quoted));
|
||||
|
||||
r = strv_split_quoted(&s, quoted, 0);
|
||||
r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
|
||||
assert_se(r == 0);
|
||||
assert_se(s);
|
||||
STRV_FOREACH(t, s) {
|
||||
@ -182,7 +182,7 @@ static void test_strv_unquote(const char *quoted, char **list) {
|
||||
char **t;
|
||||
int r;
|
||||
|
||||
r = strv_split_quoted(&s, quoted, 0);
|
||||
r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
|
||||
assert_se(r == 0);
|
||||
assert_se(s);
|
||||
j = strv_join(s, " | ");
|
||||
@ -199,7 +199,7 @@ static void test_invalid_unquote(const char *quoted) {
|
||||
char **s = NULL;
|
||||
int r;
|
||||
|
||||
r = strv_split_quoted(&s, quoted, 0);
|
||||
r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
|
||||
assert_se(s == NULL);
|
||||
assert_se(r == -EINVAL);
|
||||
}
|
||||
@ -219,6 +219,21 @@ static void test_strv_split(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_strv_split_extract(void) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const char *str = ":foo\\:bar::waldo:";
|
||||
int r;
|
||||
|
||||
r = strv_split_extract(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
|
||||
assert_se(r == 0);
|
||||
assert_se(streq_ptr(l[0], ""));
|
||||
assert_se(streq_ptr(l[1], "foo:bar"));
|
||||
assert_se(streq_ptr(l[2], ""));
|
||||
assert_se(streq_ptr(l[3], "waldo"));
|
||||
assert_se(streq_ptr(l[4], ""));
|
||||
assert_se(streq_ptr(l[5], NULL));
|
||||
}
|
||||
|
||||
static void test_strv_split_newlines(void) {
|
||||
unsigned i = 0;
|
||||
char **s;
|
||||
@ -583,6 +598,7 @@ int main(int argc, char *argv[]) {
|
||||
test_invalid_unquote("'x'y'g");
|
||||
|
||||
test_strv_split();
|
||||
test_strv_split_extract();
|
||||
test_strv_split_newlines();
|
||||
test_strv_split_nulstr();
|
||||
test_strv_parse_nulstr();
|
||||
|
Loading…
Reference in New Issue
Block a user