[llvm] r203611 - support: add a utility function to normalise path separators

Saleem Abdulrasool compnerd at compnerd.org
Tue Mar 11 15:05:42 PDT 2014


Author: compnerd
Date: Tue Mar 11 17:05:42 2014
New Revision: 203611

URL: http://llvm.org/viewvc/llvm-project?rev=203611&view=rev
Log:
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.

Modified:
    llvm/trunk/include/llvm/Support/FileSystem.h
    llvm/trunk/lib/Support/Unix/Path.inc
    llvm/trunk/lib/Support/Windows/Path.inc
    llvm/trunk/unittests/Support/Path.cpp

Modified: llvm/trunk/include/llvm/Support/FileSystem.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileSystem.h?rev=203611&r1=203610&r2=203611&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/FileSystem.h (original)
+++ llvm/trunk/include/llvm/Support/FileSystem.h Tue Mar 11 17:05:42 2014
@@ -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.

Modified: llvm/trunk/lib/Support/Unix/Path.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Path.inc?rev=203611&r1=203610&r2=203611&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Unix/Path.inc (original)
+++ llvm/trunk/lib/Support/Unix/Path.inc Tue Mar 11 17:05:42 2014
@@ -272,6 +272,19 @@ error_code create_directory(const Twine
   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) {

Modified: llvm/trunk/lib/Support/Windows/Path.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Path.inc?rev=203611&r1=203610&r2=203611&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Windows/Path.inc (original)
+++ llvm/trunk/lib/Support/Windows/Path.inc Tue Mar 11 17:05:42 2014
@@ -158,6 +158,11 @@ error_code create_directory(const Twine
   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.

Modified: llvm/trunk/unittests/Support/Path.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Path.cpp?rev=203611&r1=203610&r2=203611&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/Path.cpp (original)
+++ llvm/trunk/unittests/Support/Path.cpp Tue Mar 11 17:05:42 2014
@@ -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





More information about the llvm-commits mailing list