diff options
Diffstat (limited to 'lldb/source/Host/common/FileSpec.cpp')
| -rw-r--r-- | lldb/source/Host/common/FileSpec.cpp | 98 |
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. |

