LCOV - code coverage report
Current view: top level - basic - strv.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 302 357 84.6 %
Date: 2015-07-29 18:47:03 Functions: 35 36 97.2 %

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

Generated by: LCOV version 1.11