(root)/
diffutils-3.10/
gnulib-tests/
test-dirname.c
       1  /* Test the gnulib dirname module.
       2     Copyright (C) 2005-2007, 2009-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #include <config.h>
      18  
      19  #include "dirname.h"
      20  
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <string.h>
      24  
      25  struct test {
      26    const char *name;     /* Name under test.  */
      27    const char *dir;      /* dir_name (name).  */
      28    const char *last;     /* last_component (name).  */
      29    const char *base;     /* base_name (name).  */
      30    const char *stripped; /* name after strip_trailing_slashes (name).  */
      31    bool modified;        /* result of strip_trailing_slashes (name).  */
      32    bool absolute;        /* IS_ABSOLUTE_FILE_NAME (name).  */
      33  };
      34  
      35  static struct test tests[] = {
      36    {"d/f",       "d",    "f",    "f",    "d/f",  false,  false},
      37    {"/d/f",      "/d",   "f",    "f",    "/d/f", false,  true},
      38    {"d/f/",      "d",    "f/",   "f/",   "d/f",  true,   false},
      39    {"d/f//",     "d",    "f//",  "f/",   "d/f",  true,   false},
      40    {"f",         ".",    "f",    "f",    "f",    false,  false},
      41    {"/",         "/",    "",     "/",    "/",    false,  true},
      42  #if DOUBLE_SLASH_IS_DISTINCT_ROOT
      43    {"//",        "//",   "",     "//",   "//",   false,  true},
      44    {"//d",       "//",   "d",    "d",    "//d",  false,  true},
      45  #else
      46    {"//",        "/",    "",     "/",    "/",    true,   true},
      47    {"//d",       "/",    "d",    "d",    "//d",  false,  true},
      48  #endif
      49    {"///",       "/",    "",     "/",    "/",    true,   true},
      50    {"///a///",   "/",    "a///", "a/",   "///a", true,   true},
      51    /* POSIX requires dirname("") and basename("") to both return ".",
      52       but dir_name and base_name are defined differently.  */
      53    {"",          ".",    "",     "",     "",     false,  false},
      54    {".",         ".",    ".",    ".",    ".",    false,  false},
      55    {"..",        ".",    "..",   "..",   "..",   false,  false},
      56  #if ISSLASH ('\\')
      57    {"a\\",       ".",    "a\\",  "a\\",  "a",    true,   false},
      58    {"a\\b",      "a",    "b",    "b",    "a\\b", false,  false},
      59    {"\\",        "\\",   "",     "\\",   "\\",   false,  true},
      60    {"\\/\\",     "\\",   "",     "\\",   "\\",   true,   true},
      61    {"\\\\/",     "\\",   "",     "\\",   "\\",   true,   true},
      62    {"\\//",      "\\",   "",     "\\",   "\\",   true,   true},
      63    {"//\\",      "/",    "",     "/",    "/",    true,   true},
      64  #else
      65    {"a\\",       ".",    "a\\",  "a\\",  "a\\",  false,  false},
      66    {"a\\b",      ".",    "a\\b", "a\\b", "a\\b", false,  false},
      67    {"\\",        ".",    "\\",   "\\",   "\\",   false,  false},
      68    {"\\/\\",     "\\",   "\\",   "\\",   "\\/\\",false,  false},
      69    {"\\\\/",     ".",    "\\\\/","\\\\/","\\\\", true,   false},
      70    {"\\//",      ".",    "\\//", "\\/",  "\\",   true,   false},
      71  # if DOUBLE_SLASH_IS_DISTINCT_ROOT
      72    {"//\\",      "//",   "\\",   "\\",   "//\\", false,  true},
      73  # else
      74    {"//\\",      "/",    "\\",   "\\",   "//\\", false,  true},
      75  # endif
      76  #endif
      77  #if ISSLASH ('\\')
      78  # if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
      79    {"c:",        "c:",   "",     "c:",   "c:",   false,  false},
      80    {"c:/",       "c:/",  "",     "c:/",  "c:/",  false,  true},
      81    {"c://",      "c:/",  "",     "c:/",  "c:/",  true,   true},
      82    {"c:/d",      "c:/",  "d",    "d",    "c:/d", false,  true},
      83    {"c://d",     "c:/",  "d",    "d",    "c://d",false,  true},
      84    {"c:/d/",     "c:/",  "d/",   "d/",   "c:/d", true,   true},
      85    {"c:/d/f",    "c:/d", "f",    "f",    "c:/d/f",false, true},
      86    {"c:d",       "c:.",  "d",    "d",    "c:d",  false,  false},
      87    {"c:d/",      "c:.",  "d/",   "d/",   "c:d",  true,   false},
      88    {"c:d/f",     "c:d",  "f",    "f",    "c:d/f",false,  false},
      89    {"a:b:c",     "a:.",  "b:c",  "./b:c","a:b:c",false,  false},
      90    {"a/b:c",     "a",    "b:c",  "./b:c","a/b:c",false,  false},
      91    {"a/b:c/",    "a",    "b:c/", "./b:c/","a/b:c",true,  false},
      92  # else /* ! FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE */
      93    {"c:",        "c:",   "",     "c:",   "c:",   false,  true},
      94    {"c:/",       "c:",   "",     "c:",   "c:",   true,   true},
      95    {"c://",      "c:",   "",     "c:",   "c:",   true,   true},
      96    {"c:/d",      "c:",   "d",    "d",    "c:/d", false,  true},
      97    {"c://d",     "c:",   "d",    "d",    "c://d",false,  true},
      98    {"c:/d/",     "c:",   "d/",   "d/",   "c:/d", true,   true},
      99    {"c:/d/f",    "c:/d", "f",    "f",    "c:/d/f",false, true},
     100    {"c:d",       "c:",   "d",    "d",    "c:d",  false,  true},
     101    {"c:d/",      "c:",   "d/",   "d/",   "c:d",  true,   true},
     102    {"c:d/f",     "c:d",  "f",    "f",    "c:d/f",false,  true},
     103    {"a:b:c",     "a:",   "b:c",  "./b:c","a:b:c",false,  true},
     104    {"a/b:c",     "a",    "b:c",  "./b:c","a/b:c",false,  false},
     105    {"a/b:c/",    "a",    "b:c/", "./b:c/","a/b:c",true,  false},
     106  # endif
     107  #else /* ! ISSLASH ('\\') */
     108    {"c:",        ".",    "c:",   "c:",   "c:",   false,  false},
     109    {"c:/",       ".",    "c:/",  "c:/",  "c:",   true,   false},
     110    {"c://",      ".",    "c://", "c:/",  "c:",   true,   false},
     111    {"c:/d",      "c:",   "d",    "d",    "c:/d", false,  false},
     112    {"c://d",     "c:",   "d",    "d",    "c://d",false,  false},
     113    {"c:/d/",     "c:",   "d/",   "d/",   "c:/d", true,   false},
     114    {"c:/d/f",    "c:/d", "f",    "f",    "c:/d/f",false, false},
     115    {"c:d",       ".",    "c:d",  "c:d",  "c:d",  false,  false},
     116    {"c:d/",      ".",    "c:d/", "c:d/", "c:d",  true,   false},
     117    {"c:d/f",     "c:d",  "f",    "f",    "c:d/f",false,  false},
     118    {"a:b:c",     ".",    "a:b:c","a:b:c","a:b:c",false,  false},
     119    {"a/b:c",     "a",    "b:c",  "b:c",  "a/b:c",false,  false},
     120    {"a/b:c/",    "a",    "b:c/", "b:c/", "a/b:c",true,   false},
     121  #endif
     122    {"1:",        ".",    "1:",   "1:",   "1:",   false,  false},
     123    {"1:/",       ".",    "1:/",  "1:/",  "1:",   true,   false},
     124    {"/:",        "/",    ":",    ":",    "/:",   false,  true},
     125    {"/:/",       "/",    ":/",   ":/",   "/:",   true,   true},
     126    /* End sentinel.  */
     127    {NULL,        NULL,   NULL,   NULL,   NULL,   false,  false}
     128  };
     129  
     130  int
     131  main (void)
     132  {
     133    struct test *t;
     134    bool ok = true;
     135  
     136    for (t = tests; t->name; t++)
     137      {
     138        char *dir = dir_name (t->name);
     139        int dirlen = dir_len (t->name);
     140        char *last = last_component (t->name);
     141        char *base = base_name (t->name);
     142        int baselen = base_len (base);
     143        char *stripped = strdup (t->name);
     144        bool modified = strip_trailing_slashes (stripped);
     145        bool absolute = IS_ABSOLUTE_FILE_NAME (t->name);
     146        if (! (strcmp (dir, t->dir) == 0
     147               && (dirlen == strlen (dir)
     148                   || (dirlen + 1 == strlen (dir) && dir[dirlen] == '.'))))
     149          {
     150            ok = false;
     151            printf ("dir_name '%s': got '%s' len %d,"
     152                    " expected '%s' len %lu\n",
     153                    t->name, dir, dirlen,
     154                    t->dir, (unsigned long) strlen (t->dir));
     155          }
     156        if (strcmp (last, t->last))
     157          {
     158            ok = false;
     159            printf ("last_component '%s': got '%s', expected '%s'\n",
     160                    t->name, last, t->last);
     161          }
     162        if (! (strcmp (base, t->base) == 0
     163               && (baselen == strlen (base)
     164                   || (baselen + 1 == strlen (base)
     165                       && ISSLASH (base[baselen])))))
     166          {
     167            ok = false;
     168            printf ("base_name '%s': got '%s' len %d,"
     169                    " expected '%s' len %lu\n",
     170                    t->name, base, baselen,
     171                    t->base, (unsigned long) strlen (t->base));
     172          }
     173        if (strcmp (stripped, t->stripped) || modified != t->modified)
     174          {
     175            ok = false;
     176            printf ("strip_trailing_slashes '%s': got %s %s, expected %s %s\n",
     177                    t->name, stripped, modified ? "changed" : "unchanged",
     178                    t->stripped, t->modified ? "changed" : "unchanged");
     179          }
     180        if (t->absolute != absolute)
     181          {
     182            ok = false;
     183            printf ("'%s': got %s, expected %s\n", t->name,
     184                    absolute ? "absolute" : "relative",
     185                    t->absolute ? "absolute" : "relative");
     186          }
     187        free (dir);
     188        free (base);
     189        free (stripped);
     190      }
     191    return ok ? 0 : 1;
     192  }