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