chiark / gitweb /
Unifiy free() usage
[elogind.git] / src / basic / 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 <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <errno.h>
26
27 #include "util.h"
28 #include "strv.h"
29
30 char *strv_find(char **l, const char *name) {
31         char **i;
32
33         assert(name);
34
35         STRV_FOREACH(i, l)
36                 if (streq(*i, name))
37                         return *i;
38
39         return NULL;
40 }
41
42 char *strv_find_prefix(char **l, const char *name) {
43         char **i;
44
45         assert(name);
46
47         STRV_FOREACH(i, l)
48                 if (startswith(*i, name))
49                         return *i;
50
51         return NULL;
52 }
53
54 char *strv_find_startswith(char **l, const char *name) {
55         char **i, *e;
56
57         assert(name);
58
59         /* Like strv_find_prefix, but actually returns only the
60          * suffix, not the whole item */
61
62         STRV_FOREACH(i, l) {
63                 e = startswith(*i, name);
64                 if (e)
65                         return e;
66         }
67
68         return NULL;
69 }
70
71 void strv_clear(char **l) {
72         char **k;
73
74         if (!l)
75                 return;
76
77         for (k = l; *k; k++)
78                 free(*k);
79
80         *l = NULL;
81 }
82
83 char **strv_free(char **l) {
84         strv_clear(l);
85         free(l);
86         return NULL;
87 }
88
89 char **strv_copy(char * const *l) {
90         char **r, **k;
91
92         k = r = new(char*, strv_length(l) + 1);
93         if (!r)
94                 return NULL;
95
96         if (l)
97                 for (; *l; k++, l++) {
98                         *k = strdup(*l);
99                         if (!*k) {
100                                 strv_free(r);
101                                 return NULL;
102                         }
103                 }
104
105         *k = NULL;
106         return r;
107 }
108
109 unsigned strv_length(char * const *l) {
110         unsigned n = 0;
111
112         if (!l)
113                 return 0;
114
115         for (; *l; l++)
116                 n++;
117
118         return n;
119 }
120
121 char **strv_new_ap(const char *x, va_list ap) {
122         const char *s;
123         char **a;
124         unsigned n = 0, i = 0;
125         va_list aq;
126
127         /* As a special trick we ignore all listed strings that equal
128          * (const char*) -1. This is supposed to be used with the
129          * STRV_IFNOTNULL() macro to include possibly NULL strings in
130          * the string list. */
131
132         if (x) {
133                 n = x == (const char*) -1 ? 0 : 1;
134
135                 va_copy(aq, ap);
136                 while ((s = va_arg(aq, const char*))) {
137                         if (s == (const char*) -1)
138                                 continue;
139
140                         n++;
141                 }
142
143                 va_end(aq);
144         }
145
146         a = new(char*, n+1);
147         if (!a)
148                 return NULL;
149
150         if (x) {
151                 if (x != (const char*) -1) {
152                         a[i] = strdup(x);
153                         if (!a[i])
154                                 goto fail;
155                         i++;
156                 }
157
158                 while ((s = va_arg(ap, const char*))) {
159
160                         if (s == (const char*) -1)
161                                 continue;
162
163                         a[i] = strdup(s);
164                         if (!a[i])
165                                 goto fail;
166
167                         i++;
168                 }
169         }
170
171         a[i] = NULL;
172
173         return a;
174
175 fail:
176         strv_free(a);
177         return NULL;
178 }
179
180 char **strv_new(const char *x, ...) {
181         char **r;
182         va_list ap;
183
184         va_start(ap, x);
185         r = strv_new_ap(x, ap);
186         va_end(ap);
187
188         return r;
189 }
190
191 int strv_extend_strv(char ***a, char **b) {
192         int r;
193         char **s;
194
195         STRV_FOREACH(s, b) {
196                 r = strv_extend(a, *s);
197                 if (r < 0)
198                         return r;
199         }
200
201         return 0;
202 }
203
204 /// UNNEEDED by elogind
205 #if 0
206 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
207         int r;
208         char **s;
209
210         STRV_FOREACH(s, b) {
211                 char *v;
212
213                 v = strappend(*s, suffix);
214                 if (!v)
215                         return -ENOMEM;
216
217                 r = strv_push(a, v);
218                 if (r < 0) {
219                         free(v);
220                         return r;
221                 }
222         }
223
224         return 0;
225 }
226 #endif // 0
227
228 char **strv_split(const char *s, const char *separator) {
229         const char *word, *state;
230         size_t l;
231         unsigned n, i;
232         char **r;
233
234         assert(s);
235
236         n = 0;
237         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
238                 n++;
239
240         r = new(char*, n+1);
241         if (!r)
242                 return NULL;
243
244         i = 0;
245         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
246                 r[i] = strndup(word, l);
247                 if (!r[i]) {
248                         strv_free(r);
249                         return NULL;
250                 }
251
252                 i++;
253         }
254
255         r[i] = NULL;
256         return r;
257 }
258
259 /// UNNEEDED by elogind
260 #if 0
261 char **strv_split_newlines(const char *s) {
262         char **l;
263         unsigned n;
264
265         assert(s);
266
267         /* Special version of strv_split() that splits on newlines and
268          * suppresses an empty string at the end */
269
270         l = strv_split(s, NEWLINE);
271         if (!l)
272                 return NULL;
273
274         n = strv_length(l);
275         if (n <= 0)
276                 return l;
277
278         if (isempty(l[n-1])) {
279                 l[n-1] = mfree(l[n-1]);
280         }
281
282         return l;
283 }
284
285 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
286         size_t n = 0, allocated = 0;
287         _cleanup_strv_free_ char **l = NULL;
288         int r;
289
290         assert(t);
291         assert(s);
292
293         for (;;) {
294                 _cleanup_free_ char *word = NULL;
295
296                 r = extract_first_word(&s, &word, separators, flags);
297                 if (r < 0)
298                         return r;
299                 if (r == 0) {
300                         break;
301                 }
302
303                 if (!GREEDY_REALLOC(l, allocated, n + 2))
304                         return -ENOMEM;
305
306                 l[n++] = word;
307                 word = NULL;
308
309                 l[n] = NULL;
310         }
311
312         if (!l)
313                 l = new0(char*, 1);
314
315         *t = l;
316         l = NULL;
317
318         return 0;
319 }
320 #endif // 0
321
322 char *strv_join(char **l, const char *separator) {
323         char *r, *e;
324         char **s;
325         size_t n, k;
326
327         if (!separator)
328                 separator = " ";
329
330         k = strlen(separator);
331
332         n = 0;
333         STRV_FOREACH(s, l) {
334                 if (n != 0)
335                         n += k;
336                 n += strlen(*s);
337         }
338
339         r = new(char, n+1);
340         if (!r)
341                 return NULL;
342
343         e = r;
344         STRV_FOREACH(s, l) {
345                 if (e != r)
346                         e = stpcpy(e, separator);
347
348                 e = stpcpy(e, *s);
349         }
350
351         *e = 0;
352
353         return r;
354 }
355
356 /// UNNEEDED by elogind
357 #if 0
358 char *strv_join_quoted(char **l) {
359         char *buf = NULL;
360         char **s;
361         size_t allocated = 0, len = 0;
362
363         STRV_FOREACH(s, l) {
364                 /* assuming here that escaped string cannot be more
365                  * than twice as long, and reserving space for the
366                  * separator and quotes.
367                  */
368                 _cleanup_free_ char *esc = NULL;
369                 size_t needed;
370
371                 if (!GREEDY_REALLOC(buf, allocated,
372                                     len + strlen(*s) * 2 + 3))
373                         goto oom;
374
375                 esc = cescape(*s);
376                 if (!esc)
377                         goto oom;
378
379                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
380                                   len > 0 ? " " : "", esc);
381                 assert(needed < allocated - len);
382                 len += needed;
383         }
384
385         if (!buf)
386                 buf = malloc0(1);
387
388         return buf;
389
390  oom:
391         free(buf);
392         return NULL;
393 }
394 #endif // 0
395
396 int strv_push(char ***l, char *value) {
397         char **c;
398         unsigned n, m;
399
400         if (!value)
401                 return 0;
402
403         n = strv_length(*l);
404
405         /* Increase and check for overflow */
406         m = n + 2;
407         if (m < n)
408                 return -ENOMEM;
409
410         c = realloc_multiply(*l, sizeof(char*), m);
411         if (!c)
412                 return -ENOMEM;
413
414         c[n] = value;
415         c[n+1] = NULL;
416
417         *l = c;
418         return 0;
419 }
420
421 int strv_push_pair(char ***l, char *a, char *b) {
422         char **c;
423         unsigned n, m;
424
425         if (!a && !b)
426                 return 0;
427
428         n = strv_length(*l);
429
430         /* increase and check for overflow */
431         m = n + !!a + !!b + 1;
432         if (m < n)
433                 return -ENOMEM;
434
435         c = realloc_multiply(*l, sizeof(char*), m);
436         if (!c)
437                 return -ENOMEM;
438
439         if (a)
440                 c[n++] = a;
441         if (b)
442                 c[n++] = b;
443         c[n] = NULL;
444
445         *l = c;
446         return 0;
447 }
448
449 int strv_push_prepend(char ***l, char *value) {
450         char **c;
451         unsigned n, m, i;
452
453         if (!value)
454                 return 0;
455
456         n = strv_length(*l);
457
458         /* increase and check for overflow */
459         m = n + 2;
460         if (m < n)
461                 return -ENOMEM;
462
463         c = new(char*, m);
464         if (!c)
465                 return -ENOMEM;
466
467         for (i = 0; i < n; i++)
468                 c[i+1] = (*l)[i];
469
470         c[0] = value;
471         c[n+1] = NULL;
472
473         free(*l);
474         *l = c;
475
476         return 0;
477 }
478
479 int strv_consume(char ***l, char *value) {
480         int r;
481
482         r = strv_push(l, value);
483         if (r < 0)
484                 free(value);
485
486         return r;
487 }
488
489 /// UNNEEDED by elogind
490 #if 0
491 int strv_consume_pair(char ***l, char *a, char *b) {
492         int r;
493
494         r = strv_push_pair(l, a, b);
495         if (r < 0) {
496                 free(a);
497                 free(b);
498         }
499
500         return r;
501 }
502 #endif // 0
503
504 int strv_consume_prepend(char ***l, char *value) {
505         int r;
506
507         r = strv_push_prepend(l, value);
508         if (r < 0)
509                 free(value);
510
511         return r;
512 }
513
514 int strv_extend(char ***l, const char *value) {
515         char *v;
516
517         if (!value)
518                 return 0;
519
520         v = strdup(value);
521         if (!v)
522                 return -ENOMEM;
523
524         return strv_consume(l, v);
525 }
526
527 char **strv_uniq(char **l) {
528         char **i;
529
530         /* Drops duplicate entries. The first identical string will be
531          * kept, the others dropped */
532
533         STRV_FOREACH(i, l)
534                 strv_remove(i+1, *i);
535
536         return l;
537 }
538
539 /// UNNEEDED by elogind
540 #if 0
541 bool strv_is_uniq(char **l) {
542         char **i;
543
544         STRV_FOREACH(i, l)
545                 if (strv_find(i+1, *i))
546                         return false;
547
548         return true;
549 }
550 #endif // 0
551
552 char **strv_remove(char **l, const char *s) {
553         char **f, **t;
554
555         if (!l)
556                 return NULL;
557
558         assert(s);
559
560         /* Drops every occurrence of s in the string list, edits
561          * in-place. */
562
563         for (f = t = l; *f; f++)
564                 if (streq(*f, s))
565                         free(*f);
566                 else
567                         *(t++) = *f;
568
569         *t = NULL;
570         return l;
571 }
572
573 char **strv_parse_nulstr(const char *s, size_t l) {
574         const char *p;
575         unsigned c = 0, i = 0;
576         char **v;
577
578         assert(s || l <= 0);
579
580         if (l <= 0)
581                 return new0(char*, 1);
582
583         for (p = s; p < s + l; p++)
584                 if (*p == 0)
585                         c++;
586
587         if (s[l-1] != 0)
588                 c++;
589
590         v = new0(char*, c+1);
591         if (!v)
592                 return NULL;
593
594         p = s;
595         while (p < s + l) {
596                 const char *e;
597
598                 e = memchr(p, 0, s + l - p);
599
600                 v[i] = strndup(p, e ? e - p : s + l - p);
601                 if (!v[i]) {
602                         strv_free(v);
603                         return NULL;
604                 }
605
606                 i++;
607
608                 if (!e)
609                         break;
610
611                 p = e + 1;
612         }
613
614         assert(i == c);
615
616         return v;
617 }
618
619 char **strv_split_nulstr(const char *s) {
620         const char *i;
621         char **r = NULL;
622
623         NULSTR_FOREACH(i, s)
624                 if (strv_extend(&r, i) < 0) {
625                         strv_free(r);
626                         return NULL;
627                 }
628
629         if (!r)
630                 return strv_new(NULL, NULL);
631
632         return r;
633 }
634
635 /// UNNEEDED by elogind
636 #if 0
637 bool strv_overlap(char **a, char **b) {
638         char **i;
639
640         STRV_FOREACH(i, a)
641                 if (strv_contains(b, *i))
642                         return true;
643
644         return false;
645 }
646
647 static int str_compare(const void *_a, const void *_b) {
648         const char **a = (const char**) _a, **b = (const char**) _b;
649
650         return strcmp(*a, *b);
651 }
652
653 char **strv_sort(char **l) {
654
655         if (strv_isempty(l))
656                 return l;
657
658         qsort(l, strv_length(l), sizeof(char*), str_compare);
659         return l;
660 }
661
662 bool strv_equal(char **a, char **b) {
663         if (!a || !b)
664                 return a == b;
665
666         for ( ; *a || *b; ++a, ++b)
667                 if (!streq_ptr(*a, *b))
668                         return false;
669
670         return true;
671 }
672
673 void strv_print(char **l) {
674         char **s;
675
676         STRV_FOREACH(s, l)
677                 puts(*s);
678 }
679
680 int strv_extendf(char ***l, const char *format, ...) {
681         va_list ap;
682         char *x;
683         int r;
684
685         va_start(ap, format);
686         r = vasprintf(&x, format, ap);
687         va_end(ap);
688
689         if (r < 0)
690                 return -ENOMEM;
691
692         return strv_consume(l, x);
693 }
694
695 char **strv_reverse(char **l) {
696         unsigned n, i;
697
698         n = strv_length(l);
699         if (n <= 1)
700                 return l;
701
702         for (i = 0; i < n / 2; i++) {
703                 char *t;
704
705                 t = l[i];
706                 l[i] = l[n-1-i];
707                 l[n-1-i] = t;
708         }
709
710         return l;
711 }
712
713 char **strv_shell_escape(char **l, const char *bad) {
714         char **s;
715
716         /* Escapes every character in every string in l that is in bad,
717          * edits in-place, does not roll-back on error. */
718
719         STRV_FOREACH(s, l) {
720                 char *v;
721
722                 v = shell_escape(*s, bad);
723                 if (!v)
724                         return NULL;
725
726                 free(*s);
727                 *s = v;
728         }
729
730         return l;
731 }
732 #endif // 0
733
734 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
735         char* const* p;
736
737         STRV_FOREACH(p, patterns)
738                 if (fnmatch(*p, s, 0) == 0)
739                         return true;
740
741         return false;
742 }