]>
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_ap(const char *x
, va_list ap
) {
91 unsigned n
= 0, i
= 0;
99 while (va_arg(aq
, const char*))
104 if (!(a
= new(char*, n
+1)))
108 if (!(a
[i
] = strdup(x
))) {
115 while ((s
= va_arg(ap
, const char*))) {
116 if (!(a
[i
] = strdup(s
)))
138 char **strv_new(const char *x
, ...) {
143 r
= strv_new_ap(x
, ap
);
149 char **strv_merge(char **a
, char **b
) {
158 if (!(r
= new(char*, strv_length(a
)+strv_length(b
)+1)))
161 for (k
= r
; *a
; k
++, a
++)
162 if (!(*k
= strdup(*a
)))
165 if (!(*k
= strdup(*b
)))
172 for (k
--; k
>= r
; k
--)
180 char **strv_merge_concat(char **a
, char **b
, const char *suffix
) {
183 /* Like strv_merge(), but appends suffix to all strings in b, before adding */
188 if (!(r
= new(char*, strv_length(a
)+strv_length(b
)+1)))
191 for (k
= r
; *a
; k
++, a
++)
192 if (!(*k
= strdup(*a
)))
195 if (!(*k
= strappend(*b
, suffix
)))
202 for (k
--; k
>= r
; k
--)
211 char **strv_split(const char *s
, const char *separator
) {
221 FOREACH_WORD_SEPARATOR(w
, l
, s
, separator
, state
)
224 if (!(r
= new(char*, n
+1)))
228 FOREACH_WORD_SEPARATOR(w
, l
, s
, separator
, state
)
229 if (!(r
[i
++] = strndup(w
, l
))) {
238 char **strv_split_quoted(const char *s
) {
248 FOREACH_WORD_QUOTED(w
, l
, s
, state
)
251 if (!(r
= new(char*, n
+1)))
255 FOREACH_WORD_QUOTED(w
, l
, s
, state
)
256 if (!(r
[i
++] = strndup(w
, l
))) {
265 char *strv_join(char **l
, const char *separator
) {
273 k
= strlen(separator
);
282 if (!(r
= new(char, n
+1)))
288 e
= stpcpy(e
, separator
);
298 char **strv_append(char **l
, const char *s
) {
302 return strv_new(s
, NULL
);
307 if (!(r
= new(char*, strv_length(l
)+2)))
310 for (k
= r
; *l
; k
++, l
++)
311 if (!(*k
= strdup(*l
)))
314 if (!(*(k
++) = strdup(s
)))
321 for (k
--; k
>= r
; k
--)
329 char **strv_uniq(char **l
) {
332 /* Drops duplicate entries. The first identical string will be
333 * kept, the others dropped */
336 strv_remove(i
+1, *i
);
341 char **strv_remove(char **l
, const char *s
) {
347 /* Drops every occurence of s in the string list */
349 for (f
= t
= l
; *f
; f
++) {
363 static int env_append(char **r
, char ***k
, char **a
) {
368 /* Add the entries of a to *k unless they already exist in *r
369 * in which case they are overriden instead. This assumes
370 * there is enough space in the r */
374 size_t n
= strcspn(*a
, "=") + 1;
376 for (j
= r
; j
< *k
; j
++)
377 if (strncmp(*j
, *a
, n
) == 0)
385 if (!(*j
= strdup(*a
)))
392 char **strv_env_merge(char **x
, ...) {
397 /* Merges an arbitrary number of environment sets */
403 while ((l
= va_arg(ap
, char**)))
409 if (!(r
= new(char*, n
+1)))
415 if (env_append(r
, &k
, x
) < 0)
419 while ((l
= va_arg(ap
, char**)))
420 if (env_append(r
, &k
, l
) < 0)
430 for (k
--; k
>= r
; k
--)