X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbasic%2Fstrv.c;h=7757a444346725fa448bee8b8525eb443099aecd;hb=c6ac7991dc7a5b7a35d446bf211c947611418b70;hp=9decbb4190c4282352900679fe01ce1c8db91a03;hpb=c286398e07a7a16aa88a3437318cb2edf8c082c1;p=elogind.git
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 9decbb419..7757a4443 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
@@ -19,13 +17,20 @@
along with systemd; If not, see .
***/
-#include
+#include
+#include
#include
+#include
+#include
#include
-#include
-#include "util.h"
+#include "alloc-util.h"
+#include "escape.h"
+#include "extract-word.h"
+//#include "fileio.h"
+#include "string-util.h"
#include "strv.h"
+#include "util.h"
char *strv_find(char **l, const char *name) {
char **i;
@@ -86,6 +91,15 @@ char **strv_free(char **l) {
return NULL;
}
+char **strv_free_erase(char **l) {
+ char **i;
+
+ STRV_FOREACH(i, l)
+ string_erase(*i);
+
+ return strv_free(l);
+}
+
char **strv_copy(char * const *l) {
char **r, **k;
@@ -188,21 +202,51 @@ char **strv_new(const char *x, ...) {
return r;
}
-int strv_extend_strv(char ***a, char **b) {
- int r;
- char **s;
+#if 0 /// UNNEEDED by elogind
+int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
+ char **s, **t;
+ size_t p, q, i = 0, j;
+
+ assert(a);
+
+ if (strv_isempty(b))
+ return 0;
+
+ p = strv_length(*a);
+ q = strv_length(b);
+
+ t = realloc(*a, sizeof(char*) * (p + q + 1));
+ if (!t)
+ return -ENOMEM;
+
+ t[p] = NULL;
+ *a = t;
STRV_FOREACH(s, b) {
- r = strv_extend(a, *s);
- if (r < 0)
- return r;
+
+ if (filter_duplicates && strv_contains(t, *s))
+ continue;
+
+ t[p+i] = strdup(*s);
+ if (!t[p+i])
+ goto rollback;
+
+ i++;
+ t[p+i] = NULL;
}
- return 0;
+ assert(i <= q);
+
+ return (int) i;
+
+rollback:
+ for (j = 0; j < i; j++)
+ free(t[p + j]);
+
+ t[p] = NULL;
+ return -ENOMEM;
}
-/// UNNEEDED by elogind
-#if 0
int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
int r;
char **s;
@@ -256,8 +300,7 @@ char **strv_split(const char *s, const char *separator) {
return r;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
char **strv_split_newlines(const char *s) {
char **l;
unsigned n;
@@ -275,17 +318,15 @@ char **strv_split_newlines(const char *s) {
if (n <= 0)
return l;
- if (isempty(l[n-1])) {
- free(l[n-1]);
- l[n-1] = NULL;
- }
+ if (isempty(l[n - 1]))
+ l[n-1] = mfree(l[n-1]);
return l;
}
int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
- size_t n = 0, allocated = 0;
_cleanup_strv_free_ char **l = NULL;
+ size_t n = 0, allocated = 0;
int r;
assert(t);
@@ -297,9 +338,8 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract
r = extract_first_word(&s, &word, separators, flags);
if (r < 0)
return r;
- if (r == 0) {
+ if (r == 0)
break;
- }
if (!GREEDY_REALLOC(l, allocated, n + 2))
return -ENOMEM;
@@ -310,13 +350,16 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract
l[n] = NULL;
}
- if (!l)
+ if (!l) {
l = new0(char*, 1);
+ if (!l)
+ return -ENOMEM;
+ }
*t = l;
l = NULL;
- return 0;
+ return (int) n;
}
#endif // 0
@@ -332,7 +375,7 @@ char *strv_join(char **l, const char *separator) {
n = 0;
STRV_FOREACH(s, l) {
- if (n != 0)
+ if (s != l)
n += k;
n += strlen(*s);
}
@@ -343,7 +386,7 @@ char *strv_join(char **l, const char *separator) {
e = r;
STRV_FOREACH(s, l) {
- if (e != r)
+ if (s != l)
e = stpcpy(e, separator);
e = stpcpy(e, *s);
@@ -354,8 +397,7 @@ char *strv_join(char **l, const char *separator) {
return r;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
char *strv_join_quoted(char **l) {
char *buf = NULL;
char **s;
@@ -487,8 +529,7 @@ int strv_consume(char ***l, char *value) {
return r;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
int strv_consume_pair(char ***l, char *a, char *b) {
int r;
@@ -525,6 +566,42 @@ int strv_extend(char ***l, const char *value) {
return strv_consume(l, v);
}
+int strv_extend_front(char ***l, const char *value) {
+ size_t n, m;
+ char *v, **c;
+
+ assert(l);
+
+ /* Like strv_extend(), but prepends rather than appends the new entry */
+
+ if (!value)
+ return 0;
+
+ n = strv_length(*l);
+
+ /* Increase and overflow check. */
+ m = n + 2;
+ if (m < n)
+ return -ENOMEM;
+
+ v = strdup(value);
+ if (!v)
+ return -ENOMEM;
+
+ c = realloc_multiply(*l, sizeof(char*), m);
+ if (!c) {
+ free(v);
+ return -ENOMEM;
+ }
+
+ memmove(c+1, c, n * sizeof(char*));
+ c[0] = v;
+ c[n+1] = NULL;
+
+ *l = c;
+ return 0;
+}
+
char **strv_uniq(char **l) {
char **i;
@@ -537,8 +614,7 @@ char **strv_uniq(char **l) {
return l;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
bool strv_is_uniq(char **l) {
char **i;
@@ -633,8 +709,42 @@ char **strv_split_nulstr(const char *s) {
return r;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
+int strv_make_nulstr(char **l, char **p, size_t *q) {
+ size_t n_allocated = 0, n = 0;
+ _cleanup_free_ char *m = NULL;
+ char **i;
+
+ assert(p);
+ assert(q);
+
+ STRV_FOREACH(i, l) {
+ size_t z;
+
+ z = strlen(*i);
+
+ if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
+ return -ENOMEM;
+
+ memcpy(m + n, *i, z + 1);
+ n += z + 1;
+ }
+
+ if (!m) {
+ m = new0(char, 1);
+ if (!m)
+ return -ENOMEM;
+ n = 0;
+ }
+
+ *p = m;
+ *q = n;
+
+ m = NULL;
+
+ return 0;
+}
+
bool strv_overlap(char **a, char **b) {
char **i;
@@ -644,6 +754,7 @@ bool strv_overlap(char **a, char **b) {
return false;
}
+#endif // 0
static int str_compare(const void *_a, const void *_b) {
const char **a = (const char**) _a, **b = (const char**) _b;
@@ -660,9 +771,14 @@ char **strv_sort(char **l) {
return l;
}
+#if 0 /// UNNEEDED by elogind
bool strv_equal(char **a, char **b) {
- if (!a || !b)
- return a == b;
+
+ if (strv_isempty(a))
+ return strv_isempty(b);
+
+ if (strv_isempty(b))
+ return false;
for ( ; *a || *b; ++a, ++b)
if (!streq_ptr(*a, *b))
@@ -730,7 +846,6 @@ char **strv_shell_escape(char **l, const char *bad) {
return l;
}
-#endif // 0
bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
char* const* p;
@@ -741,3 +856,86 @@ bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
return false;
}
+
+char ***strv_free_free(char ***l) {
+ char ***i;
+
+ if (!l)
+ return NULL;
+
+ for (i = l; *i; i++)
+ strv_free(*i);
+
+ free(l);
+ return NULL;
+}
+
+char **strv_skip(char **l, size_t n) {
+
+ while (n > 0) {
+ if (strv_isempty(l))
+ return l;
+
+ l++, n--;
+ }
+
+ return l;
+}
+
+int strv_extend_n(char ***l, const char *value, size_t n) {
+ size_t i, j, k;
+ char **nl;
+
+ assert(l);
+
+ if (!value)
+ return 0;
+ if (n == 0)
+ return 0;
+
+ /* Adds the value value n times to l */
+
+ k = strv_length(*l);
+
+ nl = realloc(*l, sizeof(char*) * (k + n + 1));
+ if (!nl)
+ return -ENOMEM;
+
+ *l = nl;
+
+ for (i = k; i < k + n; i++) {
+ nl[i] = strdup(value);
+ if (!nl[i])
+ goto rollback;
+ }
+
+ nl[i] = NULL;
+ return 0;
+
+rollback:
+ for (j = k; j < i; j++)
+ free(nl[j]);
+
+ nl[k] = NULL;
+ return -ENOMEM;
+}
+
+int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
+ bool b = false;
+ char **s;
+ int r;
+
+ /* Like fputs(), but for strv, and with a less stupid argument order */
+
+ if (!space)
+ space = &b;
+
+ STRV_FOREACH(s, l) {
+ r = fputs_with_space(f, *s, separator, space);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+#endif // 0