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