diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-03-11 22:05:42 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-03-11 22:05:42 +0000 |
commit | 404a72729be98fbc41051197e0c9bb1b48c28e94 (patch) | |
tree | 78d769a62b64a535f5e1d57f9ece284fdb05a1fe | |
parent | ff73a2bf86d03dd540afccbe0ba669f1f03ea8a2 (diff) | |
download | llvm-404a72729be98fbc41051197e0c9bb1b48c28e94.tar.gz llvm-404a72729be98fbc41051197e0c9bb1b48c28e94.tar.bz2 llvm-404a72729be98fbc41051197e0c9bb1b48c28e94.tar.xz |
support: add a utility function to normalise path separators
Add a utility function to convert the Windows path separator to Unix style path
separators. This is used by a subsequent change in clang to enable the use of
Windows SDK headers on Linux.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203611 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Support/FileSystem.h | 8 | ||||
-rw-r--r-- | lib/Support/Unix/Path.inc | 13 | ||||
-rw-r--r-- | lib/Support/Windows/Path.inc | 5 | ||||
-rw-r--r-- | unittests/Support/Path.cpp | 37 |
4 files changed, 63 insertions, 0 deletions
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 906f37f7c1..c5c8415753 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -269,6 +269,14 @@ private: /// platform specific error_code. error_code make_absolute(SmallVectorImpl<char> &path); +/// @brief Normalize path separators in \a Path +/// +/// If the path contains any '\' separators, they are transformed into '/'. +/// This is particularly useful when cross-compiling Windows on Linux, but is +/// safe to invoke on Windows, which accepts both characters as a path +/// separator. +error_code normalize_separators(SmallVectorImpl<char> &Path); + /// @brief Create all the non-existent directories in path. /// /// @param path Directories to create. diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index 2b29baca73..500b7fecb7 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -272,6 +272,19 @@ error_code create_directory(const Twine &path, bool IgnoreExisting) { return error_code::success(); } +error_code normalize_separators(SmallVectorImpl<char> &Path) { + for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) { + if (*PI == '\\') { + auto PN = PI + 1; + if (PN < PE && *PN == '\\') + ++PI; // increment once, the for loop will move over the escaped slash + else + *PI = '/'; + } + } + return error_code::success(); +} + // Note that we are using symbolic link because hard links are not supported by // all filesystems (SMB doesn't). error_code create_link(const Twine &to, const Twine &from) { diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index a555f3e794..e59888e385 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -158,6 +158,11 @@ error_code create_directory(const Twine &path, bool IgnoreExisting) { return error_code::success(); } +error_code normalize_separators(SmallVectorImpl<char> &Path) { + (void) Path; + return error_code::success(); +} + // We can't use symbolic links for windows. error_code create_link(const Twine &to, const Twine &from) { // Get arguments. diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index 91e421d382..b79d05505c 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -620,4 +620,41 @@ TEST_F(FileSystemTest, FileMapping) { fs::mapped_file_region mfrrv(std::move(m)); EXPECT_EQ(mfrrv.const_data(), Data); } + +TEST(Support, NormalizePath) { +#if defined(LLVM_ON_WIN32) +#define EXPECT_PATH_IS(path__, windows__, not_windows__) \ + EXPECT_EQ(path__, windows__); +#else +#define EXPECT_PATH_IS(path__, windows__, not_windows__) \ + EXPECT_EQ(path__, not_windows__); +#endif + + SmallString<64> Path1("a"); + SmallString<64> Path2("a/b"); + SmallString<64> Path3("a\\b"); + SmallString<64> Path4("a\\\\b"); + SmallString<64> Path5("\\a"); + SmallString<64> Path6("a\\"); + + ASSERT_NO_ERROR(fs::normalize_separators(Path1)); + EXPECT_PATH_IS(Path1, "a", "a"); + + ASSERT_NO_ERROR(fs::normalize_separators(Path2)); + EXPECT_PATH_IS(Path2, "a/b", "a/b"); + + ASSERT_NO_ERROR(fs::normalize_separators(Path3)); + EXPECT_PATH_IS(Path3, "a\\b", "a/b"); + + ASSERT_NO_ERROR(fs::normalize_separators(Path4)); + EXPECT_PATH_IS(Path4, "a\\\\b", "a\\\\b"); + + ASSERT_NO_ERROR(fs::normalize_separators(Path5)); + EXPECT_PATH_IS(Path5, "\\a", "/a"); + + ASSERT_NO_ERROR(fs::normalize_separators(Path6)); + EXPECT_PATH_IS(Path6, "a\\", "a/"); + +#undef EXPECT_PATH_IS +} } // anonymous namespace |