summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-03-11 22:05:42 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-03-11 22:05:42 +0000
commit404a72729be98fbc41051197e0c9bb1b48c28e94 (patch)
tree78d769a62b64a535f5e1d57f9ece284fdb05a1fe
parentff73a2bf86d03dd540afccbe0ba669f1f03ea8a2 (diff)
downloadllvm-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.h8
-rw-r--r--lib/Support/Unix/Path.inc13
-rw-r--r--lib/Support/Windows/Path.inc5
-rw-r--r--unittests/Support/Path.cpp37
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