Home | History | Annotate | Download | only in Support
      1 //===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/Support/Path.h"
     11 #include "llvm/Support/Errc.h"
     12 #include "llvm/Support/ErrorHandling.h"
     13 #include "llvm/Support/FileSystem.h"
     14 #include "llvm/Support/MemoryBuffer.h"
     15 #include "llvm/Support/raw_ostream.h"
     16 #include "gtest/gtest.h"
     17 
     18 #ifdef LLVM_ON_WIN32
     19 #include <winerror.h>
     20 #endif
     21 
     22 using namespace llvm;
     23 using namespace llvm::sys;
     24 
     25 #define ASSERT_NO_ERROR(x)                                                     \
     26   if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
     27     SmallString<128> MessageStorage;                                           \
     28     raw_svector_ostream Message(MessageStorage);                               \
     29     Message << #x ": did not return errc::success.\n"                          \
     30             << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
     31             << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
     32     GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
     33   } else {                                                                     \
     34   }
     35 
     36 namespace {
     37 
     38 TEST(is_separator, Works) {
     39   EXPECT_TRUE(path::is_separator('/'));
     40   EXPECT_FALSE(path::is_separator('\0'));
     41   EXPECT_FALSE(path::is_separator('-'));
     42   EXPECT_FALSE(path::is_separator(' '));
     43 
     44 #ifdef LLVM_ON_WIN32
     45   EXPECT_TRUE(path::is_separator('\\'));
     46 #else
     47   EXPECT_FALSE(path::is_separator('\\'));
     48 #endif
     49 }
     50 
     51 TEST(Support, Path) {
     52   SmallVector<StringRef, 40> paths;
     53   paths.push_back("");
     54   paths.push_back(".");
     55   paths.push_back("..");
     56   paths.push_back("foo");
     57   paths.push_back("/");
     58   paths.push_back("/foo");
     59   paths.push_back("foo/");
     60   paths.push_back("/foo/");
     61   paths.push_back("foo/bar");
     62   paths.push_back("/foo/bar");
     63   paths.push_back("//net");
     64   paths.push_back("//net/foo");
     65   paths.push_back("///foo///");
     66   paths.push_back("///foo///bar");
     67   paths.push_back("/.");
     68   paths.push_back("./");
     69   paths.push_back("/..");
     70   paths.push_back("../");
     71   paths.push_back("foo/.");
     72   paths.push_back("foo/..");
     73   paths.push_back("foo/./");
     74   paths.push_back("foo/./bar");
     75   paths.push_back("foo/..");
     76   paths.push_back("foo/../");
     77   paths.push_back("foo/../bar");
     78   paths.push_back("c:");
     79   paths.push_back("c:/");
     80   paths.push_back("c:foo");
     81   paths.push_back("c:/foo");
     82   paths.push_back("c:foo/");
     83   paths.push_back("c:/foo/");
     84   paths.push_back("c:/foo/bar");
     85   paths.push_back("prn:");
     86   paths.push_back("c:\\");
     87   paths.push_back("c:foo");
     88   paths.push_back("c:\\foo");
     89   paths.push_back("c:foo\\");
     90   paths.push_back("c:\\foo\\");
     91   paths.push_back("c:\\foo/");
     92   paths.push_back("c:/foo\\bar");
     93 
     94   for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
     95                                                   e = paths.end();
     96                                                   i != e;
     97                                                   ++i) {
     98     for (sys::path::const_iterator ci = sys::path::begin(*i),
     99                                    ce = sys::path::end(*i);
    100                                    ci != ce;
    101                                    ++ci) {
    102       ASSERT_FALSE(ci->empty());
    103     }
    104 
    105 #if 0 // Valgrind is whining about this.
    106     outs() << "    Reverse Iteration: [";
    107     for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
    108                                      ce = sys::path::rend(*i);
    109                                      ci != ce;
    110                                      ++ci) {
    111       outs() << *ci << ',';
    112     }
    113     outs() << "]\n";
    114 #endif
    115 
    116     path::has_root_path(*i);
    117     path::root_path(*i);
    118     path::has_root_name(*i);
    119     path::root_name(*i);
    120     path::has_root_directory(*i);
    121     path::root_directory(*i);
    122     path::has_parent_path(*i);
    123     path::parent_path(*i);
    124     path::has_filename(*i);
    125     path::filename(*i);
    126     path::has_stem(*i);
    127     path::stem(*i);
    128     path::has_extension(*i);
    129     path::extension(*i);
    130     path::is_absolute(*i);
    131     path::is_relative(*i);
    132 
    133     SmallString<128> temp_store;
    134     temp_store = *i;
    135     ASSERT_NO_ERROR(fs::make_absolute(temp_store));
    136     temp_store = *i;
    137     path::remove_filename(temp_store);
    138 
    139     temp_store = *i;
    140     path::replace_extension(temp_store, "ext");
    141     StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
    142     stem = path::stem(filename);
    143     ext  = path::extension(filename);
    144     EXPECT_EQ(*(--sys::path::end(filename)), (stem + ext).str());
    145 
    146     path::native(*i, temp_store);
    147   }
    148 }
    149 
    150 TEST(Support, RelativePathIterator) {
    151   SmallString<64> Path(StringRef("c/d/e/foo.txt"));
    152   typedef SmallVector<StringRef, 4> PathComponents;
    153   PathComponents ExpectedPathComponents;
    154   PathComponents ActualPathComponents;
    155 
    156   StringRef(Path).split(ExpectedPathComponents, "/");
    157 
    158   for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
    159        ++I) {
    160     ActualPathComponents.push_back(*I);
    161   }
    162 
    163   ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
    164 
    165   for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
    166     EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
    167   }
    168 }
    169 
    170 TEST(Support, AbsolutePathIterator) {
    171   SmallString<64> Path(StringRef("/c/d/e/foo.txt"));
    172   typedef SmallVector<StringRef, 4> PathComponents;
    173   PathComponents ExpectedPathComponents;
    174   PathComponents ActualPathComponents;
    175 
    176   StringRef(Path).split(ExpectedPathComponents, "/");
    177 
    178   // The root path will also be a component when iterating
    179   ExpectedPathComponents[0] = "/";
    180 
    181   for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
    182        ++I) {
    183     ActualPathComponents.push_back(*I);
    184   }
    185 
    186   ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
    187 
    188   for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
    189     EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
    190   }
    191 }
    192 
    193 #ifdef LLVM_ON_WIN32
    194 TEST(Support, AbsolutePathIteratorWin32) {
    195   SmallString<64> Path(StringRef("c:\\c\\e\\foo.txt"));
    196   typedef SmallVector<StringRef, 4> PathComponents;
    197   PathComponents ExpectedPathComponents;
    198   PathComponents ActualPathComponents;
    199 
    200   StringRef(Path).split(ExpectedPathComponents, "\\");
    201 
    202   // The root path (which comes after the drive name) will also be a component
    203   // when iterating.
    204   ExpectedPathComponents.insert(ExpectedPathComponents.begin()+1, "\\");
    205 
    206   for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
    207        ++I) {
    208     ActualPathComponents.push_back(*I);
    209   }
    210 
    211   ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
    212 
    213   for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
    214     EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
    215   }
    216 }
    217 #endif // LLVM_ON_WIN32
    218 
    219 TEST(Support, AbsolutePathIteratorEnd) {
    220   // Trailing slashes are converted to '.' unless they are part of the root path.
    221   SmallVector<StringRef, 4> Paths;
    222   Paths.push_back("/foo/");
    223   Paths.push_back("/foo//");
    224   Paths.push_back("//net//");
    225 #ifdef LLVM_ON_WIN32
    226   Paths.push_back("c:\\\\");
    227 #endif
    228 
    229   for (StringRef Path : Paths) {
    230     StringRef LastComponent = *--path::end(Path);
    231     EXPECT_EQ(".", LastComponent);
    232   }
    233 
    234   SmallVector<StringRef, 3> RootPaths;
    235   RootPaths.push_back("/");
    236   RootPaths.push_back("//net/");
    237 #ifdef LLVM_ON_WIN32
    238   RootPaths.push_back("c:\\");
    239 #endif
    240 
    241   for (StringRef Path : RootPaths) {
    242     StringRef LastComponent = *--path::end(Path);
    243     EXPECT_EQ(1u, LastComponent.size());
    244     EXPECT_TRUE(path::is_separator(LastComponent[0]));
    245   }
    246 }
    247 
    248 TEST(Support, HomeDirectory) {
    249 #ifdef LLVM_ON_UNIX
    250   // This test only makes sense on Unix if $HOME is set.
    251   if (::getenv("HOME")) {
    252 #endif
    253     SmallString<128> HomeDir;
    254     EXPECT_TRUE(path::home_directory(HomeDir));
    255     EXPECT_FALSE(HomeDir.empty());
    256 #ifdef LLVM_ON_UNIX
    257   }
    258 #endif
    259 }
    260 
    261 class FileSystemTest : public testing::Test {
    262 protected:
    263   /// Unique temporary directory in which all created filesystem entities must
    264   /// be placed. It is recursively removed at the end of each test.
    265   SmallString<128> TestDirectory;
    266 
    267   virtual void SetUp() {
    268     ASSERT_NO_ERROR(
    269         fs::createUniqueDirectory("file-system-test", TestDirectory));
    270     // We don't care about this specific file.
    271     errs() << "Test Directory: " << TestDirectory << '\n';
    272     errs().flush();
    273   }
    274 
    275   virtual void TearDown() {
    276     ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
    277   }
    278 };
    279 
    280 TEST_F(FileSystemTest, Unique) {
    281   // Create a temp file.
    282   int FileDescriptor;
    283   SmallString<64> TempPath;
    284   ASSERT_NO_ERROR(
    285       fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
    286 
    287   // The same file should return an identical unique id.
    288   fs::UniqueID F1, F2;
    289   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F1));
    290   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F2));
    291   ASSERT_EQ(F1, F2);
    292 
    293   // Different files should return different unique ids.
    294   int FileDescriptor2;
    295   SmallString<64> TempPath2;
    296   ASSERT_NO_ERROR(
    297       fs::createTemporaryFile("prefix", "temp", FileDescriptor2, TempPath2));
    298 
    299   fs::UniqueID D;
    300   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D));
    301   ASSERT_NE(D, F1);
    302   ::close(FileDescriptor2);
    303 
    304   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
    305 
    306   // Two paths representing the same file on disk should still provide the
    307   // same unique id.  We can test this by making a hard link.
    308   ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
    309   fs::UniqueID D2;
    310   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D2));
    311   ASSERT_EQ(D2, F1);
    312 
    313   ::close(FileDescriptor);
    314 
    315   SmallString<128> Dir1;
    316   ASSERT_NO_ERROR(
    317      fs::createUniqueDirectory("dir1", Dir1));
    318   ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F1));
    319   ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F2));
    320   ASSERT_EQ(F1, F2);
    321 
    322   SmallString<128> Dir2;
    323   ASSERT_NO_ERROR(
    324      fs::createUniqueDirectory("dir2", Dir2));
    325   ASSERT_NO_ERROR(fs::getUniqueID(Dir2.c_str(), F2));
    326   ASSERT_NE(F1, F2);
    327 }
    328 
    329 TEST_F(FileSystemTest, TempFiles) {
    330   // Create a temp file.
    331   int FileDescriptor;
    332   SmallString<64> TempPath;
    333   ASSERT_NO_ERROR(
    334       fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
    335 
    336   // Make sure it exists.
    337   bool TempFileExists;
    338   ASSERT_NO_ERROR(sys::fs::exists(Twine(TempPath), TempFileExists));
    339   EXPECT_TRUE(TempFileExists);
    340 
    341   // Create another temp tile.
    342   int FD2;
    343   SmallString<64> TempPath2;
    344   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD2, TempPath2));
    345   ASSERT_TRUE(TempPath2.endswith(".temp"));
    346   ASSERT_NE(TempPath.str(), TempPath2.str());
    347 
    348   fs::file_status A, B;
    349   ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
    350   ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
    351   EXPECT_FALSE(fs::equivalent(A, B));
    352 
    353   ::close(FD2);
    354 
    355   // Remove Temp2.
    356   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
    357   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
    358   ASSERT_EQ(fs::remove(Twine(TempPath2), false),
    359             errc::no_such_file_or_directory);
    360 
    361   std::error_code EC = fs::status(TempPath2.c_str(), B);
    362   EXPECT_EQ(EC, errc::no_such_file_or_directory);
    363   EXPECT_EQ(B.type(), fs::file_type::file_not_found);
    364 
    365   // Make sure Temp2 doesn't exist.
    366   ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists));
    367   EXPECT_FALSE(TempFileExists);
    368 
    369   SmallString<64> TempPath3;
    370   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
    371   ASSERT_FALSE(TempPath3.endswith("."));
    372 
    373   // Create a hard link to Temp1.
    374   ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
    375   bool equal;
    376   ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
    377   EXPECT_TRUE(equal);
    378   ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
    379   ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
    380   EXPECT_TRUE(fs::equivalent(A, B));
    381 
    382   // Remove Temp1.
    383   ::close(FileDescriptor);
    384   ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
    385 
    386   // Remove the hard link.
    387   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
    388 
    389   // Make sure Temp1 doesn't exist.
    390   ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
    391   EXPECT_FALSE(TempFileExists);
    392 
    393 #ifdef LLVM_ON_WIN32
    394   // Path name > 260 chars should get an error.
    395   const char *Path270 =
    396     "abcdefghijklmnopqrstuvwxyz9abcdefghijklmnopqrstuvwxyz8"
    397     "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
    398     "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
    399     "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
    400     "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
    401   EXPECT_EQ(fs::createUniqueFile(Twine(Path270), FileDescriptor, TempPath),
    402             errc::no_such_file_or_directory);
    403 #endif
    404 }
    405 
    406 TEST_F(FileSystemTest, CreateDir) {
    407   ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
    408   ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
    409   ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false),
    410             errc::file_exists);
    411   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo"));
    412 }
    413 
    414 TEST_F(FileSystemTest, DirectoryIteration) {
    415   std::error_code ec;
    416   for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
    417     ASSERT_NO_ERROR(ec);
    418 
    419   // Create a known hierarchy to recurse over.
    420   ASSERT_NO_ERROR(
    421       fs::create_directories(Twine(TestDirectory) + "/recursive/a0/aa1"));
    422   ASSERT_NO_ERROR(
    423       fs::create_directories(Twine(TestDirectory) + "/recursive/a0/ab1"));
    424   ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) +
    425                                          "/recursive/dontlookhere/da1"));
    426   ASSERT_NO_ERROR(
    427       fs::create_directories(Twine(TestDirectory) + "/recursive/z0/za1"));
    428   ASSERT_NO_ERROR(
    429       fs::create_directories(Twine(TestDirectory) + "/recursive/pop/p1"));
    430   typedef std::vector<std::string> v_t;
    431   v_t visited;
    432   for (fs::recursive_directory_iterator i(Twine(TestDirectory)
    433          + "/recursive", ec), e; i != e; i.increment(ec)){
    434     ASSERT_NO_ERROR(ec);
    435     if (path::filename(i->path()) == "p1") {
    436       i.pop();
    437       // FIXME: recursive_directory_iterator should be more robust.
    438       if (i == e) break;
    439     }
    440     if (path::filename(i->path()) == "dontlookhere")
    441       i.no_push();
    442     visited.push_back(path::filename(i->path()));
    443   }
    444   v_t::const_iterator a0 = std::find(visited.begin(), visited.end(), "a0");
    445   v_t::const_iterator aa1 = std::find(visited.begin(), visited.end(), "aa1");
    446   v_t::const_iterator ab1 = std::find(visited.begin(), visited.end(), "ab1");
    447   v_t::const_iterator dontlookhere = std::find(visited.begin(), visited.end(),
    448                                                "dontlookhere");
    449   v_t::const_iterator da1 = std::find(visited.begin(), visited.end(), "da1");
    450   v_t::const_iterator z0 = std::find(visited.begin(), visited.end(), "z0");
    451   v_t::const_iterator za1 = std::find(visited.begin(), visited.end(), "za1");
    452   v_t::const_iterator pop = std::find(visited.begin(), visited.end(), "pop");
    453   v_t::const_iterator p1 = std::find(visited.begin(), visited.end(), "p1");
    454 
    455   // Make sure that each path was visited correctly.
    456   ASSERT_NE(a0, visited.end());
    457   ASSERT_NE(aa1, visited.end());
    458   ASSERT_NE(ab1, visited.end());
    459   ASSERT_NE(dontlookhere, visited.end());
    460   ASSERT_EQ(da1, visited.end()); // Not visited.
    461   ASSERT_NE(z0, visited.end());
    462   ASSERT_NE(za1, visited.end());
    463   ASSERT_NE(pop, visited.end());
    464   ASSERT_EQ(p1, visited.end()); // Not visited.
    465 
    466   // Make sure that parents were visited before children. No other ordering
    467   // guarantees can be made across siblings.
    468   ASSERT_LT(a0, aa1);
    469   ASSERT_LT(a0, ab1);
    470   ASSERT_LT(z0, za1);
    471 
    472   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/aa1"));
    473   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/ab1"));
    474   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0"));
    475   ASSERT_NO_ERROR(
    476       fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere/da1"));
    477   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere"));
    478   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop/p1"));
    479   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop"));
    480   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0/za1"));
    481   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0"));
    482   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive"));
    483 }
    484 
    485 const char archive[] = "!<arch>\x0A";
    486 const char bitcode[] = "\xde\xc0\x17\x0b";
    487 const char coff_object[] = "\x00\x00......";
    488 const char coff_import_library[] = "\x00\x00\xff\xff....";
    489 const char elf_relocatable[] = { 0x7f, 'E', 'L', 'F', 1, 2, 1, 0, 0,
    490                                  0,    0,   0,   0,   0, 0, 0, 0, 1 };
    491 const char macho_universal_binary[] = "\xca\xfe\xba\xbe...\0x00";
    492 const char macho_object[] = "\xfe\xed\xfa\xce..........\x00\x01";
    493 const char macho_executable[] = "\xfe\xed\xfa\xce..........\x00\x02";
    494 const char macho_fixed_virtual_memory_shared_lib[] =
    495     "\xfe\xed\xfa\xce..........\x00\x03";
    496 const char macho_core[] = "\xfe\xed\xfa\xce..........\x00\x04";
    497 const char macho_preload_executable[] = "\xfe\xed\xfa\xce..........\x00\x05";
    498 const char macho_dynamically_linked_shared_lib[] =
    499     "\xfe\xed\xfa\xce..........\x00\x06";
    500 const char macho_dynamic_linker[] = "\xfe\xed\xfa\xce..........\x00\x07";
    501 const char macho_bundle[] = "\xfe\xed\xfa\xce..........\x00\x08";
    502 const char macho_dsym_companion[] = "\xfe\xed\xfa\xce..........\x00\x0a";
    503 const char windows_resource[] = "\x00\x00\x00\x00\x020\x00\x00\x00\xff";
    504 
    505 TEST_F(FileSystemTest, Magic) {
    506   struct type {
    507     const char *filename;
    508     const char *magic_str;
    509     size_t magic_str_len;
    510     fs::file_magic magic;
    511   } types[] = {
    512 #define DEFINE(magic)                                           \
    513     { #magic, magic, sizeof(magic), fs::file_magic::magic }
    514     DEFINE(archive),
    515     DEFINE(bitcode),
    516     DEFINE(coff_object),
    517     DEFINE(coff_import_library),
    518     DEFINE(elf_relocatable),
    519     DEFINE(macho_universal_binary),
    520     DEFINE(macho_object),
    521     DEFINE(macho_executable),
    522     DEFINE(macho_fixed_virtual_memory_shared_lib),
    523     DEFINE(macho_core),
    524     DEFINE(macho_preload_executable),
    525     DEFINE(macho_dynamically_linked_shared_lib),
    526     DEFINE(macho_dynamic_linker),
    527     DEFINE(macho_bundle),
    528     DEFINE(macho_dsym_companion),
    529     DEFINE(windows_resource)
    530 #undef DEFINE
    531     };
    532 
    533   // Create some files filled with magic.
    534   for (type *i = types, *e = types + (sizeof(types) / sizeof(type)); i != e;
    535                                                                      ++i) {
    536     SmallString<128> file_pathname(TestDirectory);
    537     path::append(file_pathname, i->filename);
    538     std::string ErrMsg;
    539     raw_fd_ostream file(file_pathname.c_str(), ErrMsg, sys::fs::F_None);
    540     ASSERT_FALSE(file.has_error());
    541     StringRef magic(i->magic_str, i->magic_str_len);
    542     file << magic;
    543     file.close();
    544     EXPECT_EQ(i->magic, fs::identify_magic(magic));
    545     ASSERT_NO_ERROR(fs::remove(Twine(file_pathname)));
    546   }
    547 }
    548 
    549 #ifdef LLVM_ON_WIN32
    550 TEST_F(FileSystemTest, CarriageReturn) {
    551   SmallString<128> FilePathname(TestDirectory);
    552   std::string ErrMsg;
    553   path::append(FilePathname, "test");
    554 
    555   {
    556     raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_Text);
    557     EXPECT_EQ(ErrMsg, "");
    558     File << '\n';
    559   }
    560   {
    561     auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
    562     EXPECT_TRUE((bool)Buf);
    563     EXPECT_EQ(Buf.get()->getBuffer(), "\r\n");
    564   }
    565 
    566   {
    567     raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_None);
    568     EXPECT_EQ(ErrMsg, "");
    569     File << '\n';
    570   }
    571   {
    572     auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
    573     EXPECT_TRUE((bool)Buf);
    574     EXPECT_EQ(Buf.get()->getBuffer(), "\n");
    575   }
    576   ASSERT_NO_ERROR(fs::remove(Twine(FilePathname)));
    577 }
    578 #endif
    579 
    580 TEST_F(FileSystemTest, FileMapping) {
    581   // Create a temp file.
    582   int FileDescriptor;
    583   SmallString<64> TempPath;
    584   ASSERT_NO_ERROR(
    585       fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
    586   // Map in temp file and add some content
    587   std::error_code EC;
    588   StringRef Val("hello there");
    589   {
    590     fs::mapped_file_region mfr(FileDescriptor,
    591                                true,
    592                                fs::mapped_file_region::readwrite,
    593                                4096,
    594                                0,
    595                                EC);
    596     ASSERT_NO_ERROR(EC);
    597     std::copy(Val.begin(), Val.end(), mfr.data());
    598     // Explicitly add a 0.
    599     mfr.data()[Val.size()] = 0;
    600     // Unmap temp file
    601   }
    602 
    603   // Map it back in read-only
    604   fs::mapped_file_region mfr(Twine(TempPath),
    605                              fs::mapped_file_region::readonly,
    606                              0,
    607                              0,
    608                              EC);
    609   ASSERT_NO_ERROR(EC);
    610 
    611   // Verify content
    612   EXPECT_EQ(StringRef(mfr.const_data()), Val);
    613 
    614   // Unmap temp file
    615 
    616   fs::mapped_file_region m(Twine(TempPath),
    617                              fs::mapped_file_region::readonly,
    618                              0,
    619                              0,
    620                              EC);
    621   ASSERT_NO_ERROR(EC);
    622   const char *Data = m.const_data();
    623   fs::mapped_file_region mfrrv(std::move(m));
    624   EXPECT_EQ(mfrrv.const_data(), Data);
    625 }
    626 
    627 TEST(Support, NormalizePath) {
    628 #if defined(LLVM_ON_WIN32)
    629 #define EXPECT_PATH_IS(path__, windows__, not_windows__)                        \
    630   EXPECT_EQ(path__, windows__);
    631 #else
    632 #define EXPECT_PATH_IS(path__, windows__, not_windows__)                        \
    633   EXPECT_EQ(path__, not_windows__);
    634 #endif
    635 
    636   SmallString<64> Path1("a");
    637   SmallString<64> Path2("a/b");
    638   SmallString<64> Path3("a\\b");
    639   SmallString<64> Path4("a\\\\b");
    640   SmallString<64> Path5("\\a");
    641   SmallString<64> Path6("a\\");
    642 
    643   ASSERT_NO_ERROR(fs::normalize_separators(Path1));
    644   EXPECT_PATH_IS(Path1, "a", "a");
    645 
    646   ASSERT_NO_ERROR(fs::normalize_separators(Path2));
    647   EXPECT_PATH_IS(Path2, "a/b", "a/b");
    648 
    649   ASSERT_NO_ERROR(fs::normalize_separators(Path3));
    650   EXPECT_PATH_IS(Path3, "a\\b", "a/b");
    651 
    652   ASSERT_NO_ERROR(fs::normalize_separators(Path4));
    653   EXPECT_PATH_IS(Path4, "a\\\\b", "a\\\\b");
    654 
    655   ASSERT_NO_ERROR(fs::normalize_separators(Path5));
    656   EXPECT_PATH_IS(Path5, "\\a", "/a");
    657 
    658   ASSERT_NO_ERROR(fs::normalize_separators(Path6));
    659   EXPECT_PATH_IS(Path6, "a\\", "a/");
    660 
    661 #undef EXPECT_PATH_IS
    662 }
    663 } // anonymous namespace
    664