diff options
Diffstat (limited to 'shared/systemd/src/basic/strv.c')
| -rw-r--r-- | shared/systemd/src/basic/strv.c | 115 |
1 files changed, 72 insertions, 43 deletions
diff --git a/shared/systemd/src/basic/strv.c b/shared/systemd/src/basic/strv.c index 6f812139..30d3af46 100644 --- a/shared/systemd/src/basic/strv.c +++ b/shared/systemd/src/basic/strv.c @@ -260,44 +260,6 @@ int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) { } #endif /* NM_IGNORED */ -char **strv_split_full(const char *s, const char *separator, SplitFlags flags) { - const char *word, *state; - size_t l; - size_t n, i; - char **r; - - assert(s); - - if (!separator) - separator = WHITESPACE; - - s += strspn(s, separator); - if (isempty(s)) - return new0(char*, 1); - - n = 0; - _FOREACH_WORD(word, l, s, separator, flags, state) - n++; - - r = new(char*, n+1); - if (!r) - return NULL; - - i = 0; - _FOREACH_WORD(word, l, s, separator, flags, state) { - r[i] = strndup(word, l); - if (!r[i]) { - strv_free(r); - return NULL; - } - - i++; - } - - r[i] = NULL; - return r; -} - char **strv_split_newlines(const char *s) { char **l; size_t n; @@ -321,8 +283,7 @@ char **strv_split_newlines(const char *s) { return l; } -#if 0 /* NM_IGNORED */ -int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) { +int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags) { _cleanup_strv_free_ char **l = NULL; size_t n = 0, allocated = 0; int r; @@ -357,9 +318,62 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract return (int) n; } + +#if 0 /* NM_IGNORED */ +int strv_split_colon_pairs(char ***t, const char *s) { + _cleanup_strv_free_ char **l = NULL; + size_t n = 0, allocated = 0; + int r; + + assert(t); + assert(s); + + for (;;) { + _cleanup_free_ char *first = NULL, *second = NULL, *tuple = NULL, *second_or_empty = NULL; + + r = extract_first_word(&s, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE); + if (r < 0) + return r; + if (r == 0) + break; + + const char *p = tuple; + r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, + &first, &second, NULL); + if (r < 0) + return r; + if (r == 0) + continue; + /* Enforce that at most 2 colon-separated words are contained in each group */ + if (!isempty(p)) + return -EINVAL; + + second_or_empty = strdup(strempty(second)); + if (!second_or_empty) + return -ENOMEM; + + if (!GREEDY_REALLOC(l, allocated, n + 3)) + return -ENOMEM; + + l[n++] = TAKE_PTR(first); + l[n++] = TAKE_PTR(second_or_empty); + + l[n] = NULL; + } + + if (!l) { + l = new0(char*, 1); + if (!l) + return -ENOMEM; + } + + *t = TAKE_PTR(l); + + return (int) n; +} #endif /* NM_IGNORED */ -char *strv_join_prefix(char * const *l, const char *separator, const char *prefix) { +char *strv_join_full(char * const *l, const char *separator, const char *prefix, bool unescape_separators) { char * const *s; char *r, *e; size_t n, k, m; @@ -370,11 +384,17 @@ char *strv_join_prefix(char * const *l, const char *separator, const char *prefi k = strlen(separator); m = strlen_ptr(prefix); + if (unescape_separators) /* If there separator is multi-char, we won't know how to escape it. */ + assert(k == 1); + n = 0; STRV_FOREACH(s, l) { if (s != l) n += k; - n += m + strlen(*s); + + bool needs_escaping = unescape_separators && strchr(*s, separator[0]); + + n += m + strlen(*s) * (1 + needs_escaping); } r = new(char, n+1); @@ -389,7 +409,16 @@ char *strv_join_prefix(char * const *l, const char *separator, const char *prefi if (prefix) e = stpcpy(e, prefix); - e = stpcpy(e, *s); + bool needs_escaping = unescape_separators && strchr(*s, separator[0]); + + if (needs_escaping) + for (size_t i = 0; (*s)[i]; i++) { + if ((*s)[i] == separator[0]) + *(e++) = '\\'; + *(e++) = (*s)[i]; + } + else + e = stpcpy(e, *s); } *e = 0; |