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