strv.c revision e3ead6bb42f7c0f18d0ac100d33b71913fe4dcca
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell This file is part of systemd.
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell Copyright 2010 Lennart Poettering
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell systemd is free software; you can redistribute it and/or modify it
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell under the terms of the GNU Lesser General Public License as published by
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell the Free Software Foundation; either version 2.1 of the License, or
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell (at your option) any later version.
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell systemd is distributed in the hope that it will be useful, but
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell WITHOUT ANY WARRANTY; without even the implied warranty of
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell Lesser General Public License for more details.
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni You should have received a copy of the GNU Lesser General Public License
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell along with systemd; If not, see <http://www.gnu.org/licenses/>.
415243fbc81341293a852ff6aa14e9608d08685cCraig McDonnellchar *strv_find(char **l, const char *name) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshottchar *strv_find_prefix(char **l, const char *name) {
415243fbc81341293a852ff6aa14e9608d08685cCraig McDonnellchar *strv_find_startswith(char **l, const char *name) {
91f0e3cb60de3eba8cbb70c7e36cc0df22d71f5bRobert Wapshott char **i, *e;
415243fbc81341293a852ff6aa14e9608d08685cCraig McDonnell /* Like strv_find_prefix, but actually returns only the
415243fbc81341293a852ff6aa14e9608d08685cCraig McDonnell * suffix, not the whole item */
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantonivoid strv_clear(char **l) {
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni for (k = l; *k; k++)
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantonichar **strv_free(char **l) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshottchar **strv_copy(char * const *l) {
415243fbc81341293a852ff6aa14e9608d08685cCraig McDonnell char **r, **k;
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni for (; *l; k++, l++) {
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoniunsigned strv_length(char * const *l) {
415243fbc81341293a852ff6aa14e9608d08685cCraig McDonnell unsigned n = 0;
91f0e3cb60de3eba8cbb70c7e36cc0df22d71f5bRobert Wapshott for (; *l; l++)
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnellchar **strv_new_ap(const char *x, va_list ap) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell const char *s;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell unsigned n = 0, i = 0;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell /* As a special trick we ignore all listed strings that equal
2beebed98b4fc7f018fb224a1e4a3ab6103a4c0bCraig McDonnell * (const char*) -1. This is supposed to be used with the
return NULL;
a[i] = strdup(x);
goto fail;
a[i] = strdup(s);
goto fail;
a[i] = NULL;
fail:
strv_free(a);
return NULL;
char **strv_new(const char *x, ...) {
int strv_extend_strv(char ***a, char **b) {
STRV_FOREACH(s, b) {
r = strv_extend(a, *s);
STRV_FOREACH(s, b) {
return -ENOMEM;
r = strv_push(a, v);
free(v);
size_t l;
assert(s);
return NULL;
strv_free(r);
return NULL;
r[i] = NULL;
char **strv_split_newlines(const char *s) {
assert(s);
return NULL;
n = strv_length(l);
assert(t);
assert(s);
return -ENOMEM;
l[n++] = word;
l[n] = NULL;
l = NULL;
size_t n, k;
if (!separator)
STRV_FOREACH(s, l) {
n += strlen(*s);
return NULL;
STRV_FOREACH(s, l) {
e = stpcpy(e, *s);
char *strv_join_quoted(char **l) {
STRV_FOREACH(s, l) {
goto oom;
if (!esc)
goto oom;
if (!buf)
return buf;
oom:
return NULL;
if (!value)
n = strv_length(*l);
return -ENOMEM;
c = realloc_multiply(*l, sizeof(char*), m);
return -ENOMEM;
c[n] = value;
int strv_push_pair(char ***l, char *a, char *b) {
n = strv_length(*l);
return -ENOMEM;
c = realloc_multiply(*l, sizeof(char*), m);
return -ENOMEM;
c[n] = NULL;
if (!value)
n = strv_length(*l);
return -ENOMEM;
c = new(char*, m);
return -ENOMEM;
c[0] = value;
free(*l);
int strv_consume_pair(char ***l, char *a, char *b) {
r = strv_push_pair(l, a, b);
free(a);
free(b);
if (!value)
return -ENOMEM;
return strv_consume(l, v);
char **strv_uniq(char **l) {
STRV_FOREACH(i, l)
bool strv_is_uniq(char **l) {
STRV_FOREACH(i, l)
char **strv_remove(char **l, const char *s) {
return NULL;
assert(s);
if (streq(*f, s))
free(*f);
*t = NULL;
assert(s || l <= 0);
return NULL;
e = memchr(p, 0, s + l - p);
v[i] = strndup(p, e ? e - p : s + l - p);
strv_free(v);
return NULL;
assert(i == c);
char **strv_split_nulstr(const char *s) {
char **r = NULL;
NULSTR_FOREACH(i, s)
if (strv_extend(&r, i) < 0) {
strv_free(r);
return NULL;
bool strv_overlap(char **a, char **b) {
STRV_FOREACH(i, a)
if (strv_contains(b, *i))
return strcmp(*a, *b);
char **strv_sort(char **l) {
if (strv_isempty(l))
bool strv_equal(char **a, char **b) {
if (!streq_ptr(*a, *b))
void strv_print(char **l) {
STRV_FOREACH(s, l)
puts(*s);
return -ENOMEM;
return strv_consume(l, x);
char **strv_reverse(char **l) {
n = strv_length(l);
STRV_FOREACH(s, l) {
return NULL;
free(*s);
if (fnmatch(*p, s, 0) == 0)
char ***strv_free_free(char ***l) {
return NULL;
strv_free(*i);
free(l);
return NULL;
if (strv_isempty(l))