]>
git.ipfire.org Git - people/ms/systemd.git/blob - strv.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 char *strv_find(char **l
, const char *name
) {
44 void strv_free(char **l
) {
56 char **strv_copy(char **l
) {
59 if (!(r
= new(char*, strv_length(l
)+1)))
62 for (k
= r
; *l
; k
++, l
++)
63 if (!(*k
= strdup(*l
)))
70 for (k
--, l
--; k
>= r
; k
--, l
--)
76 unsigned strv_length(char **l
) {
88 char **strv_new(const char *x
, ...) {
91 unsigned n
= 0, i
= 0;
99 while (va_arg(ap
, const char*))
105 if (!(a
= new(char*, n
+1)))
109 if (!(a
[i
] = strdup(x
))) {
118 while ((s
= va_arg(ap
, const char*))) {
119 if (!(a
[i
] = strdup(s
)))
141 char **strv_merge(char **a
, char **b
) {
150 if (!(r
= new(char*, strv_length(a
)+strv_length(b
)+1)))
153 for (k
= r
; *a
; k
++, a
++)
154 if (!(*k
= strdup(*a
)))
157 if (!(*k
= strdup(*b
)))
164 for (k
--; k
>= r
; k
--)
172 char **strv_merge_concat(char **a
, char **b
, const char *suffix
) {
175 /* Like strv_merge(), but appends suffix to all strings in b, before adding */
180 if (!(r
= new(char*, strv_length(a
)+strv_length(b
)+1)))
183 for (k
= r
; *a
; k
++, a
++)
184 if (!(*k
= strdup(*a
)))
187 if (!(*k
= strappend(*b
, suffix
)))
194 for (k
--; k
>= r
; k
--)
203 char **strv_split(const char *s
, const char *separator
) {
213 FOREACH_WORD_SEPARATOR(w
, l
, s
, separator
, state
)
216 if (!(r
= new(char*, n
+1)))
220 FOREACH_WORD_SEPARATOR(w
, l
, s
, separator
, state
)
221 if (!(r
[i
++] = strndup(w
, l
))) {
230 char **strv_split_quoted(const char *s
) {
240 FOREACH_WORD_QUOTED(w
, l
, s
, state
)
243 if (!(r
= new(char*, n
+1)))
247 FOREACH_WORD_QUOTED(w
, l
, s
, state
)
248 if (!(r
[i
++] = strndup(w
, l
))) {
257 char *strv_join(char **l
, const char *separator
) {
265 k
= strlen(separator
);
274 if (!(r
= new(char, n
+1)))
280 e
= stpcpy(e
, separator
);
290 char **strv_append(char **l
, const char *s
) {
294 return strv_new(s
, NULL
);
299 if (!(r
= new(char*, strv_length(l
)+2)))
302 for (k
= r
; *l
; k
++, l
++)
303 if (!(*k
= strdup(*l
)))
306 if (!(*(k
++) = strdup(s
)))
313 for (k
--; k
>= r
; k
--)
321 char **strv_uniq(char **l
) {
324 /* Drops duplicate entries. The first identical string will be
325 * kept, the others dropped */
328 strv_remove(i
+1, *i
);
333 char **strv_remove(char **l
, const char *s
) {
339 /* Drops every occurence of s in the string list */
341 for (f
= t
= l
; *f
; f
++) {
355 static int env_append(char **r
, char ***k
, char **a
) {
360 /* Add the entries of a to *k unless they already exist in *r
361 * in which case they are overriden instead. This assumes
362 * there is enough space in the r */
366 size_t n
= strcspn(*a
, "=") + 1;
368 for (j
= r
; j
< *k
; j
++)
369 if (strncmp(*j
, *a
, n
) == 0)
377 if (!(*j
= strdup(*a
)))
384 char **strv_env_merge(char **x
, ...) {
389 /* Merges an arbitrary number of environment sets */
395 while ((l
= va_arg(ap
, char**)))
401 if (!(r
= new(char*, n
+1)))
407 if (env_append(r
, &k
, x
) < 0)
411 while ((l
= va_arg(ap
, char**)))
412 if (env_append(r
, &k
, l
) < 0)
422 for (k
--; k
>= r
; k
--)