[Lldb-commits] [lldb] r297598 - Use LLVM for file / directory enumeration.
Zachary Turner via lldb-commits
lldb-commits at lists.llvm.org
Sun Mar 12 19:44:39 PDT 2017
Author: zturner
Date: Sun Mar 12 21:44:39 2017
New Revision: 297598
URL: http://llvm.org/viewvc/llvm-project?rev=297598&view=rev
Log:
Use LLVM for file / directory enumeration.
FileSpec::EnumerateDirectory has a bunch of platform-specific
gunk in it for posix and non-posix platforms. We can get rid
of all this by using LLVM's easy-to-use directory iterators.
Differential Revision: https://reviews.llvm.org/D30807
Modified:
lldb/trunk/include/lldb/Host/FileSpec.h
lldb/trunk/include/lldb/Interpreter/CommandCompletions.h
lldb/trunk/source/Commands/CommandCompletions.cpp
lldb/trunk/source/Host/common/FileSpec.cpp
lldb/trunk/source/Utility/TildeExpressionResolver.cpp
Modified: lldb/trunk/include/lldb/Host/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=297598&r1=297597&r2=297598&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Host/FileSpec.h Sun Mar 12 21:44:39 2017
@@ -564,28 +564,22 @@ public:
// directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a
// directory or symlink, or next if not
- eEnumerateDirectoryResultExit, // Exit from the current directory at the
- // current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)(
void *baton, llvm::sys::fs::file_type file_type, const FileSpec &spec);
- static EnumerateDirectoryResult
- EnumerateDirectory(llvm::StringRef dir_path, bool find_directories,
- bool find_files, bool find_other,
- EnumerateDirectoryCallbackType callback,
- void *callback_baton);
+ static void EnumerateDirectory(llvm::StringRef dir_path,
+ bool find_directories, bool find_files,
+ bool find_other,
+ EnumerateDirectoryCallbackType callback,
+ void *callback_baton);
typedef std::function<EnumerateDirectoryResult(
llvm::sys::fs::file_type file_type, const FileSpec &spec)>
DirectoryCallback;
- static EnumerateDirectoryResult
- ForEachItemInDirectory(llvm::StringRef dir_path,
- DirectoryCallback const &callback);
-
protected:
//------------------------------------------------------------------
// Member variables
Modified: lldb/trunk/include/lldb/Interpreter/CommandCompletions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandCompletions.h?rev=297598&r1=297597&r2=297598&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandCompletions.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandCompletions.h Sun Mar 12 21:44:39 2017
@@ -24,7 +24,7 @@
#include "llvm/ADT/Twine.h"
namespace lldb_private {
-struct TildeExpressionResolver;
+class TildeExpressionResolver;
class CommandCompletions {
public:
//----------------------------------------------------------------------
Modified: lldb/trunk/source/Commands/CommandCompletions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandCompletions.cpp?rev=297598&r1=297597&r2=297598&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandCompletions.cpp (original)
+++ lldb/trunk/source/Commands/CommandCompletions.cpp Sun Mar 12 21:44:39 2017
@@ -195,7 +195,7 @@ static int DiskFilesOrDirectories(const
// We have a match.
fs::file_status st;
- if (EC = Entry.status(st))
+ if ((EC = Entry.status(st)))
continue;
// If it's a symlink, then we treat it as a directory as long as the target
Modified: lldb/trunk/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=297598&r1=297597&r2=297598&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSpec.cpp (original)
+++ lldb/trunk/source/Host/common/FileSpec.cpp Sun Mar 12 21:44:39 2017
@@ -7,21 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _WIN32
-#include <dirent.h>
-#else
-#include "lldb/Host/windows/windows.h"
-#endif
-#include <fcntl.h>
-#ifndef _MSC_VER
-#include <libgen.h>
-#endif
#include <fstream>
#include <set>
#include <string.h>
-#include "lldb/Host/Config.h" // Have to include this before we test the define...
-#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#include "llvm/Config/llvm-config.h"
+#ifndef LLVM_ON_WIN32
#include <pwd.h>
#endif
@@ -159,7 +150,7 @@ size_t ParentPathEnd(llvm::StringRef pat
// If you want to complete "~" to the list of users, pass it to
// ResolvePartialUsername.
void FileSpec::ResolveUsername(llvm::SmallVectorImpl<char> &path) {
-#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifndef LLVM_ON_WIN32
if (path.empty() || path[0] != '~')
return;
@@ -227,7 +218,7 @@ void FileSpec::ResolveUsername(llvm::Sma
size_t FileSpec::ResolvePartialUsername(llvm::StringRef partial_name,
StringList &matches) {
-#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifndef LLVM_ON_WIN32
size_t extant_entries = matches.GetSize();
setpwent();
@@ -251,17 +242,17 @@ size_t FileSpec::ResolvePartialUsername(
#else
// Resolving home directories is not supported, just copy the path...
return 0;
-#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#endif // #ifdef LLVM_ON_WIN32
}
void FileSpec::Resolve(llvm::SmallVectorImpl<char> &path) {
if (path.empty())
return;
-#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#ifndef LLVM_ON_WIN32
if (path[0] == '~')
ResolveUsername(path);
-#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
+#endif // #ifdef LLVM_ON_WIN32
// Save a copy of the original path that's passed in
llvm::SmallString<128> original_path(path.begin(), path.end());
@@ -776,235 +767,37 @@ size_t FileSpec::MemorySize() const {
return m_filename.MemorySize() + m_directory.MemorySize();
}
-FileSpec::EnumerateDirectoryResult
-FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
- DirectoryCallback const &callback) {
- if (dir_path.empty())
- return eEnumerateDirectoryResultNext;
-
-#ifdef _WIN32
- std::string szDir(dir_path);
- szDir += "\\*";
-
- std::wstring wszDir;
- if (!llvm::ConvertUTF8toWide(szDir, wszDir)) {
- return eEnumerateDirectoryResultNext;
- }
-
- WIN32_FIND_DATAW ffd;
- HANDLE hFind = FindFirstFileW(wszDir.c_str(), &ffd);
-
- if (hFind == INVALID_HANDLE_VALUE) {
- return eEnumerateDirectoryResultNext;
- }
-
- do {
- namespace fs = llvm::sys::fs;
- fs::file_type ft = fs::file_type::type_unknown;
- if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- size_t len = wcslen(ffd.cFileName);
-
- if (len == 1 && ffd.cFileName[0] == L'.')
- continue;
-
- if (len == 2 && ffd.cFileName[0] == L'.' && ffd.cFileName[1] == L'.')
- continue;
-
- ft = fs::file_type::directory_file;
- } else if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) {
- ft = fs::file_type::type_unknown;
- } else {
- ft = fs::file_type::regular_file;
- }
-
- std::string fileName;
- if (!llvm::convertWideToUTF8(ffd.cFileName, fileName)) {
- continue;
- }
-
- std::string child_path = llvm::join_items("\\", dir_path, fileName);
- // Don't resolve the file type or path
- FileSpec child_path_spec(child_path.data(), false);
-
- EnumerateDirectoryResult result = callback(ft, child_path_spec);
-
- switch (result) {
- case eEnumerateDirectoryResultNext:
- // Enumerate next entry in the current directory. We just
- // exit this switch and will continue enumerating the
- // current directory as we currently are...
- break;
-
- case eEnumerateDirectoryResultEnter: // Recurse into the current entry
- // if it is a directory or symlink,
- // or next if not
- if (FileSpec::ForEachItemInDirectory(child_path.data(), callback) ==
- eEnumerateDirectoryResultQuit) {
- // The subdirectory returned Quit, which means to
- // stop all directory enumerations at all levels.
- return eEnumerateDirectoryResultQuit;
- }
- break;
-
- case eEnumerateDirectoryResultExit: // Exit from the current directory
- // at the current level.
- // Exit from this directory level and tell parent to
- // keep enumerating.
- return eEnumerateDirectoryResultNext;
-
- case eEnumerateDirectoryResultQuit: // Stop directory enumerations at
- // any level
- return eEnumerateDirectoryResultQuit;
- }
- } while (FindNextFileW(hFind, &ffd) != 0);
-
- FindClose(hFind);
-#else
- std::string dir_string(dir_path);
- lldb_utility::CleanUp<DIR *, int> dir_path_dir(opendir(dir_string.c_str()),
- NULL, closedir);
- if (dir_path_dir.is_valid()) {
- char dir_path_last_char = dir_path.back();
-
- long path_max = fpathconf(dirfd(dir_path_dir.get()), _PC_NAME_MAX);
-#if defined(__APPLE_) && defined(__DARWIN_MAXPATHLEN)
- if (path_max < __DARWIN_MAXPATHLEN)
- path_max = __DARWIN_MAXPATHLEN;
-#endif
- struct dirent *buf, *dp;
- buf = (struct dirent *)malloc(offsetof(struct dirent, d_name) + path_max +
- 1);
-
- while (buf && readdir_r(dir_path_dir.get(), buf, &dp) == 0 && dp) {
- // Only search directories
- if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
- size_t len = strlen(dp->d_name);
-
- if (len == 1 && dp->d_name[0] == '.')
- continue;
-
- if (len == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
- continue;
- }
-
- using namespace llvm::sys::fs;
- file_type ft = file_type::type_unknown;
-
- switch (dp->d_type) {
- default:
- case DT_UNKNOWN:
- ft = file_type::type_unknown;
- break;
- case DT_FIFO:
- ft = file_type::fifo_file;
- break;
- case DT_CHR:
- ft = file_type::character_file;
- break;
- case DT_DIR:
- ft = file_type::directory_file;
- break;
- case DT_BLK:
- ft = file_type::block_file;
- break;
- case DT_REG:
- ft = file_type::regular_file;
- break;
- case DT_LNK:
- ft = file_type::symlink_file;
- break;
- case DT_SOCK:
- ft = file_type::socket_file;
- break;
-#if !defined(__OpenBSD__)
- case DT_WHT:
- ft = file_type::type_unknown;
- break;
-#endif
- }
-
- std::string child_path;
- // Don't make paths with "/foo//bar", that just confuses everybody.
- if (dir_path_last_char == '/')
- child_path = llvm::join_items("", dir_path, dp->d_name);
- else
- child_path = llvm::join_items('/', dir_path, dp->d_name);
-
- // Don't resolve the file type or path
- FileSpec child_path_spec(child_path, false);
-
- EnumerateDirectoryResult result = callback(ft, child_path_spec);
-
- switch (result) {
- case eEnumerateDirectoryResultNext:
- // Enumerate next entry in the current directory. We just
- // exit this switch and will continue enumerating the
- // current directory as we currently are...
- break;
-
- case eEnumerateDirectoryResultEnter: // Recurse into the current entry
- // if it is a directory or
- // symlink, or next if not
- if (FileSpec::ForEachItemInDirectory(child_path, callback) ==
- eEnumerateDirectoryResultQuit) {
- // The subdirectory returned Quit, which means to
- // stop all directory enumerations at all levels.
- if (buf)
- free(buf);
- return eEnumerateDirectoryResultQuit;
- }
- break;
-
- case eEnumerateDirectoryResultExit: // Exit from the current directory
- // at the current level.
- // Exit from this directory level and tell parent to
- // keep enumerating.
- if (buf)
- free(buf);
- return eEnumerateDirectoryResultNext;
-
- case eEnumerateDirectoryResultQuit: // Stop directory enumerations at
- // any level
- if (buf)
- free(buf);
- return eEnumerateDirectoryResultQuit;
- }
- }
- if (buf) {
- free(buf);
- }
+void FileSpec::EnumerateDirectory(llvm::StringRef dir_path,
+ bool find_directories, bool find_files,
+ bool find_other,
+ EnumerateDirectoryCallbackType callback,
+ void *callback_baton) {
+ namespace fs = llvm::sys::fs;
+ std::error_code EC;
+ fs::recursive_directory_iterator Iter(dir_path, EC);
+ fs::recursive_directory_iterator End;
+ for (; Iter != End && !EC; Iter.increment(EC)) {
+ const auto &Item = *Iter;
+ fs::file_status Status;
+ if (EC = Item.status(Status))
+ break;
+ if (!find_files && fs::is_regular_file(Status))
+ continue;
+ if (!find_directories && fs::is_directory(Status))
+ continue;
+ if (!find_other && fs::is_other(Status))
+ continue;
+
+ FileSpec Spec(Item.path(), false);
+ auto Result = callback(callback_baton, Status.type(), Spec);
+ 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();
}
-#endif
- // By default when exiting a directory, we tell the parent enumeration
- // to continue enumerating.
- return eEnumerateDirectoryResultNext;
-}
-
-FileSpec::EnumerateDirectoryResult
-FileSpec::EnumerateDirectory(llvm::StringRef dir_path, bool find_directories,
- bool find_files, bool find_other,
- EnumerateDirectoryCallbackType callback,
- void *callback_baton) {
- return ForEachItemInDirectory(
- dir_path,
- [&find_directories, &find_files, &find_other, &callback, &callback_baton](
- llvm::sys::fs::file_type file_type, const FileSpec &file_spec) {
- switch (file_type) {
- case llvm::sys::fs::file_type::directory_file:
- if (find_directories)
- return callback(callback_baton, file_type, file_spec);
- break;
- case llvm::sys::fs::file_type::regular_file:
- if (find_files)
- return callback(callback_baton, file_type, file_spec);
- break;
- default:
- if (find_other)
- return callback(callback_baton, file_type, file_spec);
- break;
- }
- return eEnumerateDirectoryResultNext;
- });
+ }
}
FileSpec
Modified: lldb/trunk/source/Utility/TildeExpressionResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/TildeExpressionResolver.cpp?rev=297598&r1=297597&r2=297598&view=diff
==============================================================================
--- lldb/trunk/source/Utility/TildeExpressionResolver.cpp (original)
+++ lldb/trunk/source/Utility/TildeExpressionResolver.cpp Sun Mar 12 21:44:39 2017
@@ -13,6 +13,10 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#if !defined(LLVM_ON_WIN32)
+#include <pwd.h>
+#endif
+
using namespace lldb_private;
using namespace llvm;
@@ -46,7 +50,7 @@ bool StandardTildeExpressionResolver::Re
if (Expr.empty())
return false;
- SmallString<32> Buffer = "~";
+ SmallString<32> Buffer("~");
setpwent();
struct passwd *user_entry;
Expr = Expr.drop_front();
More information about the lldb-commits
mailing list