chiark / gitweb /
bus: include unique and well known names in credentials object
[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_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
396 char **strv_append(char **l, const char *s) {
397         char **r, **k;
398
399         if (!l)
400                 return strv_new(s, NULL);
401
402         if (!s)
403                 return strv_copy(l);
404
405         r = new(char*, strv_length(l)+2);
406         if (!r)
407                 return NULL;
408
409         for (k = r; *l; k++, l++) {
410                 *k = strdup(*l);
411                 if (!*k)
412                         goto fail;
413         }
414
415         k[0] = strdup(s);
416         if (!k[0])
417                 goto fail;
418
419         k[1] = NULL;
420         return r;
421
422 fail:
423         strv_free(r);
424         return NULL;
425 }
426
427 int strv_push(char ***l, char *value) {
428         char **c;
429         unsigned n;
430
431         if (!value)
432                 return 0;
433
434         n = strv_length(*l);
435         c = realloc(*l, sizeof(char*) * (n + 2));
436         if (!c)
437                 return -ENOMEM;
438
439         c[n] = value;
440         c[n+1] = NULL;
441
442         *l = c;
443         return 0;
444 }
445
446 int strv_extend(char ***l, const char *value) {
447         char *v;
448         int r;
449
450         if (!value)
451                 return 0;
452
453         v = strdup(value);
454         if (!v)
455                 return -ENOMEM;
456
457         r = strv_push(l, v);
458         if (r < 0)
459                 free(v);
460
461         return r;
462 }
463
464 char **strv_uniq(char **l) {
465         char **i;
466
467         /* Drops duplicate entries. The first identical string will be
468          * kept, the others dropped */
469
470         STRV_FOREACH(i, l)
471                 strv_remove(i+1, *i);
472
473         return l;
474 }
475
476 char **strv_remove(char **l, const char *s) {
477         char **f, **t;
478
479         if (!l)
480                 return NULL;
481
482         assert(s);
483
484         /* Drops every occurrence of s in the string list, edits
485          * in-place. */
486
487         for (f = t = l; *f; f++) {
488
489                 if (streq(*f, s)) {
490                         free(*f);
491                         continue;
492                 }
493
494                 *(t++) = *f;
495         }
496
497         *t = NULL;
498         return l;
499 }
500
501 char **strv_remove_prefix(char **l, const char *s) {
502         char **f, **t;
503
504         if (!l)
505                 return NULL;
506
507         assert(s);
508
509         /* Drops every occurrence of a string prefixed with s in the
510          * string list, edits in-place. */
511
512         for (f = t = l; *f; f++) {
513
514                 if (startswith(*f, s)) {
515                         free(*f);
516                         continue;
517                 }
518
519                 *(t++) = *f;
520         }
521
522         *t = NULL;
523         return l;
524 }
525
526 char **strv_parse_nulstr(const char *s, size_t l) {
527         const char *p;
528         unsigned c = 0, i = 0;
529         char **v;
530
531         assert(s || l <= 0);
532
533         if (l <= 0)
534                 return new0(char*, 1);
535
536         for (p = s; p < s + l; p++)
537                 if (*p == 0)
538                         c++;
539
540         if (s[l-1] != 0)
541                 c++;
542
543         v = new0(char*, c+1);
544         if (!v)
545                 return NULL;
546
547         p = s;
548         while (p < s + l) {
549                 const char *e;
550
551                 e = memchr(p, 0, s + l - p);
552
553                 v[i] = strndup(p, e ? e - p : s + l - p);
554                 if (!v[i]) {
555                         strv_free(v);
556                         return NULL;
557                 }
558
559                 i++;
560
561                 if (!e)
562                         break;
563
564                 p = e + 1;
565         }
566
567         assert(i == c);
568
569         return v;
570 }
571
572 char **strv_split_nulstr(const char *s) {
573         const char *i;
574         char **r = NULL;
575
576         NULSTR_FOREACH(i, s)
577                 if (strv_extend(&r, i) < 0) {
578                         strv_free(r);
579                         return NULL;
580                 }
581
582         if (!r)
583                 return strv_new(NULL, NULL);
584
585         return r;
586 }
587
588 bool strv_overlap(char **a, char **b) {
589         char **i, **j;
590
591         STRV_FOREACH(i, a) {
592                 STRV_FOREACH(j, b) {
593                         if (streq(*i, *j))
594                                 return true;
595                 }
596         }
597
598         return false;
599 }
600
601 static int str_compare(const void *_a, const void *_b) {
602         const char **a = (const char**) _a, **b = (const char**) _b;
603
604         return strcmp(*a, *b);
605 }
606
607 char **strv_sort(char **l) {
608
609         if (strv_isempty(l))
610                 return l;
611
612         qsort(l, strv_length(l), sizeof(char*), str_compare);
613         return l;
614 }
615
616 void strv_print(char **l) {
617         char **s;
618
619         if (!l)
620                 return;
621
622         STRV_FOREACH(s, l)
623                 puts(*s);
624 }