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