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:
Richard Maw 2015-06-19 15:24:34 +00:00
parent ffcd3e89d5
commit 8adaf7bd23
7 changed files with 30 additions and 13 deletions

2
TODO
View File

@ -6,7 +6,7 @@ Bugfixes:
automount points even when the original .automount file did not exist automount points even when the original .automount file did not exist
anymore. Only the .mount unit was still around. 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] [Service]
Environment=ONE='one' "TWO='two two' too" THREE= Environment=ONE='one' "TWO='two two' too" THREE=

View File

@ -550,7 +550,7 @@ char **replace_env_argv(char **argv, char **env) {
if (e) { if (e) {
int r; int r;
r = strv_split_quoted(&m, e, EXTRACT_RELAX); r = strv_split_extract(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_QUOTES);
if (r < 0) { if (r < 0) {
ret[k] = NULL; ret[k] = NULL;
strv_free(ret); strv_free(ret);

View File

@ -278,7 +278,7 @@ char **strv_split_newlines(const char *s) {
return l; 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; size_t n = 0, allocated = 0;
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
int r; int r;
@ -289,11 +289,12 @@ int strv_split_quoted(char ***t, const char *s, ExtractFlags flags) {
for (;;) { for (;;) {
_cleanup_free_ char *word = NULL; _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) if (r < 0)
return r; return r;
if (r == 0) if (r == 0) {
break; break;
}
if (!GREEDY_REALLOC(l, allocated, n + 2)) if (!GREEDY_REALLOC(l, allocated, n + 2))
return -ENOMEM; return -ENOMEM;

View File

@ -73,7 +73,7 @@ static inline bool strv_isempty(char * const *l) {
char **strv_split(const char *s, const char *separator); char **strv_split(const char *s, const char *separator);
char **strv_split_newlines(const char *s); 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(char **l, const char *separator);
char *strv_join_quoted(char **l); char *strv_join_quoted(char **l);

View File

@ -148,7 +148,7 @@ static int spawn_getter(const char *getter, const char *url) {
_cleanup_strv_free_ char **words = NULL; _cleanup_strv_free_ char **words = NULL;
assert(getter); assert(getter);
r = strv_split_quoted(&words, getter, 0); r = strv_split_extract(&words, getter, WHITESPACE, EXTRACT_QUOTES);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to split getter option: %m"); return log_error_errno(r, "Failed to split getter option: %m");

View File

@ -222,7 +222,7 @@ static int x11_read_data(Context *c) {
if (in_section && first_word(l, "Option")) { if (in_section && first_word(l, "Option")) {
_cleanup_strv_free_ char **a = NULL; _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) if (r < 0)
return r; return r;
@ -245,7 +245,7 @@ static int x11_read_data(Context *c) {
} else if (!in_section && first_word(l, "Section")) { } else if (!in_section && first_word(l, "Section")) {
_cleanup_strv_free_ char **a = NULL; _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) if (r < 0)
return -ENOMEM; return -ENOMEM;
@ -544,7 +544,7 @@ static int read_next_mapping(const char* filename,
if (l[0] == 0 || l[0] == '#') if (l[0] == 0 || l[0] == '#')
continue; continue;
r = strv_split_quoted(&b, l, 0); r = strv_split_extract(&b, l, WHITESPACE, EXTRACT_QUOTES);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -165,7 +165,7 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
assert_se(p); assert_se(p);
assert_se(streq(p, quoted)); 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(r == 0);
assert_se(s); assert_se(s);
STRV_FOREACH(t, s) { STRV_FOREACH(t, s) {
@ -182,7 +182,7 @@ static void test_strv_unquote(const char *quoted, char **list) {
char **t; char **t;
int r; int r;
r = strv_split_quoted(&s, quoted, 0); r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
assert_se(r == 0); assert_se(r == 0);
assert_se(s); assert_se(s);
j = strv_join(s, " | "); j = strv_join(s, " | ");
@ -199,7 +199,7 @@ static void test_invalid_unquote(const char *quoted) {
char **s = NULL; char **s = NULL;
int r; int r;
r = strv_split_quoted(&s, quoted, 0); r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
assert_se(s == NULL); assert_se(s == NULL);
assert_se(r == -EINVAL); 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) { static void test_strv_split_newlines(void) {
unsigned i = 0; unsigned i = 0;
char **s; char **s;
@ -583,6 +598,7 @@ int main(int argc, char *argv[]) {
test_invalid_unquote("'x'y'g"); test_invalid_unquote("'x'y'g");
test_strv_split(); test_strv_split();
test_strv_split_extract();
test_strv_split_newlines(); test_strv_split_newlines();
test_strv_split_nulstr(); test_strv_split_nulstr();
test_strv_parse_nulstr(); test_strv_parse_nulstr();