1695b41eeSopenharmony_ci// Copyright 2011 Google Inc. All Rights Reserved.
2695b41eeSopenharmony_ci//
3695b41eeSopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4695b41eeSopenharmony_ci// you may not use this file except in compliance with the License.
5695b41eeSopenharmony_ci// You may obtain a copy of the License at
6695b41eeSopenharmony_ci//
7695b41eeSopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8695b41eeSopenharmony_ci//
9695b41eeSopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10695b41eeSopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11695b41eeSopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12695b41eeSopenharmony_ci// See the License for the specific language governing permissions and
13695b41eeSopenharmony_ci// limitations under the License.
14695b41eeSopenharmony_ci
15695b41eeSopenharmony_ci#include "util.h"
16695b41eeSopenharmony_ci
17695b41eeSopenharmony_ci#include "test.h"
18695b41eeSopenharmony_ci
19695b41eeSopenharmony_ciusing namespace std;
20695b41eeSopenharmony_ci
21695b41eeSopenharmony_cinamespace {
22695b41eeSopenharmony_ci
23695b41eeSopenharmony_civoid CanonicalizePath(string* path) {
24695b41eeSopenharmony_ci    uint64_t unused;
25695b41eeSopenharmony_ci    ::CanonicalizePath(path, &unused);
26695b41eeSopenharmony_ci}
27695b41eeSopenharmony_ci
28695b41eeSopenharmony_ci}  // namespace
29695b41eeSopenharmony_ci
30695b41eeSopenharmony_ciTEST(CanonicalizePath, PathSamples) {
31695b41eeSopenharmony_ci    string path;
32695b41eeSopenharmony_ci
33695b41eeSopenharmony_ci    CanonicalizePath(&path);
34695b41eeSopenharmony_ci    EXPECT_EQ("", path);
35695b41eeSopenharmony_ci
36695b41eeSopenharmony_ci    path = "foo.h";
37695b41eeSopenharmony_ci    CanonicalizePath(&path);
38695b41eeSopenharmony_ci    EXPECT_EQ("foo.h", path);
39695b41eeSopenharmony_ci
40695b41eeSopenharmony_ci    path = "./foo.h";
41695b41eeSopenharmony_ci    CanonicalizePath(&path);
42695b41eeSopenharmony_ci    EXPECT_EQ("foo.h", path);
43695b41eeSopenharmony_ci
44695b41eeSopenharmony_ci    path = "./foo/./bar.h";
45695b41eeSopenharmony_ci    CanonicalizePath(&path);
46695b41eeSopenharmony_ci    EXPECT_EQ("foo/bar.h", path);
47695b41eeSopenharmony_ci
48695b41eeSopenharmony_ci    path = "./x/foo/../bar.h";
49695b41eeSopenharmony_ci    CanonicalizePath(&path);
50695b41eeSopenharmony_ci    EXPECT_EQ("x/bar.h", path);
51695b41eeSopenharmony_ci
52695b41eeSopenharmony_ci    path = "./x/foo/../../bar.h";
53695b41eeSopenharmony_ci    CanonicalizePath(&path);
54695b41eeSopenharmony_ci    EXPECT_EQ("bar.h", path);
55695b41eeSopenharmony_ci
56695b41eeSopenharmony_ci    path = "foo//bar";
57695b41eeSopenharmony_ci    CanonicalizePath(&path);
58695b41eeSopenharmony_ci    EXPECT_EQ("foo/bar", path);
59695b41eeSopenharmony_ci
60695b41eeSopenharmony_ci    path = "foo//.//..///bar";
61695b41eeSopenharmony_ci    CanonicalizePath(&path);
62695b41eeSopenharmony_ci    EXPECT_EQ("bar", path);
63695b41eeSopenharmony_ci
64695b41eeSopenharmony_ci    path = "./x/../foo/../../bar.h";
65695b41eeSopenharmony_ci    CanonicalizePath(&path);
66695b41eeSopenharmony_ci    EXPECT_EQ("../bar.h", path);
67695b41eeSopenharmony_ci
68695b41eeSopenharmony_ci    path = "foo/./.";
69695b41eeSopenharmony_ci    CanonicalizePath(&path);
70695b41eeSopenharmony_ci    EXPECT_EQ("foo", path);
71695b41eeSopenharmony_ci
72695b41eeSopenharmony_ci    path = "foo/bar/..";
73695b41eeSopenharmony_ci    CanonicalizePath(&path);
74695b41eeSopenharmony_ci    EXPECT_EQ("foo", path);
75695b41eeSopenharmony_ci
76695b41eeSopenharmony_ci    path = "foo/.hidden_bar";
77695b41eeSopenharmony_ci    CanonicalizePath(&path);
78695b41eeSopenharmony_ci    EXPECT_EQ("foo/.hidden_bar", path);
79695b41eeSopenharmony_ci
80695b41eeSopenharmony_ci    path = "/foo";
81695b41eeSopenharmony_ci    CanonicalizePath(&path);
82695b41eeSopenharmony_ci    EXPECT_EQ("/foo", path);
83695b41eeSopenharmony_ci
84695b41eeSopenharmony_ci    path = "//foo";
85695b41eeSopenharmony_ci    CanonicalizePath(&path);
86695b41eeSopenharmony_ci#ifdef _WIN32
87695b41eeSopenharmony_ci    EXPECT_EQ("//foo", path);
88695b41eeSopenharmony_ci#else
89695b41eeSopenharmony_ci    EXPECT_EQ("/foo", path);
90695b41eeSopenharmony_ci#endif
91695b41eeSopenharmony_ci
92695b41eeSopenharmony_ci    path = "..";
93695b41eeSopenharmony_ci    CanonicalizePath(&path);
94695b41eeSopenharmony_ci    EXPECT_EQ("..", path);
95695b41eeSopenharmony_ci
96695b41eeSopenharmony_ci    path = "../";
97695b41eeSopenharmony_ci    CanonicalizePath(&path);
98695b41eeSopenharmony_ci    EXPECT_EQ("..", path);
99695b41eeSopenharmony_ci
100695b41eeSopenharmony_ci    path = "../foo";
101695b41eeSopenharmony_ci    CanonicalizePath(&path);
102695b41eeSopenharmony_ci    EXPECT_EQ("../foo", path);
103695b41eeSopenharmony_ci
104695b41eeSopenharmony_ci    path = "../foo/";
105695b41eeSopenharmony_ci    CanonicalizePath(&path);
106695b41eeSopenharmony_ci    EXPECT_EQ("../foo", path);
107695b41eeSopenharmony_ci
108695b41eeSopenharmony_ci    path = "../..";
109695b41eeSopenharmony_ci    CanonicalizePath(&path);
110695b41eeSopenharmony_ci    EXPECT_EQ("../..", path);
111695b41eeSopenharmony_ci
112695b41eeSopenharmony_ci    path = "../../";
113695b41eeSopenharmony_ci    CanonicalizePath(&path);
114695b41eeSopenharmony_ci    EXPECT_EQ("../..", path);
115695b41eeSopenharmony_ci
116695b41eeSopenharmony_ci    path = "./../";
117695b41eeSopenharmony_ci    CanonicalizePath(&path);
118695b41eeSopenharmony_ci    EXPECT_EQ("..", path);
119695b41eeSopenharmony_ci
120695b41eeSopenharmony_ci    path = "/..";
121695b41eeSopenharmony_ci    CanonicalizePath(&path);
122695b41eeSopenharmony_ci    EXPECT_EQ("/..", path);
123695b41eeSopenharmony_ci
124695b41eeSopenharmony_ci    path = "/../";
125695b41eeSopenharmony_ci    CanonicalizePath(&path);
126695b41eeSopenharmony_ci    EXPECT_EQ("/..", path);
127695b41eeSopenharmony_ci
128695b41eeSopenharmony_ci    path = "/../..";
129695b41eeSopenharmony_ci    CanonicalizePath(&path);
130695b41eeSopenharmony_ci    EXPECT_EQ("/../..", path);
131695b41eeSopenharmony_ci
132695b41eeSopenharmony_ci    path = "/../../";
133695b41eeSopenharmony_ci    CanonicalizePath(&path);
134695b41eeSopenharmony_ci    EXPECT_EQ("/../..", path);
135695b41eeSopenharmony_ci
136695b41eeSopenharmony_ci    path = "/";
137695b41eeSopenharmony_ci    CanonicalizePath(&path);
138695b41eeSopenharmony_ci    EXPECT_EQ("/", path);
139695b41eeSopenharmony_ci
140695b41eeSopenharmony_ci    path = "/foo/..";
141695b41eeSopenharmony_ci    CanonicalizePath(&path);
142695b41eeSopenharmony_ci    EXPECT_EQ("/", path);
143695b41eeSopenharmony_ci
144695b41eeSopenharmony_ci    path = ".";
145695b41eeSopenharmony_ci    CanonicalizePath(&path);
146695b41eeSopenharmony_ci    EXPECT_EQ(".", path);
147695b41eeSopenharmony_ci
148695b41eeSopenharmony_ci    path = "./.";
149695b41eeSopenharmony_ci    CanonicalizePath(&path);
150695b41eeSopenharmony_ci    EXPECT_EQ(".", path);
151695b41eeSopenharmony_ci
152695b41eeSopenharmony_ci    path = "foo/..";
153695b41eeSopenharmony_ci    CanonicalizePath(&path);
154695b41eeSopenharmony_ci    EXPECT_EQ(".", path);
155695b41eeSopenharmony_ci
156695b41eeSopenharmony_ci    path = "foo/.._bar";
157695b41eeSopenharmony_ci    CanonicalizePath(&path);
158695b41eeSopenharmony_ci    EXPECT_EQ("foo/.._bar", path);
159695b41eeSopenharmony_ci}
160695b41eeSopenharmony_ci
161695b41eeSopenharmony_ci#ifdef _WIN32
162695b41eeSopenharmony_ciTEST(CanonicalizePath, PathSamplesWindows) {
163695b41eeSopenharmony_ci    string path;
164695b41eeSopenharmony_ci
165695b41eeSopenharmony_ci    CanonicalizePath(&path);
166695b41eeSopenharmony_ci    EXPECT_EQ("", path);
167695b41eeSopenharmony_ci
168695b41eeSopenharmony_ci    path = "foo.h";
169695b41eeSopenharmony_ci    CanonicalizePath(&path);
170695b41eeSopenharmony_ci    EXPECT_EQ("foo.h", path);
171695b41eeSopenharmony_ci
172695b41eeSopenharmony_ci    path = ".\\foo.h";
173695b41eeSopenharmony_ci    CanonicalizePath(&path);
174695b41eeSopenharmony_ci    EXPECT_EQ("foo.h", path);
175695b41eeSopenharmony_ci
176695b41eeSopenharmony_ci    path = ".\\foo\\.\\bar.h";
177695b41eeSopenharmony_ci    CanonicalizePath(&path);
178695b41eeSopenharmony_ci    EXPECT_EQ("foo/bar.h", path);
179695b41eeSopenharmony_ci
180695b41eeSopenharmony_ci    path = ".\\x\\foo\\..\\bar.h";
181695b41eeSopenharmony_ci    CanonicalizePath(&path);
182695b41eeSopenharmony_ci    EXPECT_EQ("x/bar.h", path);
183695b41eeSopenharmony_ci
184695b41eeSopenharmony_ci    path = ".\\x\\foo\\..\\..\\bar.h";
185695b41eeSopenharmony_ci    CanonicalizePath(&path);
186695b41eeSopenharmony_ci    EXPECT_EQ("bar.h", path);
187695b41eeSopenharmony_ci
188695b41eeSopenharmony_ci    path = "foo\\\\bar";
189695b41eeSopenharmony_ci    CanonicalizePath(&path);
190695b41eeSopenharmony_ci    EXPECT_EQ("foo/bar", path);
191695b41eeSopenharmony_ci
192695b41eeSopenharmony_ci    path = "foo\\\\.\\\\..\\\\\\bar";
193695b41eeSopenharmony_ci    CanonicalizePath(&path);
194695b41eeSopenharmony_ci    EXPECT_EQ("bar", path);
195695b41eeSopenharmony_ci
196695b41eeSopenharmony_ci    path = ".\\x\\..\\foo\\..\\..\\bar.h";
197695b41eeSopenharmony_ci    CanonicalizePath(&path);
198695b41eeSopenharmony_ci    EXPECT_EQ("../bar.h", path);
199695b41eeSopenharmony_ci
200695b41eeSopenharmony_ci    path = "foo\\.\\.";
201695b41eeSopenharmony_ci    CanonicalizePath(&path);
202695b41eeSopenharmony_ci    EXPECT_EQ("foo", path);
203695b41eeSopenharmony_ci
204695b41eeSopenharmony_ci    path = "foo\\bar\\..";
205695b41eeSopenharmony_ci    CanonicalizePath(&path);
206695b41eeSopenharmony_ci    EXPECT_EQ("foo", path);
207695b41eeSopenharmony_ci
208695b41eeSopenharmony_ci    path = "foo\\.hidden_bar";
209695b41eeSopenharmony_ci    CanonicalizePath(&path);
210695b41eeSopenharmony_ci    EXPECT_EQ("foo/.hidden_bar", path);
211695b41eeSopenharmony_ci
212695b41eeSopenharmony_ci    path = "\\foo";
213695b41eeSopenharmony_ci    CanonicalizePath(&path);
214695b41eeSopenharmony_ci    EXPECT_EQ("/foo", path);
215695b41eeSopenharmony_ci
216695b41eeSopenharmony_ci    path = "\\\\foo";
217695b41eeSopenharmony_ci    CanonicalizePath(&path);
218695b41eeSopenharmony_ci    EXPECT_EQ("//foo", path);
219695b41eeSopenharmony_ci
220695b41eeSopenharmony_ci    path = "\\";
221695b41eeSopenharmony_ci    CanonicalizePath(&path);
222695b41eeSopenharmony_ci    EXPECT_EQ("/", path);
223695b41eeSopenharmony_ci}
224695b41eeSopenharmony_ci
225695b41eeSopenharmony_ciTEST(CanonicalizePath, SlashTracking) {
226695b41eeSopenharmony_ci    string path;
227695b41eeSopenharmony_ci    uint64_t slash_bits;
228695b41eeSopenharmony_ci
229695b41eeSopenharmony_ci    path = "foo.h";
230695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
231695b41eeSopenharmony_ci    EXPECT_EQ("foo.h", path);
232695b41eeSopenharmony_ci    EXPECT_EQ(0, slash_bits);
233695b41eeSopenharmony_ci
234695b41eeSopenharmony_ci    path = "a\\foo.h";
235695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
236695b41eeSopenharmony_ci    EXPECT_EQ("a/foo.h", path);
237695b41eeSopenharmony_ci    EXPECT_EQ(1, slash_bits);
238695b41eeSopenharmony_ci
239695b41eeSopenharmony_ci    path = "a/bcd/efh\\foo.h";
240695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
241695b41eeSopenharmony_ci    EXPECT_EQ("a/bcd/efh/foo.h", path);
242695b41eeSopenharmony_ci    EXPECT_EQ(4, slash_bits);
243695b41eeSopenharmony_ci
244695b41eeSopenharmony_ci    path = "a\\bcd/efh\\foo.h";
245695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
246695b41eeSopenharmony_ci    EXPECT_EQ("a/bcd/efh/foo.h", path);
247695b41eeSopenharmony_ci    EXPECT_EQ(5, slash_bits);
248695b41eeSopenharmony_ci
249695b41eeSopenharmony_ci    path = "a\\bcd\\efh\\foo.h";
250695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
251695b41eeSopenharmony_ci    EXPECT_EQ("a/bcd/efh/foo.h", path);
252695b41eeSopenharmony_ci    EXPECT_EQ(7, slash_bits);
253695b41eeSopenharmony_ci
254695b41eeSopenharmony_ci    path = "a/bcd/efh/foo.h";
255695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
256695b41eeSopenharmony_ci    EXPECT_EQ("a/bcd/efh/foo.h", path);
257695b41eeSopenharmony_ci    EXPECT_EQ(0, slash_bits);
258695b41eeSopenharmony_ci
259695b41eeSopenharmony_ci    path = "a\\./efh\\foo.h";
260695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
261695b41eeSopenharmony_ci    EXPECT_EQ("a/efh/foo.h", path);
262695b41eeSopenharmony_ci    EXPECT_EQ(3, slash_bits);
263695b41eeSopenharmony_ci
264695b41eeSopenharmony_ci    path = "a\\../efh\\foo.h";
265695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
266695b41eeSopenharmony_ci    EXPECT_EQ("efh/foo.h", path);
267695b41eeSopenharmony_ci    EXPECT_EQ(1, slash_bits);
268695b41eeSopenharmony_ci
269695b41eeSopenharmony_ci    path = "a\\b\\c\\d\\e\\f\\g\\foo.h";
270695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
271695b41eeSopenharmony_ci    EXPECT_EQ("a/b/c/d/e/f/g/foo.h", path);
272695b41eeSopenharmony_ci    EXPECT_EQ(127, slash_bits);
273695b41eeSopenharmony_ci
274695b41eeSopenharmony_ci    path = "a\\b\\c\\..\\..\\..\\g\\foo.h";
275695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
276695b41eeSopenharmony_ci    EXPECT_EQ("g/foo.h", path);
277695b41eeSopenharmony_ci    EXPECT_EQ(1, slash_bits);
278695b41eeSopenharmony_ci
279695b41eeSopenharmony_ci    path = "a\\b/c\\../../..\\g\\foo.h";
280695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
281695b41eeSopenharmony_ci    EXPECT_EQ("g/foo.h", path);
282695b41eeSopenharmony_ci    EXPECT_EQ(1, slash_bits);
283695b41eeSopenharmony_ci
284695b41eeSopenharmony_ci    path = "a\\b/c\\./../..\\g\\foo.h";
285695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
286695b41eeSopenharmony_ci    EXPECT_EQ("a/g/foo.h", path);
287695b41eeSopenharmony_ci    EXPECT_EQ(3, slash_bits);
288695b41eeSopenharmony_ci
289695b41eeSopenharmony_ci    path = "a\\b/c\\./../..\\g/foo.h";
290695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
291695b41eeSopenharmony_ci    EXPECT_EQ("a/g/foo.h", path);
292695b41eeSopenharmony_ci    EXPECT_EQ(1, slash_bits);
293695b41eeSopenharmony_ci
294695b41eeSopenharmony_ci    path = "a\\\\\\foo.h";
295695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
296695b41eeSopenharmony_ci    EXPECT_EQ("a/foo.h", path);
297695b41eeSopenharmony_ci    EXPECT_EQ(1, slash_bits);
298695b41eeSopenharmony_ci
299695b41eeSopenharmony_ci    path = "a/\\\\foo.h";
300695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
301695b41eeSopenharmony_ci    EXPECT_EQ("a/foo.h", path);
302695b41eeSopenharmony_ci    EXPECT_EQ(0, slash_bits);
303695b41eeSopenharmony_ci
304695b41eeSopenharmony_ci    path = "a\\//foo.h";
305695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
306695b41eeSopenharmony_ci    EXPECT_EQ("a/foo.h", path);
307695b41eeSopenharmony_ci    EXPECT_EQ(1, slash_bits);
308695b41eeSopenharmony_ci}
309695b41eeSopenharmony_ci
310695b41eeSopenharmony_ciTEST(CanonicalizePath, CanonicalizeNotExceedingLen) {
311695b41eeSopenharmony_ci    // Make sure searching \/ doesn't go past supplied len.
312695b41eeSopenharmony_ci    char buf[] = "foo/bar\\baz.h\\";  // Last \ past end.
313695b41eeSopenharmony_ci    uint64_t slash_bits;
314695b41eeSopenharmony_ci    size_t size = 13;
315695b41eeSopenharmony_ci    ::CanonicalizePath(buf, &size, &slash_bits);
316695b41eeSopenharmony_ci    EXPECT_EQ(0, strncmp("foo/bar/baz.h", buf, size));
317695b41eeSopenharmony_ci    EXPECT_EQ(2, slash_bits);  // Not including the trailing one.
318695b41eeSopenharmony_ci}
319695b41eeSopenharmony_ci
320695b41eeSopenharmony_ciTEST(CanonicalizePath, TooManyComponents) {
321695b41eeSopenharmony_ci    string path;
322695b41eeSopenharmony_ci    uint64_t slash_bits;
323695b41eeSopenharmony_ci
324695b41eeSopenharmony_ci    // 64 is OK.
325695b41eeSopenharmony_ci    path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
326695b41eeSopenharmony_ci                  "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x.h";
327695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
328695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0x0);
329695b41eeSopenharmony_ci
330695b41eeSopenharmony_ci    // Backslashes version.
331695b41eeSopenharmony_ci    path =
332695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
333695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
334695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
335695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x.h";
336695b41eeSopenharmony_ci
337695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
338695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0xffffffff);
339695b41eeSopenharmony_ci
340695b41eeSopenharmony_ci    // 65 is OK if #component is less than 60 after path canonicalization.
341695b41eeSopenharmony_ci    path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
342695b41eeSopenharmony_ci                  "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x/y.h";
343695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
344695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0x0);
345695b41eeSopenharmony_ci
346695b41eeSopenharmony_ci    // Backslashes version.
347695b41eeSopenharmony_ci    path =
348695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
349695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
350695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
351695b41eeSopenharmony_ci            "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x\\y.h";
352695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
353695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0x1ffffffff);
354695b41eeSopenharmony_ci
355695b41eeSopenharmony_ci
356695b41eeSopenharmony_ci    // 59 after canonicalization is OK.
357695b41eeSopenharmony_ci    path = "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
358695b41eeSopenharmony_ci                  "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/x/y.h";
359695b41eeSopenharmony_ci    EXPECT_EQ(58, std::count(path.begin(), path.end(), '/'));
360695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
361695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0x0);
362695b41eeSopenharmony_ci
363695b41eeSopenharmony_ci    // Backslashes version.
364695b41eeSopenharmony_ci    path =
365695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
366695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
367695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
368695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\x\\y.h";
369695b41eeSopenharmony_ci    EXPECT_EQ(58, std::count(path.begin(), path.end(), '\\'));
370695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
371695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0x3ffffffffffffff);
372695b41eeSopenharmony_ci
373695b41eeSopenharmony_ci    // More than 60 components is now completely ok too.
374695b41eeSopenharmony_ci    path =
375695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
376695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
377695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
378695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
379695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
380695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
381695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
382695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
383695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
384695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
385695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
386695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
387695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
388695b41eeSopenharmony_ci            "a\\a\\a\\a\\a\\a\\a\\a\\a\\x\\y.h";
389695b41eeSopenharmony_ci    EXPECT_EQ(218, std::count(path.begin(), path.end(), '\\'));
390695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
391695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0xffffffffffffffff);
392695b41eeSopenharmony_ci}
393695b41eeSopenharmony_ci#else   // !_WIN32
394695b41eeSopenharmony_ciTEST(CanonicalizePath, TooManyComponents) {
395695b41eeSopenharmony_ci    string path;
396695b41eeSopenharmony_ci    uint64_t slash_bits;
397695b41eeSopenharmony_ci
398695b41eeSopenharmony_ci    // More than 60 components is now completely ok.
399695b41eeSopenharmony_ci    path =
400695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
401695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
402695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
403695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
404695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
405695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
406695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
407695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
408695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
409695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
410695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
411695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
412695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
413695b41eeSopenharmony_ci            "a/a/a/a/a/a/a/a/a/x/y.h";
414695b41eeSopenharmony_ci    EXPECT_EQ(218, std::count(path.begin(), path.end(), '/'));
415695b41eeSopenharmony_ci    CanonicalizePath(&path, &slash_bits);
416695b41eeSopenharmony_ci    EXPECT_EQ(slash_bits, 0x0);
417695b41eeSopenharmony_ci}
418695b41eeSopenharmony_ci#endif  // !_WIN32
419695b41eeSopenharmony_ci
420695b41eeSopenharmony_ciTEST(CanonicalizePath, UpDir) {
421695b41eeSopenharmony_ci    string path, err;
422695b41eeSopenharmony_ci    path = "../../foo/bar.h";
423695b41eeSopenharmony_ci    CanonicalizePath(&path);
424695b41eeSopenharmony_ci    EXPECT_EQ("../../foo/bar.h", path);
425695b41eeSopenharmony_ci
426695b41eeSopenharmony_ci    path = "test/../../foo/bar.h";
427695b41eeSopenharmony_ci    CanonicalizePath(&path);
428695b41eeSopenharmony_ci    EXPECT_EQ("../foo/bar.h", path);
429695b41eeSopenharmony_ci}
430695b41eeSopenharmony_ci
431695b41eeSopenharmony_ciTEST(CanonicalizePath, AbsolutePath) {
432695b41eeSopenharmony_ci    string path = "/usr/include/stdio.h";
433695b41eeSopenharmony_ci    string err;
434695b41eeSopenharmony_ci    CanonicalizePath(&path);
435695b41eeSopenharmony_ci    EXPECT_EQ("/usr/include/stdio.h", path);
436695b41eeSopenharmony_ci}
437695b41eeSopenharmony_ci
438695b41eeSopenharmony_ciTEST(CanonicalizePath, NotNullTerminated) {
439695b41eeSopenharmony_ci    string path;
440695b41eeSopenharmony_ci    size_t len;
441695b41eeSopenharmony_ci    uint64_t unused;
442695b41eeSopenharmony_ci
443695b41eeSopenharmony_ci    path = "foo/. bar/.";
444695b41eeSopenharmony_ci    len = strlen("foo/.");  // Canonicalize only the part before the space.
445695b41eeSopenharmony_ci    CanonicalizePath(&path[0], &len, &unused);
446695b41eeSopenharmony_ci    EXPECT_EQ(strlen("foo"), len);
447695b41eeSopenharmony_ci    EXPECT_EQ("foo/. bar/.", string(path));
448695b41eeSopenharmony_ci
449695b41eeSopenharmony_ci    // Verify that foo/..file gets canonicalized to 'file' without
450695b41eeSopenharmony_ci    // touching the rest of the string.
451695b41eeSopenharmony_ci    path = "foo/../file bar/.";
452695b41eeSopenharmony_ci    len = strlen("foo/../file");
453695b41eeSopenharmony_ci    CanonicalizePath(&path[0], &len, &unused);
454695b41eeSopenharmony_ci    EXPECT_EQ(strlen("file"), len);
455695b41eeSopenharmony_ci    EXPECT_EQ("file../file bar/.", string(path));
456695b41eeSopenharmony_ci}
457695b41eeSopenharmony_ci
458695b41eeSopenharmony_ciTEST(PathEscaping, TortureTest) {
459695b41eeSopenharmony_ci    string result;
460695b41eeSopenharmony_ci
461695b41eeSopenharmony_ci    GetWin32EscapedString("foo bar\\\"'$@d!st!c'\\path'\\", &result);
462695b41eeSopenharmony_ci    EXPECT_EQ("\"foo bar\\\\\\\"'$@d!st!c'\\path'\\\\\"", result);
463695b41eeSopenharmony_ci    result.clear();
464695b41eeSopenharmony_ci
465695b41eeSopenharmony_ci    GetShellEscapedString("foo bar\"/'$@d!st!c'/path'", &result);
466695b41eeSopenharmony_ci    EXPECT_EQ("'foo bar\"/'\\''$@d!st!c'\\''/path'\\'''", result);
467695b41eeSopenharmony_ci}
468695b41eeSopenharmony_ci
469695b41eeSopenharmony_ciTEST(PathEscaping, SensiblePathsAreNotNeedlesslyEscaped) {
470695b41eeSopenharmony_ci    const char* path = "some/sensible/path/without/crazy/characters.c++";
471695b41eeSopenharmony_ci    string result;
472695b41eeSopenharmony_ci
473695b41eeSopenharmony_ci    GetWin32EscapedString(path, &result);
474695b41eeSopenharmony_ci    EXPECT_EQ(path, result);
475695b41eeSopenharmony_ci    result.clear();
476695b41eeSopenharmony_ci
477695b41eeSopenharmony_ci    GetShellEscapedString(path, &result);
478695b41eeSopenharmony_ci    EXPECT_EQ(path, result);
479695b41eeSopenharmony_ci}
480695b41eeSopenharmony_ci
481695b41eeSopenharmony_ciTEST(PathEscaping, SensibleWin32PathsAreNotNeedlesslyEscaped) {
482695b41eeSopenharmony_ci    const char* path = "some\\sensible\\path\\without\\crazy\\characters.c++";
483695b41eeSopenharmony_ci    string result;
484695b41eeSopenharmony_ci
485695b41eeSopenharmony_ci    GetWin32EscapedString(path, &result);
486695b41eeSopenharmony_ci    EXPECT_EQ(path, result);
487695b41eeSopenharmony_ci}
488695b41eeSopenharmony_ci
489695b41eeSopenharmony_ciTEST(StripAnsiEscapeCodes, EscapeAtEnd) {
490695b41eeSopenharmony_ci    string stripped = StripAnsiEscapeCodes("foo\33");
491695b41eeSopenharmony_ci    EXPECT_EQ("foo", stripped);
492695b41eeSopenharmony_ci
493695b41eeSopenharmony_ci    stripped = StripAnsiEscapeCodes("foo\33[");
494695b41eeSopenharmony_ci    EXPECT_EQ("foo", stripped);
495695b41eeSopenharmony_ci}
496695b41eeSopenharmony_ci
497695b41eeSopenharmony_ciTEST(StripAnsiEscapeCodes, StripColors) {
498695b41eeSopenharmony_ci    // An actual clang warning.
499695b41eeSopenharmony_ci    string input = "\33[1maffixmgr.cxx:286:15: \33[0m\33[0;1;35mwarning: "
500695b41eeSopenharmony_ci                                  "\33[0m\33[1musing the result... [-Wparentheses]\33[0m";
501695b41eeSopenharmony_ci    string stripped = StripAnsiEscapeCodes(input);
502695b41eeSopenharmony_ci    EXPECT_EQ("affixmgr.cxx:286:15: warning: using the result... [-Wparentheses]",
503695b41eeSopenharmony_ci                        stripped);
504695b41eeSopenharmony_ci}
505695b41eeSopenharmony_ci
506695b41eeSopenharmony_ciTEST(ElideMiddle, NothingToElide) {
507695b41eeSopenharmony_ci    string input = "Nothing to elide in this short string.";
508695b41eeSopenharmony_ci    EXPECT_EQ(input, ElideMiddle(input, 80));
509695b41eeSopenharmony_ci    EXPECT_EQ(input, ElideMiddle(input, 38));
510695b41eeSopenharmony_ci    EXPECT_EQ("", ElideMiddle(input, 0));
511695b41eeSopenharmony_ci    EXPECT_EQ(".", ElideMiddle(input, 1));
512695b41eeSopenharmony_ci    EXPECT_EQ("..", ElideMiddle(input, 2));
513695b41eeSopenharmony_ci    EXPECT_EQ("...", ElideMiddle(input, 3));
514695b41eeSopenharmony_ci}
515695b41eeSopenharmony_ci
516695b41eeSopenharmony_ciTEST(ElideMiddle, ElideInTheMiddle) {
517695b41eeSopenharmony_ci    string input = "01234567890123456789";
518695b41eeSopenharmony_ci    string elided = ElideMiddle(input, 10);
519695b41eeSopenharmony_ci    EXPECT_EQ("012...789", elided);
520695b41eeSopenharmony_ci    EXPECT_EQ("01234567...23456789", ElideMiddle(input, 19));
521695b41eeSopenharmony_ci}
522