chiark / gitweb /
3e7778d61ca663eab8c2f23f9d024ef14ffa842c
[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 * const *l) {
68         char **r, **k;
69
70         k = r = new(char*, strv_length(l) + 1);
71         if (!r)
72                 return NULL;
73
74         if (l)
75                 for (; *l; k++, l++) {
76                         *k = strdup(*l);
77                         if (!*k) {
78                                 strv_free(r);
79                                 return NULL;
80                         }
81                 }
82
83         *k = NULL;
84         return r;
85 }
86
87 unsigned strv_length(char * const *l) {
88         unsigned n = 0;
89
90         if (!l)
91                 return 0;
92
93         for (; *l; l++)
94                 n++;
95
96         return n;
97 }
98
99 char **strv_new_ap(const char *x, va_list ap) {
100         const char *s;
101         char **a;
102         unsigned n = 0, i = 0;
103         va_list aq;
104
105         /* As a special trick we ignore all listed strings that equal
106          * (const char*) -1. This is supposed to be used with the
107          * STRV_IFNOTNULL() macro to include possibly NULL strings in
108          * the string list. */
109
110         if (x) {
111                 n = x == (const char*) -1 ? 0 : 1;
112
113                 va_copy(aq, ap);
114                 while ((s = va_arg(aq, const char*))) {
115                         if (s == (const char*) -1)
116                                 continue;
117
118                         n++;
119                 }
120
121                 va_end(aq);
122         }
123
124         a = new(char*, n+1);
125         if (!a)
126                 return NULL;
127
128         if (x) {
129                 if (x != (const char*) -1) {
130                         a[i] = strdup(x);
131                         if (!a[i])
132                                 goto fail;
133                         i++;
134                 }
135
136                 while ((s = va_arg(ap, const char*))) {
137
138                         if (s == (const char*) -1)
139                                 continue;
140
141                         a[i] = strdup(s);
142                         if (!a[i])
143                                 goto fail;
144
145                         i++;
146                 }
147         }
148
149         a[i] = NULL;
150
151         return a;
152
153 fail:
154         strv_free(a);
155         return NULL;
156 }
157
158 char **strv_new(const char *x, ...) {
159         char **r;
160         va_list ap;
161
162         va_start(ap, x);
163         r = strv_new_ap(x, ap);
164         va_end(ap);
165
166         return r;
167 }
168
169 char **strv_merge(char **a, char **b) {
170         char **r, **k;
171
172         if (!a)
173                 return strv_copy(b);
174
175         if (!b)
176                 return strv_copy(a);
177
178         r = new(char*, strv_length(a) + strv_length(b) + 1);
179         if (!r)
180                 return NULL;
181
182         for (k = r; *a; k++, a++) {
183                 *k = strdup(*a);
184                 if (!*k)
185                         goto fail;
186         }
187
188         for (; *b; k++, b++) {
189                 *k = strdup(*b);
190                 if (!*k)
191                         goto fail;
192         }
193
194         *k = NULL;
195         return r;
196
197 fail:
198         strv_free(r);
199         return NULL;
200 }
201
202 char **strv_merge_concat(char **a, char **b, const char *suffix) {
203         char **r, **k;
204
205         /* Like strv_merge(), but appends suffix to all strings in b, before adding */
206
207         if (!b)
208                 return strv_copy(a);
209
210         r = new(char*, strv_length(a) + strv_length(b) + 1);
211         if (!r)
212                 return NULL;
213
214         k = r;
215         if (a)
216                 for (; *a; k++, a++) {
217                         *k = strdup(*a);
218                         if (!*k)
219                                 goto fail;
220                 }
221
222         for (; *b; k++, b++) {
223                 *k = strappend(*b, suffix);
224                 if (!*k)
225                         goto fail;
226         }
227
228         *k = NULL;
229         return r;
230
231 fail:
232         strv_free(r);
233         return NULL;
234
235 }
236
237 char **strv_split(const char *s, const char *separator) {
238         char *state;
239         char *w;
240         size_t l;
241         unsigned n, i;
242         char **r;
243
244         assert(s);
245
246         n = 0;
247         FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
248                 n++;
249
250         r = new(char*, n+1);
251         if (!r)
252                 return NULL;
253
254         i = 0;
255         FOREACH_WORD_SEPARATOR(w, l, s, separator, state) {
256                 r[i] = strndup(w, l);
257                 if (!r[i]) {
258                         strv_free(r);
259                         return NULL;
260                 }
261
262                 i++;
263         }
264
265         r[i] = NULL;
266         return r;
267 }
268
269 char **strv_split_quoted(const char *s) {
270         char *state;
271         char *w;
272         size_t l;
273         unsigned n, i;
274         char **r;
275
276         assert(s);
277
278         n = 0;
279         FOREACH_WORD_QUOTED(w, l, s, state)
280                 n++;
281
282         r = new(char*, n+1);
283         if (!r)
284                 return NULL;
285
286         i = 0;
287         FOREACH_WORD_QUOTED(w, l, s, state) {
288                 r[i] = cunescape_length(w, l);
289                 if (!r[i]) {
290                         strv_free(r);
291                         return NULL;
292                 }
293                 i++;
294         }
295
296         r[i] = NULL;
297         return r;
298 }
299
300 char **strv_split_newlines(const char *s) {
301         char **l;
302         unsigned n;
303
304         assert(s);
305
306         /* Special version of strv_split() that splits on newlines and
307          * suppresses an empty string at the end */
308
309         l = strv_split(s, NEWLINE);
310         if (!l)
311                 return NULL;
312
313         n = strv_length(l);
314         if (n <= 0)
315                 return l;
316
317         if (isempty(l[n-1])) {
318                 free(l[n-1]);
319                 l[n-1] = NULL;
320         }
321
322         return l;
323 }
324
325 char *strv_join(char **l, const char *separator) {
326         char *r, *e;
327         char **s;
328         size_t n, k;
329
330         if (!separator)
331                 separator = " ";
332
333         k = strlen(separator);
334
335         n = 0;
336         STRV_FOREACH(s, l) {
337                 if (n != 0)
338                         n += k;
339                 n += strlen(*s);
340         }
341
342         r = new(char, n+1);
343         if (!r)
344                 return NULL;
345
346         e = r;
347         STRV_FOREACH(s, l) {
348                 if (e != r)
349                         e = stpcpy(e, separator);
350
351                 e = stpcpy(e, *s);
352         }
353
354         *e = 0;
355
356         return r;
357 }
358
359 char **strv_append(char **l, const char *s) {
360         char **r, **k;
361
362         if (!l)
363                 return strv_new(s, NULL);
364
365         if (!s)
366                 return strv_copy(l);
367
368         r = new(char*, strv_length(l)+2);
369         if (!r)
370                 return NULL;
371
372         for (k = r; *l; k++, l++) {
373                 *k = strdup(*l);
374                 if (!*k)
375                         goto fail;
376         }
377
378         k[0] = strdup(s);
379         if (!k[0])
380                 goto fail;
381
382         k[1] = NULL;
383         return r;
384
385 fail:
386         strv_free(r);
387         return NULL;
388 }
389
390 char **strv_appendf(char **l, const char *format, ...) {
391         va_list ap;
392         _cleanup_free_ char *s = NULL;
393         int r;
394
395         va_start(ap, format);
396         r = vasprintf(&s, format, ap);
397         va_end(ap);
398
399         if (r < 0)
400                 return NULL;
401
402         return strv_append(l, s);
403 }
404
405 int strv_push(char ***l, char *value) {
406         char **c;
407         unsigned n;
408
409         if (!value)
410                 return 0;
411
412         n = strv_length(*l);
413         c = realloc(*l, sizeof(char*) * (n + 2));
414         if (!c)
415                 return -ENOMEM;
416
417         c[n] = value;
418         c[n+1] = NULL;
419
420         *l = c;
421         return 0;
422 }
423
424 int strv_extend(char ***l, const char *value) {
425         char *v;
426         int r;
427
428         if (!value)
429                 return 0;
430
431         v = strdup(value);
432         if (!v)
433                 return -ENOMEM;
434
435         r = strv_push(l, v);
436         if (r < 0)
437                 free(v);
438
439         return r;
440 }
441
442 char **strv_uniq(char **l) {
443         char **i;
444
445         /* Drops duplicate entries. The first identical string will be
446          * kept, the others dropped */
447
448         STRV_FOREACH(i, l)
449                 strv_remove(i+1, *i);
450
451         return l;
452 }
453
454 char **strv_remove(char **l, const char *s) {
455         char **f, **t;
456
457         if (!l)
458                 return NULL;
459
460         assert(s);
461
462         /* Drops every occurrence of s in the string list, edits
463          * in-place. */
464
465         for (f = t = l; *f; f++) {
466
467                 if (streq(*f, s)) {
468                         free(*f);
469                         continue;
470                 }
471
472                 *(t++) = *f;
473         }
474
475         *t = NULL;
476         return l;
477 }
478
479 char **strv_remove_prefix(char **l, const char *s) {
480         char **f, **t;
481
482         if (!l)
483                 return NULL;
484
485         assert(s);
486
487         /* Drops every occurrence of a string prefixed with s in the
488          * string list, edits in-place. */
489
490         for (f = t = l; *f; f++) {
491
492                 if (startswith(*f, s)) {
493                         free(*f);
494                         continue;
495                 }
496
497                 *(t++) = *f;
498         }
499
500         *t = NULL;
501         return l;
502 }
503
504 char **strv_parse_nulstr(const char *s, size_t l) {
505         const char *p;
506         unsigned c = 0, i = 0;
507         char **v;
508
509         assert(s || l <= 0);
510
511         if (l <= 0)
512                 return strv_new(NULL, NULL);
513
514         for (p = s; p < s + l; p++)
515                 if (*p == 0)
516                         c++;
517
518         if (s[l-1] != 0)
519                 c++;
520
521         v = new0(char*, c+1);
522         if (!v)
523                 return NULL;
524
525         p = s;
526         while (p < s + l) {
527                 const char *e;
528
529                 e = memchr(p, 0, s + l - p);
530
531                 v[i] = strndup(p, e ? e - p : s + l - p);
532                 if (!v[i]) {
533                         strv_free(v);
534                         return NULL;
535                 }
536
537                 i++;
538
539                 if (!e)
540                         break;
541
542                 p = e + 1;
543         }
544
545         assert(i == c);
546
547         return v;
548 }
549
550 char **strv_split_nulstr(const char *s) {
551         const char *i;
552         char **r = NULL;
553
554         NULSTR_FOREACH(i, s)
555                 if (strv_extend(&r, i) < 0) {
556                         strv_free(r);
557                         return NULL;
558                 }
559
560         if (!r)
561                 return strv_new(NULL, NULL);
562
563         return r;
564 }
565
566 bool strv_overlap(char **a, char **b) {
567         char **i, **j;
568
569         STRV_FOREACH(i, a) {
570                 STRV_FOREACH(j, b) {
571                         if (streq(*i, *j))
572                                 return true;
573                 }
574         }
575
576         return false;
577 }
578
579 static int str_compare(const void *_a, const void *_b) {
580         const char **a = (const char**) _a, **b = (const char**) _b;
581
582         return strcmp(*a, *b);
583 }
584
585 char **strv_sort(char **l) {
586
587         if (strv_isempty(l))
588                 return l;
589
590         qsort(l, strv_length(l), sizeof(char*), str_compare);
591         return l;
592 }
593
594 void strv_print(char **l) {
595         char **s;
596
597         if (!l)
598                 return;
599
600         STRV_FOREACH(s, l)
601                 puts(*s);
602 }