+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
char **strv_free(char **l) {
strv_clear(l);
- free(l);
- return NULL;
+ return mfree(l);
}
char **strv_free_erase(char **l) {
p = strv_length(*a);
q = strv_length(b);
- t = realloc(*a, sizeof(char*) * (p + q + 1));
+ t = reallocarray(*a, p + q + 1, sizeof(char *));
if (!t)
return -ENOMEM;
if (!GREEDY_REALLOC(l, allocated, n + 2))
return -ENOMEM;
- l[n++] = word;
- word = NULL;
+ l[n++] = TAKE_PTR(word);
l[n] = NULL;
}
return -ENOMEM;
}
- *t = l;
- l = NULL;
+ *t = TAKE_PTR(l);
return (int) n;
}
return r;
}
-char *strv_join_quoted(char **l) {
- char *buf = NULL;
- char **s;
- size_t allocated = 0, len = 0;
-
- STRV_FOREACH(s, l) {
- /* assuming here that escaped string cannot be more
- * than twice as long, and reserving space for the
- * separator and quotes.
- */
- _cleanup_free_ char *esc = NULL;
- size_t needed;
-
- if (!GREEDY_REALLOC(buf, allocated,
- len + strlen(*s) * 2 + 3))
- goto oom;
-
- esc = cescape(*s);
- if (!esc)
- goto oom;
-
- needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
- len > 0 ? " " : "", esc);
- assert(needed < allocated - len);
- len += needed;
- }
-
- if (!buf)
- buf = malloc0(1);
-
- return buf;
-
- oom:
- free(buf);
- return NULL;
-}
-
int strv_push(char ***l, char *value) {
char **c;
unsigned n, m;
if (m < n)
return -ENOMEM;
- c = realloc_multiply(*l, sizeof(char*), m);
+ c = reallocarray(*l, m, sizeof(char*));
if (!c)
return -ENOMEM;
if (m < n)
return -ENOMEM;
- c = realloc_multiply(*l, sizeof(char*), m);
+ c = reallocarray(*l, m, sizeof(char*));
if (!c)
return -ENOMEM;
return 0;
}
-int strv_push_prepend(char ***l, char *value) {
+int strv_insert(char ***l, unsigned position, char *value) {
char **c;
unsigned n, m, i;
return 0;
n = strv_length(*l);
+ position = MIN(position, n);
/* increase and check for overflow */
m = n + 2;
if (!c)
return -ENOMEM;
- for (i = 0; i < n; i++)
+ for (i = 0; i < position; i++)
+ c[i] = (*l)[i];
+ c[position] = value;
+ for (i = position; i < n; i++)
c[i+1] = (*l)[i];
- c[0] = value;
c[n+1] = NULL;
free(*l);
if (!v)
return -ENOMEM;
- c = realloc_multiply(*l, sizeof(char*), m);
+ c = reallocarray(*l, m, sizeof(char*));
if (!c) {
free(v);
return -ENOMEM;
}
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;
}
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;
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);
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;
}
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 (n <= 1)
return l;
- for (i = 0; i < n / 2; i++) {
+ for (i = 0; i < n / 2; i++)
SWAP_TWO(l[i], l[n-1-i]);
- }
return l;
}
for (i = l; *i; i++)
strv_free(*i);
- free(l);
- return NULL;
+ return mfree(l);
}
char **strv_skip(char **l, size_t n) {
k = strv_length(*l);
- nl = realloc(*l, sizeof(char*) * (k + n + 1));
+ nl = reallocarray(*l, k + n + 1, sizeof(char *));
if (!nl)
return -ENOMEM;