* modules/fnmatch (Depends-on): Depend on wchar.
[gnulib.git] / tests / test-dirname.c
1 /* Test the gnulib dirname module.
2    Copyright (C) 2005, 2006 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 2, or (at your option)
7    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 along
15    with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include "dirname.h"
23
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "strdup.h"
30
31 const char *program_name = "test-dirname";
32
33 struct test {
34   const char *name;     /* Name under test.  */
35   const char *dir;      /* dir_name (name).  */
36   const char *last;     /* last_component (name).  */
37   const char *base;     /* base_name (name).  */
38   const char *stripped; /* name after strip_trailing_slashes (name).  */
39   bool modified;        /* result of strip_trailing_slashes (name).  */
40   bool absolute;        /* IS_ABSOLUTE_FILE_NAME (name).  */
41 };
42
43 static struct test tests[] = {
44   {"d/f",       "d",    "f",    "f",    "d/f",  false,  false},
45   {"/d/f",      "/d",   "f",    "f",    "/d/f", false,  true},
46   {"d/f/",      "d",    "f/",   "f/",   "d/f",  true,   false},
47   {"d/f//",     "d",    "f//",  "f/",   "d/f",  true,   false},
48   {"f",         ".",    "f",    "f",    "f",    false,  false},
49   {"/",         "/",    "",     "/",    "/",    false,  true},
50 #if DOUBLE_SLASH_IS_DISTINCT_ROOT
51   {"//",        "//",   "",     "//",   "//",   false,  true},
52   {"//d",       "//",   "d",    "d",    "//d",  false,  true},
53 #else
54   {"//",        "/",    "",     "/",    "/",    true,   true},
55   {"//d",       "/",    "d",    "d",    "//d",  false,  true},
56 #endif
57   {"///",       "/",    "",     "/",    "/",    true,   true},
58   {"///a///",   "/",    "a///", "a/",   "///a", true,   true},
59   /* POSIX requires dirname("") and basename("") to both return ".",
60      but dir_name and base_name are defined differently.  */
61   {"",          ".",    "",     "",     "",     false,  false},
62   {".",         ".",    ".",    ".",    ".",    false,  false},
63   {"..",        ".",    "..",   "..",   "..",   false,  false},
64 #if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
65   {"a\\",       ".",    "a\\",  "a\\",  "a",    true,   false},
66   {"a\\b",      "a",    "b",    "b",    "a\\b", false,  false},
67   {"\\",        "\\",   "",     "\\",   "\\",   false,  true},
68   {"\\/\\",     "\\",   "",     "\\",   "\\",   true,   true},
69   {"\\\\/",     "\\",   "",     "\\",   "\\",   true,   true},
70   {"\\//",      "\\",   "",     "\\",   "\\",   true,   true},
71   {"//\\",      "/",    "",     "/",    "/",    true,   true},
72 #else
73   {"a\\",       ".",    "a\\",  "a\\",  "a\\",  false,  false},
74   {"a\\b",      ".",    "a\\b", "a\\b", "a\\b", false,  false},
75   {"\\",        ".",    "\\",   "\\",   "\\",   false,  false},
76   {"\\/\\",     "\\",   "\\",   "\\",   "\\/\\",false,  false},
77   {"\\\\/",     ".",    "\\\\/","\\\\/","\\\\", true,   false},
78   {"\\//",      ".",    "\\//", "\\/",  "\\",   true,   false},
79 # if DOUBLE_SLASH_IS_DISTINCT_ROOT
80   {"//\\",      "//",   "\\",   "\\",   "//\\", false,  true},
81 # else
82   {"//\\",      "/",    "\\",   "\\",   "//\\", false,  true},
83 # endif
84 #endif
85 #if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
86 # if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
87   {"c:",        "c:",   "",     "c:",   "c:",   false,  false},
88   {"c:/",       "c:/",  "",     "c:/",  "c:/",  false,  true},
89   {"c://",      "c:/",  "",     "c:/",  "c:/",  true,   true},
90   {"c:/d",      "c:/",  "d",    "d",    "c:/d", false,  true},
91   {"c://d",     "c:/",  "d",    "d",    "c://d",false,  true},
92   {"c:/d/",     "c:/",  "d/",   "d/",   "c:/d", true,   true},
93   {"c:/d/f",    "c:/d", "f",    "f",    "c:/d/f",false, true},
94   {"c:d",       "c:.",  "d",    "d",    "c:d",  false,  false},
95   {"c:d/",      "c:.",  "d/",   "d/",   "c:d",  true,   false},
96   {"c:d/f",     "c:d",  "f",    "f",    "c:d/f",false,  false},
97   {"a:b:c",     "a:.",  "b:c",  "./b:c","a:b:c",false,  false},
98   {"a/b:c",     "a",    "b:c",  "./b:c","a/b:c",false,  false},
99   {"a/b:c/",    "a",    "b:c/", "./b:c/","a/b:c",true,  false},
100 # else /* ! FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE */
101   {"c:",        "c:",   "",     "c:",   "c:",   false,  true},
102   {"c:/",       "c:",   "",     "c:",   "c:",   true,   true},
103   {"c://",      "c:",   "",     "c:",   "c:",   true,   true},
104   {"c:/d",      "c:",   "d",    "d",    "c:/d", false,  true},
105   {"c://d",     "c:",   "d",    "d",    "c://d",false,  true},
106   {"c:/d/",     "c:",   "d/",   "d/",   "c:/d", true,   true},
107   {"c:/d/f",    "c:/d", "f",    "f",    "c:/d/f",false, true},
108   {"c:d",       "c:",   "d",    "d",    "c:d",  false,  true},
109   {"c:d/",      "c:",   "d/",   "d/",   "c:d",  true,   true},
110   {"c:d/f",     "c:d",  "f",    "f",    "c:d/f",false,  true},
111   {"a:b:c",     "a:",   "b:c",  "./b:c","a:b:c",false,  true},
112   {"a/b:c",     "a",    "b:c",  "./b:c","a/b:c",false,  false},
113   {"a/b:c/",    "a",    "b:c/", "./b:c/","a/b:c",true,  false},
114 # endif
115 #else /* ! FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX */
116   {"c:",        ".",    "c:",   "c:",   "c:",   false,  false},
117   {"c:/",       ".",    "c:/",  "c:/",  "c:",   true,   false},
118   {"c://",      ".",    "c://", "c:/",  "c:",   true,   false},
119   {"c:/d",      "c:",   "d",    "d",    "c:/d", false,  false},
120   {"c://d",     "c:",   "d",    "d",    "c://d",false,  false},
121   {"c:/d/",     "c:",   "d/",   "d/",   "c:/d", true,   false},
122   {"c:/d/f",    "c:/d", "f",    "f",    "c:/d/f",false, false},
123   {"c:d",       ".",    "c:d",  "c:d",  "c:d",  false,  false},
124   {"c:d/",      ".",    "c:d/", "c:d/", "c:d",  true,   false},
125   {"c:d/f",     "c:d",  "f",    "f",    "c:d/f",false,  false},
126   {"a:b:c",     ".",    "a:b:c","a:b:c","a:b:c",false,  false},
127   {"a/b:c",     "a",    "b:c",  "b:c",  "a/b:c",false,  false},
128   {"a/b:c/",    "a",    "b:c/", "b:c/", "a/b:c",true,   false},
129 #endif
130   {"1:",        ".",    "1:",   "1:",   "1:",   false,  false},
131   {"1:/",       ".",    "1:/",  "1:/",  "1:",   true,   false},
132   {"/:",        "/",    ":",    ":",    "/:",   false,  true},
133   {"/:/",       "/",    ":/",   ":/",   "/:",   true,   true},
134   /* End sentinel.  */
135   {NULL,        NULL,   NULL,   NULL,   NULL,   false,  false}
136 };
137
138 int
139 main ()
140 {
141   struct test *t;
142   bool ok = true;
143
144   for (t = tests; t->name; t++)
145     {
146       char *dir = dir_name (t->name);
147       int dirlen = dir_len (t->name);
148       char *last = last_component (t->name);
149       char *base = base_name (t->name);
150       int baselen = base_len (base);
151       char *stripped = strdup (t->name);
152       bool modified = strip_trailing_slashes (stripped);
153       bool absolute = IS_ABSOLUTE_FILE_NAME (t->name);
154       if (! (strcmp (dir, t->dir) == 0
155              && (dirlen == strlen (dir)
156                  || (dirlen + 1 == strlen (dir) && dir[dirlen] == '.'))))
157         {
158           ok = false;
159           printf ("dir_name `%s': got `%s' len %d, expected `%s' len %d\n",
160                   t->name, dir, dirlen, t->dir, strlen (t->dir));
161         }
162       if (strcmp (last, t->last))
163         {
164           ok = false;
165           printf ("last_component `%s': got `%s', expected `%s'\n",
166                   t->name, last, t->last);
167         }
168       if (! (strcmp (base, t->base) == 0
169              && (baselen == strlen (base)
170                  || (baselen + 1 == strlen (base)
171                      && ISSLASH (base[baselen])))))
172         {
173           ok = false;
174           printf ("base_name `%s': got `%s' len %d, expected `%s' len %d\n",
175                   t->name, base, baselen, t->base, strlen (t->base));
176         }
177       if (strcmp (stripped, t->stripped) || modified != t->modified)
178         {
179           ok = false;
180           printf ("strip_trailing_slashes `%s': got %s %s, expected %s %s\n",
181                   t->name, stripped, modified ? "changed" : "unchanged",
182                   t->stripped, t->modified ? "changed" : "unchanged");
183         }
184       if (t->absolute != absolute)
185         {
186           ok = false;
187           printf ("`%s': got %s, expected %s\n", t->name,
188                   absolute ? "absolute" : "relative",
189                   t->absolute ? "absolute" : "relative");
190         }
191       free (dir);
192       free (base);
193       free (stripped);
194     }
195   return ok ? 0 : 1;
196 }