From: Jonas Devlieghere Date: Thu, 1 Nov 2018 00:26:09 +0000 (+0000) Subject: [FileSystem] Re-add EnumerateDirectory X-Git-Tag: llvmorg-8.0.0-rc1~5287 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9ca491da2f336150d700dd1e00f27bcee23bdd09;p=platform%2Fupstream%2Fllvm.git [FileSystem] Re-add EnumerateDirectory Re-enable EnumerateDirectory now that no_push is available in llvm (r345793). llvm-svn: 345799 --- diff --git a/lldb/include/lldb/Host/FileSystem.h b/lldb/include/lldb/Host/FileSystem.h index 37ad7fb..115d6d4 100644 --- a/lldb/include/lldb/Host/FileSystem.h +++ b/lldb/include/lldb/Host/FileSystem.h @@ -92,6 +92,28 @@ public: void Resolve(FileSpec &file_spec); /// @} + enum EnumerateDirectoryResult { + /// Enumerate next entry in the current directory. + eEnumerateDirectoryResultNext, + /// Recurse into the current entry if it is a directory or symlink, or next + /// if not. + eEnumerateDirectoryResultEnter, + /// Stop directory enumerations at any level. + eEnumerateDirectoryResultQuit + }; + + typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)( + void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef); + + typedef std::function + DirectoryCallback; + + void EnumerateDirectory(llvm::Twine path, bool find_directories, + bool find_files, bool find_other, + EnumerateDirectoryCallbackType callback, + void *callback_baton); + std::error_code GetRealPath(const llvm::Twine &path, llvm::SmallVectorImpl &output) const; diff --git a/lldb/source/Host/common/FileSystem.cpp b/lldb/source/Host/common/FileSystem.cpp index c985ebb..aa181ec 100644 --- a/lldb/source/Host/common/FileSystem.cpp +++ b/lldb/source/Host/common/FileSystem.cpp @@ -96,6 +96,36 @@ bool FileSystem::Readable(const FileSpec &file_spec) const { return Readable(file_spec.GetPath()); } +void FileSystem::EnumerateDirectory(Twine path, bool find_directories, + bool find_files, bool find_other, + EnumerateDirectoryCallbackType callback, + void *callback_baton) { + std::error_code EC; + vfs::recursive_directory_iterator Iter(*m_fs, path, EC); + vfs::recursive_directory_iterator End; + for (; Iter != End && !EC; Iter.increment(EC)) { + const auto &Item = *Iter; + ErrorOr Status = m_fs->status(Item.path()); + if (!Status) + break; + if (!find_files && Status->isRegularFile()) + continue; + if (!find_directories && Status->isDirectory()) + continue; + if (!find_other && Status->isOther()) + continue; + + auto Result = callback(callback_baton, Status->getType(), Item.path()); + if (Result == eEnumerateDirectoryResultQuit) + return; + if (Result == eEnumerateDirectoryResultNext) { + // Default behavior is to recurse. Opt out if the callback doesn't want + // this behavior. + Iter.no_push(); + } + } +} + std::error_code FileSystem::MakeAbsolute(SmallVectorImpl &path) const { return m_fs->makeAbsolute(path); } diff --git a/lldb/unittests/Host/FileSystemTest.cpp b/lldb/unittests/Host/FileSystemTest.cpp index 2a3c626..142ad7b 100644 --- a/lldb/unittests/Host/FileSystemTest.cpp +++ b/lldb/unittests/Host/FileSystemTest.cpp @@ -265,3 +265,27 @@ TEST(FileSystemTest, Resolve) { EXPECT_EQ("bogus", file_spec.GetPath()); } } + +FileSystem::EnumerateDirectoryResult +VFSCallback(void *baton, llvm::sys::fs::file_type file_type, + llvm::StringRef path) { + auto visited = static_cast *>(baton); + visited->push_back(path.str()); + return FileSystem::eEnumerateDirectoryResultNext; +} + +TEST(FileSystemTest, EnumerateDirectory) { + FileSystem fs(GetSimpleDummyFS()); + + std::vector visited; + + constexpr bool find_directories = true; + constexpr bool find_files = true; + constexpr bool find_other = true; + + fs.EnumerateDirectory("/", find_directories, find_files, find_other, + VFSCallback, &visited); + + EXPECT_THAT(visited, + testing::UnorderedElementsAre("/foo", "/bar", "/baz", "/qux")); +}