]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/strv.c
2 * SPDX-License-Identifier: LGPL-2.1-or-later
4 * Copyright (C) 2010 Lennart Poettering
5 * Copyright (C) 2015-2022 Karel Zak <kzak@redhat.com>
7 * This 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.
13 * Copyright (C) 2015 Karel Zak <kzak@redhat.com>
14 * Modified the original version from systemd project for util-linux.
27 void strv_clear(char **l
) {
39 char **strv_free(char **l
) {
45 char **strv_copy(char * const *l
) {
48 k
= r
= malloc(sizeof(char *) * (strv_length(l
) + 1));
53 for (; *l
; k
++, l
++) {
65 unsigned strv_length(char * const *l
) {
77 char **strv_new_ap(const char *x
, va_list ap
) {
80 unsigned n
= 0, i
= 0;
83 /* As a special trick we ignore all listed strings that equal
84 * (const char*) -1. This is supposed to be used with the
85 * STRV_IFNOTNULL() macro to include possibly NULL strings in
89 n
= x
== (const char*) -1 ? 0 : 1;
92 while ((s
= va_arg(aq
, const char*))) {
93 if (s
== (const char*) -1)
102 a
= malloc(sizeof(char *) * (n
+ 1));
107 if (x
!= (const char*) -1) {
114 while ((s
= va_arg(ap
, const char*))) {
116 if (s
== (const char*) -1)
136 char **strv_new(const char *x
, ...) {
141 r
= strv_new_ap(x
, ap
);
147 int strv_extend_strv(char ***a
, char **b
) {
152 r
= strv_extend(a
, *s
);
160 int strv_extend_strv_concat(char ***a
, char **b
, const char *suffix
) {
167 v
= strconcat(*s
, suffix
);
182 #define _FOREACH_WORD(word, length, s, separator, quoted, state) \
183 for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
185 #define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
186 _FOREACH_WORD(word, length, s, separator, false, state)
189 char **strv_split(const char *s
, const char *separator
) {
190 const char *word
, *state
;
198 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
)
201 r
= malloc(sizeof(char *) * (n
+ 1));
206 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
) {
207 r
[i
] = strndup(word
, l
);
220 char *strv_join(char **l
, const char *separator
) {
228 k
= strlen(separator
);
244 e
= stpcpy(e
, separator
);
254 int strv_push(char ***l
, char *value
) {
263 /* Increase and check for overflow */
268 c
= realloc(*l
, sizeof(char *) * m
);
279 int strv_push_prepend(char ***l
, char *value
) {
288 /* increase and check for overflow */
293 c
= malloc(sizeof(char *) * m
);
297 for (i
= 0; i
< n
; i
++)
309 int strv_consume(char ***l
, char *value
) {
312 r
= strv_push(l
, value
);
319 int strv_consume_prepend(char ***l
, char *value
) {
322 r
= strv_push_prepend(l
, value
);
329 int strv_extend(char ***l
, const char *value
) {
339 return strv_consume(l
, v
);
342 char **strv_remove(char **l
, const char *s
) {
350 /* Drops every occurrence of s in the string list, edits
353 for (f
= t
= l
; *f
; f
++)
354 if (strcmp(*f
, s
) == 0)
363 int strv_extendf(char ***l
, const char *format
, ...) {
368 va_start(ap
, format
);
369 r
= vasprintf(&x
, format
, ap
);
375 return strv_consume(l
, x
);
378 int strv_extendv(char ***l
, const char *format
, va_list ap
) {
382 r
= vasprintf(&x
, format
, ap
);
386 return strv_consume(l
, x
);
389 char **strv_reverse(char **l
) {
396 for (i
= 0; i
< n
/ 2; i
++) {