chiark / gitweb /
util: fix tty_is_vc_resolve() in a container where /sys/class/tty/console/active...
[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 <assert.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include "util.h"
29 #include "strv.h"
30
31 char *strv_find(char **l, const char *name) {
32         char **i;
33
34         assert(name);
35
36         STRV_FOREACH(i, l)
37                 if (streq(*i, name))
38                         return *i;
39
40         return NULL;
41 }
42
43 char *strv_find_prefix(char **l, const char *name) {
44         char **i;
45
46         assert(name);
47
48         STRV_FOREACH(i, l)
49                 if (startswith(*i, name))
50                         return *i;
51
52         return NULL;
53 }
54
55 void strv_free(char **l) {
56         char **k;
57
58         if (!l)
59                 return;
60
61         for (k = l; *k; k++)
62                 free(*k);
63
64         free(l);
65 }
66
67 char **strv_copy(char **l) {
68         char **r, **k;
69
70         k = r = new(char*, strv_length(l)+1);
71         if (!k)
72                 return NULL;
73
74         if (l)
75                 for (; *l; k++, l++)
76                         if (!(*k = strdup(*l)))
77                                 goto fail;
78
79         *k = NULL;
80         return r;
81
82 fail:
83         for (k--; k >= r; k--)
84                 free(*k);
85
86         free(r);
87
88         return NULL;
89 }
90
91 unsigned strv_length(char **l) {
92         unsigned n = 0;
93
94         if (!l)
95                 return 0;
96
97         for (; *l; l++)
98                 n++;
99
100         return n;
101 }
102
103 char **strv_new_ap(const char *x, va_list ap) {
104         const char *s;
105         char **a;
106         unsigned n = 0, i = 0;
107         va_list aq;
108
109         if (x) {
110                 n = 1;
111
112                 va_copy(aq, ap);
113                 while (va_arg(aq, const char*))
114                         n++;
115                 va_end(aq);
116         }
117
118         if (!(a = new(char*, n+1)))
119                 return NULL;
120
121         if (x) {
122                 if (!(a[i] = strdup(x))) {
123                         free(a);
124                         return NULL;
125                 }
126
127                 i++;
128
129                 while ((s = va_arg(ap, const char*))) {
130                         if (!(a[i] = strdup(s)))
131                                 goto fail;
132
133                         i++;
134                 }
135         }
136
137         a[i] = NULL;
138
139         return a;
140
141 fail:
142
143         for (; i > 0; i--)
144                 if (a[i-1])
145                         free(a[i-1]);
146
147         free(a);
148
149         return NULL;
150 }
151
152 char **strv_new(const char *x, ...) {
153         char **r;
154         va_list ap;
155
156         va_start(ap, x);
157         r = strv_new_ap(x, ap);
158         va_end(ap);
159
160         return r;
161 }
162
163 char **strv_merge(char **a, char **b) {
164         char **r, **k;
165
166         if (!a)
167                 return strv_copy(b);
168
169         if (!b)
170                 return strv_copy(a);
171
172         if (!(r = new(char*, strv_length(a)+strv_length(b)+1)))
173                 return NULL;
174
175         for (k = r; *a; k++, a++)
176                 if (!(*k = strdup(*a)))
177                         goto fail;
178         for (; *b; k++, b++)
179                 if (!(*k = strdup(*b)))
180                         goto fail;
181
182         *k = NULL;
183         return r;
184
185 fail:
186         for (k--; k >= r; k--)
187                 free(*k);
188
189         free(r);
190
191         return NULL;
192 }
193
194 char **strv_merge_concat(char **a, char **b, const char *suffix) {
195         char **r, **k;
196
197         /* Like strv_merge(), but appends suffix to all strings in b, before adding */
198
199         if (!b)
200                 return strv_copy(a);
201
202         r = new(char*, strv_length(a) + strv_length(b) + 1);
203         if (!r)
204                 return NULL;
205
206         k = r;
207         if (a)
208                 for (; *a; k++, a++) {
209                         *k = strdup(*a);
210                         if (!*k)
211                                 goto fail;
212                 }
213
214         for (; *b; k++, b++) {
215                 *k = strappend(*b, suffix);
216                 if (!*k)
217                         goto fail;
218         }
219
220         *k = NULL;
221         return r;
222
223 fail:
224         for (k--; k >= r; k--)
225                 free(*k);
226
227         free(r);
228
229         return NULL;
230
231 }
232
233 char **strv_split(const char *s, const char *separator) {
234         char *state;
235         char *w;
236         size_t l;
237         unsigned n, i;
238         char **r;
239
240         assert(s);
241
242         n = 0;
243         FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
244                 n++;
245
246         if (!(r = new(char*, n+1)))
247                 return NULL;
248
249         i = 0;
250         FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
251                 if (!(r[i++] = strndup(w, l))) {
252                         strv_free(r);
253                         return NULL;
254                 }
255
256         r[i] = NULL;
257         return r;
258 }
259
260 char **strv_split_quoted(const char *s) {
261         char *state;
262         char *w;
263         size_t l;
264         unsigned n, i;
265         char **r;
266
267         assert(s);
268
269         n = 0;
270         FOREACH_WORD_QUOTED(w, l, s, state)
271                 n++;
272
273         if (!(r = new(char*, n+1)))
274                 return NULL;
275
276         i = 0;
277         FOREACH_WORD_QUOTED(w, l, s, state)
278                 if (!(r[i++] = cunescape_length(w, l))) {
279                         strv_free(r);
280                         return NULL;
281                 }
282
283         r[i] = NULL;
284         return r;
285 }
286
287 char *strv_join(char **l, const char *separator) {
288         char *r, *e;
289         char **s;
290         size_t n, k;
291
292         if (!separator)
293                 separator = " ";
294
295         k = strlen(separator);
296
297         n = 0;
298         STRV_FOREACH(s, l) {
299                 if (n != 0)
300                         n += k;
301                 n += strlen(*s);
302         }
303
304         if (!(r = new(char, n+1)))
305                 return NULL;
306
307         e = r;
308         STRV_FOREACH(s, l) {
309                 if (e != r)
310                         e = stpcpy(e, separator);
311
312                 e = stpcpy(e, *s);
313         }
314
315         *e = 0;
316
317         return r;
318 }
319
320 char **strv_append(char **l, const char *s) {
321         char **r, **k;
322
323         if (!l)
324                 return strv_new(s, NULL);
325
326         if (!s)
327                 return strv_copy(l);
328
329         r = new(char*, strv_length(l)+2);
330         if (!r)
331                 return NULL;
332
333         for (k = r; *l; k++, l++)
334                 if (!(*k = strdup(*l)))
335                         goto fail;
336
337         if (!(*(k++) = strdup(s)))
338                 goto fail;
339
340         *k = NULL;
341         return r;
342
343 fail:
344         for (k--; k >= r; k--)
345                 free(*k);
346
347         free(r);
348
349         return NULL;
350 }
351
352 char **strv_uniq(char **l) {
353         char **i;
354
355         /* Drops duplicate entries. The first identical string will be
356          * kept, the others dropped */
357
358         STRV_FOREACH(i, l)
359                 strv_remove(i+1, *i);
360
361         return l;
362 }
363
364 char **strv_remove(char **l, const char *s) {
365         char **f, **t;
366
367         if (!l)
368                 return NULL;
369
370         assert(s);
371
372         /* Drops every occurrence of s in the string list, edits
373          * in-place. */
374
375         for (f = t = l; *f; f++) {
376
377                 if (streq(*f, s)) {
378                         free(*f);
379                         continue;
380                 }
381
382                 *(t++) = *f;
383         }
384
385         *t = NULL;
386         return l;
387 }
388
389 char **strv_remove_prefix(char **l, const char *s) {
390         char **f, **t;
391
392         if (!l)
393                 return NULL;
394
395         assert(s);
396
397         /* Drops every occurrence of a string prefixed with s in the
398          * string list, edits in-place. */
399
400         for (f = t = l; *f; f++) {
401
402                 if (startswith(*f, s)) {
403                         free(*f);
404                         continue;
405                 }
406
407                 *(t++) = *f;
408         }
409
410         *t = NULL;
411         return l;
412 }
413
414 static int env_append(char **r, char ***k, char **a) {
415         assert(r);
416         assert(k);
417
418         if (!a)
419                 return 0;
420
421         /* Add the entries of a to *k unless they already exist in *r
422          * in which case they are overridden instead. This assumes
423          * there is enough space in the r array. */
424
425         for (; *a; a++) {
426                 char **j;
427                 size_t n;
428
429                 n = strcspn(*a, "=");
430
431                 if ((*a)[n] == '=')
432                         n++;
433
434                 for (j = r; j < *k; j++)
435                         if (strncmp(*j, *a, n) == 0)
436                                 break;
437
438                 if (j >= *k)
439                         (*k)++;
440                 else
441                         free(*j);
442
443                 if (!(*j = strdup(*a)))
444                         return -ENOMEM;
445         }
446
447         return 0;
448 }
449
450 char **strv_env_merge(unsigned n_lists, ...) {
451         size_t n = 0;
452         char **l, **k, **r;
453         va_list ap;
454         unsigned i;
455
456         /* Merges an arbitrary number of environment sets */
457
458         va_start(ap, n_lists);
459         for (i = 0; i < n_lists; i++) {
460                 l = va_arg(ap, char**);
461                 n += strv_length(l);
462         }
463         va_end(ap);
464
465         if (!(r = new(char*, n+1)))
466                 return NULL;
467
468         k = r;
469
470         va_start(ap, n_lists);
471         for (i = 0; i < n_lists; i++) {
472                 l = va_arg(ap, char**);
473                 if (env_append(r, &k, l) < 0)
474                         goto fail;
475         }
476         va_end(ap);
477
478         *k = NULL;
479
480         return r;
481
482 fail:
483         va_end(ap);
484
485         for (k--; k >= r; k--)
486                 free(*k);
487
488         free(r);
489
490         return NULL;
491 }
492
493 static bool env_match(const char *t, const char *pattern) {
494         assert(t);
495         assert(pattern);
496
497         /* pattern a matches string a
498          *         a matches a=
499          *         a matches a=b
500          *         a= matches a=
501          *         a=b matches a=b
502          *         a= does not match a
503          *         a=b does not match a=
504          *         a=b does not match a
505          *         a=b does not match a=c */
506
507         if (streq(t, pattern))
508                 return true;
509
510         if (!strchr(pattern, '=')) {
511                 size_t l = strlen(pattern);
512
513                 return strncmp(t, pattern, l) == 0 && t[l] == '=';
514         }
515
516         return false;
517 }
518
519 char **strv_env_delete(char **x, unsigned n_lists, ...) {
520         size_t n, i = 0;
521         char **k, **r;
522         va_list ap;
523
524         /* Deletes every entry from x that is mentioned in the other
525          * string lists */
526
527         n = strv_length(x);
528
529         r = new(char*, n+1);
530         if (!r)
531                 return NULL;
532
533         STRV_FOREACH(k, x) {
534                 unsigned v;
535
536                 va_start(ap, n_lists);
537                 for (v = 0; v < n_lists; v++) {
538                         char **l, **j;
539
540                         l = va_arg(ap, char**);
541                         STRV_FOREACH(j, l)
542                                 if (env_match(*k, *j))
543                                         goto skip;
544                 }
545                 va_end(ap);
546
547                 r[i] = strdup(*k);
548                 if (!r[i]) {
549                         strv_free(r);
550                         return NULL;
551                 }
552
553                 i++;
554                 continue;
555
556         skip:
557                 va_end(ap);
558         }
559
560         r[i] = NULL;
561
562         assert(i <= n);
563
564         return r;
565 }
566
567 char **strv_env_unset(char **l, const char *p) {
568
569         char **f, **t;
570
571         if (!l)
572                 return NULL;
573
574         assert(p);
575
576         /* Drops every occurrence of the env var setting p in the
577          * string list. edits in-place. */
578
579         for (f = t = l; *f; f++) {
580
581                 if (env_match(*f, p)) {
582                         free(*f);
583                         continue;
584                 }
585
586                 *(t++) = *f;
587         }
588
589         *t = NULL;
590         return l;
591 }
592
593 char **strv_env_set(char **x, const char *p) {
594
595         char **k, **r;
596         char* m[2] = { (char*) p, NULL };
597
598         /* Overrides the env var setting of p, returns a new copy */
599
600         if (!(r = new(char*, strv_length(x)+2)))
601                 return NULL;
602
603         k = r;
604         if (env_append(r, &k, x) < 0)
605                 goto fail;
606
607         if (env_append(r, &k, m) < 0)
608                 goto fail;
609
610         *k = NULL;
611
612         return r;
613
614 fail:
615         for (k--; k >= r; k--)
616                 free(*k);
617
618         free(r);
619
620         return NULL;
621
622 }
623
624 char *strv_env_get_with_length(char **l, const char *name, size_t k) {
625         char **i;
626
627         assert(name);
628
629         STRV_FOREACH(i, l)
630                 if (strncmp(*i, name, k) == 0 &&
631                     (*i)[k] == '=')
632                         return *i + k + 1;
633
634         return NULL;
635 }
636
637 char *strv_env_get(char **l, const char *name) {
638         return strv_env_get_with_length(l, name, strlen(name));
639 }
640
641 char **strv_env_clean(char **l) {
642         char **r, **ret;
643
644         for (r = ret = l; *l; l++) {
645                 const char *equal;
646
647                 equal = strchr(*l, '=');
648
649                 if (equal && equal[1] == 0) {
650                         free(*l);
651                         continue;
652                 }
653
654                 *(r++) = *l;
655         }
656
657         *r = NULL;
658
659         return ret;
660 }
661
662 char **strv_parse_nulstr(const char *s, size_t l) {
663         const char *p;
664         unsigned c = 0, i = 0;
665         char **v;
666
667         assert(s || l <= 0);
668
669         if (l <= 0)
670                 return strv_new(NULL, NULL);
671
672         for (p = s; p < s + l; p++)
673                 if (*p == 0)
674                         c++;
675
676         if (s[l-1] != 0)
677                 c++;
678
679         if (!(v = new0(char*, c+1)))
680                 return NULL;
681
682         p = s;
683         while (p < s + l) {
684                 const char *e;
685
686                 e = memchr(p, 0, s + l - p);
687
688                 if (!(v[i++] = strndup(p, e ? e - p : s + l - p))) {
689                         strv_free(v);
690                         return NULL;
691                 }
692
693                 if (!e)
694                         break;
695
696                 p = e + 1;
697         }
698
699         assert(i == c);
700
701         return v;
702 }
703
704 bool strv_overlap(char **a, char **b) {
705         char **i, **j;
706
707         STRV_FOREACH(i, a) {
708                 STRV_FOREACH(j, b) {
709                         if (streq(*i, *j))
710                                 return true;
711                 }
712         }
713
714         return false;
715 }