chiark / gitweb /
basic/strv: add function to insert items at position
[elogind.git] / src / basic / strv.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3   This file is part of systemd.
4
5   Copyright 2010 Lennart Poettering
6
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.
11
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.
16
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/>.
19 ***/
20
21 #include <errno.h>
22 #include <fnmatch.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "alloc-util.h"
29 #include "escape.h"
30 #include "extract-word.h"
31 //#include "fileio.h"
32 #include "string-util.h"
33 #include "strv.h"
34 #include "util.h"
35
36 char *strv_find(char **l, const char *name) {
37         char **i;
38
39         assert(name);
40
41         STRV_FOREACH(i, l)
42                 if (streq(*i, name))
43                         return *i;
44
45         return NULL;
46 }
47
48 char *strv_find_prefix(char **l, const char *name) {
49         char **i;
50
51         assert(name);
52
53         STRV_FOREACH(i, l)
54                 if (startswith(*i, name))
55                         return *i;
56
57         return NULL;
58 }
59
60 char *strv_find_startswith(char **l, const char *name) {
61         char **i, *e;
62
63         assert(name);
64
65         /* Like strv_find_prefix, but actually returns only the
66          * suffix, not the whole item */
67
68         STRV_FOREACH(i, l) {
69                 e = startswith(*i, name);
70                 if (e)
71                         return e;
72         }
73
74         return NULL;
75 }
76
77 void strv_clear(char **l) {
78         char **k;
79
80         if (!l)
81                 return;
82
83         for (k = l; *k; k++)
84                 free(*k);
85
86         *l = NULL;
87 }
88
89 char **strv_free(char **l) {
90         strv_clear(l);
91         return mfree(l);
92 }
93
94 char **strv_free_erase(char **l) {
95         char **i;
96
97         STRV_FOREACH(i, l)
98                 string_erase(*i);
99
100         return strv_free(l);
101 }
102
103 char **strv_copy(char * const *l) {
104         char **r, **k;
105
106         k = r = new(char*, strv_length(l) + 1);
107         if (!r)
108                 return NULL;
109
110         if (l)
111                 for (; *l; k++, l++) {
112                         *k = strdup(*l);
113                         if (!*k) {
114                                 strv_free(r);
115                                 return NULL;
116                         }
117                 }
118
119         *k = NULL;
120         return r;
121 }
122
123 unsigned strv_length(char * const *l) {
124         unsigned n = 0;
125
126         if (!l)
127                 return 0;
128
129         for (; *l; l++)
130                 n++;
131
132         return n;
133 }
134
135 char **strv_new_ap(const char *x, va_list ap) {
136         const char *s;
137         char **a;
138         unsigned n = 0, i = 0;
139         va_list aq;
140
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. */
145
146         if (x) {
147                 n = x == STRV_IGNORE ? 0 : 1;
148
149                 va_copy(aq, ap);
150                 while ((s = va_arg(aq, const char*))) {
151                         if (s == STRV_IGNORE)
152                                 continue;
153
154                         n++;
155                 }
156
157                 va_end(aq);
158         }
159
160         a = new(char*, n+1);
161         if (!a)
162                 return NULL;
163
164         if (x) {
165                 if (x != STRV_IGNORE) {
166                         a[i] = strdup(x);
167                         if (!a[i])
168                                 goto fail;
169                         i++;
170                 }
171
172                 while ((s = va_arg(ap, const char*))) {
173
174                         if (s == STRV_IGNORE)
175                                 continue;
176
177                         a[i] = strdup(s);
178                         if (!a[i])
179                                 goto fail;
180
181                         i++;
182                 }
183         }
184
185         a[i] = NULL;
186
187         return a;
188
189 fail:
190         strv_free(a);
191         return NULL;
192 }
193
194 char **strv_new(const char *x, ...) {
195         char **r;
196         va_list ap;
197
198         va_start(ap, x);
199         r = strv_new_ap(x, ap);
200         va_end(ap);
201
202         return r;
203 }
204
205 #if 0 /// UNNEEDED by elogind
206 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
207         char **s, **t;
208         size_t p, q, i = 0, j;
209
210         assert(a);
211
212         if (strv_isempty(b))
213                 return 0;
214
215         p = strv_length(*a);
216         q = strv_length(b);
217
218         t = realloc(*a, sizeof(char*) * (p + q + 1));
219         if (!t)
220                 return -ENOMEM;
221
222         t[p] = NULL;
223         *a = t;
224
225         STRV_FOREACH(s, b) {
226
227                 if (filter_duplicates && strv_contains(t, *s))
228                         continue;
229
230                 t[p+i] = strdup(*s);
231                 if (!t[p+i])
232                         goto rollback;
233
234                 i++;
235                 t[p+i] = NULL;
236         }
237
238         assert(i <= q);
239
240         return (int) i;
241
242 rollback:
243         for (j = 0; j < i; j++)
244                 free(t[p + j]);
245
246         t[p] = NULL;
247         return -ENOMEM;
248 }
249
250 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
251         int r;
252         char **s;
253
254         STRV_FOREACH(s, b) {
255                 char *v;
256
257                 v = strappend(*s, suffix);
258                 if (!v)
259                         return -ENOMEM;
260
261                 r = strv_push(a, v);
262                 if (r < 0) {
263                         free(v);
264                         return r;
265                 }
266         }
267
268         return 0;
269 }
270 #endif // 0
271
272 char **strv_split(const char *s, const char *separator) {
273         const char *word, *state;
274         size_t l;
275         unsigned n, i;
276         char **r;
277
278         assert(s);
279
280         n = 0;
281         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
282                 n++;
283
284         r = new(char*, n+1);
285         if (!r)
286                 return NULL;
287
288         i = 0;
289         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
290                 r[i] = strndup(word, l);
291                 if (!r[i]) {
292                         strv_free(r);
293                         return NULL;
294                 }
295
296                 i++;
297         }
298
299         r[i] = NULL;
300         return r;
301 }
302
303 #if 0 /// UNNEEDED by elogind
304 char **strv_split_newlines(const char *s) {
305         char **l;
306         unsigned n;
307
308         assert(s);
309
310         /* Special version of strv_split() that splits on newlines and
311          * suppresses an empty string at the end */
312
313         l = strv_split(s, NEWLINE);
314         if (!l)
315                 return NULL;
316
317         n = strv_length(l);
318         if (n <= 0)
319                 return l;
320
321         if (isempty(l[n - 1]))
322                 l[n - 1] = mfree(l[n - 1]);
323
324         return l;
325 }
326 #endif // 0
327
328 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
329         _cleanup_strv_free_ char **l = NULL;
330         size_t n = 0, allocated = 0;
331         int r;
332
333         assert(t);
334         assert(s);
335
336         for (;;) {
337                 _cleanup_free_ char *word = NULL;
338
339                 r = extract_first_word(&s, &word, separators, flags);
340                 if (r < 0)
341                         return r;
342                 if (r == 0)
343                         break;
344
345                 if (!GREEDY_REALLOC(l, allocated, n + 2))
346                         return -ENOMEM;
347
348                 l[n++] = word;
349                 word = NULL;
350
351                 l[n] = NULL;
352         }
353
354         if (!l) {
355                 l = new0(char*, 1);
356                 if (!l)
357                         return -ENOMEM;
358         }
359
360         *t = l;
361         l = NULL;
362
363         return (int) n;
364 }
365
366 char *strv_join(char **l, const char *separator) {
367         char *r, *e;
368         char **s;
369         size_t n, k;
370
371         if (!separator)
372                 separator = " ";
373
374         k = strlen(separator);
375
376         n = 0;
377         STRV_FOREACH(s, l) {
378                 if (s != l)
379                         n += k;
380                 n += strlen(*s);
381         }
382
383         r = new(char, n+1);
384         if (!r)
385                 return NULL;
386
387         e = r;
388         STRV_FOREACH(s, l) {
389                 if (s != l)
390                         e = stpcpy(e, separator);
391
392                 e = stpcpy(e, *s);
393         }
394
395         *e = 0;
396
397         return r;
398 }
399
400 #if 0 /// UNNEEDED by elogind
401 #endif // 0
402 int strv_push(char ***l, char *value) {
403         char **c;
404         unsigned n, m;
405
406         if (!value)
407                 return 0;
408
409         n = strv_length(*l);
410
411         /* Increase and check for overflow */
412         m = n + 2;
413         if (m < n)
414                 return -ENOMEM;
415
416         c = realloc_multiply(*l, sizeof(char*), m);
417         if (!c)
418                 return -ENOMEM;
419
420         c[n] = value;
421         c[n+1] = NULL;
422
423         *l = c;
424         return 0;
425 }
426
427 int strv_push_pair(char ***l, char *a, char *b) {
428         char **c;
429         unsigned n, m;
430
431         if (!a && !b)
432                 return 0;
433
434         n = strv_length(*l);
435
436         /* increase and check for overflow */
437         m = n + !!a + !!b + 1;
438         if (m < n)
439                 return -ENOMEM;
440
441         c = realloc_multiply(*l, sizeof(char*), m);
442         if (!c)
443                 return -ENOMEM;
444
445         if (a)
446                 c[n++] = a;
447         if (b)
448                 c[n++] = b;
449         c[n] = NULL;
450
451         *l = c;
452         return 0;
453 }
454
455 int strv_insert(char ***l, unsigned position, char *value) {
456         char **c;
457         unsigned n, m, i;
458
459         if (!value)
460                 return 0;
461
462         n = strv_length(*l);
463         position = MIN(position, n);
464
465         /* increase and check for overflow */
466         m = n + 2;
467         if (m < n)
468                 return -ENOMEM;
469
470         c = new(char*, m);
471         if (!c)
472                 return -ENOMEM;
473
474         for (i = 0; i < position; i++)
475                 c[i] = (*l)[i];
476         c[position] = value;
477         for (i = position; i < n; i++)
478                 c[i+1] = (*l)[i];
479
480         c[n+1] = NULL;
481
482         free(*l);
483         *l = c;
484
485         return 0;
486 }
487
488 int strv_consume(char ***l, char *value) {
489         int r;
490
491         r = strv_push(l, value);
492         if (r < 0)
493                 free(value);
494
495         return r;
496 }
497
498 #if 0 /// UNNEEDED by elogind
499 int strv_consume_pair(char ***l, char *a, char *b) {
500         int r;
501
502         r = strv_push_pair(l, a, b);
503         if (r < 0) {
504                 free(a);
505                 free(b);
506         }
507
508         return r;
509 }
510 #endif // 0
511
512 int strv_consume_prepend(char ***l, char *value) {
513         int r;
514
515         r = strv_push_prepend(l, value);
516         if (r < 0)
517                 free(value);
518
519         return r;
520 }
521
522 int strv_extend(char ***l, const char *value) {
523         char *v;
524
525         if (!value)
526                 return 0;
527
528         v = strdup(value);
529         if (!v)
530                 return -ENOMEM;
531
532         return strv_consume(l, v);
533 }
534
535 int strv_extend_front(char ***l, const char *value) {
536         size_t n, m;
537         char *v, **c;
538
539         assert(l);
540
541         /* Like strv_extend(), but prepends rather than appends the new entry */
542
543         if (!value)
544                 return 0;
545
546         n = strv_length(*l);
547
548         /* Increase and overflow check. */
549         m = n + 2;
550         if (m < n)
551                 return -ENOMEM;
552
553         v = strdup(value);
554         if (!v)
555                 return -ENOMEM;
556
557         c = realloc_multiply(*l, sizeof(char*), m);
558         if (!c) {
559                 free(v);
560                 return -ENOMEM;
561         }
562
563         memmove(c+1, c, n * sizeof(char*));
564         c[0] = v;
565         c[n+1] = NULL;
566
567         *l = c;
568         return 0;
569 }
570
571 char **strv_uniq(char **l) {
572         char **i;
573
574         /* Drops duplicate entries. The first identical string will be
575          * kept, the others dropped */
576
577         STRV_FOREACH(i, l)
578                 strv_remove(i+1, *i);
579
580         return l;
581 }
582
583 #if 0 /// UNNEEDED by elogind
584 bool strv_is_uniq(char **l) {
585         char **i;
586
587         STRV_FOREACH(i, l)
588                 if (strv_find(i+1, *i))
589                         return false;
590
591         return true;
592 }
593 #endif // 0
594
595 char **strv_remove(char **l, const char *s) {
596         char **f, **t;
597
598         if (!l)
599                 return NULL;
600
601         assert(s);
602
603         /* Drops every occurrence of s in the string list, edits
604          * in-place. */
605
606         for (f = t = l; *f; f++)
607                 if (streq(*f, s))
608                         free(*f);
609                 else
610                         *(t++) = *f;
611
612         *t = NULL;
613         return l;
614 }
615
616 char **strv_parse_nulstr(const char *s, size_t l) {
617         /* l is the length of the input data, which will be split at NULs into
618          * elements of the resulting strv. Hence, the number of items in the resulting strv
619          * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
620          * unless s[l-1] is NUL, in which case the final empty string is not stored in
621          * the resulting strv, and length is equal to the number of NUL bytes.
622          *
623          * Note that contrary to a normal nulstr which cannot contain empty strings, because
624          * the input data is terminated by any two consequent NUL bytes, this parser accepts
625          * empty strings in s.
626          */
627
628         const char *p;
629         unsigned c = 0, i = 0;
630         char **v;
631
632         assert(s || l <= 0);
633
634         if (l <= 0)
635                 return new0(char*, 1);
636
637         for (p = s; p < s + l; p++)
638                 if (*p == 0)
639                         c++;
640
641         if (s[l-1] != 0)
642                 c++;
643
644         v = new0(char*, c+1);
645         if (!v)
646                 return NULL;
647
648         p = s;
649         while (p < s + l) {
650                 const char *e;
651
652                 e = memchr(p, 0, s + l - p);
653
654                 v[i] = strndup(p, e ? e - p : s + l - p);
655                 if (!v[i]) {
656                         strv_free(v);
657                         return NULL;
658                 }
659
660                 i++;
661
662                 if (!e)
663                         break;
664
665                 p = e + 1;
666         }
667
668         assert(i == c);
669
670         return v;
671 }
672
673 char **strv_split_nulstr(const char *s) {
674         const char *i;
675         char **r = NULL;
676
677         NULSTR_FOREACH(i, s)
678                 if (strv_extend(&r, i) < 0) {
679                         strv_free(r);
680                         return NULL;
681                 }
682
683         if (!r)
684                 return strv_new(NULL, NULL);
685
686         return r;
687 }
688
689 #if 0 /// UNNEEDED by elogind
690 int strv_make_nulstr(char **l, char **p, size_t *q) {
691         /* A valid nulstr with two NULs at the end will be created, but
692          * q will be the length without the two trailing NULs. Thus the output
693          * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
694          * and can also be parsed by strv_parse_nulstr as long as the length
695          * is provided separately.
696          */
697
698         size_t n_allocated = 0, n = 0;
699         _cleanup_free_ char *m = NULL;
700         char **i;
701
702         assert(p);
703         assert(q);
704
705         STRV_FOREACH(i, l) {
706                 size_t z;
707
708                 z = strlen(*i);
709
710                 if (!GREEDY_REALLOC(m, n_allocated, n + z + 2))
711                         return -ENOMEM;
712
713                 memcpy(m + n, *i, z + 1);
714                 n += z + 1;
715         }
716
717         if (!m) {
718                 m = new0(char, 1);
719                 if (!m)
720                         return -ENOMEM;
721                 n = 1;
722         } else
723                 /* make sure there is a second extra NUL at the end of resulting nulstr */
724                 m[n] = '\0';
725
726         assert(n > 0);
727         *p = m;
728         *q = n - 1;
729
730         m = NULL;
731
732         return 0;
733 }
734
735 bool strv_overlap(char **a, char **b) {
736         char **i;
737
738         STRV_FOREACH(i, a)
739                 if (strv_contains(b, *i))
740                         return true;
741
742         return false;
743 }
744 #endif // 0
745
746 static int str_compare(const void *_a, const void *_b) {
747         const char **a = (const char**) _a, **b = (const char**) _b;
748
749         return strcmp(*a, *b);
750 }
751
752 char **strv_sort(char **l) {
753         qsort_safe(l, strv_length(l), sizeof(char*), str_compare);
754         return l;
755 }
756
757 bool strv_equal(char **a, char **b) {
758
759         if (strv_isempty(a))
760                 return strv_isempty(b);
761
762         if (strv_isempty(b))
763                 return false;
764
765         for ( ; *a || *b; ++a, ++b)
766                 if (!streq_ptr(*a, *b))
767                         return false;
768
769         return true;
770 }
771
772 void strv_print(char **l) {
773         char **s;
774
775         STRV_FOREACH(s, l)
776                 puts(*s);
777 }
778
779 #if 0 /// UNNEEDED by elogind
780 int strv_extendf(char ***l, const char *format, ...) {
781         va_list ap;
782         char *x;
783         int r;
784
785         va_start(ap, format);
786         r = vasprintf(&x, format, ap);
787         va_end(ap);
788
789         if (r < 0)
790                 return -ENOMEM;
791
792         return strv_consume(l, x);
793 }
794
795 char **strv_reverse(char **l) {
796         unsigned n, i;
797
798         n = strv_length(l);
799         if (n <= 1)
800                 return l;
801
802         for (i = 0; i < n / 2; i++)
803                 SWAP_TWO(l[i], l[n-1-i]);
804
805         return l;
806 }
807
808 char **strv_shell_escape(char **l, const char *bad) {
809         char **s;
810
811         /* Escapes every character in every string in l that is in bad,
812          * edits in-place, does not roll-back on error. */
813
814         STRV_FOREACH(s, l) {
815                 char *v;
816
817                 v = shell_escape(*s, bad);
818                 if (!v)
819                         return NULL;
820
821                 free(*s);
822                 *s = v;
823         }
824
825         return l;
826 }
827
828 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
829         char* const* p;
830
831         STRV_FOREACH(p, patterns)
832                 if (fnmatch(*p, s, flags) == 0)
833                         return true;
834
835         return false;
836 }
837
838 char ***strv_free_free(char ***l) {
839         char ***i;
840
841         if (!l)
842                 return NULL;
843
844         for (i = l; *i; i++)
845                 strv_free(*i);
846
847         return mfree(l);
848 }
849
850 char **strv_skip(char **l, size_t n) {
851
852         while (n > 0) {
853                 if (strv_isempty(l))
854                         return l;
855
856                 l++, n--;
857         }
858
859         return l;
860 }
861 #endif // 0
862
863 int strv_extend_n(char ***l, const char *value, size_t n) {
864         size_t i, j, k;
865         char **nl;
866
867         assert(l);
868
869         if (!value)
870                 return 0;
871         if (n == 0)
872                 return 0;
873
874         /* Adds the value n times to l */
875
876         k = strv_length(*l);
877
878         nl = realloc(*l, sizeof(char*) * (k + n + 1));
879         if (!nl)
880                 return -ENOMEM;
881
882         *l = nl;
883
884         for (i = k; i < k + n; i++) {
885                 nl[i] = strdup(value);
886                 if (!nl[i])
887                         goto rollback;
888         }
889
890         nl[i] = NULL;
891         return 0;
892
893 rollback:
894         for (j = k; j < i; j++)
895                 free(nl[j]);
896
897         nl[k] = NULL;
898         return -ENOMEM;
899 }
900
901 #if 0 /// UNNEEDED by elogind
902 int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
903         bool b = false;
904         char **s;
905         int r;
906
907         /* Like fputs(), but for strv, and with a less stupid argument order */
908
909         if (!space)
910                 space = &b;
911
912         STRV_FOREACH(s, l) {
913                 r = fputs_with_space(f, *s, separator, space);
914                 if (r < 0)
915                         return r;
916         }
917
918         return 0;
919 }
920 #endif // 0