X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fstrv.c;h=a66369602bbbc98051fbd675628fcfdc1dea47f9;hp=2ebd0ee53a92199d4cd59b3d960bec9c18751ce3;hb=f60f22dfbb8cfa0eb55d1896db0e4c3f7d3cfacb;hpb=a4bfb3990be698b1f5c691a73823c040ffe919d5 diff --git a/src/strv.c b/src/strv.c index 2ebd0ee53..a66369602 100644 --- a/src/strv.c +++ b/src/strv.c @@ -264,7 +264,7 @@ char **strv_split_quoted(const char *s) { i = 0; FOREACH_WORD_QUOTED(w, l, s, state) - if (!(r[i++] = strndup(w, l))) { + if (!(r[i++] = cunescape_length(w, l))) { strv_free(r); return NULL; } @@ -374,7 +374,9 @@ char **strv_remove(char **l, const char *s) { static int env_append(char **r, char ***k, char **a) { assert(r); assert(k); - assert(a); + + if (!a) + return 0; /* Add the entries of a to *k unless they already exist in *r * in which case they are overriden instead. This assumes @@ -400,38 +402,33 @@ static int env_append(char **r, char ***k, char **a) { return 0; } -char **strv_env_merge(char **x, ...) { +char **strv_env_merge(unsigned n_lists, ...) { size_t n = 0; char **l, **k, **r; va_list ap; + unsigned i; /* Merges an arbitrary number of environment sets */ - if (x) { - n += strv_length(x); - - va_start(ap, x); - while ((l = va_arg(ap, char**))) - n += strv_length(l); - va_end(ap); + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + n += strv_length(l); } - + va_end(ap); if (!(r = new(char*, n+1))) return NULL; k = r; - if (x) { - if (env_append(r, &k, x) < 0) + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + if (env_append(r, &k, l) < 0) goto fail; - - va_start(ap, x); - while ((l = va_arg(ap, char**))) - if (env_append(r, &k, l) < 0) - goto fail; - va_end(ap); } + va_end(ap); *k = NULL; @@ -472,7 +469,7 @@ static bool env_match(const char *t, const char *pattern) { return false; } -char **strv_env_delete(char **x, ...) { +char **strv_env_delete(char **x, unsigned n_lists, ...) { size_t n = 0, i = 0; char **l, **k, **r, **j; va_list ap; @@ -486,12 +483,14 @@ char **strv_env_delete(char **x, ...) { return NULL; STRV_FOREACH(k, x) { - va_start(ap, x); + va_start(ap, n_lists); - while ((l = va_arg(ap, char**))) + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); STRV_FOREACH(j, l) if (env_match(*k, *j)) goto delete; + } va_end(ap); @@ -512,3 +511,31 @@ char **strv_env_delete(char **x, ...) { return r; } + +char **strv_env_set(char **x, const char *p) { + + char **k, **r; + + if (!(r = new(char*, strv_length(x)+2))) + return NULL; + + k = r; + if (env_append(r, &k, x) < 0) + goto fail; + + if (!(*(k++) = strdup(p))) + goto fail; + + *k = NULL; + + return r; + +fail: + for (k--; k >= r; k--) + free(*k); + + free(r); + + return NULL; + +}