1 /* Test the gnulib dirname module.
2 Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc.
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.
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.
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/>. */
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). */
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},
46 {"//", "/", "", "/", "/", true, true},
47 {"//d", "/", "d", "d", "//d", false, true},
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},
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},
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},
74 {"//\\", "/", "\\", "\\", "//\\", false, true},
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},
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},
122 {"1:", ".", "1:", "1:", "1:", false, false},
123 {"1:/", ".", "1:/", "1:/", "1:", true, false},
124 {"/:", "/", ":", ":", "/:", false, true},
125 {"/:/", "/", ":/", ":/", "/:", true, true},
127 {NULL
, NULL
, NULL
, NULL
, NULL
, false, false}
136 for (t
= tests
; t
->name
; t
++)
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
] == '.'))))
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
));
156 if (strcmp (last
, t
->last
))
159 printf ("last_component '%s': got '%s', expected '%s'\n",
160 t
->name
, last
, t
->last
);
162 if (! (strcmp (base
, t
->base
) == 0
163 && (baselen
== strlen (base
)
164 || (baselen
+ 1 == strlen (base
)
165 && ISSLASH (base
[baselen
])))))
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
));
173 if (strcmp (stripped
, t
->stripped
) || modified
!= t
->modified
)
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");
180 if (t
->absolute
!= absolute
)
183 printf ("'%s': got %s, expected %s\n", t
->name
,
184 absolute
? "absolute" : "relative",
185 t
->absolute
? "absolute" : "relative");