X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fstrv.c;h=0afd9865d9c7316fd35d155d6388182d64065091;hb=5d6ab905c00342d012aed559a859b373512e4650;hp=d1c7b2c32d89c31b121fc6ef1c0c719a9167c81c;hpb=a6ff950e71ea665fff99740f7b3e0137d451a79e;p=elogind.git diff --git a/src/strv.c b/src/strv.c index d1c7b2c32..0afd9865d 100644 --- a/src/strv.c +++ b/src/strv.c @@ -70,17 +70,20 @@ char **strv_copy(char **l) { if (!(r = new(char*, strv_length(l)+1))) return NULL; - for (k = r; *l; k++, l++) - if (!(*k = strdup(*l))) - goto fail; + if (l) + for (k = r; *l; k++, l++) + if (!(*k = strdup(*l))) + goto fail; *k = NULL; return r; fail: - for (k--, l--; k >= r; k--, l--) + for (k--; k >= r; k--) free(*k); + free(r); + return NULL; } @@ -355,7 +358,10 @@ char **strv_remove(char **l, const char *s) { if (!l) return NULL; - /* Drops every occurence of s in the string list */ + assert(s); + + /* Drops every occurrence of s in the string list, edits + * in-place. */ for (f = t = l; *f; f++) { @@ -379,12 +385,17 @@ static int env_append(char **r, char ***k, char **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 + * in which case they are overridden instead. This assumes * there is enough space in the r array. */ for (; *a; a++) { char **j; - size_t n = strcspn(*a, "=") + 1; + size_t n; + + n = strcspn(*a, "="); + + if ((*a)[n] == '=') + n++; for (j = r; j < *k; j++) if (strncmp(*j, *a, n) == 0) @@ -435,6 +446,8 @@ char **strv_env_merge(unsigned n_lists, ...) { return r; fail: + va_end(ap); + for (k--; k >= r; k--) free(*k); @@ -474,7 +487,7 @@ char **strv_env_delete(char **x, unsigned n_lists, ...) { char **l, **k, **r, **j; va_list ap; - /* Deletes every entry fromx that is mentioned in the other + /* Deletes every entry from x that is mentioned in the other * string lists */ n = strv_length(x); @@ -577,3 +590,45 @@ char **strv_env_clean(char **l) { return ret; } + +char **strv_parse_nulstr(const char *s, size_t l) { + const char *p; + unsigned c = 0, i = 0; + char **v; + + assert(s || l <= 0); + + if (l <= 0) + return strv_new(NULL, NULL); + + for (p = s; p < s + l; p++) + if (*p == 0) + c++; + + if (s[l-1] != 0) + c++; + + if (!(v = new0(char*, c+1))) + return NULL; + + p = s; + while (p < s + l) { + const char *e; + + e = memchr(p, 0, s + l - p); + + if (!(v[i++] = strndup(p, e ? e - p : s + l - p))) { + strv_free(v); + return NULL; + } + + if (!e) + break; + + p = e + 1; + } + + assert(i == c); + + return v; +}