t0060: verify that basename() and dirname() work as expected

Unfortunately, some libgen implementations yield outcomes different from what Git expects. For example, mingw-w64-crt provides a basename() function, that shortens `path0/` to `path`! So let's verify that the basename() and dirname() functions we use conform to what Git expects. Derived-from-code-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jan 12, 2016 at 08:57 UTC 7d1aaa684d42964b8b287b8c9450184dfd5bce85
2 files changed +169
t/t0060-path-utils.sh
+3
@@ -59,6 +59,9 @@ case $(uname -s) in
59 ;;
60 esac
61
62 +test_expect_success basename 'test-path-utils basename'
63 +test_expect_success dirname 'test-path-utils dirname'
64 +
65 norm_path "" ""
66 norm_path . ""
67 norm_path ./ ""
test-path-utils.c
+166
@@ -39,6 +39,166 @@ static void normalize_argv_string(const char **var, const char *input)
39 die("Bad value: %s\n", input);
40 }
41
42 +struct test_data {
43 + const char *from; /* input: transform from this ... */
44 + const char *to; /* output: ... to this. */
45 +};
46 +
47 +static int test_function(struct test_data *data, char *(*func)(char *input),
48 + const char *funcname)
49 +{
50 + int failed = 0, i;
51 + char buffer[1024];
52 + char *to;
53 +
54 + for (i = 0; data[i].to; i++) {
55 + if (!data[i].from)
56 + to = func(NULL);
57 + else {
58 + strcpy(buffer, data[i].from);
59 + to = func(buffer);
60 + }
61 + if (strcmp(to, data[i].to)) {
62 + error("FAIL: %s(%s) => '%s' != '%s'\n",
63 + funcname, data[i].from, to, data[i].to);
64 + failed = 1;
65 + }
66 + }
67 + return failed;
68 +}
69 +
70 +static struct test_data basename_data[] = {
71 + /* --- POSIX type paths --- */
72 + { NULL, "." },
73 + { "", "." },
74 + { ".", "." },
75 + { "..", ".." },
76 + { "/", "/" },
77 +#if defined(__CYGWIN__) && !defined(NO_LIBGEN_H)
78 + { "//", "//" },
79 + { "///", "//" },
80 + { "////", "//" },
81 +#else
82 + { "//", "/" },
83 + { "///", "/" },
84 + { "////", "/" },
85 +#endif
86 + { "usr", "usr" },
87 + { "/usr", "usr" },
88 + { "/usr/", "usr" },
89 + { "/usr//", "usr" },
90 + { "/usr/lib", "lib" },
91 + { "usr/lib", "lib" },
92 + { "usr/lib///", "lib" },
93 +
94 +#if defined(__MINGW32__) || defined(_MSC_VER)
95 +
96 + /* --- win32 type paths --- */
97 + { "\\usr", "usr" },
98 + { "\\usr\\", "usr" },
99 + { "\\usr\\\\", "usr" },
100 + { "\\usr\\lib", "lib" },
101 + { "usr\\lib", "lib" },
102 + { "usr\\lib\\\\\\", "lib" },
103 + { "C:/usr", "usr" },
104 + { "C:/usr", "usr" },
105 + { "C:/usr/", "usr" },
106 + { "C:/usr//", "usr" },
107 + { "C:/usr/lib", "lib" },
108 + { "C:usr/lib", "lib" },
109 + { "C:usr/lib///", "lib" },
110 + { "C:", "." },
111 + { "C:a", "a" },
112 + { "C:/", "/" },
113 + { "C:///", "/" },
114 +#if defined(NO_LIBGEN_H)
115 + { "\\", "\\" },
116 + { "\\\\", "\\" },
117 + { "\\\\\\", "\\" },
118 +#else
119 +
120 + /* win32 platform variations: */
121 +#if defined(__MINGW32__)
122 + { "\\", "/" },
123 + { "\\\\", "/" },
124 + { "\\\\\\", "/" },
125 +#endif
126 +
127 +#if defined(_MSC_VER)
128 + { "\\", "\\" },
129 + { "\\\\", "\\" },
130 + { "\\\\\\", "\\" },
131 +#endif
132 +
133 +#endif
134 +#endif
135 + { NULL, NULL }
136 +};
137 +
138 +static struct test_data dirname_data[] = {
139 + /* --- POSIX type paths --- */
140 + { NULL, "." },
141 + { "", "." },
142 + { ".", "." },
143 + { "..", "." },
144 + { "/", "/" },
145 + { "//", "//" },
146 +#if defined(__CYGWIN__) && !defined(NO_LIBGEN_H)
147 + { "///", "//" },
148 + { "////", "//" },
149 +#else
150 + { "///", "/" },
151 + { "////", "/" },
152 +#endif
153 + { "usr", "." },
154 + { "/usr", "/" },
155 + { "/usr/", "/" },
156 + { "/usr//", "/" },
157 + { "/usr/lib", "/usr" },
158 + { "usr/lib", "usr" },
159 + { "usr/lib///", "usr" },
160 +
161 +#if defined(__MINGW32__) || defined(_MSC_VER)
162 +
163 + /* --- win32 type paths --- */
164 + { "\\", "\\" },
165 + { "\\\\", "\\\\" },
166 + { "\\usr", "\\" },
167 + { "\\usr\\", "\\" },
168 + { "\\usr\\\\", "\\" },
169 + { "\\usr\\lib", "\\usr" },
170 + { "usr\\lib", "usr" },
171 + { "usr\\lib\\\\\\", "usr" },
172 + { "C:a", "C:." },
173 + { "C:/", "C:/" },
174 + { "C:///", "C:/" },
175 + { "C:/usr", "C:/" },
176 + { "C:/usr/", "C:/" },
177 + { "C:/usr//", "C:/" },
178 + { "C:/usr/lib", "C:/usr" },
179 + { "C:usr/lib", "C:usr" },
180 + { "C:usr/lib///", "C:usr" },
181 + { "\\\\\\", "\\" },
182 + { "\\\\\\\\", "\\" },
183 +#if defined(NO_LIBGEN_H)
184 + { "C:", "C:." },
185 +#else
186 +
187 + /* win32 platform variations: */
188 +#if defined(__MINGW32__)
189 + /* the following is clearly wrong ... */
190 + { "C:", "." },
191 +#endif
192 +
193 +#if defined(_MSC_VER)
194 + { "C:", "C:." },
195 +#endif
196 +
197 +#endif
198 +#endif
199 + { NULL, NULL }
200 +};
201 +
202 int main(int argc, char **argv)
203 {
204 if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@@ -133,6 +293,12 @@ int main(int argc, char **argv)
293 return 0;
294 }
295
296 + if (argc == 2 && !strcmp(argv[1], "basename"))
297 + return test_function(basename_data, basename, argv[1]);
298 +
299 + if (argc == 2 && !strcmp(argv[1], "dirname"))
300 + return test_function(dirname_data, dirname, argv[1]);
301 +
302 fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
303 argv[1] ? argv[1] : "(there was none)");
304 return 1;