1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* util/support/t_path.c - Path manipulation tests */
3 /*
4 * Copyright (C) 2011 by the Massachusetts Institute of Technology.
5 * All rights reserved.
6 *
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
11 *
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 */
26
27 #include <k5-platform.h>
28
29 /* For testing purposes, use a different symbol for Windows path semantics. */
30 #ifdef _WIN32
31 #define WINDOWS_PATHS
32 #endif
33
34 /*
35 * The ultimate arbiter of these tests is the dirname, basename, and isabs
36 * methods of the Python posixpath and ntpath modules.
37 */
38
39 struct {
40 const char *path;
41 const char *posix_dirname;
42 const char *posix_basename;
43 const char *win_dirname;
44 const char *win_basename;
45 } split_tests[] = {
46 { "", "", "", "", "" },
47 { "a/b/c", "a/b", "c", "a/b", "c" },
48 { "a/b/", "a/b", "", "a/b", "" },
49 { "a\\b\\c", "", "a\\b\\c", "a\\b", "c" },
50 { "a\\b\\", "", "a\\b\\", "a\\b", "" },
51 { "a/b\\c", "a", "b\\c", "a/b", "c" },
52 { "a//b", "a", "b", "a", "b" },
53 { "a/\\/b", "a/\\", "b", "a", "b" },
54 { "a//b/c", "a//b", "c", "a//b", "c" },
55
56 { "/", "/", "", "/", "" },
57 { "\\", "", "\\", "\\", "" },
58 { "/a/b/c", "/a/b", "c", "/a/b", "c" },
59 { "\\a/b/c", "\\a/b", "c", "\\a/b", "c" },
60 { "/a", "/", "a", "/", "a" },
61 { "//a", "//", "a", "//", "a" },
62 { "\\//\\a", "\\", "\\a", "\\//\\", "a" },
63
64 { "/:", "/", ":", "/:", "" },
65 { "c:\\", "", "c:\\", "c:\\", "" },
66 { "c:/", "c:", "", "c:/", "" },
67 { "c:/\\a", "c:", "\\a", "c:/\\", "a" },
68 { "c:a", "", "c:a", "c:", "a" },
69 };
70
71 struct {
72 const char *path1;
73 const char *path2;
74 const char *posix_result;
75 const char *win_result;
76 } join_tests[] = {
77 { "", "", "", "" },
78 { "", "a", "a", "a" },
79 { "", "/a", "/a", "/a" },
80 { "", "c:", "c:", "c:" },
81
82 { "a", "", "a/", "a\\" },
83 { "a/", "", "a/", "a/" },
84 { "a\\", "", "a\\/", "a\\" },
85 { "a/\\", "", "a/\\/", "a/\\" },
86
87 { "a", "b", "a/b", "a\\b" },
88 { "a", "/b", "/b", "/b" },
89 { "a", "c:", "a/c:", "a\\c:" },
90 { "a", "c:/", "a/c:/", "c:/" },
91 { "a", "c:/a", "a/c:/a", "c:/a" },
92 { "a", "/:", "/:", "a/:" },
93 { "a/", "b", "a/b", "a/b" },
94 { "a/", "", "a/", "a/" },
95 { "a\\", "b", "a\\/b", "a\\b" },
96
97 { "a//", "b", "a//b", "a//b" },
98 { "a/\\", "b", "a/\\/b", "a/\\b" },
99 };
100
101 struct {
102 const char *path;
103 int posix_result;
104 int win_result;
105 } isabs_tests[] = {
106 { "", 0, 0 },
107 { "/", 1, 1 },
108 { "/a", 1, 1 },
109 { "a/b", 0, 0 },
110 { "\\", 0, 1 },
111 { "\\a", 0, 1 },
112 { "c:", 0, 0 },
113 { "/:", 1, 0 },
114 { "\\:", 0, 0 },
115 { "c:/a", 0, 1 },
116 { "c:\\a", 0, 1 },
117 { "c:a", 0, 0 },
118 { "c:a/b", 0, 0 },
119 { "/:a/b", 1, 0 },
120 };
121
122 int
main(void)123 main(void)
124 {
125 char *dirname, *basename, *joined;
126 const char *edirname, *ebasename, *ejoined, *ipath, *path1, *path2;
127 int result, eresult, status = 0;
128 size_t i;
129
130 for (i = 0; i < sizeof(split_tests) / sizeof(*split_tests); i++) {
131 ipath = split_tests[i].path;
132 #ifdef WINDOWS_PATHS
133 edirname = split_tests[i].win_dirname;
134 ebasename = split_tests[i].win_basename;
135 #else
136 edirname = split_tests[i].posix_dirname;
137 ebasename = split_tests[i].posix_basename;
138 #endif
139 if (k5_path_split(ipath, NULL, NULL) != 0)
140 abort();
141 if (k5_path_split(ipath, &dirname, NULL) != 0)
142 abort();
143 free(dirname);
144 if (k5_path_split(ipath, NULL, &basename) != 0)
145 abort();
146 free(basename);
147 if (k5_path_split(ipath, &dirname, &basename) != 0)
148 abort();
149 if (strcmp(dirname, edirname) != 0) {
150 fprintf(stderr, "Split test %d: dirname %s != expected %s\n",
151 (int)i, dirname, edirname);
152 status = 1;
153 }
154 if (strcmp(basename, ebasename) != 0) {
155 fprintf(stderr, "Split test %d: basename %s != expected %s\n",
156 (int)i, basename, ebasename);
157 status = 1;
158 }
159 free(dirname);
160 free(basename);
161 }
162
163 for (i = 0; i < sizeof(join_tests) / sizeof(*join_tests); i++) {
164 path1 = join_tests[i].path1;
165 path2 = join_tests[i].path2;
166 #ifdef WINDOWS_PATHS
167 ejoined = join_tests[i].win_result;
168 #else
169 ejoined = join_tests[i].posix_result;
170 #endif
171 if (k5_path_join(path1, path2, &joined) != 0)
172 abort();
173 if (strcmp(joined, ejoined) != 0) {
174 fprintf(stderr, "Join test %d: %s != expected %s\n",
175 (int)i, joined, ejoined);
176 status = 1;
177 }
178 free(joined);
179 }
180
181 for (i = 0; i < sizeof(isabs_tests) / sizeof(*isabs_tests); i++) {
182 #ifdef WINDOWS_PATHS
183 eresult = isabs_tests[i].win_result;
184 #else
185 eresult = isabs_tests[i].posix_result;
186 #endif
187 result = k5_path_isabs(isabs_tests[i].path);
188 if (result != eresult) {
189 fprintf(stderr, "isabs test %d: %d != expected %d\n",
190 (int)i, result, eresult);
191 status = 1;
192 }
193 }
194
195 return status;
196 }
197