]> granicus.if.org Git - llvm/commitdiff
Process tilde in llvm::sys::path::native
authorSerge Pavlov <sepavloff@gmail.com>
Wed, 1 Mar 2017 09:38:15 +0000 (09:38 +0000)
committerSerge Pavlov <sepavloff@gmail.com>
Wed, 1 Mar 2017 09:38:15 +0000 (09:38 +0000)
Windows does not treat `~` as a reference to home directory, so the call
to `llvm::sys::path::native` on, say, `~/somedir` produces `~\somedir`,
which has different meaning than the original path. With this change
tilde is expanded on Windows to user profile directory. Such behavior
keeps original meaning of the path and is consistent with the algorithm
of `llvm::sys::path::home_directory`.

Differential Revision: https://reviews.llvm.org/D27527

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296590 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/Path.cpp
unittests/Support/Path.cpp

index 4bb035eeccca817b9e3b78a2a128adf52ca38578..0709ec272f598fc25c0cf0bfb44ba38a58d2330e 100644 (file)
@@ -556,8 +556,16 @@ void native(const Twine &path, SmallVectorImpl<char> &result) {
 }
 
 void native(SmallVectorImpl<char> &Path) {
+  if (Path.empty())
+    return;
 #ifdef LLVM_ON_WIN32
   std::replace(Path.begin(), Path.end(), '/', '\\');
+  if (Path[0] == '~' && (Path.size() == 1 || is_separator(Path[1]))) {
+    SmallString<128> PathHome;
+    home_directory(PathHome);
+    PathHome.append(Path.begin() + 1, Path.end());
+    Path = PathHome;
+  }
 #else
   for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
     if (*PI == '\\') {
index 24f16fd16969d81748b4e212c019a6869d7b544b..a93f929af78a96a98a721402e334748abb2ba98d 100644 (file)
@@ -968,6 +968,33 @@ TEST(Support, NormalizePath) {
   EXPECT_PATH_IS(Path6, "a\\", "a/");
 
 #undef EXPECT_PATH_IS
+
+#if defined(LLVM_ON_WIN32)
+  SmallString<64> PathHome;
+  path::home_directory(PathHome);
+
+  const char *Path7a = "~/aaa";
+  SmallString<64> Path7(Path7a);
+  path::native(Path7);
+  EXPECT_TRUE(Path7.endswith("\\aaa"));
+  EXPECT_TRUE(Path7.startswith(PathHome));
+  EXPECT_EQ(Path7.size(), PathHome.size() + strlen(Path7a + 1));
+
+  const char *Path8a = "~";
+  SmallString<64> Path8(Path8a);
+  path::native(Path8);
+  EXPECT_EQ(Path8, PathHome);
+
+  const char *Path9a = "~aaa";
+  SmallString<64> Path9(Path9a);
+  path::native(Path9);
+  EXPECT_EQ(Path9, "~aaa");
+
+  const char *Path10a = "aaa/~/b";
+  SmallString<64> Path10(Path10a);
+  path::native(Path10);
+  EXPECT_EQ(Path10, "aaa\\~\\b");
+#endif
 }
 
 TEST(Support, RemoveLeadingDotSlash) {