chiark / gitweb /
basic: include only what we use
[elogind.git] / src / basic / strv.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
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   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fnmatch.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "alloc-util.h"
30 #include "escape.h"
31 #include "extract-word.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         free(l);
92         return NULL;
93 }
94
95 char **strv_free_erase(char **l) {
96         char **i;
97
98         STRV_FOREACH(i, l)
99                 string_erase(*i);
100
101         return strv_free(l);
102 }
103
104 char **strv_copy(char * const *l) {
105         char **r, **k;
106
107         k = r = new(char*, strv_length(l) + 1);
108         if (!r)
109                 return NULL;
110
111         if (l)
112                 for (; *l; k++, l++) {
113                         *k = strdup(*l);
114                         if (!*k) {
115                                 strv_free(r);
116                                 return NULL;
117                         }
118                 }
119
120         *k = NULL;
121         return r;
122 }
123
124 unsigned strv_length(char * const *l) {
125         unsigned n = 0;
126
127         if (!l)
128                 return 0;
129
130         for (; *l; l++)
131                 n++;
132
133         return n;
134 }
135
136 char **strv_new_ap(const char *x, va_list ap) {
137         const char *s;
138         char **a;
139         unsigned n = 0, i = 0;
140         va_list aq;
141
142         /* As a special trick we ignore all listed strings that equal
143          * (const char*) -1. This is supposed to be used with the
144          * STRV_IFNOTNULL() macro to include possibly NULL strings in
145          * the string list. */
146
147         if (x) {
148                 n = x == (const char*) -1 ? 0 : 1;
149
150                 va_copy(aq, ap);
151                 while ((s = va_arg(aq, const char*))) {
152                         if (s == (const char*) -1)
153                                 continue;
154
155                         n++;
156                 }
157
158                 va_end(aq);
159         }
160
161         a = new(char*, n+1);
162         if (!a)
163                 return NULL;
164
165         if (x) {
166                 if (x != (const char*) -1) {
167                         a[i] = strdup(x);
168                         if (!a[i])
169                                 goto fail;
170                         i++;
171                 }
172
173                 while ((s = va_arg(ap, const char*))) {
174
175                         if (s == (const char*) -1)
176                                 continue;
177
178                         a[i] = strdup(s);
179                         if (!a[i])
180                                 goto fail;
181
182                         i++;
183                 }
184         }
185
186         a[i] = NULL;
187
188         return a;
189
190 fail:
191         strv_free(a);
192         return NULL;
193 }
194
195 char **strv_new(const char *x, ...) {
196         char **r;
197         va_list ap;
198
199         va_start(ap, x);
200         r = strv_new_ap(x, ap);
201         va_end(ap);
202
203         return r;
204 }
205
206 #if 0 /// UNNEEDED by elogind
207 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
208         char **s, **t;
209         size_t p, q, i = 0, j;
210
211         assert(a);
212
213         if (strv_isempty(b))
214                 return 0;
215
216         p = strv_length(*a);
217         q = strv_length(b);
218
219         t = realloc(*a, sizeof(char*) * (p + q + 1));
220         if (!t)
221                 return -ENOMEM;
222
223         t[p] = NULL;
224         *a = t;
225
226         STRV_FOREACH(s, b) {
227
228                 if (filter_duplicates && strv_contains(t, *s))
229                         continue;
230
231                 t[p+i] = strdup(*s);
232                 if (!t[p+i])
233                         goto rollback;
234
235                 i++;
236                 t[p+i] = NULL;
237         }
238
239         assert(i <= q);
240
241         return (int) i;
242
243 rollback:
244         for (j = 0; j < i; j++)
245                 free(t[p + j]);
246
247         t[p] = NULL;
248         return -ENOMEM;
249 }
250
251 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
252         int r;
253         char **s;
254
255         STRV_FOREACH(s, b) {
256                 char *v;
257
258                 v = strappend(*s, suffix);
259                 if (!v)
260                         return -ENOMEM;
261
262                 r = strv_push(a, v);
263                 if (r < 0) {
264                         free(v);
265                         return r;
266                 }
267         }
268
269         return 0;
270 }
271 #endif // 0
272
273 char **strv_split(const char *s, const char *separator) {
274         const char *word, *state;
275         size_t l;
276         unsigned n, i;
277         char **r;
278
279         assert(s);
280
281         n = 0;
282         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
283                 n++;
284
285         r = new(char*, n+1);
286         if (!r)
287                 return NULL;
288
289         i = 0;
290         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
291                 r[i] = strndup(word, l);
292                 if (!r[i]) {
293                         strv_free(r);
294                         return NULL;
295                 }
296
297                 i++;
298         }
299
300         r[i] = NULL;
301         return r;
302 }
303
304 #if 0 /// UNNEEDED by elogind
305 char **strv_split_newlines(const char *s) {
306         char **l;
307         unsigned n;
308
309         assert(s);
310
311         /* Special version of strv_split() that splits on newlines and
312          * suppresses an empty string at the end */
313
314         l = strv_split(s, NEWLINE);
315         if (!l)
316                 return NULL;
317
318         n = strv_length(l);
319         if (n <= 0)
320                 return l;
321
322         if (isempty(l[n - 1]))
323                 l[n-1] = mfree(l[n-1]);
324
325         return l;
326 }
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 #endif // 0
366
367 char *strv_join(char **l, const char *separator) {
368         char *r, *e;
369         char **s;
370         size_t n, k;
371
372         if (!separator)
373                 separator = " ";
374
375         k = strlen(separator);
376
377         n = 0;
378         STRV_FOREACH(s, l) {
379                 if (n != 0)
380                         n += k;
381                 n += strlen(*s);
382         }
383
384         r = new(char, n+1);
385         if (!r)
386                 return NULL;
387
388         e = r;
389         STRV_FOREACH(s, l) {
390                 if (e != r)
391                         e = stpcpy(e, separator);
392
393                 e = stpcpy(e, *s);
394         }
395
396         *e = 0;
397
398         return r;
399 }
400
401 #if 0 /// UNNEEDED by elogind
402 char *strv_join_quoted(char **l) {
403         char *buf = NULL;
404         char **s;
405         size_t allocated = 0, len = 0;
406
407         STRV_FOREACH(s, l) {
408                 /* assuming here that escaped string cannot be more
409                  * than twice as long, and reserving space for the
410                  * separator and quotes.
411                  */
412                 _cleanup_free_ char *esc = NULL;
413                 size_t needed;
414
415                 if (!GREEDY_REALLOC(buf, allocated,
416                                     len + strlen(*s) * 2 + 3))
417                         goto oom;
418
419                 esc = cescape(*s);
420                 if (!esc)
421                         goto oom;
422
423                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
424                                   len > 0 ? " " : "", esc);
425                 assert(needed < allocated - len);
426                 len += needed;
427         }
428
429         if (!buf)
430                 buf = malloc0(1);
431
432         return buf;
433
434  oom:
435         free(buf);
436         return NULL;
437 }
438 #endif // 0
439
440 int strv_push(char ***l, char *value) {
441         char **c;
442         unsigned n, m;
443
444         if (!value)
445                 return 0;
446
447         n = strv_length(*l);
448
449         /* Increase and check for overflow */
450         m = n + 2;
451         if (m < n)
452                 return -ENOMEM;
453
454         c = realloc_multiply(*l, sizeof(char*), m);
455         if (!c)
456                 return -ENOMEM;
457
458         c[n] = value;
459         c[n+1] = NULL;
460
461         *l = c;
462         return 0;
463 }
464
465 int strv_push_pair(char ***l, char *a, char *b) {
466         char **c;
467         unsigned n, m;
468
469         if (!a && !b)
470                 return 0;
471
472         n = strv_length(*l);
473
474         /* increase and check for overflow */
475         m = n + !!a + !!b + 1;
476         if (m < n)
477                 return -ENOMEM;
478
479         c = realloc_multiply(*l, sizeof(char*), m);
480         if (!c)
481                 return -ENOMEM;
482
483         if (a)
484                 c[n++] = a;
485         if (b)
486                 c[n++] = b;
487         c[n] = NULL;
488
489         *l = c;
490         return 0;
491 }
492
493 int strv_push_prepend(char ***l, char *value) {
494         char **c;
495         unsigned n, m, i;
496
497         if (!value)
498                 return 0;
499
500         n = strv_length(*l);
501
502         /* increase and check for overflow */
503         m = n + 2;
504         if (m < n)
505                 return -ENOMEM;
506
507         c = new(char*, m);
508         if (!c)
509                 return -ENOMEM;
510
511         for (i = 0; i < n; i++)
512                 c[i+1] = (*l)[i];
513
514         c[0] = value;
515         c[n+1] = NULL;
516
517         free(*l);
518         *l = c;
519
520         return 0;
521 }
522
523 int strv_consume(char ***l, char *value) {
524         int r;
525
526         r = strv_push(l, value);
527         if (r < 0)
528                 free(value);
529
530         return r;
531 }
532
533 #if 0 /// UNNEEDED by elogind
534 int strv_consume_pair(char ***l, char *a, char *b) {
535         int r;
536
537         r = strv_push_pair(l, a, b);
538         if (r < 0) {
539                 free(a);
540                 free(b);
541         }
542
543         return r;
544 }
545 #endif // 0
546
547 int strv_consume_prepend(char ***l, char *value) {
548         int r;
549
550         r = strv_push_prepend(l, value);
551         if (r < 0)
552                 free(value);
553
554         return r;
555 }
556
557 int strv_extend(char ***l, const char *value) {
558         char *v;
559
560         if (!value)
561                 return 0;
562
563         v = strdup(value);
564         if (!v)
565                 return -ENOMEM;
566
567         return strv_consume(l, v);
568 }
569
570 char **strv_uniq(char **l) {
571         char **i;
572
573         /* Drops duplicate entries. The first identical string will be
574          * kept, the others dropped */
575
576         STRV_FOREACH(i, l)
577                 strv_remove(i+1, *i);
578
579         return l;
580 }
581
582 #if 0 /// UNNEEDED by elogind
583 bool strv_is_uniq(char **l) {
584         char **i;
585
586         STRV_FOREACH(i, l)
587                 if (strv_find(i+1, *i))
588                         return false;
589
590         return true;
591 }
592 #endif // 0
593
594 char **strv_remove(char **l, const char *s) {
595         char **f, **t;
596
597         if (!l)
598                 return NULL;
599
600         assert(s);
601
602         /* Drops every occurrence of s in the string list, edits
603          * in-place. */
604
605         for (f = t = l; *f; f++)
606                 if (streq(*f, s))
607                         free(*f);
608                 else
609                         *(t++) = *f;
610
611         *t = NULL;
612         return l;
613 }
614
615 char **strv_parse_nulstr(const char *s, size_t l) {
616         const char *p;
617         unsigned c = 0, i = 0;
618         char **v;
619
620         assert(s || l <= 0);
621
622         if (l <= 0)
623                 return new0(char*, 1);
624
625         for (p = s; p < s + l; p++)
626                 if (*p == 0)
627                         c++;
628
629         if (s[l-1] != 0)
630                 c++;
631
632         v = new0(char*, c+1);
633         if (!v)
634                 return NULL;
635
636         p = s;
637         while (p < s + l) {
638                 const char *e;
639
640                 e = memchr(p, 0, s + l - p);
641
642                 v[i] = strndup(p, e ? e - p : s + l - p);
643                 if (!v[i]) {
644                         strv_free(v);
645                         return NULL;
646                 }
647
648                 i++;
649
650                 if (!e)
651                         break;
652
653                 p = e + 1;
654         }
655
656         assert(i == c);
657
658         return v;
659 }
660
661 char **strv_split_nulstr(const char *s) {
662         const char *i;
663         char **r = NULL;
664
665         NULSTR_FOREACH(i, s)
666                 if (strv_extend(&r, i) < 0) {
667                         strv_free(r);
668                         return NULL;
669                 }
670
671         if (!r)
672                 return strv_new(NULL, NULL);
673
674         return r;
675 }
676
677 #if 0 /// UNNEEDED by elogind
678 int strv_make_nulstr(char **l, char **p, size_t *q) {
679         size_t n_allocated = 0, n = 0;
680         _cleanup_free_ char *m = NULL;
681         char **i;
682
683         assert(p);
684         assert(q);
685
686         STRV_FOREACH(i, l) {
687                 size_t z;
688
689                 z = strlen(*i);
690
691                 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
692                         return -ENOMEM;
693
694                 memcpy(m + n, *i, z + 1);
695                 n += z + 1;
696         }
697
698         if (!m) {
699                 m = new0(char, 1);
700                 if (!m)
701                         return -ENOMEM;
702                 n = 0;
703         }
704
705         *p = m;
706         *q = n;
707
708         m = NULL;
709
710         return 0;
711 }
712
713 bool strv_overlap(char **a, char **b) {
714         char **i;
715
716         STRV_FOREACH(i, a)
717                 if (strv_contains(b, *i))
718                         return true;
719
720         return false;
721 }
722 #endif // 0
723
724 static int str_compare(const void *_a, const void *_b) {
725         const char **a = (const char**) _a, **b = (const char**) _b;
726
727         return strcmp(*a, *b);
728 }
729
730 char **strv_sort(char **l) {
731
732         if (strv_isempty(l))
733                 return l;
734
735         qsort(l, strv_length(l), sizeof(char*), str_compare);
736         return l;
737 }
738
739 #if 0 /// UNNEEDED by elogind
740 bool strv_equal(char **a, char **b) {
741
742         if (strv_isempty(a))
743                 return strv_isempty(b);
744
745         if (strv_isempty(b))
746                 return false;
747
748         for ( ; *a || *b; ++a, ++b)
749                 if (!streq_ptr(*a, *b))
750                         return false;
751
752         return true;
753 }
754
755 void strv_print(char **l) {
756         char **s;
757
758         STRV_FOREACH(s, l)
759                 puts(*s);
760 }
761
762 int strv_extendf(char ***l, const char *format, ...) {
763         va_list ap;
764         char *x;
765         int r;
766
767         va_start(ap, format);
768         r = vasprintf(&x, format, ap);
769         va_end(ap);
770
771         if (r < 0)
772                 return -ENOMEM;
773
774         return strv_consume(l, x);
775 }
776
777 char **strv_reverse(char **l) {
778         unsigned n, i;
779
780         n = strv_length(l);
781         if (n <= 1)
782                 return l;
783
784         for (i = 0; i < n / 2; i++) {
785                 char *t;
786
787                 t = l[i];
788                 l[i] = l[n-1-i];
789                 l[n-1-i] = t;
790         }
791
792         return l;
793 }
794
795 char **strv_shell_escape(char **l, const char *bad) {
796         char **s;
797
798         /* Escapes every character in every string in l that is in bad,
799          * edits in-place, does not roll-back on error. */
800
801         STRV_FOREACH(s, l) {
802                 char *v;
803
804                 v = shell_escape(*s, bad);
805                 if (!v)
806                         return NULL;
807
808                 free(*s);
809                 *s = v;
810         }
811
812         return l;
813 }
814
815 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
816         char* const* p;
817
818         STRV_FOREACH(p, patterns)
819                 if (fnmatch(*p, s, 0) == 0)
820                         return true;
821
822         return false;
823 }
824
825 char ***strv_free_free(char ***l) {
826         char ***i;
827
828         if (!l)
829                 return NULL;
830
831         for (i = l; *i; i++)
832                 strv_free(*i);
833
834         free(l);
835         return NULL;
836 }
837
838 char **strv_skip(char **l, size_t n) {
839
840         while (n > 0) {
841                 if (strv_isempty(l))
842                         return l;
843
844                 l++, n--;
845         }
846
847         return l;
848 }
849
850 int strv_extend_n(char ***l, const char *value, size_t n) {
851         size_t i, j, k;
852         char **nl;
853
854         assert(l);
855
856         if (!value)
857                 return 0;
858         if (n == 0)
859                 return 0;
860
861         /* Adds the value value n times to l */
862
863         k = strv_length(*l);
864
865         nl = realloc(*l, sizeof(char*) * (k + n + 1));
866         if (!nl)
867                 return -ENOMEM;
868
869         *l = nl;
870
871         for (i = k; i < k + n; i++) {
872                 nl[i] = strdup(value);
873                 if (!nl[i])
874                         goto rollback;
875         }
876
877         nl[i] = NULL;
878         return 0;
879
880 rollback:
881         for (j = k; j < i; j++)
882                 free(nl[j]);
883
884         nl[k] = NULL;
885         return -ENOMEM;
886 }
887 #endif // 0