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