[VFS] Implement getRealPath in InMemoryFileSystem.

Reviewers: bkramer

Subscribers: cfe-commits

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

llvm-svn: 333172
This commit is contained in:
Eric Liu 2018-05-24 11:17:00 +00:00
parent 34391f097d
commit 33dd619c80
3 changed files with 43 additions and 0 deletions

View File

@ -374,6 +374,14 @@ public:
llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
return WorkingDirectory;
}
/// Canonicalizes \p Path by combining with the current working
/// directory and normalizing the path (e.g. remove dots). If the current
/// working directory is not set, this returns errc::operation_not_permitted.
///
/// This doesn't resolve symlinks as they are not supported in in-memory file
/// system.
std::error_code getRealPath(const Twine &Path,
SmallVectorImpl<char> &Output) const override;
std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
};

View File

@ -788,6 +788,19 @@ std::error_code InMemoryFileSystem::setCurrentWorkingDirectory(const Twine &P) {
return {};
}
std::error_code
InMemoryFileSystem::getRealPath(const Twine &Path,
SmallVectorImpl<char> &Output) const {
auto CWD = getCurrentWorkingDirectory();
if (!CWD || CWD->empty())
return errc::operation_not_permitted;
Path.toVector(Output);
if (auto EC = makeAbsolute(Output))
return EC;
llvm::sys::path::remove_dots(Output, /*remove_dot_dot=*/true);
return {};
}
} // namespace vfs
} // namespace clang

View File

@ -813,6 +813,28 @@ TEST_F(InMemoryFileSystemTest, WorkingDirectory) {
NormalizedFS.getCurrentWorkingDirectory().get()));
}
TEST_F(InMemoryFileSystemTest, GetRealPath) {
SmallString<16> Path;
EXPECT_EQ(FS.getRealPath("b", Path), errc::operation_not_permitted);
auto GetRealPath = [this](StringRef P) {
SmallString<16> Output;
auto EC = FS.getRealPath(P, Output);
EXPECT_FALSE(EC);
return Output.str().str();
};
FS.setCurrentWorkingDirectory("a");
EXPECT_EQ(GetRealPath("b"), "a/b");
EXPECT_EQ(GetRealPath("../b"), "b");
EXPECT_EQ(GetRealPath("b/./c"), "a/b/c");
FS.setCurrentWorkingDirectory("/a");
EXPECT_EQ(GetRealPath("b"), "/a/b");
EXPECT_EQ(GetRealPath("../b"), "/b");
EXPECT_EQ(GetRealPath("b/./c"), "/a/b/c");
}
TEST_F(InMemoryFileSystemTest, AddFileWithUser) {
FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), 0xFEEDFACE);
auto Stat = FS.status("/a");