chiark / gitweb /
Remove utmp stuff that has found it's way back in.
[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) {
192         int r;
193         char **s;
194
195         STRV_FOREACH(s, b) {
196                 r = strv_extend(a, *s);
197                 if (r < 0)
198                         return r;
199         }
200
201         return 0;
202 }
203
204 /// UNNEEDED by elogind
205 #if 0
206 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
207         int r;
208         char **s;
209
210         STRV_FOREACH(s, b) {
211                 char *v;
212
213                 v = strappend(*s, suffix);
214                 if (!v)
215                         return -ENOMEM;
216
217                 r = strv_push(a, v);
218                 if (r < 0) {
219                         free(v);
220                         return r;
221                 }
222         }
223
224         return 0;
225 }
226 #endif // 0
227
228 char **strv_split(const char *s, const char *separator) {
229         const char *word, *state;
230         size_t l;
231         unsigned n, i;
232         char **r;
233
234         assert(s);
235
236         n = 0;
237         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
238                 n++;
239
240         r = new(char*, n+1);
241         if (!r)
242                 return NULL;
243
244         i = 0;
245         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
246                 r[i] = strndup(word, l);
247                 if (!r[i]) {
248                         strv_free(r);
249                         return NULL;
250                 }
251
252                 i++;
253         }
254
255         r[i] = NULL;
256         return r;
257 }
258
259 /// UNNEEDED by elogind
260 #if 0
261 char **strv_split_newlines(const char *s) {
262         char **l;
263         unsigned n;
264
265         assert(s);
266
267         /* Special version of strv_split() that splits on newlines and
268          * suppresses an empty string at the end */
269
270         l = strv_split(s, NEWLINE);
271         if (!l)
272                 return NULL;
273
274         n = strv_length(l);
275         if (n <= 0)
276                 return l;
277
278         if (isempty(l[n-1])) {
279                 free(l[n-1]);
280                 l[n-1] = NULL;
281         }
282
283         return l;
284 }
285
286 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
287         size_t n = 0, allocated = 0;
288         _cleanup_strv_free_ char **l = NULL;
289         int r;
290
291         assert(t);
292         assert(s);
293
294         for (;;) {
295                 _cleanup_free_ char *word = NULL;
296
297                 r = extract_first_word(&s, &word, separators, flags);
298                 if (r < 0)
299                         return r;
300                 if (r == 0) {
301                         break;
302                 }
303
304                 if (!GREEDY_REALLOC(l, allocated, n + 2))
305                         return -ENOMEM;
306
307                 l[n++] = word;
308                 word = NULL;
309
310                 l[n] = NULL;
311         }
312
313         if (!l)
314                 l = new0(char*, 1);
315
316         *t = l;
317         l = NULL;
318
319         return 0;
320 }
321 #endif // 0
322
323 char *strv_join(char **l, const char *separator) {
324         char *r, *e;
325         char **s;
326         size_t n, k;
327
328         if (!separator)
329                 separator = " ";
330
331         k = strlen(separator);
332
333         n = 0;
334         STRV_FOREACH(s, l) {
335                 if (n != 0)
336                         n += k;
337                 n += strlen(*s);
338         }
339
340         r = new(char, n+1);
341         if (!r)
342                 return NULL;
343
344         e = r;
345         STRV_FOREACH(s, l) {
346                 if (e != r)
347                         e = stpcpy(e, separator);
348
349                 e = stpcpy(e, *s);
350         }
351
352         *e = 0;
353
354         return r;
355 }
356
357 /// UNNEEDED by elogind
358 #if 0
359 char *strv_join_quoted(char **l) {
360         char *buf = NULL;
361         char **s;
362         size_t allocated = 0, len = 0;
363
364         STRV_FOREACH(s, l) {
365                 /* assuming here that escaped string cannot be more
366                  * than twice as long, and reserving space for the
367                  * separator and quotes.
368                  */
369                 _cleanup_free_ char *esc = NULL;
370                 size_t needed;
371
372                 if (!GREEDY_REALLOC(buf, allocated,
373                                     len + strlen(*s) * 2 + 3))
374                         goto oom;
375
376                 esc = cescape(*s);
377                 if (!esc)
378                         goto oom;
379
380                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
381                                   len > 0 ? " " : "", esc);
382                 assert(needed < allocated - len);
383                 len += needed;
384         }
385
386         if (!buf)
387                 buf = malloc0(1);
388
389         return buf;
390
391  oom:
392         free(buf);
393         return NULL;
394 }
395 #endif // 0
396
397 int strv_push(char ***l, char *value) {
398         char **c;
399         unsigned n, m;
400
401         if (!value)
402                 return 0;
403
404         n = strv_length(*l);
405
406         /* Increase and check for overflow */
407         m = n + 2;
408         if (m < n)
409                 return -ENOMEM;
410
411         c = realloc_multiply(*l, sizeof(char*), m);
412         if (!c)
413                 return -ENOMEM;
414
415         c[n] = value;
416         c[n+1] = NULL;
417
418         *l = c;
419         return 0;
420 }
421
422 int strv_push_pair(char ***l, char *a, char *b) {
423         char **c;
424         unsigned n, m;
425
426         if (!a && !b)
427                 return 0;
428
429         n = strv_length(*l);
430
431         /* increase and check for overflow */
432         m = n + !!a + !!b + 1;
433         if (m < n)
434                 return -ENOMEM;
435
436         c = realloc_multiply(*l, sizeof(char*), m);
437         if (!c)
438                 return -ENOMEM;
439
440         if (a)
441                 c[n++] = a;
442         if (b)
443                 c[n++] = b;
444         c[n] = NULL;
445
446         *l = c;
447         return 0;
448 }
449
450 int strv_push_prepend(char ***l, char *value) {
451         char **c;
452         unsigned n, m, i;
453
454         if (!value)
455                 return 0;
456
457         n = strv_length(*l);
458
459         /* increase and check for overflow */
460         m = n + 2;
461         if (m < n)
462                 return -ENOMEM;
463
464         c = new(char*, m);
465         if (!c)
466                 return -ENOMEM;
467
468         for (i = 0; i < n; i++)
469                 c[i+1] = (*l)[i];
470
471         c[0] = value;
472         c[n+1] = NULL;
473
474         free(*l);
475         *l = c;
476
477         return 0;
478 }
479
480 int strv_consume(char ***l, char *value) {
481         int r;
482
483         r = strv_push(l, value);
484         if (r < 0)
485                 free(value);
486
487         return r;
488 }
489
490 /// UNNEEDED by elogind
491 #if 0
492 int strv_consume_pair(char ***l, char *a, char *b) {
493         int r;
494
495         r = strv_push_pair(l, a, b);
496         if (r < 0) {
497                 free(a);
498                 free(b);
499         }
500
501         return r;
502 }
503 #endif // 0
504
505 int strv_consume_prepend(char ***l, char *value) {
506         int r;
507
508         r = strv_push_prepend(l, value);
509         if (r < 0)
510                 free(value);
511
512         return r;
513 }
514
515 int strv_extend(char ***l, const char *value) {
516         char *v;
517
518         if (!value)
519                 return 0;
520
521         v = strdup(value);
522         if (!v)
523                 return -ENOMEM;
524
525         return strv_consume(l, v);
526 }
527
528 char **strv_uniq(char **l) {
529         char **i;
530
531         /* Drops duplicate entries. The first identical string will be
532          * kept, the others dropped */
533
534         STRV_FOREACH(i, l)
535                 strv_remove(i+1, *i);
536
537         return l;
538 }
539
540 /// UNNEEDED by elogind
541 #if 0
542 bool strv_is_uniq(char **l) {
543         char **i;
544
545         STRV_FOREACH(i, l)
546                 if (strv_find(i+1, *i))
547                         return false;
548
549         return true;
550 }
551 #endif // 0
552
553 char **strv_remove(char **l, const char *s) {
554         char **f, **t;
555
556         if (!l)
557                 return NULL;
558
559         assert(s);
560
561         /* Drops every occurrence of s in the string list, edits
562          * in-place. */
563
564         for (f = t = l; *f; f++)
565                 if (streq(*f, s))
566                         free(*f);
567                 else
568                         *(t++) = *f;
569
570         *t = NULL;
571         return l;
572 }
573
574 char **strv_parse_nulstr(const char *s, size_t l) {
575         const char *p;
576         unsigned c = 0, i = 0;
577         char **v;
578
579         assert(s || l <= 0);
580
581         if (l <= 0)
582                 return new0(char*, 1);
583
584         for (p = s; p < s + l; p++)
585                 if (*p == 0)
586                         c++;
587
588         if (s[l-1] != 0)
589                 c++;
590
591         v = new0(char*, c+1);
592         if (!v)
593                 return NULL;
594
595         p = s;
596         while (p < s + l) {
597                 const char *e;
598
599                 e = memchr(p, 0, s + l - p);
600
601                 v[i] = strndup(p, e ? e - p : s + l - p);
602                 if (!v[i]) {
603                         strv_free(v);
604                         return NULL;
605                 }
606
607                 i++;
608
609                 if (!e)
610                         break;
611
612                 p = e + 1;
613         }
614
615         assert(i == c);
616
617         return v;
618 }
619
620 char **strv_split_nulstr(const char *s) {
621         const char *i;
622         char **r = NULL;
623
624         NULSTR_FOREACH(i, s)
625                 if (strv_extend(&r, i) < 0) {
626                         strv_free(r);
627                         return NULL;
628                 }
629
630         if (!r)
631                 return strv_new(NULL, NULL);
632
633         return r;
634 }
635
636 bool strv_overlap(char **a, char **b) {
637         char **i;
638
639         STRV_FOREACH(i, a)
640                 if (strv_contains(b, *i))
641                         return true;
642
643         return false;
644 }
645
646 static int str_compare(const void *_a, const void *_b) {
647         const char **a = (const char**) _a, **b = (const char**) _b;
648
649         return strcmp(*a, *b);
650 }
651
652 char **strv_sort(char **l) {
653
654         if (strv_isempty(l))
655                 return l;
656
657         qsort(l, strv_length(l), sizeof(char*), str_compare);
658         return l;
659 }
660
661 /// UNNEEDED by elogind
662 #if 0
663 bool strv_equal(char **a, char **b) {
664         if (!a || !b)
665                 return a == b;
666
667         for ( ; *a || *b; ++a, ++b)
668                 if (!streq_ptr(*a, *b))
669                         return false;
670
671         return true;
672 }
673 #endif // 0
674
675 void strv_print(char **l) {
676         char **s;
677
678         STRV_FOREACH(s, l)
679                 puts(*s);
680 }
681
682 /// UNNEEDED by elogind
683 #if 0
684 int strv_extendf(char ***l, const char *format, ...) {
685         va_list ap;
686         char *x;
687         int r;
688
689         va_start(ap, format);
690         r = vasprintf(&x, format, ap);
691         va_end(ap);
692
693         if (r < 0)
694                 return -ENOMEM;
695
696         return strv_consume(l, x);
697 }
698
699 char **strv_reverse(char **l) {
700         unsigned n, i;
701
702         n = strv_length(l);
703         if (n <= 1)
704                 return l;
705
706         for (i = 0; i < n / 2; i++) {
707                 char *t;
708
709                 t = l[i];
710                 l[i] = l[n-1-i];
711                 l[n-1-i] = t;
712         }
713
714         return l;
715 }
716
717 char **strv_shell_escape(char **l, const char *bad) {
718         char **s;
719
720         /* Escapes every character in every string in l that is in bad,
721          * edits in-place, does not roll-back on error. */
722
723         STRV_FOREACH(s, l) {
724                 char *v;
725
726                 v = shell_escape(*s, bad);
727                 if (!v)
728                         return NULL;
729
730                 free(*s);
731                 *s = v;
732         }
733
734         return l;
735 }
736 #endif // 0
737
738 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
739         char* const* p;
740
741         STRV_FOREACH(p, patterns)
742                 if (fnmatch(*p, s, 0) == 0)
743                         return true;
744
745         return false;
746 }