aboutsummaryrefslogtreecommitdiffstats
path: root/unittests/Support/Path.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Support/Path.cpp')
-rw-r--r--unittests/Support/Path.cpp129
1 files changed, 95 insertions, 34 deletions
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index cf2e1ee..502cda2 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -16,6 +16,7 @@
#include "gtest/gtest.h"
#ifdef LLVM_ON_WIN32
+#include <Windows.h>
#include <winerror.h>
#endif
@@ -91,6 +92,7 @@ TEST(Support, Path) {
paths.push_back("c:\\foo/");
paths.push_back("c:/foo\\bar");
+ SmallVector<StringRef, 5> ComponentStack;
for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
e = paths.end();
i != e;
@@ -100,18 +102,17 @@ TEST(Support, Path) {
ci != ce;
++ci) {
ASSERT_FALSE(ci->empty());
+ ComponentStack.push_back(*ci);
}
-#if 0 // Valgrind is whining about this.
- outs() << " Reverse Iteration: [";
for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
ce = sys::path::rend(*i);
ci != ce;
++ci) {
- outs() << *ci << ',';
+ ASSERT_TRUE(*ci == ComponentStack.back());
+ ComponentStack.pop_back();
}
- outs() << "]\n";
-#endif
+ ASSERT_TRUE(ComponentStack.empty());
path::has_root_path(*i);
path::root_path(*i);
@@ -141,7 +142,7 @@ TEST(Support, Path) {
StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
stem = path::stem(filename);
ext = path::extension(filename);
- EXPECT_EQ(*(--sys::path::end(filename)), (stem + ext).str());
+ EXPECT_EQ(*sys::path::rbegin(filename), (stem + ext).str());
path::native(*i, temp_store);
}
@@ -227,7 +228,7 @@ TEST(Support, AbsolutePathIteratorEnd) {
#endif
for (StringRef Path : Paths) {
- StringRef LastComponent = *--path::end(Path);
+ StringRef LastComponent = *path::rbegin(Path);
EXPECT_EQ(".", LastComponent);
}
@@ -239,7 +240,7 @@ TEST(Support, AbsolutePathIteratorEnd) {
#endif
for (StringRef Path : RootPaths) {
- StringRef LastComponent = *--path::end(Path);
+ StringRef LastComponent = *path::rbegin(Path);
EXPECT_EQ(1u, LastComponent.size());
EXPECT_TRUE(path::is_separator(LastComponent[0]));
}
@@ -261,7 +262,7 @@ TEST(Support, HomeDirectory) {
class FileSystemTest : public testing::Test {
protected:
/// Unique temporary directory in which all created filesystem entities must
- /// be placed. It is recursively removed at the end of each test.
+ /// be placed. It is removed at the end of each test (must be empty).
SmallString<128> TestDirectory;
virtual void SetUp() {
@@ -334,9 +335,7 @@ TEST_F(FileSystemTest, TempFiles) {
fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
// Make sure it exists.
- bool TempFileExists;
- ASSERT_NO_ERROR(sys::fs::exists(Twine(TempPath), TempFileExists));
- EXPECT_TRUE(TempFileExists);
+ ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
// Create another temp tile.
int FD2;
@@ -363,8 +362,8 @@ TEST_F(FileSystemTest, TempFiles) {
EXPECT_EQ(B.type(), fs::file_type::file_not_found);
// Make sure Temp2 doesn't exist.
- ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists));
- EXPECT_FALSE(TempFileExists);
+ ASSERT_EQ(fs::access(Twine(TempPath2), sys::fs::AccessMode::Exist),
+ errc::no_such_file_or_directory);
SmallString<64> TempPath3;
ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
@@ -387,8 +386,8 @@ TEST_F(FileSystemTest, TempFiles) {
ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
// Make sure Temp1 doesn't exist.
- ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
- EXPECT_FALSE(TempFileExists);
+ ASSERT_EQ(fs::access(Twine(TempPath), sys::fs::AccessMode::Exist),
+ errc::no_such_file_or_directory);
#ifdef LLVM_ON_WIN32
// Path name > 260 chars should get an error.
@@ -398,8 +397,16 @@ TEST_F(FileSystemTest, TempFiles) {
"abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
"abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
"abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
- EXPECT_EQ(fs::createUniqueFile(Twine(Path270), FileDescriptor, TempPath),
- errc::no_such_file_or_directory);
+ EXPECT_EQ(fs::createUniqueFile(Path270, FileDescriptor, TempPath),
+ errc::invalid_argument);
+ // Relative path < 247 chars, no problem.
+ const char *Path216 =
+ "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
+ "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
+ "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
+ "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
+ ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath));
+ ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
#endif
}
@@ -409,6 +416,54 @@ TEST_F(FileSystemTest, CreateDir) {
ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false),
errc::file_exists);
ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo"));
+
+#ifdef LLVM_ON_WIN32
+ // Prove that create_directories() can handle a pathname > 248 characters,
+ // which is the documented limit for CreateDirectory().
+ // (248 is MAX_PATH subtracting room for an 8.3 filename.)
+ // Generate a directory path guaranteed to fall into that range.
+ size_t TmpLen = TestDirectory.size();
+ const char *OneDir = "\\123456789";
+ size_t OneDirLen = strlen(OneDir);
+ ASSERT_LT(OneDirLen, 12U);
+ size_t NLevels = ((248 - TmpLen) / OneDirLen) + 1;
+ SmallString<260> LongDir(TestDirectory);
+ for (size_t I = 0; I < NLevels; ++I)
+ LongDir.append(OneDir);
+ ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
+ ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
+ ASSERT_EQ(fs::create_directories(Twine(LongDir), false),
+ errc::file_exists);
+ // Tidy up, "recursively" removing the directories.
+ StringRef ThisDir(LongDir);
+ for (size_t J = 0; J < NLevels; ++J) {
+ ASSERT_NO_ERROR(fs::remove(ThisDir));
+ ThisDir = path::parent_path(ThisDir);
+ }
+
+ // Similarly for a relative pathname. Need to set the current directory to
+ // TestDirectory so that the one we create ends up in the right place.
+ char PreviousDir[260];
+ size_t PreviousDirLen = ::GetCurrentDirectoryA(260, PreviousDir);
+ ASSERT_GT(PreviousDirLen, 0U);
+ ASSERT_LT(PreviousDirLen, 260U);
+ ASSERT_NE(::SetCurrentDirectoryA(TestDirectory.c_str()), 0);
+ LongDir.clear();
+ // Generate a relative directory name with absolute length > 248.
+ size_t LongDirLen = 249 - TestDirectory.size();
+ LongDir.assign(LongDirLen, 'a');
+ ASSERT_NO_ERROR(fs::create_directory(Twine(LongDir)));
+ // While we're here, prove that .. and . handling works in these long paths.
+ const char *DotDotDirs = "\\..\\.\\b";
+ LongDir.append(DotDotDirs);
+ ASSERT_NO_ERROR(fs::create_directory("b"));
+ ASSERT_EQ(fs::create_directory(Twine(LongDir), false), errc::file_exists);
+ // And clean up.
+ ASSERT_NO_ERROR(fs::remove("b"));
+ ASSERT_NO_ERROR(fs::remove(
+ Twine(LongDir.substr(0, LongDir.size() - strlen(DotDotDirs)))));
+ ASSERT_NE(::SetCurrentDirectoryA(PreviousDir), 0);
+#endif
}
TEST_F(FileSystemTest, DirectoryIteration) {
@@ -485,6 +540,8 @@ TEST_F(FileSystemTest, DirectoryIteration) {
const char archive[] = "!<arch>\x0A";
const char bitcode[] = "\xde\xc0\x17\x0b";
const char coff_object[] = "\x00\x00......";
+const char coff_bigobj[] = "\x00\x00\xff\xff\x00\x02......"
+ "\xc7\xa1\xba\xd1\xee\xba\xa9\x4b\xaf\x20\xfa\xf6\x6a\xa4\xdc\xb8";
const char coff_import_library[] = "\x00\x00\xff\xff....";
const char elf_relocatable[] = { 0x7f, 'E', 'L', 'F', 1, 2, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1 };
@@ -501,6 +558,8 @@ const char macho_dynamic_linker[] = "\xfe\xed\xfa\xce..........\x00\x07";
const char macho_bundle[] = "\xfe\xed\xfa\xce..........\x00\x08";
const char macho_dsym_companion[] = "\xfe\xed\xfa\xce..........\x00\x0a";
const char windows_resource[] = "\x00\x00\x00\x00\x020\x00\x00\x00\xff";
+const char macho_dynamically_linked_shared_lib_stub[] =
+ "\xfe\xed\xfa\xce..........\x00\x09";
TEST_F(FileSystemTest, Magic) {
struct type {
@@ -514,6 +573,7 @@ TEST_F(FileSystemTest, Magic) {
DEFINE(archive),
DEFINE(bitcode),
DEFINE(coff_object),
+ { "coff_bigobj", coff_bigobj, sizeof(coff_bigobj), fs::file_magic::coff_object },
DEFINE(coff_import_library),
DEFINE(elf_relocatable),
DEFINE(macho_universal_binary),
@@ -525,6 +585,7 @@ TEST_F(FileSystemTest, Magic) {
DEFINE(macho_dynamically_linked_shared_lib),
DEFINE(macho_dynamic_linker),
DEFINE(macho_bundle),
+ DEFINE(macho_dynamically_linked_shared_lib_stub),
DEFINE(macho_dsym_companion),
DEFINE(windows_resource)
#undef DEFINE
@@ -535,8 +596,8 @@ TEST_F(FileSystemTest, Magic) {
++i) {
SmallString<128> file_pathname(TestDirectory);
path::append(file_pathname, i->filename);
- std::string ErrMsg;
- raw_fd_ostream file(file_pathname.c_str(), ErrMsg, sys::fs::F_None);
+ std::error_code EC;
+ raw_fd_ostream file(file_pathname, EC, sys::fs::F_None);
ASSERT_FALSE(file.has_error());
StringRef magic(i->magic_str, i->magic_str_len);
file << magic;
@@ -549,27 +610,27 @@ TEST_F(FileSystemTest, Magic) {
#ifdef LLVM_ON_WIN32
TEST_F(FileSystemTest, CarriageReturn) {
SmallString<128> FilePathname(TestDirectory);
- std::string ErrMsg;
+ std::error_code EC;
path::append(FilePathname, "test");
{
- raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_Text);
- EXPECT_EQ(ErrMsg, "");
+ raw_fd_ostream File(FilePathname, EC, sys::fs::F_Text);
+ ASSERT_NO_ERROR(EC);
File << '\n';
}
{
- auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
+ auto Buf = MemoryBuffer::getFile(FilePathname.str());
EXPECT_TRUE((bool)Buf);
EXPECT_EQ(Buf.get()->getBuffer(), "\r\n");
}
{
- raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_None);
- EXPECT_EQ(ErrMsg, "");
+ raw_fd_ostream File(FilePathname, EC, sys::fs::F_None);
+ ASSERT_NO_ERROR(EC);
File << '\n';
}
{
- auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
+ auto Buf = MemoryBuffer::getFile(FilePathname.str());
EXPECT_TRUE((bool)Buf);
EXPECT_EQ(Buf.get()->getBuffer(), "\n");
}
@@ -640,22 +701,22 @@ TEST(Support, NormalizePath) {
SmallString<64> Path5("\\a");
SmallString<64> Path6("a\\");
- ASSERT_NO_ERROR(fs::normalize_separators(Path1));
+ path::native(Path1);
EXPECT_PATH_IS(Path1, "a", "a");
- ASSERT_NO_ERROR(fs::normalize_separators(Path2));
- EXPECT_PATH_IS(Path2, "a/b", "a/b");
+ path::native(Path2);
+ EXPECT_PATH_IS(Path2, "a\\b", "a/b");
- ASSERT_NO_ERROR(fs::normalize_separators(Path3));
+ path::native(Path3);
EXPECT_PATH_IS(Path3, "a\\b", "a/b");
- ASSERT_NO_ERROR(fs::normalize_separators(Path4));
+ path::native(Path4);
EXPECT_PATH_IS(Path4, "a\\\\b", "a\\\\b");
- ASSERT_NO_ERROR(fs::normalize_separators(Path5));
+ path::native(Path5);
EXPECT_PATH_IS(Path5, "\\a", "/a");
- ASSERT_NO_ERROR(fs::normalize_separators(Path6));
+ path::native(Path6);
EXPECT_PATH_IS(Path6, "a\\", "a/");
#undef EXPECT_PATH_IS