summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/common/FileSpec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/common/FileSpec.cpp')
-rw-r--r--lldb/source/Host/common/FileSpec.cpp98
1 files changed, 96 insertions, 2 deletions
diff --git a/lldb/source/Host/common/FileSpec.cpp b/lldb/source/Host/common/FileSpec.cpp
index 08d626e836a..0bf7681aa48 100644
--- a/lldb/source/Host/common/FileSpec.cpp
+++ b/lldb/source/Host/common/FileSpec.cpp
@@ -8,7 +8,11 @@
//===----------------------------------------------------------------------===//
+#ifndef _WIN32
#include <dirent.h>
+#else
+#include "lldb/Host/windows/windows.h"
+#endif
#include <fcntl.h>
#include <libgen.h>
#include <sys/stat.h>
@@ -616,10 +620,12 @@ FileSpec::GetFileType () const
switch (file_type)
{
case S_IFDIR: return eFileTypeDirectory;
- case S_IFIFO: return eFileTypePipe;
case S_IFREG: return eFileTypeRegular;
+#ifndef _WIN32
+ case S_IFIFO: return eFileTypePipe;
case S_IFSOCK: return eFileTypeSocket;
case S_IFLNK: return eFileTypeSymbolicLink;
+#endif
default:
break;
}
@@ -907,7 +913,94 @@ FileSpec::EnumerateDirectory
{
if (dir_path && dir_path[0])
{
- lldb_utility::CleanUp <DIR *, int> dir_path_dir (opendir(dir_path), NULL, closedir);
+#if _WIN32
+ char szDir[MAX_PATH];
+ strcpy_s(szDir, MAX_PATH, dir_path);
+ strcat_s(szDir, MAX_PATH, "\\*");
+
+ WIN32_FIND_DATA ffd;
+ HANDLE hFind = FindFirstFile(szDir, &ffd);
+
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ return eEnumerateDirectoryResultNext;
+ }
+
+ do
+ {
+ bool call_callback = false;
+ FileSpec::FileType file_type = eFileTypeUnknown;
+ if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ size_t len = strlen(ffd.cFileName);
+
+ if (len == 1 && ffd.cFileName[0] == '.')
+ continue;
+
+ if (len == 2 && ffd.cFileName[0] == '.' && ffd.cFileName[1] == '.')
+ continue;
+
+ file_type = eFileTypeDirectory;
+ call_callback = find_directories;
+ }
+ else if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE)
+ {
+ file_type = eFileTypeOther;
+ call_callback = find_other;
+ }
+ else
+ {
+ file_type = eFileTypeRegular;
+ call_callback = find_files;
+ }
+ if (call_callback)
+ {
+ char child_path[MAX_PATH];
+ const int child_path_len = ::snprintf (child_path, sizeof(child_path), "%s\\%s", dir_path, ffd.cFileName);
+ if (child_path_len < (int)(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)
+ {
+ 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;
+ }
+ }
+ }
+ } while (FindNextFile(hFind, &ffd) != 0);
+
+ FindClose(hFind);
+#else
+ lldb_utility::CleanUp <DIR *, int> dir_path_dir(opendir(dir_path), NULL, closedir);
if (dir_path_dir.is_valid())
{
long path_max = fpathconf (dirfd (dir_path_dir.get()), _PC_NAME_MAX);
@@ -1006,6 +1099,7 @@ FileSpec::EnumerateDirectory
free (buf);
}
}
+#endif
}
// By default when exiting a directory, we tell the parent enumeration
// to continue enumerating.
OpenPOWER on IntegriCloud