LCOV - code coverage report
Current view: top level - common - t-stringhelp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 199 280 71.1 %
Date: 2015-11-05 17:10:59 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /* t-stringhelp.c - Regression tests for stringhelp.c
       2             :  * Copyright (C) 2007 Free Software Foundation, Inc.
       3             :  *               2015  g10 Code GmbH
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * GnuPG is free software; you can redistribute it and/or modify it
       8             :  * under the terms of either
       9             :  *
      10             :  *   - the GNU Lesser General Public License as published by the Free
      11             :  *     Software Foundation; either version 3 of the License, or (at
      12             :  *     your option) any later version.
      13             :  *
      14             :  * or
      15             :  *
      16             :  *   - the GNU General Public License as published by the Free
      17             :  *     Software Foundation; either version 2 of the License, or (at
      18             :  *     your option) any later version.
      19             :  *
      20             :  * or both in parallel, as here.
      21             :  *
      22             :  * GnuPG is distributed in the hope that it will be useful, but
      23             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      24             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      25             :  * General Public License for more details.
      26             :  *
      27             :  * You should have received a copies of the GNU General Public License
      28             :  * and the GNU Lesser General Public License along with this program;
      29             :  * if not, see <http://www.gnu.org/licenses/>.
      30             :  */
      31             : 
      32             : #include <config.h>
      33             : #include <stdio.h>
      34             : #include <stdlib.h>
      35             : #include <string.h>
      36             : #include <errno.h>
      37             : #ifdef HAVE_PWD_H
      38             : # include <pwd.h>
      39             : #endif
      40             : #include <unistd.h>
      41             : #include <sys/types.h>
      42             : 
      43             : #include "stringhelp.h"
      44             : 
      45             : #include "t-support.h"
      46             : 
      47             : 
      48             : static char *home_buffer;
      49             : 
      50             : 
      51             : const char *
      52           1 : gethome (void)
      53             : {
      54           1 :   if (!home_buffer)
      55             :     {
      56           1 :       char *home = getenv("HOME");
      57             : 
      58           1 :       if(home)
      59           1 :         home_buffer = xstrdup (home);
      60             : #if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H)
      61             :       else
      62             :         {
      63             :           struct passwd *pwd;
      64             : 
      65           0 :           pwd = getpwuid (getuid());
      66           0 :           if (pwd)
      67           0 :             home_buffer = xstrdup (pwd->pw_dir);
      68             :         }
      69             : #endif
      70             :     }
      71           1 :   return home_buffer;
      72             : }
      73             : 
      74             : 
      75             : static char *
      76           1 : mygetcwd (void)
      77             : {
      78             :   char *buffer;
      79           1 :   size_t size = 100;
      80             : 
      81             :   for (;;)
      82             :     {
      83           1 :       buffer = xmalloc (size+1);
      84             : #ifdef HAVE_W32CE_SYSTEM
      85             :       strcpy (buffer, "/");  /* Always "/".  */
      86             :       return buffer;
      87             : #else
      88           1 :       if (getcwd (buffer, size) == buffer)
      89           2 :         return buffer;
      90           0 :       xfree (buffer);
      91           0 :       if (errno != ERANGE)
      92             :         {
      93           0 :           fprintf (stderr,"error getting current cwd: %s\n",
      94           0 :                    strerror (errno));
      95           0 :           exit (2);
      96             :         }
      97           0 :       size *= 2;
      98             : #endif
      99           0 :     }
     100             : }
     101             : 
     102             : 
     103             : static void
     104           1 : test_percent_escape (void)
     105             : {
     106             :   char *result;
     107             :   static struct {
     108             :     const char *extra;
     109             :     const char *value;
     110             :     const char *expected;
     111             :   } tests[] =
     112             :     {
     113             :       { NULL, "", "" },
     114             :       { NULL, "%", "%25" },
     115             :       { NULL, "%%", "%25%25" },
     116             :       { NULL, " %", " %25" },
     117             :       { NULL, ":", "%3a" },
     118             :       { NULL, " :", " %3a" },
     119             :       { NULL, ": ", "%3a " },
     120             :       { NULL, " : ", " %3a " },
     121             :       { NULL, "::", "%3a%3a" },
     122             :       { NULL, ": :", "%3a %3a" },
     123             :       { NULL, "%:", "%25%3a" },
     124             :       { NULL, ":%", "%3a%25" },
     125             :       { "\\\n:", ":%", "%3a%25" },
     126             :       { "\\\n:", "\\:%", "%5c%3a%25" },
     127             :       { "\\\n:", "\n:%", "%0a%3a%25" },
     128             :       { "\\\n:", "\xff:%", "\xff%3a%25" },
     129             :       { "\\\n:", "\xfe:%", "\xfe%3a%25" },
     130             :       { "\\\n:", "\x01:%", "\x01%3a%25" },
     131             :       { "\x01",  "\x01:%", "%01%3a%25" },
     132             :       { "\xfe",  "\xfe:%", "%fe%3a%25" },
     133             :       { "\xfe",  "\xff:%", "\xff%3a%25" },
     134             : 
     135             :       { NULL, NULL, NULL }
     136             :     };
     137             :   int testno;
     138             : 
     139           1 :   result = percent_escape (NULL, NULL);
     140           1 :   if (result)
     141           0 :     fail (0);
     142          22 :   for (testno=0; tests[testno].value; testno++)
     143             :     {
     144          21 :       result = percent_escape (tests[testno].value, tests[testno].extra);
     145          21 :       if (!result)
     146           0 :         fail (testno);
     147          21 :       if (strcmp (result, tests[testno].expected))
     148           0 :         fail (testno);
     149          21 :       xfree (result);
     150             :     }
     151             : 
     152           1 : }
     153             : 
     154             : 
     155             : static void
     156           1 : test_compare_filenames (void)
     157             : {
     158             :   struct {
     159             :     const char *a;
     160             :     const char *b;
     161             :     int result;
     162           1 :   } tests[] = {
     163             :     { "", "", 0 },
     164             :     { "", "a", -1 },
     165             :     { "a", "", 1 },
     166             :     { "a", "a", 0 },
     167             :     { "a", "aa", -1 },
     168             :     { "aa", "a", 1 },
     169             :     { "a",  "b", -1  },
     170             : 
     171             : #ifdef HAVE_W32_SYSTEM
     172             :     { "a", "A", 0 },
     173             :     { "A", "a", 0 },
     174             :     { "foo/bar", "foo\\bar", 0 },
     175             :     { "foo\\bar", "foo/bar", 0 },
     176             :     { "foo\\", "foo/", 0 },
     177             :     { "foo/", "foo\\", 0 },
     178             : #endif /*HAVE_W32_SYSTEM*/
     179             :     { NULL, NULL, 0}
     180             :   };
     181             :   int testno, result;
     182             : 
     183           8 :   for (testno=0; tests[testno].a; testno++)
     184             :     {
     185           7 :       result = compare_filenames (tests[testno].a, tests[testno].b);
     186           7 :       result = result < 0? -1 : result > 0? 1 : 0;
     187           7 :       if (result != tests[testno].result)
     188           0 :         fail (testno);
     189             :     }
     190           1 : }
     191             : 
     192             : 
     193             : static void
     194           1 : test_strconcat (void)
     195             : {
     196             :   char *out;
     197             : 
     198           1 :   out = strconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     199             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     200             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     201             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     202             :                    "1", "2", "3", "4", "5", "6", "7", NULL);
     203           1 :   if (!out)
     204           0 :     fail (0);
     205             :   else
     206           1 :     xfree (out);
     207           1 :   out = strconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     208             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     209             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     210             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     211             :                    "1", "2", "3", "4", "5", "6", "7", "8", NULL);
     212           1 :   if (out)
     213           0 :     fail (0);
     214           1 :   else if (errno != EINVAL)
     215           0 :     fail (0);
     216             : 
     217           1 :   out = strconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     218             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     219             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     220             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     221             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL);
     222           1 :   if (out)
     223           0 :     fail (0);
     224           1 :   else if (errno != EINVAL)
     225           0 :     fail (0);
     226             : 
     227             : #if __GNUC__ < 4 /* gcc 4.0 has a sentinel attribute.  */
     228             :   out = strconcat (NULL);
     229             :   if (!out || *out)
     230             :     fail (1);
     231             : #endif
     232           1 :   out = strconcat (NULL, NULL);
     233           1 :   if (!out || *out)
     234           0 :     fail (1);
     235           1 :   out = strconcat ("", NULL);
     236           1 :   if (!out || *out)
     237           0 :     fail (1);
     238           1 :   xfree (out);
     239             : 
     240           1 :   out = strconcat ("", "", NULL);
     241           1 :   if (!out || *out)
     242           0 :     fail (2);
     243           1 :   xfree (out);
     244             : 
     245           1 :   out = strconcat ("a", "b", NULL);
     246           1 :   if (!out || strcmp (out, "ab"))
     247           0 :     fail (3);
     248           1 :   xfree (out);
     249           1 :   out = strconcat ("a", "b", "c", NULL);
     250           1 :   if (!out || strcmp (out, "abc"))
     251           0 :     fail (3);
     252           1 :   xfree (out);
     253             : 
     254           1 :   out = strconcat ("a", "b", "cc", NULL);
     255           1 :   if (!out || strcmp (out, "abcc"))
     256           0 :     fail (4);
     257           1 :   xfree (out);
     258           1 :   out = strconcat ("a1", "b1", "c1", NULL);
     259           1 :   if (!out || strcmp (out, "a1b1c1"))
     260           0 :     fail (4);
     261           1 :   xfree (out);
     262             : 
     263           1 :   out = strconcat ("", " long b ", "", "--even-longer--", NULL);
     264           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     265           0 :     fail (5);
     266           1 :   xfree (out);
     267             : 
     268           1 :   out = strconcat ("", " long b ", "", "--even-longer--", NULL);
     269           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     270           0 :     fail (5);
     271           1 :   xfree (out);
     272           1 : }
     273             : 
     274             : static void
     275           1 : test_xstrconcat (void)
     276             : {
     277             :   char *out;
     278             : 
     279           1 :   out = xstrconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     280             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     281             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     282             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     283             :                    "1", "2", "3", "4", "5", "6", "7", NULL);
     284           1 :   if (!out)
     285           0 :     fail (0);
     286             : 
     287             : #if __GNUC__ < 4 /* gcc 4.0 has a sentinel attribute.  */
     288             :   out = xstrconcat (NULL);
     289             :   if (!out)
     290             :     fail (1);
     291             : #endif
     292           1 :   out = xstrconcat (NULL, NULL);
     293           1 :   if (!out)
     294           0 :     fail (1);
     295           1 :   out = xstrconcat ("", NULL);
     296           1 :   if (!out || *out)
     297           0 :     fail (1);
     298           1 :   xfree (out);
     299             : 
     300           1 :   out = xstrconcat ("", "", NULL);
     301           1 :   if (!out || *out)
     302           0 :     fail (2);
     303           1 :   xfree (out);
     304             : 
     305           1 :   out = xstrconcat ("a", "b", NULL);
     306           1 :   if (!out || strcmp (out, "ab"))
     307           0 :     fail (3);
     308           1 :   xfree (out);
     309           1 :   out = xstrconcat ("a", "b", "c", NULL);
     310           1 :   if (!out || strcmp (out, "abc"))
     311           0 :     fail (3);
     312           1 :   xfree (out);
     313             : 
     314           1 :   out = xstrconcat ("a", "b", "cc", NULL);
     315           1 :   if (!out || strcmp (out, "abcc"))
     316           0 :     fail (4);
     317           1 :   xfree (out);
     318           1 :   out = xstrconcat ("a1", "b1", "c1", NULL);
     319           1 :   if (!out || strcmp (out, "a1b1c1"))
     320           0 :     fail (4);
     321           1 :   xfree (out);
     322             : 
     323           1 :   out = xstrconcat ("", " long b ", "", "--even-longer--", NULL);
     324           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     325           0 :     fail (5);
     326           1 :   xfree (out);
     327             : 
     328           1 :   out = xstrconcat ("", " long b ", "", "--even-longer--", NULL);
     329           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     330           0 :     fail (5);
     331           1 :   xfree (out);
     332           1 : }
     333             : 
     334             : 
     335             : static void
     336           1 : test_make_filename_try (void)
     337             : {
     338             :   char *out;
     339           1 :   const char *home = gethome ();
     340           1 :   size_t homelen = home? strlen (home):0;
     341             : 
     342           1 :   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     343             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     344             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     345             :                            "1", "2", "3", NULL);
     346           1 :   if (out)
     347           0 :     fail (0);
     348           1 :   else if (errno != EINVAL)
     349           0 :     fail (0);
     350           1 :   xfree (out);
     351           1 :   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     352             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     353             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     354             :                            "1", "2", "3", "4", NULL);
     355           1 :   if (out)
     356           0 :     fail (0);
     357           1 :   else if (errno != EINVAL)
     358           0 :     fail (0);
     359           1 :   xfree (out);
     360             : 
     361           1 :   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     362             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     363             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     364             :                            "1", "2", NULL);
     365           1 :   if (!out || strcmp (out,
     366             :                       "1/2/3/4/5/6/7/8/9/10/"
     367             :                       "1/2/3/4/5/6/7/8/9/10/"
     368             :                       "1/2/3/4/5/6/7/8/9/10/"
     369             :                       "1/2"))
     370           0 :     fail (0);
     371           1 :   xfree (out);
     372             : 
     373           1 :   out = make_filename_try ("foo", "~/bar", "baz/cde", NULL);
     374           1 :   if (!out || strcmp (out, "foo/~/bar/baz/cde"))
     375           0 :     fail (1);
     376           1 :   xfree (out);
     377             : 
     378           1 :   out = make_filename_try ("foo", "~/bar", "baz/cde/", NULL);
     379           1 :   if (!out || strcmp (out, "foo/~/bar/baz/cde/"))
     380           0 :     fail (1);
     381           1 :   xfree (out);
     382             : 
     383           1 :   out = make_filename_try ("/foo", "~/bar", "baz/cde/", NULL);
     384           1 :   if (!out || strcmp (out, "/foo/~/bar/baz/cde/"))
     385           0 :     fail (1);
     386           1 :   xfree (out);
     387             : 
     388           1 :   out = make_filename_try ("//foo", "~/bar", "baz/cde/", NULL);
     389           1 :   if (!out || strcmp (out, "//foo/~/bar/baz/cde/"))
     390           0 :     fail (1);
     391           1 :   xfree (out);
     392             : 
     393           1 :   out = make_filename_try ("", "~/bar", "baz/cde", NULL);
     394           1 :   if (!out || strcmp (out, "/~/bar/baz/cde"))
     395           0 :     fail (1);
     396           1 :   xfree (out);
     397             : 
     398             : 
     399           1 :   out = make_filename_try ("~/foo", "bar", NULL);
     400           1 :   if (!out)
     401           0 :     fail (2);
     402           1 :   if (home)
     403             :     {
     404           1 :       if (strlen (out) < homelen + 7)
     405           0 :         fail (2);
     406           1 :       if (strncmp (out, home, homelen))
     407           0 :         fail (2);
     408           1 :       if (strcmp (out+homelen, "/foo/bar"))
     409           0 :         fail (2);
     410             :     }
     411             :   else
     412             :     {
     413           0 :       if (strcmp (out, "~/foo/bar"))
     414           0 :         fail (2);
     415             :     }
     416           1 :   xfree (out);
     417             : 
     418           1 :   out = make_filename_try ("~", "bar", NULL);
     419           1 :   if (!out)
     420           0 :     fail (2);
     421           1 :   if (home)
     422             :     {
     423           1 :       if (strlen (out) < homelen + 3)
     424           0 :         fail (2);
     425           1 :       if (strncmp (out, home, homelen))
     426           0 :         fail (2);
     427           1 :       if (strcmp (out+homelen, "/bar"))
     428           0 :         fail (2);
     429             :     }
     430             :   else
     431             :     {
     432           0 :       if (strcmp (out, "~/bar"))
     433           0 :         fail (2);
     434             :     }
     435           1 :   xfree (out);
     436           1 : }
     437             : 
     438             : 
     439             : static void
     440           1 : test_make_absfilename_try (void)
     441             : {
     442             :   char *out;
     443           1 :   char *cwd = mygetcwd ();
     444           1 :   size_t cwdlen = strlen (cwd);
     445             : 
     446           1 :   out = make_absfilename_try ("foo", "bar", NULL);
     447           1 :   if (!out)
     448           0 :     fail (0);
     449           1 :   if (strlen (out) < cwdlen + 7)
     450           0 :     fail (0);
     451           1 :   if (strncmp (out, cwd, cwdlen))
     452           0 :     fail (0);
     453           1 :   if (strcmp (out+cwdlen, "/foo/bar"))
     454           0 :     fail (0);
     455           1 :   xfree (out);
     456             : 
     457           1 :   out = make_absfilename_try ("./foo", NULL);
     458           1 :   if (!out)
     459           0 :     fail (1);
     460           1 :   if (strlen (out) < cwdlen + 5)
     461           0 :     fail (1);
     462           1 :   if (strncmp (out, cwd, cwdlen))
     463           0 :     fail (1);
     464           1 :   if (strcmp (out+cwdlen, "/./foo"))
     465           0 :     fail (1);
     466           1 :   xfree (out);
     467             : 
     468           1 :   out = make_absfilename_try (".", NULL);
     469           1 :   if (!out)
     470           0 :     fail (2);
     471           1 :   if (strlen (out) < cwdlen)
     472           0 :     fail (2);
     473           1 :   if (strncmp (out, cwd, cwdlen))
     474           0 :     fail (2);
     475           1 :   if (strcmp (out+cwdlen, ""))
     476           0 :     fail (2);
     477           1 :   xfree (out);
     478             : 
     479           1 :   xfree (cwd);
     480           1 : }
     481             : 
     482             : static void
     483           1 : test_strsplit (void)
     484             : {
     485             :   struct {
     486             :     const char *s;
     487             :     char delim;
     488             :     char replacement;
     489             :     const char *fields_expected[10];
     490           1 :   } tv[] = {
     491             :     {
     492             :       "a:bc:cde:fghi:jklmn::foo:", ':', '\0',
     493             :       { "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL }
     494             :     },
     495             :     {
     496             :       ",a,bc,,def,", ',', '!',
     497             :       { "!a!bc!!def!", "a!bc!!def!", "bc!!def!", "!def!", "def!", "", NULL }
     498             :     },
     499             :     {
     500             :       "", ':', ',',
     501             :       { "", NULL }
     502             :     }
     503             :   };
     504             : 
     505             :   int tidx;
     506             : 
     507           4 :   for (tidx = 0; tidx < DIM(tv); tidx++)
     508             :     {
     509             :       char *s2;
     510             :       int field_count;
     511             :       char **fields;
     512             :       int field_count_expected;
     513             :       int i;
     514             : 
     515             :       /* Count the fields.  */
     516          21 :       for (field_count_expected = 0;
     517          18 :            tv[tidx].fields_expected[field_count_expected];
     518          15 :            field_count_expected ++)
     519             :         ;
     520             : 
     521             :       /* We need to copy s since strsplit modifies it in place.  */
     522           3 :       s2 = xstrdup (tv[tidx].s);
     523           3 :       fields = strsplit (s2, tv[tidx].delim, tv[tidx].replacement,
     524             :                          &field_count);
     525             : 
     526           3 :       if (field_count != field_count_expected)
     527           0 :         fail (tidx * 1000);
     528             : 
     529          18 :       for (i = 0; i < field_count_expected; i ++)
     530          15 :         if (strcmp (tv[tidx].fields_expected[i], fields[i]) != 0)
     531             :           {
     532           0 :             printf ("For field %d, expected '%s', but got '%s'\n",
     533           0 :                     i, tv[tidx].fields_expected[i], fields[i]);
     534           0 :             fail (tidx * 1000 + i + 1);
     535             :           }
     536             : 
     537           3 :       xfree (s2);
     538             :     }
     539           1 : }
     540             : 
     541             : 
     542             : 
     543             : static void
     544           1 : test_strtokenize (void)
     545             : {
     546             :   struct {
     547             :     const char *s;
     548             :     const char *delim;
     549             :     const char *fields_expected[10];
     550           1 :   } tv[] = {
     551             :     {
     552             :       "", ":",
     553             :       { "", NULL }
     554             :     },
     555             :     {
     556             :       "a", ":",
     557             :       { "a", NULL }
     558             :     },
     559             :     {
     560             :       ":", ":",
     561             :       { "", "", NULL }
     562             :     },
     563             :     {
     564             :       "::", ":",
     565             :       { "", "", "", NULL }
     566             :     },
     567             :     {
     568             :       "a:b:c", ":",
     569             :       { "a", "b", "c", NULL }
     570             :     },
     571             :     {
     572             :       "a:b:", ":",
     573             :       { "a", "b", "", NULL }
     574             :     },
     575             :     {
     576             :       "a:b", ":",
     577             :       { "a", "b", NULL }
     578             :     },
     579             :     {
     580             :       "aa:b:cd", ":",
     581             :       { "aa", "b", "cd", NULL }
     582             :     },
     583             :     {
     584             :       "aa::b:cd", ":",
     585             :       { "aa", "", "b", "cd", NULL }
     586             :     },
     587             :     {
     588             :       "::b:cd", ":",
     589             :       { "", "", "b", "cd", NULL }
     590             :     },
     591             :     {
     592             :       "aa:   : b:cd ", ":",
     593             :       { "aa", "", "b", "cd", NULL }
     594             :     },
     595             :     {
     596             :       "  aa:   : b:  cd ", ":",
     597             :       { "aa", "", "b", "cd", NULL }
     598             :     },
     599             :     {
     600             :       "  ", ":",
     601             :       { "", NULL }
     602             :     },
     603             :     {
     604             :       "  :", ":",
     605             :       { "", "", NULL }
     606             :     },
     607             :     {
     608             :       "  : ", ":",
     609             :       { "", "", NULL }
     610             :     },
     611             :     {
     612             :       ": ", ":",
     613             :       { "", "", NULL }
     614             :     },
     615             :     {
     616             :       ": x ", ":",
     617             :       { "", "x", NULL }
     618             :     },
     619             :     {
     620             :       "a:bc:cde:fghi:jklmn::foo:", ":",
     621             :       { "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL }
     622             :     },
     623             :     {
     624             :       ",a,bc,,def,", ",",
     625             :       { "", "a", "bc", "", "def", "", NULL }
     626             :     },
     627             :     {
     628             :       " a ", " ",
     629             :       { "", "a", "", NULL }
     630             :     },
     631             :     {
     632             :       " ", " ",
     633             :       { "", "", NULL }
     634             :     },
     635             :     {
     636             :       "", " ",
     637             :       { "", NULL }
     638             :     }
     639             :   };
     640             : 
     641             :   int tidx;
     642             : 
     643          23 :   for (tidx = 0; tidx < DIM(tv); tidx++)
     644             :     {
     645             :       char **fields;
     646             :       int field_count;
     647             :       int field_count_expected;
     648             :       int i;
     649             : 
     650         107 :       for (field_count_expected = 0;
     651          85 :            tv[tidx].fields_expected[field_count_expected];
     652          63 :            field_count_expected ++)
     653             :         ;
     654             : 
     655          22 :       fields = strtokenize (tv[tidx].s, tv[tidx].delim);
     656          22 :       if (!fields)
     657           0 :         fail (tidx * 1000);
     658             :       else
     659             :         {
     660          22 :           for (field_count = 0; fields[field_count]; field_count++)
     661             :             ;
     662          22 :           if (field_count != field_count_expected)
     663           0 :             fail (tidx * 1000);
     664             :           else
     665             :             {
     666          85 :               for (i = 0; i < field_count_expected; i++)
     667          63 :                 if (strcmp (tv[tidx].fields_expected[i], fields[i]))
     668             :                   {
     669           0 :                     printf ("For field %d, expected '%s', but got '%s'\n",
     670           0 :                             i, tv[tidx].fields_expected[i], fields[i]);
     671           0 :                     fail (tidx * 1000 + i + 1);
     672             :                   }
     673             :             }
     674             :           }
     675             : 
     676          22 :       xfree (fields);
     677             :     }
     678           1 : }
     679             : 
     680             : 
     681             : int
     682           1 : main (int argc, char **argv)
     683             : {
     684             :   (void)argc;
     685             :   (void)argv;
     686             : 
     687           1 :   test_percent_escape ();
     688           1 :   test_compare_filenames ();
     689           1 :   test_strconcat ();
     690           1 :   test_xstrconcat ();
     691           1 :   test_make_filename_try ();
     692           1 :   test_make_absfilename_try ();
     693           1 :   test_strsplit ();
     694           1 :   test_strtokenize ();
     695             : 
     696           1 :   xfree (home_buffer);
     697           1 :   return 0;
     698             : }

Generated by: LCOV version 1.11