1013d15a677f70aa9c91fa09707e5d4248146b99dMichael J. Spencer//===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
2f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//
3f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//                     The LLVM Compiler Infrastructure
4f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//
5f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer// This file is distributed under the University of Illinois Open Source
6f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer// License. See LICENSE.TXT for details.
7f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//
8f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//===----------------------------------------------------------------------===//
9f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
10a11c3e25015a62c817e60ec4f955a7f3f3bb6c67Rafael Espindola#include "llvm/Support/Path.h"
11f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/ConvertUTF.h"
12c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/Errc.h"
13753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer#include "llvm/Support/ErrorHandling.h"
145a88dda4be791426ab4d20a6a6c9c65d66614a27Chandler Carruth#include "llvm/Support/FileSystem.h"
15c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola#include "llvm/Support/MemoryBuffer.h"
16f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer#include "llvm/Support/raw_ostream.h"
17f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer#include "gtest/gtest.h"
18f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#ifdef LLVM_ON_WIN32
20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/ADT/ArrayRef.h"
21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include <windows.h>
22c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <winerror.h>
23c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#endif
24c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
25f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#ifdef LLVM_ON_UNIX
26f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include <sys/stat.h>
27f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#endif
28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
29dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerusing namespace llvm;
303cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencerusing namespace llvm::sys;
31dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
32c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#define ASSERT_NO_ERROR(x)                                                     \
33c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
34c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SmallString<128> MessageStorage;                                           \
35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    raw_svector_ostream Message(MessageStorage);                               \
36c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Message << #x ": did not return errc::success.\n"                          \
37c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
38c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
39c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
40c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else {                                                                     \
41c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
42ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer
43f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencernamespace {
44f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
4563cc3a85cc10093f83f76ea9192f77929b58569eZhanyong WanTEST(is_separator, Works) {
4663cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_TRUE(path::is_separator('/'));
4763cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator('\0'));
4863cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator('-'));
4963cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator(' '));
5063cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan
5163cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#ifdef LLVM_ON_WIN32
5263cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_TRUE(path::is_separator('\\'));
5363cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#else
5463cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator('\\'));
5563cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#endif
5663cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan}
5763cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan
58013d15a677f70aa9c91fa09707e5d4248146b99dMichael J. SpencerTEST(Support, Path) {
59dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallVector<StringRef, 40> paths;
60dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("");
61dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back(".");
62dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("..");
63dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo");
64dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/");
65dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/foo");
66dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/");
67dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/foo/");
68dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/bar");
69dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/foo/bar");
70dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("//net");
71dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("//net/foo");
72dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("///foo///");
73dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("///foo///bar");
74dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/.");
75dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("./");
76dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/..");
77dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("../");
78dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/.");
79dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/..");
80dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/./");
81dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/./bar");
82dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/..");
83dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/../");
84dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/../bar");
85dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:");
86dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/");
87dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo");
88dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo");
89dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo/");
90dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo/");
91dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo/bar");
92dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("prn:");
93dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\");
94dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo");
95dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\foo");
96dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo\\");
97dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\foo\\");
98dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\foo/");
99dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo\\bar");
100dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<StringRef, 5> ComponentStack;
102dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
103dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  e = paths.end();
104dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  i != e;
105dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  ++i) {
106dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    for (sys::path::const_iterator ci = sys::path::begin(*i),
107dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                   ce = sys::path::end(*i);
108dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                   ci != ce;
109dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                   ++ci) {
110371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer      ASSERT_FALSE(ci->empty());
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ComponentStack.push_back(*ci);
112dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
113dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
114a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
115a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer                                     ce = sys::path::rend(*i);
116a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer                                     ci != ce;
117a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer                                     ++ci) {
11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ASSERT_TRUE(*ci == ComponentStack.back());
11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ComponentStack.pop_back();
120a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    }
12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ASSERT_TRUE(ComponentStack.empty());
122a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
1235029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_root_path(*i);
1245029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::root_path(*i);
1255029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_root_name(*i);
1265029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::root_name(*i);
1275029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_root_directory(*i);
1285029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::root_directory(*i);
1295029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_parent_path(*i);
1305029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::parent_path(*i);
1315029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_filename(*i);
1325029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::filename(*i);
1335029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_stem(*i);
1345029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::stem(*i);
1355029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_extension(*i);
1365029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::extension(*i);
1375029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::is_absolute(*i);
1385029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::is_relative(*i);
1391d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer
140ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer    SmallString<128> temp_store;
141371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    temp_store = *i;
142ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer    ASSERT_NO_ERROR(fs::make_absolute(temp_store));
143371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    temp_store = *i;
144936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::remove_filename(temp_store);
1451d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer
146371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    temp_store = *i;
147936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::replace_extension(temp_store, "ext");
1481d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer    StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
1495029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    stem = path::stem(filename);
1505029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    ext  = path::extension(filename);
15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    EXPECT_EQ(*sys::path::rbegin(filename), (stem + ext).str());
1521d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer
153936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::native(*i, temp_store);
154dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<32> Relative("foo.cpp");
157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_NO_ERROR(sys::fs::make_absolute("/root", Relative));
158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Relative[5] = '/'; // Fix up windows paths.
159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_EQ("/root/foo.cpp", Relative);
1602558516859ac52a17c85afff01073303bd522979Michael J. Spencer}
1612558516859ac52a17c85afff01073303bd522979Michael J. Spencer
162225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. SirajTEST(Support, RelativePathIterator) {
163225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  SmallString<64> Path(StringRef("c/d/e/foo.txt"));
164225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  typedef SmallVector<StringRef, 4> PathComponents;
165225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  PathComponents ExpectedPathComponents;
166225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  PathComponents ActualPathComponents;
167225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef(Path).split(ExpectedPathComponents, '/');
169225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
170225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
171225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj       ++I) {
172225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj    ActualPathComponents.push_back(*I);
173225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  }
174225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
175225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
176225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
177225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
178225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj    EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
179225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  }
180225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj}
181225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
1824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarTEST(Support, RelativePathDotIterator) {
1834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  SmallString<64> Path(StringRef(".c/.d/../."));
1844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  typedef SmallVector<StringRef, 4> PathComponents;
1854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  PathComponents ExpectedPathComponents;
1864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  PathComponents ActualPathComponents;
1874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef(Path).split(ExpectedPathComponents, '/');
1894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
1914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar       ++I) {
1924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    ActualPathComponents.push_back(*I);
1934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
1964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
1984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
1994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
2004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
2014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
202225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. SirajTEST(Support, AbsolutePathIterator) {
203225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  SmallString<64> Path(StringRef("/c/d/e/foo.txt"));
204225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  typedef SmallVector<StringRef, 4> PathComponents;
205225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  PathComponents ExpectedPathComponents;
206225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  PathComponents ActualPathComponents;
2074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef(Path).split(ExpectedPathComponents, '/');
2094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
2104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  // The root path will also be a component when iterating
2114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  ExpectedPathComponents[0] = "/";
2124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
2134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
2144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar       ++I) {
2154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    ActualPathComponents.push_back(*I);
2164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
2174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
2184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
2194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
2204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
2214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
2224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
2234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
2244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
2254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarTEST(Support, AbsolutePathDotIterator) {
2264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  SmallString<64> Path(StringRef("/.c/.d/../."));
2274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  typedef SmallVector<StringRef, 4> PathComponents;
2284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  PathComponents ExpectedPathComponents;
2294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  PathComponents ActualPathComponents;
230225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef(Path).split(ExpectedPathComponents, '/');
232225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
233225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  // The root path will also be a component when iterating
234225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  ExpectedPathComponents[0] = "/";
235225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
236225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
237225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj       ++I) {
238225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj    ActualPathComponents.push_back(*I);
239225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  }
240225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
241225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
242225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
243225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
244225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj    EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
245225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  }
246225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj}
247225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
248225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj#ifdef LLVM_ON_WIN32
249225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. SirajTEST(Support, AbsolutePathIteratorWin32) {
250225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  SmallString<64> Path(StringRef("c:\\c\\e\\foo.txt"));
251225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  typedef SmallVector<StringRef, 4> PathComponents;
252225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  PathComponents ExpectedPathComponents;
253225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  PathComponents ActualPathComponents;
254225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
255225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  StringRef(Path).split(ExpectedPathComponents, "\\");
256225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
257225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  // The root path (which comes after the drive name) will also be a component
258225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  // when iterating.
259225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  ExpectedPathComponents.insert(ExpectedPathComponents.begin()+1, "\\");
260225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
261225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
262225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj       ++I) {
263225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj    ActualPathComponents.push_back(*I);
264225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  }
265225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
266225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
267225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
268225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
269225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj    EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
270225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj  }
271225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj}
272225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj#endif // LLVM_ON_WIN32
273225396c2b52a50fa8a781e9a7b5cc81dceae010aTareq A. Siraj
27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST(Support, AbsolutePathIteratorEnd) {
27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Trailing slashes are converted to '.' unless they are part of the root path.
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<StringRef, 4> Paths;
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Paths.push_back("/foo/");
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Paths.push_back("/foo//");
27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Paths.push_back("//net//");
28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifdef LLVM_ON_WIN32
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Paths.push_back("c:\\\\");
28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (StringRef Path : Paths) {
28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef LastComponent = *path::rbegin(Path);
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EXPECT_EQ(".", LastComponent);
28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<StringRef, 3> RootPaths;
29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RootPaths.push_back("/");
29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RootPaths.push_back("//net/");
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifdef LLVM_ON_WIN32
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RootPaths.push_back("c:\\");
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (StringRef Path : RootPaths) {
29737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef LastComponent = *path::rbegin(Path);
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EXPECT_EQ(1u, LastComponent.size());
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EXPECT_TRUE(path::is_separator(LastComponent[0]));
30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST(Support, HomeDirectory) {
304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::string expected;
305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#ifdef LLVM_ON_WIN32
306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (wchar_t const *path = ::_wgetenv(L"USERPROFILE")) {
307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto pathLen = ::wcslen(path);
308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ArrayRef<char> ref{reinterpret_cast<char const *>(path),
309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                       pathLen * sizeof(wchar_t)};
310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    convertUTF16ToUTF8String(ref, expected);
311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#else
313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (char const *path = ::getenv("HOME"))
314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    expected = path;
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Do not try to test it if we don't know what to expect.
317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // On Windows we use something better than env vars.
318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!expected.empty()) {
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallString<128> HomeDir;
320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto status = path::home_directory(HomeDir);
321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_TRUE(status);
322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ(expected, HomeDir);
32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarTEST(Support, UserCacheDirectory) {
327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<13> CacheDir;
328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<20> CacheDir2;
329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto Status = path::user_cache_directory(CacheDir, "");
330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TRUE(Status ^ CacheDir.empty());
331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Status) {
333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_TRUE(path::user_cache_directory(CacheDir2, "")); // should succeed
334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ(CacheDir, CacheDir2); // and return same paths
335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_TRUE(path::user_cache_directory(CacheDir, "A", "B", "file.c"));
337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto It = path::rbegin(CacheDir);
338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ("file.c", *It);
339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ("B", *++It);
340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ("A", *++It);
341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto ParentDir = *++It;
342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Test Unicode: "<user_cache_dir>/(pi)r^2/aleth.0"
344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_TRUE(path::user_cache_directory(CacheDir2, "\xCF\x80r\xC2\xB2",
345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                           "\xE2\x84\xB5.0"));
346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto It2 = path::rbegin(CacheDir2);
347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ("\xE2\x84\xB5.0", *It2);
348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ("\xCF\x80r\xC2\xB2", *++It2);
349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto ParentDir2 = *++It2;
350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EXPECT_EQ(ParentDir, ParentDir2);
352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarTEST(Support, TempDirectory) {
356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<32> TempDir;
357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  path::system_temp_directory(false, TempDir);
358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TRUE(!TempDir.empty());
359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  TempDir.clear();
360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  path::system_temp_directory(true, TempDir);
361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TRUE(!TempDir.empty());
362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#ifdef LLVM_ON_WIN32
365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic std::string path2regex(std::string Path) {
366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  size_t Pos = 0;
367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  while ((Pos = Path.find('\\', Pos)) != std::string::npos) {
368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Path.replace(Pos, 1, "\\\\");
369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Pos += 2;
370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Path;
372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
373f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Helper for running temp dir test in separated process. See below.
375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#define EXPECT_TEMP_DIR(prepare, expected)                                     \
376f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EXIT(                                                                 \
377f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      {                                                                        \
378f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        prepare;                                                               \
379f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SmallString<300> TempDir;                                              \
380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        path::system_temp_directory(true, TempDir);                            \
381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        raw_os_ostream(std::cerr) << TempDir;                                  \
382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        std::exit(0);                                                          \
383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      },                                                                       \
384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ::testing::ExitedWithCode(0), path2regex(expected))
385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarTEST(SupportDeathTest, TempDirectoryOnWindows) {
387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // In this test we want to check how system_temp_directory responds to
388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // different values of specific env vars. To prevent corrupting env vars of
389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // the current process all checks are done in separated processes.
390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:\\OtherFolder"), "C:\\OtherFolder");
391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:/Unix/Path/Seperators"),
392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  "C:\\Unix\\Path\\Seperators");
393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"Local Path"), ".+\\Local Path$");
394f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"F:\\TrailingSep\\"), "F:\\TrailingSep");
395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(
396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      _wputenv_s(L"TMP", L"C:\\2\x03C0r-\x00B5\x00B3\\\x2135\x2080"),
397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      "C:\\2\xCF\x80r-\xC2\xB5\xC2\xB3\\\xE2\x84\xB5\xE2\x82\x80");
398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Test $TMP empty, $TEMP set.
400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(
401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      {
402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        _wputenv_s(L"TMP", L"");
403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        _wputenv_s(L"TEMP", L"C:\\Valid\\Path");
404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      },
405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      "C:\\Valid\\Path");
406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
407f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // All related env vars empty
408f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(
409f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  {
410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    _wputenv_s(L"TMP", L"");
411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    _wputenv_s(L"TEMP", L"");
412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    _wputenv_s(L"USERPROFILE", L"");
413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  },
414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    "C:\\Temp");
415f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
416f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Test evn var / path with 260 chars.
417f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<270> Expected{"C:\\Temp\\AB\\123456789"};
418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  while (Expected.size() < 260)
419f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Expected.append("\\DirNameWith19Charss");
420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_EQ(260U, Expected.size());
421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TEMP_DIR(_putenv_s("TMP", Expected.c_str()), Expected.c_str());
422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
423f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#endif
424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
4252558516859ac52a17c85afff01073303bd522979Michael J. Spencerclass FileSystemTest : public testing::Test {
4262558516859ac52a17c85afff01073303bd522979Michael J. Spencerprotected:
4272558516859ac52a17c85afff01073303bd522979Michael J. Spencer  /// Unique temporary directory in which all created filesystem entities must
42837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// be placed. It is removed at the end of each test (must be empty).
4292558516859ac52a17c85afff01073303bd522979Michael J. Spencer  SmallString<128> TestDirectory;
4302558516859ac52a17c85afff01073303bd522979Michael J. Spencer
4310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  void SetUp() override {
4322558516859ac52a17c85afff01073303bd522979Michael J. Spencer    ASSERT_NO_ERROR(
43308ddd12e444880b4d570ac42a42414a227022190Rafael Espindola        fs::createUniqueDirectory("file-system-test", TestDirectory));
4342558516859ac52a17c85afff01073303bd522979Michael J. Spencer    // We don't care about this specific file.
435f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    errs() << "Test Directory: " << TestDirectory << '\n';
436f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    errs().flush();
4372558516859ac52a17c85afff01073303bd522979Michael J. Spencer  }
4383cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
4390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  void TearDown() override { ASSERT_NO_ERROR(fs::remove(TestDirectory.str())); }
4402558516859ac52a17c85afff01073303bd522979Michael J. Spencer};
4412558516859ac52a17c85afff01073303bd522979Michael J. Spencer
4424655485eb7dc1d137595149b9bd58eb73e11bb19Aaron BallmanTEST_F(FileSystemTest, Unique) {
4434655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  // Create a temp file.
4444655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  int FileDescriptor;
4454655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  SmallString<64> TempPath;
4464655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ASSERT_NO_ERROR(
4471276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
4484655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman
4494655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  // The same file should return an identical unique id.
4503ed45fe2be4356351942a2cfe9bd92e996d4fcadRafael Espindola  fs::UniqueID F1, F2;
4519aa3365426ef5b8b82361945bc6a8dbcd3d2bc2aRafael Espindola  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F1));
4529aa3365426ef5b8b82361945bc6a8dbcd3d2bc2aRafael Espindola  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F2));
4534655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ASSERT_EQ(F1, F2);
4544655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman
4554655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  // Different files should return different unique ids.
4564655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  int FileDescriptor2;
4574655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  SmallString<64> TempPath2;
4584655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ASSERT_NO_ERROR(
4591276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola      fs::createTemporaryFile("prefix", "temp", FileDescriptor2, TempPath2));
4601276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola
4613ed45fe2be4356351942a2cfe9bd92e996d4fcadRafael Espindola  fs::UniqueID D;
4629aa3365426ef5b8b82361945bc6a8dbcd3d2bc2aRafael Espindola  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D));
4634655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ASSERT_NE(D, F1);
4644655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ::close(FileDescriptor2);
4654655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman
4664655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
4674655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman
4684655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  // Two paths representing the same file on disk should still provide the
4694655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  // same unique id.  We can test this by making a hard link.
47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
4713ed45fe2be4356351942a2cfe9bd92e996d4fcadRafael Espindola  fs::UniqueID D2;
4729aa3365426ef5b8b82361945bc6a8dbcd3d2bc2aRafael Espindola  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D2));
4734655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ASSERT_EQ(D2, F1);
4744655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman
4754655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman  ::close(FileDescriptor);
476f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola
477f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  SmallString<128> Dir1;
478f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  ASSERT_NO_ERROR(
479f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola     fs::createUniqueDirectory("dir1", Dir1));
480f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F1));
481f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F2));
482f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  ASSERT_EQ(F1, F2);
483f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola
484f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  SmallString<128> Dir2;
485f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  ASSERT_NO_ERROR(
486f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola     fs::createUniqueDirectory("dir2", Dir2));
487f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  ASSERT_NO_ERROR(fs::getUniqueID(Dir2.c_str(), F2));
488f4ab63f3d8efa70053786d8a0e57b3bf76ae4ee5Rafael Espindola  ASSERT_NE(F1, F2);
4894655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman}
4904655485eb7dc1d137595149b9bd58eb73e11bb19Aaron Ballman
4912558516859ac52a17c85afff01073303bd522979Michael J. SpencerTEST_F(FileSystemTest, TempFiles) {
4929ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Create a temp file.
4933cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  int FileDescriptor;
4943cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  SmallString<64> TempPath;
495ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(
4961276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
4973cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
4989ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Make sure it exists.
49937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
5003cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
5019ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Create another temp tile.
5029ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  int FD2;
5039ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  SmallString<64> TempPath2;
5041276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD2, TempPath2));
505268f400c57ccbb81da34ff1ab1eb001cbb0df1f1Rafael Espindola  ASSERT_TRUE(TempPath2.endswith(".temp"));
5069ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  ASSERT_NE(TempPath.str(), TempPath2.str());
5079ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
508d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  fs::file_status A, B;
509d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
510d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
511d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  EXPECT_FALSE(fs::equivalent(A, B));
512d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer
5139ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  ::close(FD2);
5141c881d9d35a7880d0c102119b29d20ceb2ed1975Rafael Espindola
5159ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Remove Temp2.
51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_EQ(fs::remove(Twine(TempPath2), false),
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            errc::no_such_file_or_directory);
5209ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
521c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC = fs::status(TempPath2.c_str(), B);
5229ce8b2818d0c143fd58f4772d2002a15653079ddRafael Espindola  EXPECT_EQ(EC, errc::no_such_file_or_directory);
5239ce8b2818d0c143fd58f4772d2002a15653079ddRafael Espindola  EXPECT_EQ(B.type(), fs::file_type::file_not_found);
5249ce8b2818d0c143fd58f4772d2002a15653079ddRafael Espindola
5259ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Make sure Temp2 doesn't exist.
52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_EQ(fs::access(Twine(TempPath2), sys::fs::AccessMode::Exist),
52737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            errc::no_such_file_or_directory);
5289ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
529268f400c57ccbb81da34ff1ab1eb001cbb0df1f1Rafael Espindola  SmallString<64> TempPath3;
530268f400c57ccbb81da34ff1ab1eb001cbb0df1f1Rafael Espindola  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
531268f400c57ccbb81da34ff1ab1eb001cbb0df1f1Rafael Espindola  ASSERT_FALSE(TempPath3.endswith("."));
532268f400c57ccbb81da34ff1ab1eb001cbb0df1f1Rafael Espindola
5339ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Create a hard link to Temp1.
53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
5359ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  bool equal;
536ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
5379ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  EXPECT_TRUE(equal);
538d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
539d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
540d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  EXPECT_TRUE(fs::equivalent(A, B));
5419ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
5429ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Remove Temp1.
5433cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  ::close(FileDescriptor);
54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
5453cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
5469ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Remove the hard link.
54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
5489ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
5499ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Make sure Temp1 doesn't exist.
55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_EQ(fs::access(Twine(TempPath), sys::fs::AccessMode::Exist),
55137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            errc::no_such_file_or_directory);
552551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman
553551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman#ifdef LLVM_ON_WIN32
554551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman  // Path name > 260 chars should get an error.
555551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman  const char *Path270 =
556551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman    "abcdefghijklmnopqrstuvwxyz9abcdefghijklmnopqrstuvwxyz8"
557551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman    "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
558551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman    "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
559551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman    "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
560551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman    "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
56137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  EXPECT_EQ(fs::createUniqueFile(Path270, FileDescriptor, TempPath),
56237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            errc::invalid_argument);
56337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Relative path < 247 chars, no problem.
56437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *Path216 =
56537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
56637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
56737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
56837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
56937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath));
57037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
571551152f7d8c330692ed8ea9fc26fb6dd5efd118bAaron Ballman#endif
5722558516859ac52a17c85afff01073303bd522979Michael J. Spencer}
573753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer
57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST_F(FileSystemTest, CreateDir) {
57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false),
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            errc::file_exists);
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo"));
58037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#ifdef LLVM_ON_UNIX
582f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Set a 0000 umask so that we can test our directory permissions.
583f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  mode_t OldUmask = ::umask(0000);
584f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
585f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  fs::file_status Status;
586f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_NO_ERROR(
587f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      fs::create_directory(Twine(TestDirectory) + "baz500", false,
588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                           fs::perms::owner_read | fs::perms::owner_exe));
589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz500", Status));
590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_EQ(Status.permissions() & fs::perms::all_all,
591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            fs::perms::owner_read | fs::perms::owner_exe);
592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "baz777", false,
593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                       fs::perms::all_all));
594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz777", Status));
595f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ASSERT_EQ(Status.permissions() & fs::perms::all_all, fs::perms::all_all);
596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Restore umask to be safe.
598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ::umask(OldUmask);
599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#endif
600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
60137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifdef LLVM_ON_WIN32
60237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Prove that create_directories() can handle a pathname > 248 characters,
60337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // which is the documented limit for CreateDirectory().
60437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // (248 is MAX_PATH subtracting room for an 8.3 filename.)
60537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Generate a directory path guaranteed to fall into that range.
60637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  size_t TmpLen = TestDirectory.size();
60737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *OneDir = "\\123456789";
60837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  size_t OneDirLen = strlen(OneDir);
60937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_LT(OneDirLen, 12U);
61037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  size_t NLevels = ((248 - TmpLen) / OneDirLen) + 1;
61137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallString<260> LongDir(TestDirectory);
61237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (size_t I = 0; I < NLevels; ++I)
61337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    LongDir.append(OneDir);
61437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
61537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
61637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_EQ(fs::create_directories(Twine(LongDir), false),
61737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            errc::file_exists);
61837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Tidy up, "recursively" removing the directories.
61937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef ThisDir(LongDir);
62037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (size_t J = 0; J < NLevels; ++J) {
62137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ASSERT_NO_ERROR(fs::remove(ThisDir));
62237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThisDir = path::parent_path(ThisDir);
62337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
62437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
62537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Similarly for a relative pathname.  Need to set the current directory to
62637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // TestDirectory so that the one we create ends up in the right place.
62737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  char PreviousDir[260];
62837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  size_t PreviousDirLen = ::GetCurrentDirectoryA(260, PreviousDir);
62937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_GT(PreviousDirLen, 0U);
63037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_LT(PreviousDirLen, 260U);
63137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NE(::SetCurrentDirectoryA(TestDirectory.c_str()), 0);
63237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  LongDir.clear();
63337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Generate a relative directory name with absolute length > 248.
63437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  size_t LongDirLen = 249 - TestDirectory.size();
63537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  LongDir.assign(LongDirLen, 'a');
63637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::create_directory(Twine(LongDir)));
63737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // While we're here, prove that .. and . handling works in these long paths.
63837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *DotDotDirs = "\\..\\.\\b";
63937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  LongDir.append(DotDotDirs);
64037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::create_directory("b"));
64137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_EQ(fs::create_directory(Twine(LongDir), false), errc::file_exists);
64237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // And clean up.
64337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::remove("b"));
64437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NO_ERROR(fs::remove(
64537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Twine(LongDir.substr(0, LongDir.size() - strlen(DotDotDirs)))));
64637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ASSERT_NE(::SetCurrentDirectoryA(PreviousDir), 0);
64737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6502558516859ac52a17c85afff01073303bd522979Michael J. SpencerTEST_F(FileSystemTest, DirectoryIteration) {
651c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code ec;
652f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer  for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
653f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer    ASSERT_NO_ERROR(ec);
654a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer
655a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // Create a known hierarchy to recurse over.
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(
65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      fs::create_directories(Twine(TestDirectory) + "/recursive/a0/aa1"));
65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(
65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      fs::create_directories(Twine(TestDirectory) + "/recursive/a0/ab1"));
66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) +
66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                         "/recursive/dontlookhere/da1"));
66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(
66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      fs::create_directories(Twine(TestDirectory) + "/recursive/z0/za1"));
66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(
66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      fs::create_directories(Twine(TestDirectory) + "/recursive/pop/p1"));
666a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  typedef std::vector<std::string> v_t;
667a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t visited;
668a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  for (fs::recursive_directory_iterator i(Twine(TestDirectory)
669a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer         + "/recursive", ec), e; i != e; i.increment(ec)){
670a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer    ASSERT_NO_ERROR(ec);
67152ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi    if (path::filename(i->path()) == "p1") {
672a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer      i.pop();
67352ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi      // FIXME: recursive_directory_iterator should be more robust.
67452ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi      if (i == e) break;
67552ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi    }
676bd3825ecd1e7101ba8da024557e9f8d97686e70dMichael J. Spencer    if (path::filename(i->path()) == "dontlookhere")
677bd3825ecd1e7101ba8da024557e9f8d97686e70dMichael J. Spencer      i.no_push();
678a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer    visited.push_back(path::filename(i->path()));
679a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  }
680a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator a0 = std::find(visited.begin(), visited.end(), "a0");
681a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator aa1 = std::find(visited.begin(), visited.end(), "aa1");
682a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator ab1 = std::find(visited.begin(), visited.end(), "ab1");
683a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator dontlookhere = std::find(visited.begin(), visited.end(),
684a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer                                               "dontlookhere");
685a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator da1 = std::find(visited.begin(), visited.end(), "da1");
686a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator z0 = std::find(visited.begin(), visited.end(), "z0");
687a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator za1 = std::find(visited.begin(), visited.end(), "za1");
688a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator pop = std::find(visited.begin(), visited.end(), "pop");
689a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator p1 = std::find(visited.begin(), visited.end(), "p1");
690a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer
691a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // Make sure that each path was visited correctly.
692a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(a0, visited.end());
693a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(aa1, visited.end());
694a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(ab1, visited.end());
695a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(dontlookhere, visited.end());
696a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_EQ(da1, visited.end()); // Not visited.
697a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(z0, visited.end());
698a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(za1, visited.end());
699a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(pop, visited.end());
700a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_EQ(p1, visited.end()); // Not visited.
701a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer
702a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // Make sure that parents were visited before children. No other ordering
703a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // guarantees can be made across siblings.
704a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_LT(a0, aa1);
705a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_LT(a0, ab1);
706a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_LT(z0, za1);
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/aa1"));
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/ab1"));
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0"));
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere/da1"));
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere"));
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop/p1"));
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop"));
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0/za1"));
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0"));
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive"));
719de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
720de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Test recursive_directory_iterator level()
721de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(
722de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      fs::create_directories(Twine(TestDirectory) + "/reclevel/a/b/c"));
723de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  fs::recursive_directory_iterator I(Twine(TestDirectory) + "/reclevel", ec), E;
724de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  for (int l = 0; I != E; I.increment(ec), ++l) {
725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(ec);
726de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    EXPECT_EQ(I.level(), l);
727de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
728de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  EXPECT_EQ(I, E);
729de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b/c"));
730de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b"));
731de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a"));
732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel"));
733f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer}
734238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer
735c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyamaconst char archive[] = "!<arch>\x0A";
736c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyamaconst char bitcode[] = "\xde\xc0\x17\x0b";
737b850a05f2c914fef74dbafbf61470512a976c632Rui Ueyamaconst char coff_object[] = "\x00\x00......";
73837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesconst char coff_bigobj[] = "\x00\x00\xff\xff\x00\x02......"
73937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    "\xc7\xa1\xba\xd1\xee\xba\xa9\x4b\xaf\x20\xfa\xf6\x6a\xa4\xdc\xb8";
7408a631b2cbe2f8621eb3679a4898205da577453b7Rui Ueyamaconst char coff_import_library[] = "\x00\x00\xff\xff....";
741c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyamaconst char elf_relocatable[] = { 0x7f, 'E', 'L', 'F', 1, 2, 1, 0, 0,
742c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama                                 0,    0,   0,   0,   0, 0, 0, 0, 1 };
743de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_universal_binary[] = "\xca\xfe\xba\xbe...\x00";
744de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_object[] =
745de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x01............";
746de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_executable[] =
747de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x02............";
748c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyamaconst char macho_fixed_virtual_memory_shared_lib[] =
749de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x03............";
750de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_core[] =
751de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x04............";
752de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_preload_executable[] =
753de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x05............";
754c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyamaconst char macho_dynamically_linked_shared_lib[] =
755de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x06............";
756de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_dynamic_linker[] =
757de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x07............";
758de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_bundle[] =
759de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x08............";
760de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_dsym_companion[] =
761de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x0a............";
762de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarconst char macho_kext_bundle[] =
763de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x0b............";
764c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyamaconst char windows_resource[] = "\x00\x00\x00\x00\x020\x00\x00\x00\xff";
76537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesconst char macho_dynamically_linked_shared_lib_stub[] =
766de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    "\xfe\xed\xfa\xce........\x00\x00\x00\x09............";
767c0a74e28cf937f0e847b1bb907c396411e2aac36Michael J. Spencer
768238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. SpencerTEST_F(FileSystemTest, Magic) {
769238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer  struct type {
770238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    const char *filename;
771238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    const char *magic_str;
772c0a74e28cf937f0e847b1bb907c396411e2aac36Michael J. Spencer    size_t magic_str_len;
773c0a74e28cf937f0e847b1bb907c396411e2aac36Michael J. Spencer    fs::file_magic magic;
774c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama  } types[] = {
775c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama#define DEFINE(magic)                                           \
776c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    { #magic, magic, sizeof(magic), fs::file_magic::magic }
777c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(archive),
778c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(bitcode),
779b850a05f2c914fef74dbafbf61470512a976c632Rui Ueyama    DEFINE(coff_object),
78037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    { "coff_bigobj", coff_bigobj, sizeof(coff_bigobj), fs::file_magic::coff_object },
7818a631b2cbe2f8621eb3679a4898205da577453b7Rui Ueyama    DEFINE(coff_import_library),
782c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(elf_relocatable),
783c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_universal_binary),
784c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_object),
785c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_executable),
786c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_fixed_virtual_memory_shared_lib),
787c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_core),
788c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_preload_executable),
789c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_dynamically_linked_shared_lib),
790c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_dynamic_linker),
791c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_bundle),
79237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DEFINE(macho_dynamically_linked_shared_lib_stub),
793c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(macho_dsym_companion),
794ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DEFINE(macho_kext_bundle),
795c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    DEFINE(windows_resource)
796c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama#undef DEFINE
797c9024c6ebcea89746e01207195eeb52c60c3c3bbRui Ueyama    };
798238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer
799238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer  // Create some files filled with magic.
800238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer  for (type *i = types, *e = types + (sizeof(types) / sizeof(type)); i != e;
801238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer                                                                     ++i) {
802238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    SmallString<128> file_pathname(TestDirectory);
803238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    path::append(file_pathname, i->filename);
80437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::error_code EC;
80537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    raw_fd_ostream file(file_pathname, EC, sys::fs::F_None);
806238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    ASSERT_FALSE(file.has_error());
807238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    StringRef magic(i->magic_str, i->magic_str_len);
808238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    file << magic;
809248f9f280756a1d6eb20a97ee4ab457ec18170f6Michael J. Spencer    file.close();
810c0a74e28cf937f0e847b1bb907c396411e2aac36Michael J. Spencer    EXPECT_EQ(i->magic, fs::identify_magic(magic));
81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ASSERT_NO_ERROR(fs::remove(Twine(file_pathname)));
812753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  }
813f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer}
814f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
815c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola#ifdef LLVM_ON_WIN32
816c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael EspindolaTEST_F(FileSystemTest, CarriageReturn) {
817c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  SmallString<128> FilePathname(TestDirectory);
81837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::error_code EC;
819c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  path::append(FilePathname, "test");
820c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola
821c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  {
82237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    raw_fd_ostream File(FilePathname, EC, sys::fs::F_Text);
82337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ASSERT_NO_ERROR(EC);
824c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola    File << '\n';
825c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  }
826c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  {
82737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto Buf = MemoryBuffer::getFile(FilePathname.str());
828c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    EXPECT_TRUE((bool)Buf);
829c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    EXPECT_EQ(Buf.get()->getBuffer(), "\r\n");
830c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  }
831c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola
832c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  {
83337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    raw_fd_ostream File(FilePathname, EC, sys::fs::F_None);
83437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ASSERT_NO_ERROR(EC);
835c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola    File << '\n';
836c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  }
837c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  {
83837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto Buf = MemoryBuffer::getFile(FilePathname.str());
839c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    EXPECT_TRUE((bool)Buf);
840c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    EXPECT_EQ(Buf.get()->getBuffer(), "\n");
841c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola  }
84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ASSERT_NO_ERROR(fs::remove(Twine(FilePathname)));
843c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola}
844c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola#endif
845c9c9825c93791e0b1c0055e1d47ad2e6a703931eRafael Espindola
846ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesTEST_F(FileSystemTest, Resize) {
847ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  int FD;
848ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallString<64> TempPath;
849ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
850ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ASSERT_NO_ERROR(fs::resize_file(FD, 123));
851ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  fs::file_status Status;
852ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ASSERT_NO_ERROR(fs::status(FD, Status));
853ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ASSERT_EQ(Status.getSize(), 123U);
854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
856ca077ec5ea41f4537ae58e141781be622d09c786Nick KledzikTEST_F(FileSystemTest, FileMapping) {
857ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Create a temp file.
858ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  int FileDescriptor;
859ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  SmallString<64> TempPath;
860ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  ASSERT_NO_ERROR(
8611276b396130a0cdbbb8e6c05a6e43123df18ed60Rafael Espindola      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
862ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned Size = 4096;
863ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ASSERT_NO_ERROR(fs::resize_file(FileDescriptor, Size));
864ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
865ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Map in temp file and add some content
866c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC;
8671ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  StringRef Val("hello there");
8681ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  {
8691ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    fs::mapped_file_region mfr(FileDescriptor,
870ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               fs::mapped_file_region::readwrite, Size, 0, EC);
8711ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    ASSERT_NO_ERROR(EC);
8721ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    std::copy(Val.begin(), Val.end(), mfr.data());
8731ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    // Explicitly add a 0.
8741ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    mfr.data()[Val.size()] = 0;
8751ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    // Unmap temp file
8761ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  }
877e0573aab49d3835362d4f5e12cead20276ef4739Rui Ueyama
878ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Map it back in read-only
879ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  int FD;
880ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  EC = fs::openFileForRead(Twine(TempPath), FD);
881ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ASSERT_NO_ERROR(EC);
882ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC);
8831ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  ASSERT_NO_ERROR(EC);
884e0573aab49d3835362d4f5e12cead20276ef4739Rui Ueyama
885ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Verify content
8861ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  EXPECT_EQ(StringRef(mfr.const_data()), Val);
887e0573aab49d3835362d4f5e12cead20276ef4739Rui Ueyama
888ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Unmap temp file
889ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC);
8901ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  ASSERT_NO_ERROR(EC);
891ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ASSERT_EQ(close(FD), 0);
89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST(Support, NormalizePath) {
89536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#if defined(LLVM_ON_WIN32)
89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define EXPECT_PATH_IS(path__, windows__, not_windows__)                        \
89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(path__, windows__);
89836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#else
89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define EXPECT_PATH_IS(path__, windows__, not_windows__)                        \
90036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(path__, not_windows__);
9011ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer#endif
90236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallString<64> Path1("a");
90436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallString<64> Path2("a/b");
90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallString<64> Path3("a\\b");
90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallString<64> Path4("a\\\\b");
90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallString<64> Path5("\\a");
90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallString<64> Path6("a\\");
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  path::native(Path1);
91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_PATH_IS(Path1, "a", "a");
91236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  path::native(Path2);
91437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  EXPECT_PATH_IS(Path2, "a\\b", "a/b");
91536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  path::native(Path3);
91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_PATH_IS(Path3, "a\\b", "a/b");
91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  path::native(Path4);
92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_PATH_IS(Path4, "a\\\\b", "a\\\\b");
92136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
92237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  path::native(Path5);
92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_PATH_IS(Path5, "\\a", "/a");
92436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
92537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  path::native(Path6);
92636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_PATH_IS(Path6, "a\\", "a/");
92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#undef EXPECT_PATH_IS
9291ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer}
930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarTEST(Support, RemoveLeadingDotSlash) {
932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef Path1("././/foolz/wat");
933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef Path2("./////");
934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Path1 = path::remove_leading_dotslash(Path1);
936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ(Path1, "foolz/wat");
937f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Path2 = path::remove_leading_dotslash(Path2);
938f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ(Path2, "");
939f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
940f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
941f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic std::string remove_dots(StringRef path,
942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool remove_dot_dot) {
943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<256> buffer(path);
944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  path::remove_dots(buffer, remove_dot_dot);
945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return buffer.str();
946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
947f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
948f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarTEST(Support, RemoveDots) {
949f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#if defined(LLVM_ON_WIN32)
950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("foolz\\wat", remove_dots(".\\.\\\\foolz\\wat", false));
951f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("", remove_dots(".\\\\\\\\\\", false));
952f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
953f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("a\\..\\b\\c", remove_dots(".\\a\\..\\b\\c", false));
954f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("b\\c", remove_dots(".\\a\\..\\b\\c", true));
955f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("c", remove_dots(".\\.\\c", true));
956f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
957f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<64> Path1(".\\.\\c");
958f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TRUE(path::remove_dots(Path1, true));
959f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("c", Path1);
960f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#else
961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("foolz/wat", remove_dots("././/foolz/wat", false));
962f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("", remove_dots("./////", false));
963f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("a/../b/c", remove_dots("./a/../b/c", false));
965f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("b/c", remove_dots("./a/../b/c", true));
966f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("c", remove_dots("././c", true));
967f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
968f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallString<64> Path1("././c");
969f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_TRUE(path::remove_dots(Path1, true));
970f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  EXPECT_EQ("c", Path1);
971f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#endif
972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
973de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
974de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarTEST(Support, ReplacePathPrefix) {
975de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> Path1("/foo");
976de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> Path2("/old/foo");
977de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> OldPrefix("/old");
978de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> NewPrefix("/new");
979de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> NewPrefix2("/longernew");
980de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> EmptyPrefix("");
981de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
982de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> Path = Path1;
983de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  path::replace_path_prefix(Path, OldPrefix, NewPrefix);
984de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  EXPECT_EQ(Path, "/foo");
985de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Path = Path2;
986de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  path::replace_path_prefix(Path, OldPrefix, NewPrefix);
987de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  EXPECT_EQ(Path, "/new/foo");
988de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Path = Path2;
989de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  path::replace_path_prefix(Path, OldPrefix, NewPrefix2);
990de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  EXPECT_EQ(Path, "/longernew/foo");
991de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Path = Path1;
992de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  path::replace_path_prefix(Path, EmptyPrefix, NewPrefix);
993de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  EXPECT_EQ(Path, "/new/foo");
994de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Path = Path2;
995de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  path::replace_path_prefix(Path, OldPrefix, EmptyPrefix);
996de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  EXPECT_EQ(Path, "/foo");
997de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
998de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
999de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarTEST_F(FileSystemTest, PathFromFD) {
1000de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Create a temp file.
1001de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int FileDescriptor;
1002de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> TempPath;
1003de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(
1004de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
1005de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1006de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Make sure it exists.
1007de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
1008de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1009de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Try to get the path from the file descriptor
1010de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> ResultPath;
1011de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::error_code ErrorCode =
1012de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      fs::getPathFromOpenFD(FileDescriptor, ResultPath);
1013de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1014de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // If we succeeded, check that the paths are the same (modulo case):
1015de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ErrorCode) {
1016de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // The paths returned by createTemporaryFile and getPathFromOpenFD
1017de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // should reference the same file on disk.
1018de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::UniqueID D1, D2;
1019de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
1020de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
1021de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_EQ(D1, D2);
1022de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1023de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1024de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ::close(FileDescriptor);
1025de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1026de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1027de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarTEST_F(FileSystemTest, PathFromFDWin32) {
1028de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Create a temp file.
1029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int FileDescriptor;
1030de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> TempPath;
1031de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(
1032de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
1033de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1034de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Make sure it exists.
1035de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
1036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallVector<char, 8> ResultPath;
1038de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::error_code ErrorCode =
1039de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::getPathFromOpenFD(FileDescriptor, ResultPath);
1040de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1041de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ErrorCode) {
1042de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // Now that we know how much space is required for the path, create a path
1043de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // buffer with exactly enough space (sans null terminator, which should not
1044de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // be present), and call getPathFromOpenFD again to ensure that the API
1045de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // properly handles exactly-sized buffers.
1046de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SmallVector<char, 8> ExactSizedPath(ResultPath.size());
1047de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorCode = fs::getPathFromOpenFD(FileDescriptor, ExactSizedPath);
1048de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ResultPath = ExactSizedPath;
1049de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1050de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ErrorCode) {
1052de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::UniqueID D1, D2;
1053de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
1054de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
1055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_EQ(D1, D2);
1056de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1057de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ::close(FileDescriptor);
1058de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1059de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1060de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarTEST_F(FileSystemTest, PathFromFDUnicode) {
1061de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Create a temp file.
1062de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int FileDescriptor;
1063de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> TempPath;
1064de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1065de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Test Unicode: "<temp directory>/(pi)r^2<temp rand chars>.aleth.0"
1066de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(
1067de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::createTemporaryFile("\xCF\x80r\xC2\xB2",
1068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                            "\xE2\x84\xB5.0", FileDescriptor, TempPath));
1069de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1070de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Make sure it exists.
1071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
1072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1073de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallVector<char, 8> ResultPath;
1074de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::error_code ErrorCode =
1075de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::getPathFromOpenFD(FileDescriptor, ResultPath);
1076de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1077de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ErrorCode) {
1078de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::UniqueID D1, D2;
1079de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
1080de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
1081de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_EQ(D1, D2);
1082de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1083de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ::close(FileDescriptor);
1084de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1085de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1086de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarTEST_F(FileSystemTest, OpenFileForRead) {
1087de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Create a temp file.
1088de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int FileDescriptor;
1089de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> TempPath;
1090de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(
1091de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
1092de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1093de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Make sure it exists.
1094de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
1095de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1096de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Open the file for read
1097de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int FileDescriptor2;
1098de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<64> ResultPath;
1099de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ASSERT_NO_ERROR(
1100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      fs::openFileForRead(Twine(TempPath), FileDescriptor2, &ResultPath))
1101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // If we succeeded, check that the paths are the same (modulo case):
1103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ResultPath.empty()) {
1104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // The paths returned by createTemporaryFile and getPathFromOpenFD
1105de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // should reference the same file on disk.
1106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    fs::UniqueID D1, D2;
1107de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
1108de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
1109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ASSERT_EQ(D1, D2);
1110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ::close(FileDescriptor);
1113de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1114f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer} // anonymous namespace
1115