X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbasic%2Fstrv.c;h=f0c764b17ae16dc74cd53a485d8dcf78f21bc57c;hb=9800a6ceb4801bb1f3e851b2244c84a8d8f116b1;hp=251031e012c078fdb4f597f3d25d09599edaa923;hpb=7a6781d5aa01c5609232f60bbda7ba9a5bd1f74c;p=elogind.git diff --git a/src/basic/strv.c b/src/basic/strv.c index 251031e01..f0c764b17 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -87,8 +87,7 @@ void strv_clear(char **l) { char **strv_free(char **l) { strv_clear(l); - free(l); - return NULL; + return mfree(l); } char **strv_free_erase(char **l) { @@ -323,6 +322,7 @@ char **strv_split_newlines(const char *s) { return l; } +#endif // 0 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) { _cleanup_strv_free_ char **l = NULL; @@ -361,7 +361,6 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract return (int) n; } -#endif // 0 char *strv_join(char **l, const char *separator) { char *r, *e; @@ -431,8 +430,7 @@ char *strv_join_quoted(char **l) { return buf; oom: - free(buf); - return NULL; + return mfree(buf); } #endif // 0 @@ -648,6 +646,17 @@ char **strv_remove(char **l, const char *s) { } char **strv_parse_nulstr(const char *s, size_t l) { + /* l is the length of the input data, which will be split at NULs into + * elements of the resulting strv. Hence, the number of items in the resulting strv + * will be equal to one plus the number of NUL bytes in the l bytes starting at s, + * unless s[l-1] is NUL, in which case the final empty string is not stored in + * the resulting strv, and length is equal to the number of NUL bytes. + * + * Note that contrary to a normal nulstr which cannot contain empty strings, because + * the input data is terminated by any two consequent NUL bytes, this parser accepts + * empty strings in s. + */ + const char *p; unsigned c = 0, i = 0; char **v; @@ -711,6 +720,13 @@ char **strv_split_nulstr(const char *s) { #if 0 /// UNNEEDED by elogind int strv_make_nulstr(char **l, char **p, size_t *q) { + /* A valid nulstr with two NULs at the end will be created, but + * q will be the length without the two trailing NULs. Thus the output + * string is a valid nulstr and can be iterated over using NULSTR_FOREACH, + * and can also be parsed by strv_parse_nulstr as long as the length + * is provided separately. + */ + size_t n_allocated = 0, n = 0; _cleanup_free_ char *m = NULL; char **i; @@ -723,7 +739,7 @@ int strv_make_nulstr(char **l, char **p, size_t *q) { z = strlen(*i); - if (!GREEDY_REALLOC(m, n_allocated, n + z + 1)) + if (!GREEDY_REALLOC(m, n_allocated, n + z + 2)) return -ENOMEM; memcpy(m + n, *i, z + 1); @@ -734,11 +750,14 @@ int strv_make_nulstr(char **l, char **p, size_t *q) { m = new0(char, 1); if (!m) return -ENOMEM; - n = 0; - } + n = 1; + } else + /* make sure there is a second extra NUL at the end of resulting nulstr */ + m[n] = '\0'; + assert(n > 0); *p = m; - *q = n; + *q = n - 1; m = NULL; @@ -763,15 +782,10 @@ static int str_compare(const void *_a, const void *_b) { } char **strv_sort(char **l) { - - if (strv_isempty(l)) - return l; - - qsort(l, strv_length(l), sizeof(char*), str_compare); + qsort_safe(l, strv_length(l), sizeof(char*), str_compare); return l; } -#if 0 /// UNNEEDED by elogind bool strv_equal(char **a, char **b) { if (strv_isempty(a)) @@ -794,6 +808,7 @@ void strv_print(char **l) { puts(*s); } +#if 0 /// UNNEEDED by elogind int strv_extendf(char ***l, const char *format, ...) { va_list ap; char *x; @@ -861,8 +876,7 @@ char ***strv_free_free(char ***l) { for (i = l; *i; i++) strv_free(*i); - free(l); - return NULL; + return mfree(l); } char **strv_skip(char **l, size_t n) {