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