summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/FileSpec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/FileSpec.cpp')
-rw-r--r--lldb/source/Core/FileSpec.cpp103
1 files changed, 102 insertions, 1 deletions
diff --git a/lldb/source/Core/FileSpec.cpp b/lldb/source/Core/FileSpec.cpp
index f1850439bc1..d0749bd3554 100644
--- a/lldb/source/Core/FileSpec.cpp
+++ b/lldb/source/Core/FileSpec.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
+#include <dirent.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdlib.h>
@@ -27,6 +28,7 @@
#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/Stream.h"
#include "lldb/Host/Host.h"
+#include "lldb/Utility/CleanUp.h"
using namespace lldb;
using namespace lldb_private;
@@ -572,7 +574,7 @@ FileSpec::GetFileType () const
default:
break;
}
- return eFileTypeUknown;
+ return eFileTypeUnknown;
}
return eFileTypeInvalid;
}
@@ -805,3 +807,102 @@ FileSpec::ReadFileLines (STLStringArray &lines)
}
return lines.size();
}
+
+FileSpec::EnumerateDirectoryResult
+FileSpec::EnumerateDirectory
+(
+ const char *dir_path,
+ bool find_directories,
+ bool find_files,
+ bool find_other,
+ EnumerateDirectoryCallbackType callback,
+ void *callback_baton
+)
+{
+ if (dir_path && dir_path[0])
+ {
+ lldb_utility::CleanUp <DIR *, int> dir_path_dir (opendir(dir_path), NULL, closedir);
+ if (dir_path_dir.is_valid())
+ {
+ struct dirent* dp;
+ while ((dp = readdir(dir_path_dir.get())) != NULL)
+ {
+ // Only search directories
+ if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
+ {
+ if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+ continue;
+
+ if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
+ continue;
+ }
+
+ bool call_callback = false;
+ FileSpec::FileType file_type = eFileTypeUnknown;
+
+ switch (dp->d_type)
+ {
+ default:
+ case DT_UNKNOWN: file_type = eFileTypeUnknown; call_callback = true; break;
+ case DT_FIFO: file_type = eFileTypePipe; call_callback = find_other; break;
+ case DT_CHR: file_type = eFileTypeOther; call_callback = find_other; break;
+ case DT_DIR: file_type = eFileTypeDirectory; call_callback = find_directories; break;
+ case DT_BLK: file_type = eFileTypeOther; call_callback = find_other; break;
+ case DT_REG: file_type = eFileTypeRegular; call_callback = find_files; break;
+ case DT_LNK: file_type = eFileTypeSymbolicLink; call_callback = find_other; break;
+ case DT_SOCK: file_type = eFileTypeSocket; call_callback = find_other; break;
+ case DT_WHT: file_type = eFileTypeOther; call_callback = find_other; break;
+ }
+
+ if (call_callback)
+ {
+ char child_path[PATH_MAX];
+ const int child_path_len = ::snprintf (child_path, sizeof(child_path), "%s/%s", dir_path, dp->d_name);
+ if (child_path_len < sizeof(child_path) - 1)
+ {
+ // Don't resolve the file type or path
+ FileSpec child_path_spec (child_path, false);
+
+ EnumerateDirectoryResult result = callback (callback_baton, file_type, child_path_spec);
+
+ switch (result)
+ {
+ default:
+ 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::EnumerateDirectory (child_path,
+ find_directories,
+ find_files,
+ find_other,
+ callback,
+ callback_baton) == 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;
+ }
+ }
+ }
+ }
+ }
+ }
+ // By default when exiting a directory, we tell the parent enumeration
+ // to continue enumerating.
+ return eEnumerateDirectoryResultNext;
+}
+
OpenPOWER on IntegriCloud