X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fstrv.c;h=b4c476eff27df9858698ad4f52e66210b6696bb7;hb=a1948c7bfeb87b54bc7715a44490c01593ee6e23;hp=607c221ae66790b86311bdc36625039e2f401c20;hpb=49b832c5b810f4d8bb59249ff25472fd670503dc;p=elogind.git diff --git a/src/shared/strv.c b/src/shared/strv.c index 607c221ae..b4c476eff 100644 --- a/src/shared/strv.c +++ b/src/shared/strv.c @@ -166,72 +166,38 @@ char **strv_new(const char *x, ...) { return r; } -char **strv_merge(char **a, char **b) { - char **r, **k; - - if (!a) - return strv_copy(b); - - if (!b) - return strv_copy(a); - - r = new(char*, strv_length(a) + strv_length(b) + 1); - if (!r) - return NULL; - - for (k = r; *a; k++, a++) { - *k = strdup(*a); - if (!*k) - goto fail; - } +int strv_extend_strv(char ***a, char **b) { + int r; + char **s; - for (; *b; k++, b++) { - *k = strdup(*b); - if (!*k) - goto fail; + STRV_FOREACH(s, b) { + r = strv_extend(a, *s); + if (r < 0) + return r; } - *k = NULL; - return r; - -fail: - strv_free(r); - return NULL; + return 0; } -char **strv_merge_concat(char **a, char **b, const char *suffix) { - char **r, **k; - - /* Like strv_merge(), but appends suffix to all strings in b, before adding */ +int strv_extend_strv_concat(char ***a, char **b, const char *suffix) { + int r; + char **s; - if (!b) - return strv_copy(a); + STRV_FOREACH(s, b) { + char *v; - r = new(char*, strv_length(a) + strv_length(b) + 1); - if (!r) - return NULL; + v = strappend(*s, suffix); + if (!v) + return -ENOMEM; - k = r; - if (a) - for (; *a; k++, a++) { - *k = strdup(*a); - if (!*k) - goto fail; + r = strv_push(a, v); + if (r < 0) { + free(v); + return r; } - - for (; *b; k++, b++) { - *k = strappend(*b, suffix); - if (!*k) - goto fail; } - *k = NULL; - return r; - -fail: - strv_free(r); - return NULL; - + return 0; } char **strv_split(const char *s, const char *separator) { @@ -393,59 +359,71 @@ char *strv_join_quoted(char **l) { return NULL; } -char **strv_append(char **l, const char *s) { - char **r, **k; - - if (!l) - return strv_new(s, NULL); - - if (!s) - return strv_copy(l); - - r = new(char*, strv_length(l)+2); - if (!r) - return NULL; +int strv_push(char ***l, char *value) { + char **c; + unsigned n; - for (k = r; *l; k++, l++) { - *k = strdup(*l); - if (!*k) - goto fail; - } + if (!value) + return 0; - k[0] = strdup(s); - if (!k[0]) - goto fail; + n = strv_length(*l); + c = realloc(*l, sizeof(char*) * (n + 2)); + if (!c) + return -ENOMEM; - k[1] = NULL; - return r; + c[n] = value; + c[n+1] = NULL; -fail: - strv_free(r); - return NULL; + *l = c; + return 0; } -int strv_push(char ***l, char *value) { +int strv_push_prepend(char ***l, char *value) { char **c; - unsigned n; + unsigned n, i; if (!value) return 0; n = strv_length(*l); - c = realloc(*l, sizeof(char*) * (n + 2)); + c = new(char*, n + 2); if (!c) return -ENOMEM; - c[n] = value; + for (i = 0; i < n; i++) + c[i+1] = (*l)[i]; + + c[0] = value; c[n+1] = NULL; + free(*l); *l = c; + return 0; } +int strv_consume(char ***l, char *value) { + int r; + + r = strv_push(l, value); + if (r < 0) + free(value); + + return r; +} + +int strv_consume_prepend(char ***l, char *value) { + int r; + + r = strv_push_prepend(l, value); + if (r < 0) + free(value); + + return r; +} + int strv_extend(char ***l, const char *value) { char *v; - int r; if (!value) return 0; @@ -454,11 +432,7 @@ int strv_extend(char ***l, const char *value) { if (!v) return -ENOMEM; - r = strv_push(l, v); - if (r < 0) - free(v); - - return r; + return strv_consume(l, v); } char **strv_uniq(char **l) { @@ -484,40 +458,11 @@ char **strv_remove(char **l, const char *s) { /* Drops every occurrence of s in the string list, edits * in-place. */ - for (f = t = l; *f; f++) { - - if (streq(*f, s)) { + for (f = t = l; *f; f++) + if (streq(*f, s)) free(*f); - continue; - } - - *(t++) = *f; - } - - *t = NULL; - return l; -} - -char **strv_remove_prefix(char **l, const char *s) { - char **f, **t; - - if (!l) - return NULL; - - assert(s); - - /* Drops every occurrence of a string prefixed with s in the - * string list, edits in-place. */ - - for (f = t = l; *f; f++) { - - if (startswith(*f, s)) { - free(*f); - continue; - } - - *(t++) = *f; - } + else + *(t++) = *f; *t = NULL; return l; @@ -586,14 +531,11 @@ char **strv_split_nulstr(const char *s) { } bool strv_overlap(char **a, char **b) { - char **i, **j; + char **i; - STRV_FOREACH(i, a) { - STRV_FOREACH(j, b) { - if (streq(*i, *j)) - return true; - } - } + STRV_FOREACH(i, a) + if (strv_contains(b, *i)) + return true; return false; } @@ -616,9 +558,21 @@ char **strv_sort(char **l) { void strv_print(char **l) { char **s; - if (!l) - return; - STRV_FOREACH(s, l) puts(*s); } + +int strv_extendf(char ***l, const char *format, ...) { + va_list ap; + char *x; + int r; + + va_start(ap, format); + r = vasprintf(&x, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return strv_consume(l, x); +}