chiark / gitweb /
man: fix name of systemd.journal-fields(7)
[elogind.git] / src / shared / 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 void strv_free(char **l) {
84         strv_clear(l);
85         free(l);
86 }
87
88 char **strv_copy(char * const *l) {
89         char **r, **k;
90
91         k = r = new(char*, strv_length(l) + 1);
92         if (!r)
93                 return NULL;
94
95         if (l)
96                 for (; *l; k++, l++) {
97                         *k = strdup(*l);
98                         if (!*k) {
99                                 strv_free(r);
100                                 return NULL;
101                         }
102                 }
103
104         *k = NULL;
105         return r;
106 }
107
108 unsigned strv_length(char * const *l) {
109         unsigned n = 0;
110
111         if (!l)
112                 return 0;
113
114         for (; *l; l++)
115                 n++;
116
117         return n;
118 }
119
120 char **strv_new_ap(const char *x, va_list ap) {
121         const char *s;
122         char **a;
123         unsigned n = 0, i = 0;
124         va_list aq;
125
126         /* As a special trick we ignore all listed strings that equal
127          * (const char*) -1. This is supposed to be used with the
128          * STRV_IFNOTNULL() macro to include possibly NULL strings in
129          * the string list. */
130
131         if (x) {
132                 n = x == (const char*) -1 ? 0 : 1;
133
134                 va_copy(aq, ap);
135                 while ((s = va_arg(aq, const char*))) {
136                         if (s == (const char*) -1)
137                                 continue;
138
139                         n++;
140                 }
141
142                 va_end(aq);
143         }
144
145         a = new(char*, n+1);
146         if (!a)
147                 return NULL;
148
149         if (x) {
150                 if (x != (const char*) -1) {
151                         a[i] = strdup(x);
152                         if (!a[i])
153                                 goto fail;
154                         i++;
155                 }
156
157                 while ((s = va_arg(ap, const char*))) {
158
159                         if (s == (const char*) -1)
160                                 continue;
161
162                         a[i] = strdup(s);
163                         if (!a[i])
164                                 goto fail;
165
166                         i++;
167                 }
168         }
169
170         a[i] = NULL;
171
172         return a;
173
174 fail:
175         strv_free(a);
176         return NULL;
177 }
178
179 char **strv_new(const char *x, ...) {
180         char **r;
181         va_list ap;
182
183         va_start(ap, x);
184         r = strv_new_ap(x, ap);
185         va_end(ap);
186
187         return r;
188 }
189
190 int strv_extend_strv(char ***a, char **b) {
191         int r;
192         char **s;
193
194         STRV_FOREACH(s, b) {
195                 r = strv_extend(a, *s);
196                 if (r < 0)
197                         return r;
198         }
199
200         return 0;
201 }
202
203 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
204         int r;
205         char **s;
206
207         STRV_FOREACH(s, b) {
208                 char *v;
209
210                 v = strappend(*s, suffix);
211                 if (!v)
212                         return -ENOMEM;
213
214                 r = strv_push(a, v);
215                 if (r < 0) {
216                         free(v);
217                         return r;
218                 }
219         }
220
221         return 0;
222 }
223
224 char **strv_split(const char *s, const char *separator) {
225         const char *word, *state;
226         size_t l;
227         unsigned n, i;
228         char **r;
229
230         assert(s);
231
232         n = 0;
233         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
234                 n++;
235
236         r = new(char*, n+1);
237         if (!r)
238                 return NULL;
239
240         i = 0;
241         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
242                 r[i] = strndup(word, l);
243                 if (!r[i]) {
244                         strv_free(r);
245                         return NULL;
246                 }
247
248                 i++;
249         }
250
251         r[i] = NULL;
252         return r;
253 }
254
255 char **strv_split_newlines(const char *s) {
256         char **l;
257         unsigned n;
258
259         assert(s);
260
261         /* Special version of strv_split() that splits on newlines and
262          * suppresses an empty string at the end */
263
264         l = strv_split(s, NEWLINE);
265         if (!l)
266                 return NULL;
267
268         n = strv_length(l);
269         if (n <= 0)
270                 return l;
271
272         if (isempty(l[n-1])) {
273                 free(l[n-1]);
274                 l[n-1] = NULL;
275         }
276
277         return l;
278 }
279
280 int strv_split_quoted(char ***t, const char *s, bool relax) {
281         size_t n = 0, allocated = 0;
282         _cleanup_strv_free_ char **l = NULL;
283         int r;
284
285         assert(t);
286         assert(s);
287
288         for (;;) {
289                 _cleanup_free_ char *word = NULL;
290
291                 r = unquote_first_word(&s, &word, relax);
292                 if (r < 0)
293                         return r;
294                 if (r == 0)
295                         break;
296
297                 if (!GREEDY_REALLOC(l, allocated, n + 2))
298                         return -ENOMEM;
299
300                 l[n++] = word;
301                 word = NULL;
302
303                 l[n] = NULL;
304         }
305
306         if (!l)
307                 l = new0(char*, 1);
308
309         *t = l;
310         l = NULL;
311
312         return 0;
313 }
314
315 char *strv_join(char **l, const char *separator) {
316         char *r, *e;
317         char **s;
318         size_t n, k;
319
320         if (!separator)
321                 separator = " ";
322
323         k = strlen(separator);
324
325         n = 0;
326         STRV_FOREACH(s, l) {
327                 if (n != 0)
328                         n += k;
329                 n += strlen(*s);
330         }
331
332         r = new(char, n+1);
333         if (!r)
334                 return NULL;
335
336         e = r;
337         STRV_FOREACH(s, l) {
338                 if (e != r)
339                         e = stpcpy(e, separator);
340
341                 e = stpcpy(e, *s);
342         }
343
344         *e = 0;
345
346         return r;
347 }
348
349 char *strv_join_quoted(char **l) {
350         char *buf = NULL;
351         char **s;
352         size_t allocated = 0, len = 0;
353
354         STRV_FOREACH(s, l) {
355                 /* assuming here that escaped string cannot be more
356                  * than twice as long, and reserving space for the
357                  * separator and quotes.
358                  */
359                 _cleanup_free_ char *esc = NULL;
360                 size_t needed;
361
362                 if (!GREEDY_REALLOC(buf, allocated,
363                                     len + strlen(*s) * 2 + 3))
364                         goto oom;
365
366                 esc = cescape(*s);
367                 if (!esc)
368                         goto oom;
369
370                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
371                                   len > 0 ? " " : "", esc);
372                 assert(needed < allocated - len);
373                 len += needed;
374         }
375
376         if (!buf)
377                 buf = malloc0(1);
378
379         return buf;
380
381  oom:
382         free(buf);
383         return NULL;
384 }
385
386 int strv_push(char ***l, char *value) {
387         char **c;
388         unsigned n, m;
389
390         if (!value)
391                 return 0;
392
393         n = strv_length(*l);
394
395         /* Increase and check for overflow */
396         m = n + 2;
397         if (m < n)
398                 return -ENOMEM;
399
400         c = realloc_multiply(*l, sizeof(char*), m);
401         if (!c)
402                 return -ENOMEM;
403
404         c[n] = value;
405         c[n+1] = NULL;
406
407         *l = c;
408         return 0;
409 }
410
411 int strv_push_pair(char ***l, char *a, char *b) {
412         char **c;
413         unsigned n, m;
414
415         if (!a && !b)
416                 return 0;
417
418         n = strv_length(*l);
419
420         /* increase and check for overflow */
421         m = n + !!a + !!b + 1;
422         if (m < n)
423                 return -ENOMEM;
424
425         c = realloc_multiply(*l, sizeof(char*), m);
426         if (!c)
427                 return -ENOMEM;
428
429         if (a)
430                 c[n++] = a;
431         if (b)
432                 c[n++] = b;
433         c[n] = NULL;
434
435         *l = c;
436         return 0;
437 }
438
439 int strv_push_prepend(char ***l, char *value) {
440         char **c;
441         unsigned n, m, i;
442
443         if (!value)
444                 return 0;
445
446         n = strv_length(*l);
447
448         /* increase and check for overflow */
449         m = n + 2;
450         if (m < n)
451                 return -ENOMEM;
452
453         c = new(char*, m);
454         if (!c)
455                 return -ENOMEM;
456
457         for (i = 0; i < n; i++)
458                 c[i+1] = (*l)[i];
459
460         c[0] = value;
461         c[n+1] = NULL;
462
463         free(*l);
464         *l = c;
465
466         return 0;
467 }
468
469 int strv_consume(char ***l, char *value) {
470         int r;
471
472         r = strv_push(l, value);
473         if (r < 0)
474                 free(value);
475
476         return r;
477 }
478
479 int strv_consume_pair(char ***l, char *a, char *b) {
480         int r;
481
482         r = strv_push_pair(l, a, b);
483         if (r < 0) {
484                 free(a);
485                 free(b);
486         }
487
488         return r;
489 }
490
491 int strv_consume_prepend(char ***l, char *value) {
492         int r;
493
494         r = strv_push_prepend(l, value);
495         if (r < 0)
496                 free(value);
497
498         return r;
499 }
500
501 int strv_extend(char ***l, const char *value) {
502         char *v;
503
504         if (!value)
505                 return 0;
506
507         v = strdup(value);
508         if (!v)
509                 return -ENOMEM;
510
511         return strv_consume(l, v);
512 }
513
514 char **strv_uniq(char **l) {
515         char **i;
516
517         /* Drops duplicate entries. The first identical string will be
518          * kept, the others dropped */
519
520         STRV_FOREACH(i, l)
521                 strv_remove(i+1, *i);
522
523         return l;
524 }
525
526 bool strv_is_uniq(char **l) {
527         char **i;
528
529         STRV_FOREACH(i, l)
530                 if (strv_find(i+1, *i))
531                         return false;
532
533         return true;
534 }
535
536 char **strv_remove(char **l, const char *s) {
537         char **f, **t;
538
539         if (!l)
540                 return NULL;
541
542         assert(s);
543
544         /* Drops every occurrence of s in the string list, edits
545          * in-place. */
546
547         for (f = t = l; *f; f++)
548                 if (streq(*f, s))
549                         free(*f);
550                 else
551                         *(t++) = *f;
552
553         *t = NULL;
554         return l;
555 }
556
557 char **strv_parse_nulstr(const char *s, size_t l) {
558         const char *p;
559         unsigned c = 0, i = 0;
560         char **v;
561
562         assert(s || l <= 0);
563
564         if (l <= 0)
565                 return new0(char*, 1);
566
567         for (p = s; p < s + l; p++)
568                 if (*p == 0)
569                         c++;
570
571         if (s[l-1] != 0)
572                 c++;
573
574         v = new0(char*, c+1);
575         if (!v)
576                 return NULL;
577
578         p = s;
579         while (p < s + l) {
580                 const char *e;
581
582                 e = memchr(p, 0, s + l - p);
583
584                 v[i] = strndup(p, e ? e - p : s + l - p);
585                 if (!v[i]) {
586                         strv_free(v);
587                         return NULL;
588                 }
589
590                 i++;
591
592                 if (!e)
593                         break;
594
595                 p = e + 1;
596         }
597
598         assert(i == c);
599
600         return v;
601 }
602
603 char **strv_split_nulstr(const char *s) {
604         const char *i;
605         char **r = NULL;
606
607         NULSTR_FOREACH(i, s)
608                 if (strv_extend(&r, i) < 0) {
609                         strv_free(r);
610                         return NULL;
611                 }
612
613         if (!r)
614                 return strv_new(NULL, NULL);
615
616         return r;
617 }
618
619 bool strv_overlap(char **a, char **b) {
620         char **i;
621
622         STRV_FOREACH(i, a)
623                 if (strv_contains(b, *i))
624                         return true;
625
626         return false;
627 }
628
629 static int str_compare(const void *_a, const void *_b) {
630         const char **a = (const char**) _a, **b = (const char**) _b;
631
632         return strcmp(*a, *b);
633 }
634
635 char **strv_sort(char **l) {
636
637         if (strv_isempty(l))
638                 return l;
639
640         qsort(l, strv_length(l), sizeof(char*), str_compare);
641         return l;
642 }
643
644 bool strv_equal(char **a, char **b) {
645         if (!a || !b)
646                 return a == b;
647
648         for ( ; *a || *b; ++a, ++b)
649                 if (!streq_ptr(*a, *b))
650                         return false;
651
652         return true;
653 }
654
655 void strv_print(char **l) {
656         char **s;
657
658         STRV_FOREACH(s, l)
659                 puts(*s);
660 }
661
662 int strv_extendf(char ***l, const char *format, ...) {
663         va_list ap;
664         char *x;
665         int r;
666
667         va_start(ap, format);
668         r = vasprintf(&x, format, ap);
669         va_end(ap);
670
671         if (r < 0)
672                 return -ENOMEM;
673
674         return strv_consume(l, x);
675 }
676
677 char **strv_reverse(char **l) {
678         unsigned n, i;
679
680         n = strv_length(l);
681         if (n <= 1)
682                 return l;
683
684         for (i = 0; i < n / 2; i++) {
685                 char *t;
686
687                 t = l[i];
688                 l[i] = l[n-1-i];
689                 l[n-1-i] = t;
690         }
691
692         return l;
693 }
694
695 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
696         char* const* p;
697
698         STRV_FOREACH(p, patterns)
699                 if (fnmatch(*p, s, 0) == 0)
700                         return true;
701
702         return false;
703 }