LCOV - code coverage report
Current view: top level - common - t-stringhelp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 241 346 69.7 %
Date: 2016-09-12 13:01:59 Functions: 14 15 93.3 %

          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             : #include <assert.h>
      38             : #ifdef HAVE_PWD_H
      39             : # include <pwd.h>
      40             : #endif
      41             : #include <unistd.h>
      42             : #include <sys/types.h>
      43             : 
      44             : #include "t-support.h"
      45             : #include "stringhelp.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 :       else 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           1 :   xfree (out);
     227             : 
     228             : #if __GNUC__ < 4 /* gcc 4.0 has a sentinel attribute.  */
     229             :   out = strconcat (NULL);
     230             :   if (!out || *out)
     231             :     fail (1);
     232             : #endif
     233           1 :   out = strconcat (NULL, NULL);
     234           1 :   if (!out || *out)
     235           0 :     fail (1);
     236           1 :   xfree (out);
     237             : 
     238           1 :   out = strconcat ("", NULL);
     239           1 :   if (!out || *out)
     240           0 :     fail (1);
     241           1 :   xfree (out);
     242             : 
     243           1 :   out = strconcat ("", "", NULL);
     244           1 :   if (!out || *out)
     245           0 :     fail (2);
     246           1 :   xfree (out);
     247             : 
     248           1 :   out = strconcat ("a", "b", NULL);
     249           1 :   if (!out || strcmp (out, "ab"))
     250           0 :     fail (3);
     251           1 :   xfree (out);
     252           1 :   out = strconcat ("a", "b", "c", NULL);
     253           1 :   if (!out || strcmp (out, "abc"))
     254           0 :     fail (3);
     255           1 :   xfree (out);
     256             : 
     257           1 :   out = strconcat ("a", "b", "cc", NULL);
     258           1 :   if (!out || strcmp (out, "abcc"))
     259           0 :     fail (4);
     260           1 :   xfree (out);
     261           1 :   out = strconcat ("a1", "b1", "c1", NULL);
     262           1 :   if (!out || strcmp (out, "a1b1c1"))
     263           0 :     fail (4);
     264           1 :   xfree (out);
     265             : 
     266           1 :   out = strconcat ("", " long b ", "", "--even-longer--", NULL);
     267           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     268           0 :     fail (5);
     269           1 :   xfree (out);
     270             : 
     271           1 :   out = strconcat ("", " long b ", "", "--even-longer--", NULL);
     272           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     273           0 :     fail (5);
     274           1 :   xfree (out);
     275           1 : }
     276             : 
     277             : static void
     278           1 : test_xstrconcat (void)
     279             : {
     280             :   char *out;
     281             : 
     282           1 :   out = xstrconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     283             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     284             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     285             :                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     286             :                    "1", "2", "3", "4", "5", "6", "7", NULL);
     287           1 :   if (!out)
     288           0 :     fail (0);
     289           1 :   xfree (out);
     290             : 
     291             : #if __GNUC__ < 4 /* gcc 4.0 has a sentinel attribute.  */
     292             :   out = xstrconcat (NULL);
     293             :   if (!out)
     294             :     fail (1);
     295             : #endif
     296           1 :   out = xstrconcat (NULL, NULL);
     297           1 :   if (!out)
     298           0 :     fail (1);
     299           1 :   xfree (out);
     300             : 
     301           1 :   out = xstrconcat ("", NULL);
     302           1 :   if (!out || *out)
     303           0 :     fail (1);
     304           1 :   xfree (out);
     305             : 
     306           1 :   out = xstrconcat ("", "", NULL);
     307           1 :   if (!out || *out)
     308           0 :     fail (2);
     309           1 :   xfree (out);
     310             : 
     311           1 :   out = xstrconcat ("a", "b", NULL);
     312           1 :   if (!out || strcmp (out, "ab"))
     313           0 :     fail (3);
     314           1 :   xfree (out);
     315           1 :   out = xstrconcat ("a", "b", "c", NULL);
     316           1 :   if (!out || strcmp (out, "abc"))
     317           0 :     fail (3);
     318           1 :   xfree (out);
     319             : 
     320           1 :   out = xstrconcat ("a", "b", "cc", NULL);
     321           1 :   if (!out || strcmp (out, "abcc"))
     322           0 :     fail (4);
     323           1 :   xfree (out);
     324           1 :   out = xstrconcat ("a1", "b1", "c1", NULL);
     325           1 :   if (!out || strcmp (out, "a1b1c1"))
     326           0 :     fail (4);
     327           1 :   xfree (out);
     328             : 
     329           1 :   out = xstrconcat ("", " long b ", "", "--even-longer--", NULL);
     330           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     331           0 :     fail (5);
     332           1 :   xfree (out);
     333             : 
     334           1 :   out = xstrconcat ("", " long b ", "", "--even-longer--", NULL);
     335           1 :   if (!out || strcmp (out, " long b --even-longer--"))
     336           0 :     fail (5);
     337           1 :   xfree (out);
     338           1 : }
     339             : 
     340             : 
     341             : static void
     342           1 : test_make_filename_try (void)
     343             : {
     344             :   char *out;
     345           1 :   const char *home = gethome ();
     346           1 :   size_t homelen = home? strlen (home):0;
     347             : 
     348           1 :   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     349             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     350             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     351             :                            "1", "2", "3", NULL);
     352           1 :   if (out)
     353           0 :     fail (0);
     354           1 :   else if (errno != EINVAL)
     355           0 :     fail (0);
     356           1 :   xfree (out);
     357           1 :   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     358             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     359             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     360             :                            "1", "2", "3", "4", NULL);
     361           1 :   if (out)
     362           0 :     fail (0);
     363           1 :   else if (errno != EINVAL)
     364           0 :     fail (0);
     365           1 :   xfree (out);
     366             : 
     367           1 :   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     368             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     369             :                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
     370             :                            "1", "2", NULL);
     371           1 :   if (!out || strcmp (out,
     372             :                       "1/2/3/4/5/6/7/8/9/10/"
     373             :                       "1/2/3/4/5/6/7/8/9/10/"
     374             :                       "1/2/3/4/5/6/7/8/9/10/"
     375             :                       "1/2"))
     376           0 :     fail (0);
     377           1 :   xfree (out);
     378             : 
     379           1 :   out = make_filename_try ("foo", "~/bar", "baz/cde", NULL);
     380           1 :   if (!out || strcmp (out, "foo/~/bar/baz/cde"))
     381           0 :     fail (1);
     382           1 :   xfree (out);
     383             : 
     384           1 :   out = make_filename_try ("foo", "~/bar", "baz/cde/", NULL);
     385           1 :   if (!out || strcmp (out, "foo/~/bar/baz/cde/"))
     386           0 :     fail (1);
     387           1 :   xfree (out);
     388             : 
     389           1 :   out = make_filename_try ("/foo", "~/bar", "baz/cde/", NULL);
     390           1 :   if (!out || strcmp (out, "/foo/~/bar/baz/cde/"))
     391           0 :     fail (1);
     392           1 :   xfree (out);
     393             : 
     394           1 :   out = make_filename_try ("//foo", "~/bar", "baz/cde/", NULL);
     395           1 :   if (!out || strcmp (out, "//foo/~/bar/baz/cde/"))
     396           0 :     fail (1);
     397           1 :   xfree (out);
     398             : 
     399           1 :   out = make_filename_try ("", "~/bar", "baz/cde", NULL);
     400           1 :   if (!out || strcmp (out, "/~/bar/baz/cde"))
     401           0 :     fail (1);
     402           1 :   xfree (out);
     403             : 
     404             : 
     405           1 :   out = make_filename_try ("~/foo", "bar", NULL);
     406           1 :   if (!out)
     407           0 :     fail (2);
     408           1 :   else if (home)
     409             :     {
     410           1 :       if (strlen (out) < homelen + 7)
     411           0 :         fail (2);
     412           1 :       else if (strncmp (out, home, homelen))
     413           0 :         fail (2);
     414           1 :       else if (strcmp (out+homelen, "/foo/bar"))
     415           0 :         fail (2);
     416             :     }
     417             :   else
     418             :     {
     419           0 :       if (strcmp (out, "~/foo/bar"))
     420           0 :         fail (2);
     421             :     }
     422           1 :   xfree (out);
     423             : 
     424           1 :   out = make_filename_try ("~", "bar", NULL);
     425           1 :   if (!out)
     426           0 :     fail (2);
     427           1 :   else if (home)
     428             :     {
     429           1 :       if (strlen (out) < homelen + 3)
     430           0 :         fail (2);
     431           1 :       else if (strncmp (out, home, homelen))
     432           0 :         fail (2);
     433           1 :       else if (strcmp (out+homelen, "/bar"))
     434           0 :         fail (2);
     435             :     }
     436             :   else
     437             :     {
     438           0 :       if (strcmp (out, "~/bar"))
     439           0 :         fail (2);
     440             :     }
     441           1 :   xfree (out);
     442           1 : }
     443             : 
     444             : 
     445             : static void
     446           1 : test_make_absfilename_try (void)
     447             : {
     448             :   char *out;
     449           1 :   char *cwd = mygetcwd ();
     450           1 :   size_t cwdlen = strlen (cwd);
     451             : 
     452           1 :   out = make_absfilename_try ("foo", "bar", NULL);
     453           1 :   if (!out)
     454           0 :     fail (0);
     455           1 :   else if (strlen (out) < cwdlen + 7)
     456           0 :     fail (0);
     457           1 :   else if (strncmp (out, cwd, cwdlen))
     458           0 :     fail (0);
     459           1 :   else if (strcmp (out+cwdlen, "/foo/bar"))
     460           0 :     fail (0);
     461           1 :   xfree (out);
     462             : 
     463           1 :   out = make_absfilename_try ("./foo", NULL);
     464           1 :   if (!out)
     465           0 :     fail (1);
     466           1 :   else if (strlen (out) < cwdlen + 5)
     467           0 :     fail (1);
     468           1 :   else if (strncmp (out, cwd, cwdlen))
     469           0 :     fail (1);
     470           1 :   else if (strcmp (out+cwdlen, "/./foo"))
     471           0 :     fail (1);
     472           1 :   xfree (out);
     473             : 
     474           1 :   out = make_absfilename_try (".", NULL);
     475           1 :   if (!out)
     476           0 :     fail (2);
     477           1 :   else if (strlen (out) < cwdlen)
     478           0 :     fail (2);
     479           1 :   else if (strncmp (out, cwd, cwdlen))
     480           0 :     fail (2);
     481           1 :   else if (strcmp (out+cwdlen, ""))
     482           0 :     fail (2);
     483           1 :   xfree (out);
     484             : 
     485           1 :   xfree (cwd);
     486           1 : }
     487             : 
     488             : static void
     489           1 : test_strsplit (void)
     490             : {
     491             :   struct {
     492             :     const char *s;
     493             :     char delim;
     494             :     char replacement;
     495             :     const char *fields_expected[10];
     496           1 :   } tv[] = {
     497             :     {
     498             :       "a:bc:cde:fghi:jklmn::foo:", ':', '\0',
     499             :       { "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL }
     500             :     },
     501             :     {
     502             :       ",a,bc,,def,", ',', '!',
     503             :       { "!a!bc!!def!", "a!bc!!def!", "bc!!def!", "!def!", "def!", "", NULL }
     504             :     },
     505             :     {
     506             :       "", ':', ',',
     507             :       { "", NULL }
     508             :     }
     509             :   };
     510             : 
     511             :   int tidx;
     512             : 
     513           4 :   for (tidx = 0; tidx < DIM(tv); tidx++)
     514             :     {
     515             :       char *s2;
     516             :       int field_count;
     517             :       char **fields;
     518             :       int field_count_expected;
     519             :       int i;
     520             : 
     521             :       /* Count the fields.  */
     522          21 :       for (field_count_expected = 0;
     523          18 :            tv[tidx].fields_expected[field_count_expected];
     524          15 :            field_count_expected ++)
     525             :         ;
     526             : 
     527             :       /* We need to copy s since strsplit modifies it in place.  */
     528           3 :       s2 = xstrdup (tv[tidx].s);
     529           3 :       fields = strsplit (s2, tv[tidx].delim, tv[tidx].replacement,
     530             :                          &field_count);
     531             : 
     532           3 :       if (field_count != field_count_expected)
     533           0 :         fail (tidx * 1000);
     534             : 
     535          18 :       for (i = 0; i < field_count_expected; i ++)
     536          15 :         if (strcmp (tv[tidx].fields_expected[i], fields[i]) != 0)
     537             :           {
     538           0 :             printf ("For field %d, expected '%s', but got '%s'\n",
     539           0 :                     i, tv[tidx].fields_expected[i], fields[i]);
     540           0 :             fail (tidx * 1000 + i + 1);
     541             :           }
     542             : 
     543           3 :       xfree (fields);
     544           3 :       xfree (s2);
     545             :     }
     546           1 : }
     547             : 
     548             : 
     549             : 
     550             : static void
     551           1 : test_strtokenize (void)
     552             : {
     553             :   struct {
     554             :     const char *s;
     555             :     const char *delim;
     556             :     const char *fields_expected[10];
     557           1 :   } tv[] = {
     558             :     {
     559             :       "", ":",
     560             :       { "", NULL }
     561             :     },
     562             :     {
     563             :       "a", ":",
     564             :       { "a", NULL }
     565             :     },
     566             :     {
     567             :       ":", ":",
     568             :       { "", "", NULL }
     569             :     },
     570             :     {
     571             :       "::", ":",
     572             :       { "", "", "", NULL }
     573             :     },
     574             :     {
     575             :       "a:b:c", ":",
     576             :       { "a", "b", "c", NULL }
     577             :     },
     578             :     {
     579             :       "a:b:", ":",
     580             :       { "a", "b", "", NULL }
     581             :     },
     582             :     {
     583             :       "a:b", ":",
     584             :       { "a", "b", NULL }
     585             :     },
     586             :     {
     587             :       "aa:b:cd", ":",
     588             :       { "aa", "b", "cd", NULL }
     589             :     },
     590             :     {
     591             :       "aa::b:cd", ":",
     592             :       { "aa", "", "b", "cd", NULL }
     593             :     },
     594             :     {
     595             :       "::b:cd", ":",
     596             :       { "", "", "b", "cd", NULL }
     597             :     },
     598             :     {
     599             :       "aa:   : b:cd ", ":",
     600             :       { "aa", "", "b", "cd", NULL }
     601             :     },
     602             :     {
     603             :       "  aa:   : b:  cd ", ":",
     604             :       { "aa", "", "b", "cd", NULL }
     605             :     },
     606             :     {
     607             :       "  ", ":",
     608             :       { "", NULL }
     609             :     },
     610             :     {
     611             :       "  :", ":",
     612             :       { "", "", NULL }
     613             :     },
     614             :     {
     615             :       "  : ", ":",
     616             :       { "", "", NULL }
     617             :     },
     618             :     {
     619             :       ": ", ":",
     620             :       { "", "", NULL }
     621             :     },
     622             :     {
     623             :       ": x ", ":",
     624             :       { "", "x", NULL }
     625             :     },
     626             :     {
     627             :       "a:bc:cde:fghi:jklmn::foo:", ":",
     628             :       { "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL }
     629             :     },
     630             :     {
     631             :       ",a,bc,,def,", ",",
     632             :       { "", "a", "bc", "", "def", "", NULL }
     633             :     },
     634             :     {
     635             :       " a ", " ",
     636             :       { "", "a", "", NULL }
     637             :     },
     638             :     {
     639             :       " ", " ",
     640             :       { "", "", NULL }
     641             :     },
     642             :     {
     643             :       "", " ",
     644             :       { "", NULL }
     645             :     }
     646             :   };
     647             : 
     648             :   int tidx;
     649             : 
     650          23 :   for (tidx = 0; tidx < DIM(tv); tidx++)
     651             :     {
     652             :       char **fields;
     653             :       int field_count;
     654             :       int field_count_expected;
     655             :       int i;
     656             : 
     657         107 :       for (field_count_expected = 0;
     658          85 :            tv[tidx].fields_expected[field_count_expected];
     659          63 :            field_count_expected ++)
     660             :         ;
     661             : 
     662          22 :       fields = strtokenize (tv[tidx].s, tv[tidx].delim);
     663          22 :       if (!fields)
     664           0 :         fail (tidx * 1000);
     665             :       else
     666             :         {
     667          22 :           for (field_count = 0; fields[field_count]; field_count++)
     668             :             ;
     669          22 :           if (field_count != field_count_expected)
     670           0 :             fail (tidx * 1000);
     671             :           else
     672             :             {
     673          85 :               for (i = 0; i < field_count_expected; i++)
     674          63 :                 if (strcmp (tv[tidx].fields_expected[i], fields[i]))
     675             :                   {
     676           0 :                     printf ("For field %d, expected '%s', but got '%s'\n",
     677           0 :                             i, tv[tidx].fields_expected[i], fields[i]);
     678           0 :                     fail (tidx * 1000 + i + 1);
     679             :                   }
     680             :             }
     681             :           }
     682             : 
     683          22 :       xfree (fields);
     684             :     }
     685           1 : }
     686             : 
     687             : 
     688             : static void
     689           1 : test_split_fields (void)
     690             : {
     691             :   struct {
     692             :     const char *s;
     693             :     int nfields;
     694             :     const char *fields_expected[10];
     695           1 :   } tv[] = {
     696             :     {
     697             :       "a bc cde fghi jklmn   foo ", 6,
     698             :       { "a", "bc", "cde", "fghi", "jklmn", "foo", NULL }
     699             :     },
     700             :     {
     701             :       " a bc  def ", 2,
     702             :       { "a", "bc", "def", NULL }
     703             :     },
     704             :     {
     705             :       " a bc  def ", 3,
     706             :       { "a", "bc", "def", NULL }
     707             :     },
     708             :     {
     709             :       " a bc  def ", 4,
     710             :       { "a", "bc", "def", NULL }
     711             :     },
     712             :     {
     713             :       "", 0,
     714             :       { NULL }
     715             :     }
     716             :   };
     717             : 
     718             :   int tidx;
     719             :   char *fields[10];
     720             :   int field_count_expected, nfields, field_count, i;
     721             :   char *s2;
     722             : 
     723           6 :   for (tidx = 0; tidx < DIM(tv); tidx++)
     724             :     {
     725           5 :       nfields = tv[tidx].nfields;
     726           5 :       assert (nfields <= DIM (fields));
     727             : 
     728             :       /* Count the fields.  */
     729          25 :       for (field_count_expected = 0;
     730          20 :            tv[tidx].fields_expected[field_count_expected];
     731          15 :            field_count_expected ++)
     732             :         ;
     733           5 :       if (field_count_expected > nfields)
     734           1 :         field_count_expected = nfields;
     735             : 
     736             :       /* We need to copy s since split_fields modifies in place.  */
     737           5 :       s2 = xstrdup (tv[tidx].s);
     738           5 :       field_count = split_fields (s2, fields, nfields);
     739             : 
     740           5 :       if (field_count != field_count_expected)
     741             :         {
     742           0 :           printf ("%s: tidx %d: expected %d, got %d\n",
     743             :                   __func__, tidx, field_count_expected, field_count);
     744           0 :           fail (tidx * 1000);
     745             :         }
     746             :       else
     747             :         {
     748          19 :           for (i = 0; i < field_count_expected; i ++)
     749          14 :             if (strcmp (tv[tidx].fields_expected[i], fields[i]))
     750             :               {
     751           0 :                 printf ("%s: tidx %d, field %d: expected '%s', got '%s'\n",
     752             :                         __func__,
     753             :                         tidx, i, tv[tidx].fields_expected[i], fields[i]);
     754           0 :                 fail (tidx * 1000 + i + 1);
     755             :               }
     756             :         }
     757             : 
     758           5 :       xfree (s2);
     759             :     }
     760           1 : }
     761             : 
     762             : 
     763             : static char *
     764           0 : stresc (char *s)
     765             : {
     766             :   char *p;
     767           0 :   int l = strlen (s) + 1;
     768             : 
     769           0 :   for (p = s; *p; p ++)
     770           0 :     if (*p == '\n')
     771           0 :       l ++;
     772             : 
     773           0 :   p = xmalloc (l);
     774           0 :   for (l = 0; *s; s ++, l ++)
     775             :     {
     776           0 :       if (*s == ' ')
     777           0 :         p[l] = '_';
     778           0 :       else if (*p == '\n')
     779             :         {
     780           0 :           p[l ++] = '\\';
     781           0 :           p[l ++] = 'n';
     782           0 :           p[l] = '\n';
     783             :         }
     784             :       else
     785           0 :         p[l] = *s;
     786             :     }
     787           0 :   p[l] = *s;
     788             : 
     789           0 :   return p;
     790             : }
     791             : 
     792             : 
     793             : static void
     794           1 : test_format_text (void)
     795             : {
     796             :   struct test
     797             :   {
     798             :     int target_cols, max_cols;
     799             :     char *input;
     800             :     char *expected;
     801             :   };
     802             : 
     803           1 :   struct test tests[] = {
     804             :     {
     805             :       10, 12,
     806             :       "",
     807             :       "",
     808             :     },
     809             :     {
     810             :       10, 12,
     811             :       " ",
     812             :       "",
     813             :     },
     814             :     {
     815             :       10, 12,
     816             :       "  ",
     817             :       "",
     818             :     },
     819             :     {
     820             :       10, 12,
     821             :       " \n ",
     822             :       " \n",
     823             :     },
     824             :     {
     825             :       10, 12,
     826             :       " \n  \n ",
     827             :       " \n  \n",
     828             :     },
     829             :     {
     830             :       10, 12,
     831             :       "0123456789 0123456789 0",
     832             :       "0123456789\n0123456789\n0",
     833             :     },
     834             :     {
     835             :       10, 12,
     836             :       "   0123456789   0123456789   0  ",
     837             :       "   0123456789\n0123456789\n0",
     838             :     },
     839             :     {
     840             :       10, 12,
     841             :       "01 34 67 90 23 56  89 12 45 67 89 1",
     842             :       "01 34 67\n90 23 56\n89 12 45\n67 89 1"
     843             :     },
     844             :     {
     845             :       10, 12,
     846             :       "01 34 67 90 23 56  89 12 45 67 89 1",
     847             :       "01 34 67\n90 23 56\n89 12 45\n67 89 1"
     848             :     },
     849             :     {
     850             :       72, 80,
     851             :       "Warning: if you think you've seen more than 10 messages "
     852             :       "signed by this key, then this key might be a forgery!  "
     853             :       "Carefully examine the email address for small variations "
     854             :       "(e.g., additional white space).  If the key is suspect, "
     855             :       "then use 'gpg --tofu-policy bad \"FINGERPRINT\"' to mark it as being bad.\n",
     856             :       "Warning: if you think you've seen more than 10 messages signed by this\n"
     857             :       "key, then this key might be a forgery!  Carefully examine the email\n"
     858             :       "address for small variations (e.g., additional white space).  If the key\n"
     859             :       "is suspect, then use 'gpg --tofu-policy bad \"FINGERPRINT\"' to mark it as\n"
     860             :       "being bad.\n"
     861             : 
     862             :     },
     863             :     {
     864             :       72, 80,
     865             :       "Normally, there is only a single key associated with an email "
     866             :       "address.  However, people sometimes generate a new key if "
     867             :       "their key is too old or they think it might be compromised.  "
     868             :       "Alternatively, a new key may indicate a man-in-the-middle "
     869             :       "attack!  Before accepting this key, you should talk to or "
     870             :       "call the person to make sure this new key is legitimate.",
     871             :       "Normally, there is only a single key associated with an email "
     872             :       "address.\nHowever, people sometimes generate a new key if "
     873             :       "their key is too old or\nthey think it might be compromised.  "
     874             :       "Alternatively, a new key may indicate\na man-in-the-middle "
     875             :       "attack!  Before accepting this key, you should talk\nto or "
     876             :       "call the person to make sure this new key is legitimate.",
     877             :     }
     878             :   };
     879             : 
     880             :   int i;
     881           1 :   int failed = 0;
     882             : 
     883          12 :   for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i ++)
     884             :     {
     885          11 :       struct test *test = &tests[i];
     886          11 :       char *result =
     887          11 :         format_text (test->input, 0, test->target_cols, test->max_cols);
     888          11 :       if (strcmp (result, test->expected) != 0)
     889             :         {
     890           0 :           printf ("%s: Test #%d failed.\nExpected: '%s'\nResult: '%s'\n",
     891             :                   __func__, i + 1, stresc (test->expected), stresc (result));
     892           0 :           failed ++;
     893             :         }
     894          11 :       xfree (result);
     895             :     }
     896             : 
     897           1 :   if (failed)
     898           0 :     fail(0);
     899           1 : }
     900             : 
     901             : 
     902             : static void
     903           1 : test_compare_version_strings (void)
     904             : {
     905           1 :   struct { const char *a; const char *b; int okay; } tests[] = {
     906             :     { "1.0.0",   "1.0.0", 1 },
     907             :     { "1.0.0-",  "1.0.0", 1 },
     908             :     { "1.0.0-1", "1.0.0", 1 },
     909             :     { "1.0.0.1", "1.0.0", 1 },
     910             :     { "1.0.0",   "1.0.1", 0 },
     911             :     { "1.0.0-",  "1.0.1", 0 },
     912             :     { "1.0.0-1", "1.0.1", 0 },
     913             :     { "1.0.0.1", "1.0.1", 0 },
     914             :     { "1.0.0",   "1.1.0", 0 },
     915             :     { "1.0.0-",  "1.1.0", 0 },
     916             :     { "1.0.0-1", "1.1.0", 0 },
     917             :     { "1.0.0.1", "1.1.0", 0 },
     918             : 
     919             :     { "1.0.0",   "1.0.0-", 1 },
     920             :     { "1.0.0",   "1.0.0-1", 1 },
     921             :     { "1.0.0",   "1.0.0.1", 1 },
     922             :     { "1.1.0",   "1.0.0", 1 },
     923             :     { "1.1.1",   "1.1.0", 1 },
     924             :     { "1.1.2",   "1.1.2", 1 },
     925             :     { "1.1.2",   "1.0.2", 1 },
     926             :     { "1.1.2",   "0.0.2", 1 },
     927             :     { "1.1.2",   "1.1.3", 0 },
     928             : 
     929             :     { "0.99.1",  "0.9.9", 1 },
     930             :     { "0.9.1",   "0.91.0", 0 },
     931             : 
     932             :     { "1.5.3",   "1.5",  1 },
     933             :     { "1.5.0",   "1.5",  1 },
     934             :     { "1.4.99",  "1.5",  0 },
     935             :     { "1.5",     "1.4.99",  1 },
     936             :     { "1.5",     "1.5.0",  1 },
     937             :     { "1.5",     "1.5.1",  0 },
     938             : 
     939             :     { "1.5.3-x17",   "1.5-23",  1 },
     940             : 
     941             :     { "1.5.3a",   "1.5.3",  1 },
     942             :     { "1.5.3a",   "1.5.3b",  1 },
     943             : 
     944             :     { NULL, NULL, 0 }
     945             :   };
     946             :   int idx;
     947             :   int res;
     948             : 
     949          34 :   for (idx=0; idx < DIM(tests); idx++)
     950             :     {
     951          33 :       res = compare_version_strings (tests[idx].a, tests[idx].b);
     952             :       /* printf ("test %d: '%s'  '%s'  %d  ->  %d\n", */
     953             :       /*         idx, tests[idx].a, tests[idx].b, tests[idx].okay, res); */
     954          33 :       if (res != tests[idx].okay)
     955           0 :         fail (idx);
     956             :     }
     957           1 : }
     958             : 
     959             : 
     960             : int
     961           1 : main (int argc, char **argv)
     962             : {
     963             :   (void)argc;
     964             :   (void)argv;
     965             : 
     966           1 :   test_percent_escape ();
     967           1 :   test_compare_filenames ();
     968           1 :   test_strconcat ();
     969           1 :   test_xstrconcat ();
     970           1 :   test_make_filename_try ();
     971           1 :   test_make_absfilename_try ();
     972           1 :   test_strsplit ();
     973           1 :   test_strtokenize ();
     974           1 :   test_split_fields ();
     975           1 :   test_compare_version_strings ();
     976           1 :   test_format_text ();
     977             : 
     978           1 :   xfree (home_buffer);
     979           1 :   return !!errcount;
     980             : }

Generated by: LCOV version 1.11