LCOV - code coverage report
Current view: top level - test - test-strv.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 675 675 100.0 %
Date: 2019-08-22 15:41:25 Functions: 44 44 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <string.h>
       4             : 
       5             : #include "alloc-util.h"
       6             : #include "escape.h"
       7             : #include "nulstr-util.h"
       8             : #include "specifier.h"
       9             : #include "string-util.h"
      10             : #include "strv.h"
      11             : 
      12           1 : static void test_specifier_printf(void) {
      13             :         static const Specifier table[] = {
      14             :                 { 'a', specifier_string, (char*) "AAAA" },
      15             :                 { 'b', specifier_string, (char*) "BBBB" },
      16             :                 { 'm', specifier_machine_id, NULL },
      17             :                 { 'B', specifier_boot_id, NULL },
      18             :                 { 'H', specifier_host_name, NULL },
      19             :                 { 'v', specifier_kernel_release, NULL },
      20             :                 {}
      21             :         };
      22             : 
      23           1 :         _cleanup_free_ char *w = NULL;
      24             :         int r;
      25             : 
      26           1 :         log_info("/* %s */", __func__);
      27             : 
      28           1 :         r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w);
      29           1 :         assert_se(r >= 0);
      30           1 :         assert_se(w);
      31             : 
      32           1 :         puts(w);
      33           1 :         assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
      34             : 
      35           1 :         free(w);
      36           1 :         r = specifier_printf("machine=%m, boot=%B, host=%H, version=%v", table, NULL, &w);
      37           1 :         assert_se(r >= 0);
      38           1 :         assert_se(w);
      39           1 :         puts(w);
      40           1 : }
      41             : 
      42           1 : static void test_str_in_set(void) {
      43           1 :         log_info("/* %s */", __func__);
      44             : 
      45           1 :         assert_se(STR_IN_SET("x", "x", "y", "z"));
      46           1 :         assert_se(!STR_IN_SET("X", "x", "y", "z"));
      47           1 :         assert_se(!STR_IN_SET("", "x", "y", "z"));
      48           1 :         assert_se(STR_IN_SET("x", "w", "x"));
      49           1 : }
      50             : 
      51           1 : static void test_strptr_in_set(void) {
      52           1 :         log_info("/* %s */", __func__);
      53             : 
      54           1 :         assert_se(STRPTR_IN_SET("x", "x", "y", "z"));
      55           1 :         assert_se(!STRPTR_IN_SET("X", "x", "y", "z"));
      56           1 :         assert_se(!STRPTR_IN_SET("", "x", "y", "z"));
      57           1 :         assert_se(STRPTR_IN_SET("x", "w", "x"));
      58             : 
      59           1 :         assert_se(!STRPTR_IN_SET(NULL, "x", "y", "z"));
      60           1 :         assert_se(!STRPTR_IN_SET(NULL, ""));
      61             :         /* strv cannot contain a null, hence the result below */
      62           1 :         assert_se(!STRPTR_IN_SET(NULL, NULL));
      63           1 : }
      64             : 
      65           1 : static void test_startswith_set(void) {
      66           1 :         log_info("/* %s */", __func__);
      67             : 
      68           4 :         assert_se(!STARTSWITH_SET("foo", "bar", "baz", "waldo"));
      69           2 :         assert_se(!STARTSWITH_SET("foo", "bar"));
      70             : 
      71           1 :         assert_se(STARTSWITH_SET("abc", "a", "ab", "abc"));
      72           2 :         assert_se(STARTSWITH_SET("abc", "ax", "ab", "abc"));
      73           3 :         assert_se(STARTSWITH_SET("abc", "ax", "abx", "abc"));
      74           4 :         assert_se(!STARTSWITH_SET("abc", "ax", "abx", "abcx"));
      75             : 
      76           3 :         assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "foo", "zzz"), "bar"));
      77           3 :         assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "", "zzz"), "foobar"));
      78           4 :         assert_se(streq_ptr(STARTSWITH_SET("", "hhh", "kkk", "zzz", ""), ""));
      79           1 : }
      80             : 
      81             : static const char* const input_table_multiple[] = {
      82             :         "one",
      83             :         "two",
      84             :         "three",
      85             :         NULL,
      86             : };
      87             : 
      88             : static const char* const input_table_quoted[] = {
      89             :         "one",
      90             :         "  two\t three ",
      91             :         " four  five",
      92             :         NULL,
      93             : };
      94             : 
      95             : static const char* const input_table_one[] = {
      96             :         "one",
      97             :         NULL,
      98             : };
      99             : 
     100             : static const char* const input_table_none[] = {
     101             :         NULL,
     102             : };
     103             : 
     104             : static const char* const input_table_two_empties[] = {
     105             :         "",
     106             :         "",
     107             :         NULL,
     108             : };
     109             : 
     110             : static const char* const input_table_one_empty[] = {
     111             :         "",
     112             :         NULL,
     113             : };
     114             : 
     115           1 : static void test_strv_find(void) {
     116           1 :         log_info("/* %s */", __func__);
     117             : 
     118           1 :         assert_se(strv_find((char **)input_table_multiple, "three"));
     119           1 :         assert_se(!strv_find((char **)input_table_multiple, "four"));
     120           1 : }
     121             : 
     122           1 : static void test_strv_find_prefix(void) {
     123           1 :         log_info("/* %s */", __func__);
     124             : 
     125           1 :         assert_se(strv_find_prefix((char **)input_table_multiple, "o"));
     126           1 :         assert_se(strv_find_prefix((char **)input_table_multiple, "one"));
     127           1 :         assert_se(strv_find_prefix((char **)input_table_multiple, ""));
     128           1 :         assert_se(!strv_find_prefix((char **)input_table_multiple, "xxx"));
     129           1 :         assert_se(!strv_find_prefix((char **)input_table_multiple, "onee"));
     130           1 : }
     131             : 
     132           1 : static void test_strv_find_startswith(void) {
     133             :         char *r;
     134             : 
     135           1 :         log_info("/* %s */", __func__);
     136             : 
     137           1 :         r = strv_find_startswith((char **)input_table_multiple, "o");
     138           1 :         assert_se(r && streq(r, "ne"));
     139             : 
     140           1 :         r = strv_find_startswith((char **)input_table_multiple, "one");
     141           1 :         assert_se(r && streq(r, ""));
     142             : 
     143           1 :         r = strv_find_startswith((char **)input_table_multiple, "");
     144           1 :         assert_se(r && streq(r, "one"));
     145             : 
     146           1 :         assert_se(!strv_find_startswith((char **)input_table_multiple, "xxx"));
     147           1 :         assert_se(!strv_find_startswith((char **)input_table_multiple, "onee"));
     148           1 : }
     149             : 
     150           1 : static void test_strv_join(void) {
     151           1 :         _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
     152             : 
     153           1 :         log_info("/* %s */", __func__);
     154             : 
     155           1 :         p = strv_join((char **)input_table_multiple, ", ");
     156           1 :         assert_se(p);
     157           1 :         assert_se(streq(p, "one, two, three"));
     158             : 
     159           1 :         q = strv_join((char **)input_table_multiple, ";");
     160           1 :         assert_se(q);
     161           1 :         assert_se(streq(q, "one;two;three"));
     162             : 
     163           1 :         r = strv_join((char **)input_table_multiple, NULL);
     164           1 :         assert_se(r);
     165           1 :         assert_se(streq(r, "one two three"));
     166             : 
     167           1 :         s = strv_join((char **)input_table_one, ", ");
     168           1 :         assert_se(s);
     169           1 :         assert_se(streq(s, "one"));
     170             : 
     171           1 :         t = strv_join((char **)input_table_none, ", ");
     172           1 :         assert_se(t);
     173           1 :         assert_se(streq(t, ""));
     174             : 
     175           1 :         v = strv_join((char **)input_table_two_empties, ", ");
     176           1 :         assert_se(v);
     177           1 :         assert_se(streq(v, ", "));
     178             : 
     179           1 :         w = strv_join((char **)input_table_one_empty, ", ");
     180           1 :         assert_se(w);
     181           1 :         assert_se(streq(w, ""));
     182           1 : }
     183             : 
     184           1 : static void test_strv_join_prefix(void) {
     185           1 :         _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
     186             : 
     187           1 :         log_info("/* %s */", __func__);
     188             : 
     189           1 :         p = strv_join_prefix((char **)input_table_multiple, ", ", "foo");
     190           1 :         assert_se(p);
     191           1 :         assert_se(streq(p, "fooone, footwo, foothree"));
     192             : 
     193           1 :         q = strv_join_prefix((char **)input_table_multiple, ";", "foo");
     194           1 :         assert_se(q);
     195           1 :         assert_se(streq(q, "fooone;footwo;foothree"));
     196             : 
     197           1 :         r = strv_join_prefix((char **)input_table_multiple, NULL, "foo");
     198           1 :         assert_se(r);
     199           1 :         assert_se(streq(r, "fooone footwo foothree"));
     200             : 
     201           1 :         s = strv_join_prefix((char **)input_table_one, ", ", "foo");
     202           1 :         assert_se(s);
     203           1 :         assert_se(streq(s, "fooone"));
     204             : 
     205           1 :         t = strv_join_prefix((char **)input_table_none, ", ", "foo");
     206           1 :         assert_se(t);
     207           1 :         assert_se(streq(t, ""));
     208             : 
     209           1 :         v = strv_join_prefix((char **)input_table_two_empties, ", ", "foo");
     210           1 :         assert_se(v);
     211           1 :         assert_se(streq(v, "foo, foo"));
     212             : 
     213           1 :         w = strv_join_prefix((char **)input_table_one_empty, ", ", "foo");
     214           1 :         assert_se(w);
     215           1 :         assert_se(streq(w, "foo"));
     216           1 : }
     217             : 
     218          13 : static void test_strv_unquote(const char *quoted, char **list) {
     219          13 :         _cleanup_strv_free_ char **s;
     220          13 :         _cleanup_free_ char *j;
     221          13 :         unsigned i = 0;
     222             :         char **t;
     223             :         int r;
     224             : 
     225          13 :         log_info("/* %s */", __func__);
     226             : 
     227          13 :         r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_UNQUOTE);
     228          13 :         assert_se(r == (int) strv_length(list));
     229          13 :         assert_se(s);
     230          13 :         j = strv_join(s, " | ");
     231          13 :         assert_se(j);
     232          13 :         puts(j);
     233             : 
     234          26 :         STRV_FOREACH(t, s)
     235          13 :                 assert_se(streq(list[i++], *t));
     236             : 
     237          13 :         assert_se(list[i] == NULL);
     238          13 : }
     239             : 
     240           7 : static void test_invalid_unquote(const char *quoted) {
     241           7 :         char **s = NULL;
     242             :         int r;
     243             : 
     244           7 :         log_info("/* %s */", __func__);
     245             : 
     246           7 :         r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_UNQUOTE);
     247           7 :         assert_se(s == NULL);
     248           7 :         assert_se(r == -EINVAL);
     249           7 : }
     250             : 
     251           1 : static void test_strv_split(void) {
     252           1 :         _cleanup_(strv_free_erasep) char **l = NULL;
     253           1 :         const char str[] = "one,two,three";
     254             : 
     255           1 :         log_info("/* %s */", __func__);
     256             : 
     257           1 :         l = strv_split(str, ",");
     258           1 :         assert_se(l);
     259           1 :         assert_se(strv_equal(l, (char**) input_table_multiple));
     260             : 
     261           1 :         strv_free_erase(l);
     262             : 
     263           1 :         l = strv_split("    one    two\t three", WHITESPACE);
     264           1 :         assert_se(l);
     265           1 :         assert_se(strv_equal(l, (char**) input_table_multiple));
     266             : 
     267           1 :         strv_free_erase(l);
     268             : 
     269             :         /* Setting NULL for separator is equivalent to WHITESPACE */
     270           1 :         l = strv_split("    one    two\t three", NULL);
     271           1 :         assert_se(l);
     272           1 :         assert_se(strv_equal(l, (char**) input_table_multiple));
     273             : 
     274           1 :         strv_free_erase(l);
     275             : 
     276           1 :         l = strv_split_full("    one    two\t three", NULL, 0);
     277           1 :         assert_se(l);
     278           1 :         assert_se(strv_equal(l, (char**) input_table_multiple));
     279             : 
     280           1 :         strv_free_erase(l);
     281             : 
     282           1 :         l = strv_split_full("    'one'  \"  two\t three \" ' four  five'", NULL, SPLIT_QUOTES);
     283           1 :         assert_se(l);
     284           1 :         assert_se(strv_equal(l, (char**) input_table_quoted));
     285             : 
     286           1 :         strv_free_erase(l);
     287             : 
     288             :         /* missing last quote ignores the last element. */
     289           1 :         l = strv_split_full("    'one'  \"  two\t three \" ' four  five'  ' ignored element ", NULL, SPLIT_QUOTES);
     290           1 :         assert_se(l);
     291           1 :         assert_se(strv_equal(l, (char**) input_table_quoted));
     292             : 
     293           1 :         strv_free_erase(l);
     294             : 
     295             :         /* missing last quote, but the last element is _not_ ignored with SPLIT_RELAX. */
     296           1 :         l = strv_split_full("    'one'  \"  two\t three \" ' four  five", NULL, SPLIT_QUOTES | SPLIT_RELAX);
     297           1 :         assert_se(l);
     298           1 :         assert_se(strv_equal(l, (char**) input_table_quoted));
     299             : 
     300           1 :         strv_free_erase(l);
     301             : 
     302             :         /* missing separator between */
     303           1 :         l = strv_split_full("    'one'  \"  two\t three \"' four  five'", NULL, SPLIT_QUOTES | SPLIT_RELAX);
     304           1 :         assert_se(l);
     305           1 :         assert_se(strv_equal(l, (char**) input_table_quoted));
     306             : 
     307           1 :         strv_free_erase(l);
     308             : 
     309           1 :         l = strv_split_full("    'one'  \"  two\t three \"' four  five", NULL, SPLIT_QUOTES | SPLIT_RELAX);
     310           1 :         assert_se(l);
     311           1 :         assert_se(strv_equal(l, (char**) input_table_quoted));
     312           1 : }
     313             : 
     314           1 : static void test_strv_split_empty(void) {
     315           1 :         _cleanup_strv_free_ char **l = NULL;
     316             : 
     317           1 :         log_info("/* %s */", __func__);
     318             : 
     319           1 :         l = strv_split("", WHITESPACE);
     320           1 :         assert_se(l);
     321           1 :         assert_se(strv_isempty(l));
     322             : 
     323           1 :         strv_free(l);
     324           1 :         l = strv_split("", NULL);
     325           1 :         assert_se(l);
     326           1 :         assert_se(strv_isempty(l));
     327             : 
     328           1 :         strv_free(l);
     329           1 :         l = strv_split_full("", NULL, 0);
     330           1 :         assert_se(l);
     331           1 :         assert_se(strv_isempty(l));
     332             : 
     333           1 :         strv_free(l);
     334           1 :         l = strv_split_full("", NULL, SPLIT_QUOTES);
     335           1 :         assert_se(l);
     336           1 :         assert_se(strv_isempty(l));
     337             : 
     338           1 :         strv_free(l);
     339           1 :         l = strv_split_full("", WHITESPACE, SPLIT_QUOTES);
     340           1 :         assert_se(l);
     341           1 :         assert_se(strv_isempty(l));
     342             : 
     343           1 :         strv_free(l);
     344           1 :         l = strv_split_full("", WHITESPACE, SPLIT_QUOTES | SPLIT_RELAX);
     345           1 :         assert_se(l);
     346           1 :         assert_se(strv_isempty(l));
     347             : 
     348           1 :         strv_free(l);
     349           1 :         l = strv_split("    ", WHITESPACE);
     350           1 :         assert_se(l);
     351           1 :         assert_se(strv_isempty(l));
     352             : 
     353           1 :         strv_free(l);
     354           1 :         l = strv_split("    ", NULL);
     355           1 :         assert_se(l);
     356           1 :         assert_se(strv_isempty(l));
     357             : 
     358           1 :         strv_free(l);
     359           1 :         l = strv_split_full("    ", NULL, 0);
     360           1 :         assert_se(l);
     361           1 :         assert_se(strv_isempty(l));
     362             : 
     363           1 :         strv_free(l);
     364           1 :         l = strv_split_full("    ", WHITESPACE, SPLIT_QUOTES);
     365           1 :         assert_se(l);
     366           1 :         assert_se(strv_isempty(l));
     367             : 
     368           1 :         strv_free(l);
     369           1 :         l = strv_split_full("    ", NULL, SPLIT_QUOTES);
     370           1 :         assert_se(l);
     371           1 :         assert_se(strv_isempty(l));
     372             : 
     373           1 :         strv_free(l);
     374           1 :         l = strv_split_full("    ", NULL, SPLIT_QUOTES | SPLIT_RELAX);
     375           1 :         assert_se(l);
     376           1 :         assert_se(strv_isempty(l));
     377           1 : }
     378             : 
     379           1 : static void test_strv_split_extract(void) {
     380           1 :         _cleanup_strv_free_ char **l = NULL;
     381           1 :         const char *str = ":foo\\:bar::waldo:";
     382             :         int r;
     383             : 
     384           1 :         log_info("/* %s */", __func__);
     385             : 
     386           1 :         r = strv_split_extract(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
     387           1 :         assert_se(r == (int) strv_length(l));
     388           1 :         assert_se(streq_ptr(l[0], ""));
     389           1 :         assert_se(streq_ptr(l[1], "foo:bar"));
     390           1 :         assert_se(streq_ptr(l[2], ""));
     391           1 :         assert_se(streq_ptr(l[3], "waldo"));
     392           1 :         assert_se(streq_ptr(l[4], ""));
     393           1 :         assert_se(streq_ptr(l[5], NULL));
     394           1 : }
     395             : 
     396           1 : static void test_strv_split_newlines(void) {
     397           1 :         unsigned i = 0;
     398             :         char **s;
     399           1 :         _cleanup_strv_free_ char **l = NULL;
     400           1 :         const char str[] = "one\ntwo\nthree";
     401             : 
     402           1 :         log_info("/* %s */", __func__);
     403             : 
     404           1 :         l = strv_split_newlines(str);
     405           1 :         assert_se(l);
     406             : 
     407           4 :         STRV_FOREACH(s, l) {
     408           3 :                 assert_se(streq(*s, input_table_multiple[i++]));
     409             :         }
     410           1 : }
     411             : 
     412           1 : static void test_strv_split_nulstr(void) {
     413           1 :         _cleanup_strv_free_ char **l = NULL;
     414           1 :         const char nulstr[] = "str0\0str1\0str2\0str3\0";
     415             : 
     416           1 :         log_info("/* %s */", __func__);
     417             : 
     418           1 :         l = strv_split_nulstr (nulstr);
     419           1 :         assert_se(l);
     420             : 
     421           1 :         assert_se(streq(l[0], "str0"));
     422           1 :         assert_se(streq(l[1], "str1"));
     423           1 :         assert_se(streq(l[2], "str2"));
     424           1 :         assert_se(streq(l[3], "str3"));
     425           1 : }
     426             : 
     427           1 : static void test_strv_parse_nulstr(void) {
     428           1 :         _cleanup_strv_free_ char **l = NULL;
     429           1 :         const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
     430             : 
     431           1 :         log_info("/* %s */", __func__);
     432             : 
     433           1 :         l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
     434           1 :         assert_se(l);
     435           1 :         puts("Parse nulstr:");
     436           1 :         strv_print(l);
     437             : 
     438           1 :         assert_se(streq(l[0], "hoge"));
     439           1 :         assert_se(streq(l[1], "hoge2"));
     440           1 :         assert_se(streq(l[2], "hoge3"));
     441           1 :         assert_se(streq(l[3], ""));
     442           1 :         assert_se(streq(l[4], "hoge5"));
     443           1 :         assert_se(streq(l[5], ""));
     444           1 :         assert_se(streq(l[6], "xxx"));
     445           1 : }
     446             : 
     447           1 : static void test_strv_overlap(void) {
     448           1 :         const char * const input_table[] = {
     449             :                 "one",
     450             :                 "two",
     451             :                 "three",
     452             :                 NULL
     453             :         };
     454           1 :         const char * const input_table_overlap[] = {
     455             :                 "two",
     456             :                 NULL
     457             :         };
     458           1 :         const char * const input_table_unique[] = {
     459             :                 "four",
     460             :                 "five",
     461             :                 "six",
     462             :                 NULL
     463             :         };
     464             : 
     465           1 :         log_info("/* %s */", __func__);
     466             : 
     467           1 :         assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
     468           1 :         assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
     469           1 : }
     470             : 
     471           1 : static void test_strv_sort(void) {
     472           1 :         const char* input_table[] = {
     473             :                 "durian",
     474             :                 "apple",
     475             :                 "citrus",
     476             :                  "CAPITAL LETTERS FIRST",
     477             :                 "banana",
     478             :                 NULL
     479             :         };
     480             : 
     481           1 :         log_info("/* %s */", __func__);
     482             : 
     483           1 :         strv_sort((char **)input_table);
     484             : 
     485           1 :         assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
     486           1 :         assert_se(streq(input_table[1], "apple"));
     487           1 :         assert_se(streq(input_table[2], "banana"));
     488           1 :         assert_se(streq(input_table[3], "citrus"));
     489           1 :         assert_se(streq(input_table[4], "durian"));
     490           1 : }
     491             : 
     492           1 : static void test_strv_extend_strv_concat(void) {
     493           1 :         _cleanup_strv_free_ char **a = NULL, **b = NULL;
     494             : 
     495           1 :         log_info("/* %s */", __func__);
     496             : 
     497           1 :         a = strv_new("without", "suffix");
     498           1 :         b = strv_new("with", "suffix");
     499           1 :         assert_se(a);
     500           1 :         assert_se(b);
     501             : 
     502           1 :         assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
     503             : 
     504           1 :         assert_se(streq(a[0], "without"));
     505           1 :         assert_se(streq(a[1], "suffix"));
     506           1 :         assert_se(streq(a[2], "with_suffix"));
     507           1 :         assert_se(streq(a[3], "suffix_suffix"));
     508           1 : }
     509             : 
     510           1 : static void test_strv_extend_strv(void) {
     511           1 :         _cleanup_strv_free_ char **a = NULL, **b = NULL, **n = NULL;
     512             : 
     513           1 :         log_info("/* %s */", __func__);
     514             : 
     515           1 :         a = strv_new("abc", "def", "ghi");
     516           1 :         b = strv_new("jkl", "mno", "abc", "pqr");
     517           1 :         assert_se(a);
     518           1 :         assert_se(b);
     519             : 
     520           1 :         assert_se(strv_extend_strv(&a, b, true) == 3);
     521             : 
     522           1 :         assert_se(streq(a[0], "abc"));
     523           1 :         assert_se(streq(a[1], "def"));
     524           1 :         assert_se(streq(a[2], "ghi"));
     525           1 :         assert_se(streq(a[3], "jkl"));
     526           1 :         assert_se(streq(a[4], "mno"));
     527           1 :         assert_se(streq(a[5], "pqr"));
     528           1 :         assert_se(strv_length(a) == 6);
     529             : 
     530           1 :         assert_se(strv_extend_strv(&n, b, false) >= 0);
     531           1 :         assert_se(streq(n[0], "jkl"));
     532           1 :         assert_se(streq(n[1], "mno"));
     533           1 :         assert_se(streq(n[2], "abc"));
     534           1 :         assert_se(streq(n[3], "pqr"));
     535           1 :         assert_se(strv_length(n) == 4);
     536           1 : }
     537             : 
     538           1 : static void test_strv_extend(void) {
     539           1 :         _cleanup_strv_free_ char **a = NULL, **b = NULL;
     540             : 
     541           1 :         log_info("/* %s */", __func__);
     542             : 
     543           1 :         a = strv_new("test", "test1");
     544           1 :         assert_se(a);
     545           1 :         assert_se(strv_extend(&a, "test2") >= 0);
     546           1 :         assert_se(strv_extend(&b, "test3") >= 0);
     547             : 
     548           1 :         assert_se(streq(a[0], "test"));
     549           1 :         assert_se(streq(a[1], "test1"));
     550           1 :         assert_se(streq(a[2], "test2"));
     551           1 :         assert_se(streq(b[0], "test3"));
     552           1 : }
     553             : 
     554           1 : static void test_strv_extendf(void) {
     555           1 :         _cleanup_strv_free_ char **a = NULL, **b = NULL;
     556             : 
     557           1 :         log_info("/* %s */", __func__);
     558             : 
     559           1 :         a = strv_new("test", "test1");
     560           1 :         assert_se(a);
     561           1 :         assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
     562           1 :         assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
     563             : 
     564           1 :         assert_se(streq(a[0], "test"));
     565           1 :         assert_se(streq(a[1], "test1"));
     566           1 :         assert_se(streq(a[2], "test2 foo 128 bar"));
     567           1 :         assert_se(streq(b[0], "test3 bar foo 128"));
     568           1 : }
     569             : 
     570           1 : static void test_strv_foreach(void) {
     571           1 :         _cleanup_strv_free_ char **a;
     572           1 :         unsigned i = 0;
     573             :         char **check;
     574             : 
     575           1 :         log_info("/* %s */", __func__);
     576             : 
     577           1 :         a = strv_new("one", "two", "three");
     578           1 :         assert_se(a);
     579             : 
     580           4 :         STRV_FOREACH(check, a)
     581           3 :                 assert_se(streq(*check, input_table_multiple[i++]));
     582           1 : }
     583             : 
     584           1 : static void test_strv_foreach_backwards(void) {
     585           1 :         _cleanup_strv_free_ char **a;
     586           1 :         unsigned i = 2;
     587             :         char **check;
     588             : 
     589           1 :         log_info("/* %s */", __func__);
     590             : 
     591           1 :         a = strv_new("one", "two", "three");
     592             : 
     593           1 :         assert_se(a);
     594             : 
     595           4 :         STRV_FOREACH_BACKWARDS(check, a)
     596           3 :                 assert_se(streq_ptr(*check, input_table_multiple[i--]));
     597             : 
     598           1 :         STRV_FOREACH_BACKWARDS(check, (char**) NULL)
     599             :                 assert_not_reached("Let's see that we check empty strv right, too.");
     600             : 
     601           1 :         STRV_FOREACH_BACKWARDS(check, (char**) { NULL })
     602             :                 assert_not_reached("Let's see that we check empty strv right, too.");
     603           1 : }
     604             : 
     605           1 : static void test_strv_foreach_pair(void) {
     606           1 :         _cleanup_strv_free_ char **a = NULL;
     607             :         char **x, **y;
     608             : 
     609           1 :         log_info("/* %s */", __func__);
     610             : 
     611           1 :         a = strv_new("pair_one",   "pair_one",
     612             :                      "pair_two",   "pair_two",
     613             :                      "pair_three", "pair_three");
     614           4 :         STRV_FOREACH_PAIR(x, y, a)
     615           3 :                 assert_se(streq(*x, *y));
     616           1 : }
     617             : 
     618           3 : static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
     619             :         char **j;
     620             :         unsigned i;
     621             : 
     622           3 :         log_info("/* %s */", __func__);
     623             : 
     624           5 :         j = strv_from_stdarg_alloca(first);
     625             : 
     626           3 :         for (i = 0;; i++) {
     627           6 :                 assert_se(streq_ptr(l[i], j[i]));
     628             : 
     629           6 :                 if (!l[i])
     630           3 :                         break;
     631             :         }
     632           3 : }
     633             : 
     634           1 : static void test_strv_from_stdarg_alloca(void) {
     635           1 :         log_info("/* %s */", __func__);
     636             : 
     637           1 :         test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
     638           1 :         test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
     639           1 :         test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
     640           1 : }
     641             : 
     642           1 : static void test_strv_insert(void) {
     643           1 :         _cleanup_strv_free_ char **a = NULL;
     644             : 
     645           1 :         log_info("/* %s */", __func__);
     646             : 
     647           1 :         assert_se(strv_insert(&a, 0, strdup("first")) == 0);
     648           1 :         assert_se(streq(a[0], "first"));
     649           1 :         assert_se(!a[1]);
     650             : 
     651           1 :         assert_se(strv_insert(&a, 0, NULL) == 0);
     652           1 :         assert_se(streq(a[0], "first"));
     653           1 :         assert_se(!a[1]);
     654             : 
     655           1 :         assert_se(strv_insert(&a, 1, strdup("two")) == 0);
     656           1 :         assert_se(streq(a[0], "first"));
     657           1 :         assert_se(streq(a[1], "two"));
     658           1 :         assert_se(!a[2]);
     659             : 
     660           1 :         assert_se(strv_insert(&a, 4, strdup("tri")) == 0);
     661           1 :         assert_se(streq(a[0], "first"));
     662           1 :         assert_se(streq(a[1], "two"));
     663           1 :         assert_se(streq(a[2], "tri"));
     664           1 :         assert_se(!a[3]);
     665             : 
     666           1 :         assert_se(strv_insert(&a, 1, strdup("duo")) == 0);
     667           1 :         assert_se(streq(a[0], "first"));
     668           1 :         assert_se(streq(a[1], "duo"));
     669           1 :         assert_se(streq(a[2], "two"));
     670           1 :         assert_se(streq(a[3], "tri"));
     671           1 :         assert_se(!a[4]);
     672           1 : }
     673             : 
     674           1 : static void test_strv_push_prepend(void) {
     675           1 :         _cleanup_strv_free_ char **a = NULL;
     676             : 
     677           1 :         log_info("/* %s */", __func__);
     678             : 
     679           1 :         a = strv_new("foo", "bar", "three");
     680             : 
     681           1 :         assert_se(strv_push_prepend(&a, strdup("first")) >= 0);
     682           1 :         assert_se(streq(a[0], "first"));
     683           1 :         assert_se(streq(a[1], "foo"));
     684           1 :         assert_se(streq(a[2], "bar"));
     685           1 :         assert_se(streq(a[3], "three"));
     686           1 :         assert_se(!a[4]);
     687             : 
     688           1 :         assert_se(strv_consume_prepend(&a, strdup("first2")) >= 0);
     689           1 :         assert_se(streq(a[0], "first2"));
     690           1 :         assert_se(streq(a[1], "first"));
     691           1 :         assert_se(streq(a[2], "foo"));
     692           1 :         assert_se(streq(a[3], "bar"));
     693           1 :         assert_se(streq(a[4], "three"));
     694           1 :         assert_se(!a[5]);
     695           1 : }
     696             : 
     697           1 : static void test_strv_push(void) {
     698           1 :         _cleanup_strv_free_ char **a = NULL;
     699             :         char *i, *j;
     700             : 
     701           1 :         log_info("/* %s */", __func__);
     702             : 
     703           1 :         assert_se(i = strdup("foo"));
     704           1 :         assert_se(strv_push(&a, i) >= 0);
     705             : 
     706           1 :         assert_se(i = strdup("a"));
     707           1 :         assert_se(j = strdup("b"));
     708           1 :         assert_se(strv_push_pair(&a, i, j) >= 0);
     709             : 
     710           1 :         assert_se(streq_ptr(a[0], "foo"));
     711           1 :         assert_se(streq_ptr(a[1], "a"));
     712           1 :         assert_se(streq_ptr(a[2], "b"));
     713           1 :         assert_se(streq_ptr(a[3], NULL));
     714           1 : }
     715             : 
     716           1 : static void test_strv_equal(void) {
     717           1 :         _cleanup_strv_free_ char **a = NULL;
     718           1 :         _cleanup_strv_free_ char **b = NULL;
     719           1 :         _cleanup_strv_free_ char **c = NULL;
     720             : 
     721           1 :         log_info("/* %s */", __func__);
     722             : 
     723           1 :         a = strv_new("one", "two", "three");
     724           1 :         assert_se(a);
     725           1 :         b = strv_new("one", "two", "three");
     726           1 :         assert_se(a);
     727           1 :         c = strv_new("one", "two", "three", "four");
     728           1 :         assert_se(a);
     729             : 
     730           1 :         assert_se(strv_equal(a, a));
     731           1 :         assert_se(strv_equal(a, b));
     732           1 :         assert_se(strv_equal(NULL, NULL));
     733             : 
     734           1 :         assert_se(!strv_equal(a, c));
     735           1 :         assert_se(!strv_equal(b, c));
     736           1 :         assert_se(!strv_equal(b, NULL));
     737           1 : }
     738             : 
     739           1 : static void test_strv_is_uniq(void) {
     740           1 :         _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
     741             : 
     742           1 :         log_info("/* %s */", __func__);
     743             : 
     744           1 :         a = strv_new(NULL);
     745           1 :         assert_se(a);
     746           1 :         assert_se(strv_is_uniq(a));
     747             : 
     748           1 :         b = strv_new("foo");
     749           1 :         assert_se(b);
     750           1 :         assert_se(strv_is_uniq(b));
     751             : 
     752           1 :         c = strv_new("foo", "bar");
     753           1 :         assert_se(c);
     754           1 :         assert_se(strv_is_uniq(c));
     755             : 
     756           1 :         d = strv_new("foo", "bar", "waldo", "bar", "piep");
     757           1 :         assert_se(d);
     758           1 :         assert_se(!strv_is_uniq(d));
     759           1 : }
     760             : 
     761           1 : static void test_strv_reverse(void) {
     762           1 :         _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
     763             : 
     764           1 :         log_info("/* %s */", __func__);
     765             : 
     766           1 :         a = strv_new(NULL);
     767           1 :         assert_se(a);
     768             : 
     769           1 :         strv_reverse(a);
     770           1 :         assert_se(strv_isempty(a));
     771             : 
     772           1 :         b = strv_new("foo");
     773           1 :         assert_se(b);
     774           1 :         strv_reverse(b);
     775           1 :         assert_se(streq_ptr(b[0], "foo"));
     776           1 :         assert_se(streq_ptr(b[1], NULL));
     777             : 
     778           1 :         c = strv_new("foo", "bar");
     779           1 :         assert_se(c);
     780           1 :         strv_reverse(c);
     781           1 :         assert_se(streq_ptr(c[0], "bar"));
     782           1 :         assert_se(streq_ptr(c[1], "foo"));
     783           1 :         assert_se(streq_ptr(c[2], NULL));
     784             : 
     785           1 :         d = strv_new("foo", "bar", "waldo");
     786           1 :         assert_se(d);
     787           1 :         strv_reverse(d);
     788           1 :         assert_se(streq_ptr(d[0], "waldo"));
     789           1 :         assert_se(streq_ptr(d[1], "bar"));
     790           1 :         assert_se(streq_ptr(d[2], "foo"));
     791           1 :         assert_se(streq_ptr(d[3], NULL));
     792           1 : }
     793             : 
     794           1 : static void test_strv_shell_escape(void) {
     795           1 :         _cleanup_strv_free_ char **v = NULL;
     796             : 
     797           1 :         log_info("/* %s */", __func__);
     798             : 
     799           1 :         v = strv_new("foo:bar", "bar,baz", "wal\\do");
     800           1 :         assert_se(v);
     801           1 :         assert_se(strv_shell_escape(v, ",:"));
     802           1 :         assert_se(streq_ptr(v[0], "foo\\:bar"));
     803           1 :         assert_se(streq_ptr(v[1], "bar\\,baz"));
     804           1 :         assert_se(streq_ptr(v[2], "wal\\\\do"));
     805           1 :         assert_se(streq_ptr(v[3], NULL));
     806           1 : }
     807             : 
     808          12 : static void test_strv_skip_one(char **a, size_t n, char **b) {
     809          12 :         a = strv_skip(a, n);
     810          12 :         assert_se(strv_equal(a, b));
     811          12 : }
     812             : 
     813           1 : static void test_strv_skip(void) {
     814           1 :         log_info("/* %s */", __func__);
     815             : 
     816           1 :         test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
     817           1 :         test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
     818           1 :         test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
     819           1 :         test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
     820           1 :         test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
     821           1 :         test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
     822             : 
     823           1 :         test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
     824           1 :         test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
     825           1 :         test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
     826             : 
     827           1 :         test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
     828           1 :         test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
     829           1 :         test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
     830           1 : }
     831             : 
     832           1 : static void test_strv_extend_n(void) {
     833           1 :         _cleanup_strv_free_ char **v = NULL;
     834             : 
     835           1 :         log_info("/* %s */", __func__);
     836             : 
     837           1 :         v = strv_new("foo", "bar");
     838           1 :         assert_se(v);
     839             : 
     840           1 :         assert_se(strv_extend_n(&v, "waldo", 3) >= 0);
     841           1 :         assert_se(strv_extend_n(&v, "piep", 2) >= 0);
     842             : 
     843           1 :         assert_se(streq(v[0], "foo"));
     844           1 :         assert_se(streq(v[1], "bar"));
     845           1 :         assert_se(streq(v[2], "waldo"));
     846           1 :         assert_se(streq(v[3], "waldo"));
     847           1 :         assert_se(streq(v[4], "waldo"));
     848           1 :         assert_se(streq(v[5], "piep"));
     849           1 :         assert_se(streq(v[6], "piep"));
     850           1 :         assert_se(v[7] == NULL);
     851             : 
     852           1 :         v = strv_free(v);
     853             : 
     854           1 :         assert_se(strv_extend_n(&v, "foo", 1) >= 0);
     855           1 :         assert_se(strv_extend_n(&v, "bar", 0) >= 0);
     856             : 
     857           1 :         assert_se(streq(v[0], "foo"));
     858           1 :         assert_se(v[1] == NULL);
     859           1 : }
     860             : 
     861           5 : static void test_strv_make_nulstr_one(char **l) {
     862           5 :         _cleanup_free_ char *b = NULL, *c = NULL;
     863           5 :         _cleanup_strv_free_ char **q = NULL;
     864           5 :         const char *s = NULL;
     865             :         size_t n, m;
     866           5 :         unsigned i = 0;
     867             : 
     868           5 :         log_info("/* %s */", __func__);
     869             : 
     870           5 :         assert_se(strv_make_nulstr(l, &b, &n) >= 0);
     871           5 :         assert_se(q = strv_parse_nulstr(b, n));
     872           5 :         assert_se(strv_equal(l, q));
     873             : 
     874           5 :         assert_se(strv_make_nulstr(q, &c, &m) >= 0);
     875           5 :         assert_se(m == n);
     876           5 :         assert_se(memcmp(b, c, m) == 0);
     877             : 
     878          11 :         NULSTR_FOREACH(s, b)
     879           6 :                 assert_se(streq(s, l[i++]));
     880           5 :         assert_se(i == strv_length(l));
     881           5 : }
     882             : 
     883           1 : static void test_strv_make_nulstr(void) {
     884           1 :         log_info("/* %s */", __func__);
     885             : 
     886           1 :         test_strv_make_nulstr_one(NULL);
     887           1 :         test_strv_make_nulstr_one(STRV_MAKE(NULL));
     888           1 :         test_strv_make_nulstr_one(STRV_MAKE("foo"));
     889           1 :         test_strv_make_nulstr_one(STRV_MAKE("foo", "bar"));
     890           1 :         test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
     891           1 : }
     892             : 
     893           1 : static void test_strv_free_free(void) {
     894             :         char ***t;
     895             : 
     896           1 :         log_info("/* %s */", __func__);
     897             : 
     898           1 :         assert_se(t = new(char**, 3));
     899           1 :         assert_se(t[0] = strv_new("a", "b"));
     900           1 :         assert_se(t[1] = strv_new("c", "d", "e"));
     901           1 :         t[2] = NULL;
     902             : 
     903           1 :         t = strv_free_free(t);
     904           1 : }
     905             : 
     906           1 : static void test_foreach_string(void) {
     907           1 :         const char * const t[] = {
     908             :                 "foo",
     909             :                 "bar",
     910             :                 "waldo",
     911             :                 NULL
     912             :         };
     913             :         const char *x;
     914           1 :         unsigned i = 0;
     915             : 
     916           1 :         log_info("/* %s */", __func__);
     917             : 
     918           4 :         FOREACH_STRING(x, "foo", "bar", "waldo")
     919           3 :                 assert_se(streq_ptr(t[i++], x));
     920             : 
     921           1 :         assert_se(i == 3);
     922             : 
     923           2 :         FOREACH_STRING(x, "zzz")
     924           1 :                 assert_se(streq(x, "zzz"));
     925           1 : }
     926             : 
     927           1 : static void test_strv_fnmatch(void) {
     928           1 :         _cleanup_strv_free_ char **v = NULL;
     929             : 
     930           1 :         log_info("/* %s */", __func__);
     931             : 
     932           1 :         assert_se(!strv_fnmatch(STRV_MAKE_EMPTY, "a", 0));
     933             : 
     934           1 :         v = strv_new("*\\*");
     935           1 :         assert_se(!strv_fnmatch(v, "\\", 0));
     936           1 :         assert_se(strv_fnmatch(v, "\\", FNM_NOESCAPE));
     937           1 : }
     938             : 
     939           1 : int main(int argc, char *argv[]) {
     940           1 :         test_specifier_printf();
     941           1 :         test_str_in_set();
     942           1 :         test_strptr_in_set();
     943           1 :         test_startswith_set();
     944           1 :         test_strv_foreach();
     945           1 :         test_strv_foreach_backwards();
     946           1 :         test_strv_foreach_pair();
     947           1 :         test_strv_find();
     948           1 :         test_strv_find_prefix();
     949           1 :         test_strv_find_startswith();
     950           1 :         test_strv_join();
     951           1 :         test_strv_join_prefix();
     952             : 
     953           1 :         test_strv_unquote("    foo=bar     \"waldo\"    zzz    ", STRV_MAKE("foo=bar", "waldo", "zzz"));
     954           1 :         test_strv_unquote("", STRV_MAKE_EMPTY);
     955           1 :         test_strv_unquote(" ", STRV_MAKE_EMPTY);
     956           1 :         test_strv_unquote("   ", STRV_MAKE_EMPTY);
     957           1 :         test_strv_unquote("   x", STRV_MAKE("x"));
     958           1 :         test_strv_unquote("x   ", STRV_MAKE("x"));
     959           1 :         test_strv_unquote("  x   ", STRV_MAKE("x"));
     960           1 :         test_strv_unquote("  \"x\"   ", STRV_MAKE("x"));
     961           1 :         test_strv_unquote("  'x'   ", STRV_MAKE("x"));
     962           1 :         test_strv_unquote("  'x\"'   ", STRV_MAKE("x\""));
     963           1 :         test_strv_unquote("  \"x'\"   ", STRV_MAKE("x'"));
     964           1 :         test_strv_unquote("a  '--b=c \"d e\"'", STRV_MAKE("a", "--b=c \"d e\""));
     965             : 
     966             :         /* trailing backslashes */
     967           1 :         test_strv_unquote("  x\\\\", STRV_MAKE("x\\"));
     968           1 :         test_invalid_unquote("  x\\");
     969             : 
     970           1 :         test_invalid_unquote("a  --b='c \"d e\"''");
     971           1 :         test_invalid_unquote("a  --b='c \"d e\" '\"");
     972           1 :         test_invalid_unquote("a  --b='c \"d e\"garbage");
     973           1 :         test_invalid_unquote("'");
     974           1 :         test_invalid_unquote("\"");
     975           1 :         test_invalid_unquote("'x'y'g");
     976             : 
     977           1 :         test_strv_split();
     978           1 :         test_strv_split_empty();
     979           1 :         test_strv_split_extract();
     980           1 :         test_strv_split_newlines();
     981           1 :         test_strv_split_nulstr();
     982           1 :         test_strv_parse_nulstr();
     983           1 :         test_strv_overlap();
     984           1 :         test_strv_sort();
     985           1 :         test_strv_extend_strv();
     986           1 :         test_strv_extend_strv_concat();
     987           1 :         test_strv_extend();
     988           1 :         test_strv_extendf();
     989           1 :         test_strv_from_stdarg_alloca();
     990           1 :         test_strv_insert();
     991           1 :         test_strv_push_prepend();
     992           1 :         test_strv_push();
     993           1 :         test_strv_equal();
     994           1 :         test_strv_is_uniq();
     995           1 :         test_strv_reverse();
     996           1 :         test_strv_shell_escape();
     997           1 :         test_strv_skip();
     998           1 :         test_strv_extend_n();
     999           1 :         test_strv_make_nulstr();
    1000           1 :         test_strv_free_free();
    1001             : 
    1002           1 :         test_foreach_string();
    1003           1 :         test_strv_fnmatch();
    1004             : 
    1005           1 :         return 0;
    1006             : }

Generated by: LCOV version 1.14