]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strv.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include "alloc-util.h"
30 #include "extract-word.h"
32 #include "string-util.h"
36 char *strv_find(char **l
, const char *name
) {
48 char *strv_find_prefix(char **l
, const char *name
) {
54 if (startswith(*i
, name
))
60 char *strv_find_startswith(char **l
, const char *name
) {
65 /* Like strv_find_prefix, but actually returns only the
66 * suffix, not the whole item */
69 e
= startswith(*i
, name
);
77 void strv_clear(char **l
) {
89 char **strv_free(char **l
) {
94 char **strv_free_erase(char **l
) {
103 char **strv_copy(char * const *l
) {
106 k
= r
= new(char*, strv_length(l
) + 1);
111 for (; *l
; k
++, l
++) {
123 unsigned strv_length(char * const *l
) {
135 char **strv_new_ap(const char *x
, va_list ap
) {
138 unsigned n
= 0, i
= 0;
141 /* As a special trick we ignore all listed strings that equal
142 * STRV_IGNORE. This is supposed to be used with the
143 * STRV_IFNOTNULL() macro to include possibly NULL strings in
144 * the string list. */
147 n
= x
== STRV_IGNORE
? 0 : 1;
150 while ((s
= va_arg(aq
, const char*))) {
151 if (s
== STRV_IGNORE
)
165 if (x
!= STRV_IGNORE
) {
172 while ((s
= va_arg(ap
, const char*))) {
174 if (s
== STRV_IGNORE
)
194 char **strv_new(const char *x
, ...) {
199 r
= strv_new_ap(x
, ap
);
205 int strv_extend_strv(char ***a
, char **b
, bool filter_duplicates
) {
207 size_t p
, q
, i
= 0, j
;
217 t
= realloc(*a
, sizeof(char*) * (p
+ q
+ 1));
226 if (filter_duplicates
&& strv_contains(t
, *s
))
242 for (j
= 0; j
< i
; j
++)
249 int strv_extend_strv_concat(char ***a
, char **b
, const char *suffix
) {
256 v
= strappend(*s
, suffix
);
270 char **strv_split(const char *s
, const char *separator
) {
271 const char *word
, *state
;
279 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
)
287 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
) {
288 r
[i
] = strndup(word
, l
);
301 char **strv_split_newlines(const char *s
) {
307 /* Special version of strv_split() that splits on newlines and
308 * suppresses an empty string at the end */
310 l
= strv_split(s
, NEWLINE
);
318 if (isempty(l
[n
- 1]))
319 l
[n
- 1] = mfree(l
[n
- 1]);
324 int strv_split_extract(char ***t
, const char *s
, const char *separators
, ExtractFlags flags
) {
325 _cleanup_strv_free_
char **l
= NULL
;
326 size_t n
= 0, allocated
= 0;
333 _cleanup_free_
char *word
= NULL
;
335 r
= extract_first_word(&s
, &word
, separators
, flags
);
341 if (!GREEDY_REALLOC(l
, allocated
, n
+ 2))
362 char *strv_join(char **l
, const char *separator
) {
370 k
= strlen(separator
);
386 e
= stpcpy(e
, separator
);
396 char *strv_join_quoted(char **l
) {
399 size_t allocated
= 0, len
= 0;
402 /* assuming here that escaped string cannot be more
403 * than twice as long, and reserving space for the
404 * separator and quotes.
406 _cleanup_free_
char *esc
= NULL
;
409 if (!GREEDY_REALLOC(buf
, allocated
,
410 len
+ strlen(*s
) * 2 + 3))
417 needed
= snprintf(buf
+ len
, allocated
- len
, "%s\"%s\"",
418 len
> 0 ? " " : "", esc
);
419 assert(needed
< allocated
- len
);
432 int strv_push(char ***l
, char *value
) {
441 /* Increase and check for overflow */
446 c
= realloc_multiply(*l
, sizeof(char*), m
);
457 int strv_push_pair(char ***l
, char *a
, char *b
) {
466 /* increase and check for overflow */
467 m
= n
+ !!a
+ !!b
+ 1;
471 c
= realloc_multiply(*l
, sizeof(char*), m
);
485 int strv_push_prepend(char ***l
, char *value
) {
494 /* increase and check for overflow */
503 for (i
= 0; i
< n
; i
++)
515 int strv_consume(char ***l
, char *value
) {
518 r
= strv_push(l
, value
);
525 int strv_consume_pair(char ***l
, char *a
, char *b
) {
528 r
= strv_push_pair(l
, a
, b
);
537 int strv_consume_prepend(char ***l
, char *value
) {
540 r
= strv_push_prepend(l
, value
);
547 int strv_extend(char ***l
, const char *value
) {
557 return strv_consume(l
, v
);
560 int strv_extend_front(char ***l
, const char *value
) {
566 /* Like strv_extend(), but prepends rather than appends the new entry */
573 /* Increase and overflow check. */
582 c
= realloc_multiply(*l
, sizeof(char*), m
);
588 memmove(c
+1, c
, n
* sizeof(char*));
596 char **strv_uniq(char **l
) {
599 /* Drops duplicate entries. The first identical string will be
600 * kept, the others dropped */
603 strv_remove(i
+1, *i
);
608 bool strv_is_uniq(char **l
) {
612 if (strv_find(i
+1, *i
))
618 char **strv_remove(char **l
, const char *s
) {
626 /* Drops every occurrence of s in the string list, edits
629 for (f
= t
= l
; *f
; f
++)
639 char **strv_parse_nulstr(const char *s
, size_t l
) {
640 /* l is the length of the input data, which will be split at NULs into
641 * elements of the resulting strv. Hence, the number of items in the resulting strv
642 * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
643 * unless s[l-1] is NUL, in which case the final empty string is not stored in
644 * the resulting strv, and length is equal to the number of NUL bytes.
646 * Note that contrary to a normal nulstr which cannot contain empty strings, because
647 * the input data is terminated by any two consequent NUL bytes, this parser accepts
648 * empty strings in s.
652 unsigned c
= 0, i
= 0;
658 return new0(char*, 1);
660 for (p
= s
; p
< s
+ l
; p
++)
667 v
= new0(char*, c
+1);
675 e
= memchr(p
, 0, s
+ l
- p
);
677 v
[i
] = strndup(p
, e
? e
- p
: s
+ l
- p
);
696 char **strv_split_nulstr(const char *s
) {
701 if (strv_extend(&r
, i
) < 0) {
707 return strv_new(NULL
, NULL
);
712 int strv_make_nulstr(char **l
, char **p
, size_t *q
) {
713 /* A valid nulstr with two NULs at the end will be created, but
714 * q will be the length without the two trailing NULs. Thus the output
715 * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
716 * and can also be parsed by strv_parse_nulstr as long as the length
717 * is provided separately.
720 size_t n_allocated
= 0, n
= 0;
721 _cleanup_free_
char *m
= NULL
;
732 if (!GREEDY_REALLOC(m
, n_allocated
, n
+ z
+ 2))
735 memcpy(m
+ n
, *i
, z
+ 1);
745 /* make sure there is a second extra NUL at the end of resulting nulstr */
757 bool strv_overlap(char **a
, char **b
) {
761 if (strv_contains(b
, *i
))
767 static int str_compare(const void *_a
, const void *_b
) {
768 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
770 return strcmp(*a
, *b
);
773 char **strv_sort(char **l
) {
774 qsort_safe(l
, strv_length(l
), sizeof(char*), str_compare
);
778 bool strv_equal(char **a
, char **b
) {
781 return strv_isempty(b
);
786 for ( ; *a
|| *b
; ++a
, ++b
)
787 if (!streq_ptr(*a
, *b
))
793 void strv_print(char **l
) {
800 int strv_extendf(char ***l
, const char *format
, ...) {
805 va_start(ap
, format
);
806 r
= vasprintf(&x
, format
, ap
);
812 return strv_consume(l
, x
);
815 char **strv_reverse(char **l
) {
822 for (i
= 0; i
< n
/ 2; i
++)
823 SWAP_TWO(l
[i
], l
[n
-1-i
]);
828 char **strv_shell_escape(char **l
, const char *bad
) {
831 /* Escapes every character in every string in l that is in bad,
832 * edits in-place, does not roll-back on error. */
837 v
= shell_escape(*s
, bad
);
848 bool strv_fnmatch(char* const* patterns
, const char *s
, int flags
) {
851 STRV_FOREACH(p
, patterns
)
852 if (fnmatch(*p
, s
, flags
) == 0)
858 char ***strv_free_free(char ***l
) {
870 char **strv_skip(char **l
, size_t n
) {
882 int strv_extend_n(char ***l
, const char *value
, size_t n
) {
893 /* Adds the value n times to l */
897 nl
= realloc(*l
, sizeof(char*) * (k
+ n
+ 1));
903 for (i
= k
; i
< k
+ n
; i
++) {
904 nl
[i
] = strdup(value
);
913 for (j
= k
; j
< i
; j
++)
920 int fputstrv(FILE *f
, char **l
, const char *separator
, bool *space
) {
925 /* Like fputs(), but for strv, and with a less stupid argument order */
931 r
= fputs_with_space(f
, *s
, separator
, space
);