summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Support/Path.cpp13
-rw-r--r--llvm/lib/Support/Unix/Path.inc79
-rw-r--r--llvm/lib/Support/Windows/Path.inc80
3 files changed, 95 insertions, 77 deletions
diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index 59c0aa6ee5e..41f25648985 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -1085,12 +1085,13 @@ std::error_code is_other(const Twine &Path, bool &Result) {
return std::error_code();
}
-void directory_entry::replace_filename(const Twine &filename,
- basic_file_status st) {
- SmallString<128> path = path::parent_path(Path);
- path::append(path, filename);
- Path = path.str();
- Status = st;
+void directory_entry::replace_filename(const Twine &Filename, file_type Type,
+ basic_file_status Status) {
+ SmallString<128> PathStr = path::parent_path(Path);
+ path::append(PathStr, Filename);
+ this->Path = PathStr.str();
+ this->Type = Type;
+ this->Status = Status;
}
ErrorOr<perms> getPermissions(const Twine &Path) {
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index ba483c832c1..e0f0144c14b 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -523,38 +523,40 @@ static void expandTildeExpr(SmallVectorImpl<char> &Path) {
llvm::sys::path::append(Path, Storage);
}
+static file_type typeForMode(mode_t Mode) {
+ if (S_ISDIR(Mode))
+ return file_type::directory_file;
+ else if (S_ISREG(Mode))
+ return file_type::regular_file;
+ else if (S_ISBLK(Mode))
+ return file_type::block_file;
+ else if (S_ISCHR(Mode))
+ return file_type::character_file;
+ else if (S_ISFIFO(Mode))
+ return file_type::fifo_file;
+ else if (S_ISSOCK(Mode))
+ return file_type::socket_file;
+ else if (S_ISLNK(Mode))
+ return file_type::symlink_file;
+ return file_type::type_unknown;
+}
+
static std::error_code fillStatus(int StatRet, const struct stat &Status,
file_status &Result) {
if (StatRet != 0) {
- std::error_code ec(errno, std::generic_category());
- if (ec == errc::no_such_file_or_directory)
+ std::error_code EC(errno, std::generic_category());
+ if (EC == errc::no_such_file_or_directory)
Result = file_status(file_type::file_not_found);
else
Result = file_status(file_type::status_error);
- return ec;
+ return EC;
}
- file_type Type = file_type::type_unknown;
-
- if (S_ISDIR(Status.st_mode))
- Type = file_type::directory_file;
- else if (S_ISREG(Status.st_mode))
- Type = file_type::regular_file;
- else if (S_ISBLK(Status.st_mode))
- Type = file_type::block_file;
- else if (S_ISCHR(Status.st_mode))
- Type = file_type::character_file;
- else if (S_ISFIFO(Status.st_mode))
- Type = file_type::fifo_file;
- else if (S_ISSOCK(Status.st_mode))
- Type = file_type::socket_file;
- else if (S_ISLNK(Status.st_mode))
- Type = file_type::symlink_file;
-
perms Perms = static_cast<perms>(Status.st_mode) & all_perms;
- Result = file_status(Type, Perms, Status.st_dev, Status.st_nlink,
- Status.st_ino, Status.st_atime, Status.st_mtime,
- Status.st_uid, Status.st_gid, Status.st_size);
+ Result = file_status(typeForMode(Status.st_mode), Perms, Status.st_dev,
+ Status.st_nlink, Status.st_ino, Status.st_atime,
+ Status.st_mtime, Status.st_uid, Status.st_gid,
+ Status.st_size);
return std::error_code();
}
@@ -696,19 +698,30 @@ std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
return std::error_code();
}
-std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
+static file_type direntType(dirent* Entry) {
+ // Most platforms provide the file type in the dirent: Linux/BSD/Mac.
+ // The DTTOIF macro lets us reuse our status -> type conversion.
+#if defined(_DIRENT_HAVE_D_TYPE) && defined(DTTOIF)
+ return typeForMode(DTTOIF(Entry->d_type));
+#else
+ // Other platforms such as Solaris require a stat() to get the type.
+ return file_type::type_unknown;
+#endif
+}
+
+std::error_code detail::directory_iterator_increment(detail::DirIterState &It) {
errno = 0;
- dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle));
- if (cur_dir == nullptr && errno != 0) {
+ dirent *CurDir = ::readdir(reinterpret_cast<DIR *>(It.IterationHandle));
+ if (CurDir == nullptr && errno != 0) {
return std::error_code(errno, std::generic_category());
- } else if (cur_dir != nullptr) {
- StringRef name(cur_dir->d_name);
- if ((name.size() == 1 && name[0] == '.') ||
- (name.size() == 2 && name[0] == '.' && name[1] == '.'))
- return directory_iterator_increment(it);
- it.CurrentEntry.replace_filename(name);
+ } else if (CurDir != nullptr) {
+ StringRef Name(CurDir->d_name);
+ if ((Name.size() == 1 && Name[0] == '.') ||
+ (Name.size() == 2 && Name[0] == '.' && Name[1] == '.'))
+ return directory_iterator_increment(It);
+ It.CurrentEntry.replace_filename(Name, direntType(CurDir));
} else
- return directory_iterator_destruct(it);
+ return directory_iterator_destruct(It);
return std::error_code();
}
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 57557dbc3da..84565dccbdf 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -902,28 +902,28 @@ static basic_file_status status_from_find_data(WIN32_FIND_DATAW *FindData) {
FindData->nFileSizeHigh, FindData->nFileSizeLow);
}
-std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
- StringRef path,
- bool follow_symlinks) {
- SmallVector<wchar_t, 128> path_utf16;
+std::error_code detail::directory_iterator_construct(detail::DirIterState &IT,
+ StringRef Path,
+ bool FollowSymlinks) {
+ SmallVector<wchar_t, 128> PathUTF16;
- if (std::error_code ec = widenPath(path, path_utf16))
- return ec;
+ if (std::error_code EC = widenPath(Path, PathUTF16))
+ return EC;
// Convert path to the format that Windows is happy with.
- if (path_utf16.size() > 0 &&
- !is_separator(path_utf16[path.size() - 1]) &&
- path_utf16[path.size() - 1] != L':') {
- path_utf16.push_back(L'\\');
- path_utf16.push_back(L'*');
+ if (PathUTF16.size() > 0 &&
+ !is_separator(PathUTF16[Path.size() - 1]) &&
+ PathUTF16[Path.size() - 1] != L':') {
+ PathUTF16.push_back(L'\\');
+ PathUTF16.push_back(L'*');
} else {
- path_utf16.push_back(L'*');
+ PathUTF16.push_back(L'*');
}
// Get the first directory entry.
WIN32_FIND_DATAW FirstFind;
ScopedFindHandle FindHandle(::FindFirstFileExW(
- c_str(path_utf16), FindExInfoBasic, &FirstFind, FindExSearchNameMatch,
+ c_str(PathUTF16), FindExInfoBasic, &FirstFind, FindExSearchNameMatch,
NULL, FIND_FIRST_EX_LARGE_FETCH));
if (!FindHandle)
return mapWindowsError(::GetLastError());
@@ -936,43 +936,45 @@ std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
DWORD LastError = ::GetLastError();
// Check for end.
if (LastError == ERROR_NO_MORE_FILES)
- return detail::directory_iterator_destruct(it);
+ return detail::directory_iterator_destruct(IT);
return mapWindowsError(LastError);
} else
FilenameLen = ::wcslen(FirstFind.cFileName);
// Construct the current directory entry.
- SmallString<128> directory_entry_name_utf8;
- if (std::error_code ec =
+ SmallString<128> DirectoryEntryNameUTF8;
+ if (std::error_code EC =
UTF16ToUTF8(FirstFind.cFileName, ::wcslen(FirstFind.cFileName),
- directory_entry_name_utf8))
- return ec;
+ DirectoryEntryNameUTF8))
+ return EC;
- it.IterationHandle = intptr_t(FindHandle.take());
- SmallString<128> directory_entry_path(path);
- path::append(directory_entry_path, directory_entry_name_utf8);
- it.CurrentEntry = directory_entry(directory_entry_path, follow_symlinks,
- status_from_find_data(&FirstFind));
+ IT.IterationHandle = intptr_t(FindHandle.take());
+ SmallString<128> DirectoryEntryPath(Path);
+ path::append(DirectoryEntryPath, DirectoryEntryNameUTF8);
+ IT.CurrentEntry =
+ directory_entry(DirectoryEntryPath, FollowSymlinks,
+ file_type_from_attrs(FirstFind.dwFileAttributes),
+ status_from_find_data(&FirstFind));
return std::error_code();
}
-std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
- if (it.IterationHandle != 0)
+std::error_code detail::directory_iterator_destruct(detail::DirIterState &IT) {
+ if (IT.IterationHandle != 0)
// Closes the handle if it's valid.
- ScopedFindHandle close(HANDLE(it.IterationHandle));
- it.IterationHandle = 0;
- it.CurrentEntry = directory_entry();
+ ScopedFindHandle close(HANDLE(IT.IterationHandle));
+ IT.IterationHandle = 0;
+ IT.CurrentEntry = directory_entry();
return std::error_code();
}
-std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
+std::error_code detail::directory_iterator_increment(detail::DirIterState &IT) {
WIN32_FIND_DATAW FindData;
- if (!::FindNextFileW(HANDLE(it.IterationHandle), &FindData)) {
+ if (!::FindNextFileW(HANDLE(IT.IterationHandle), &FindData)) {
DWORD LastError = ::GetLastError();
// Check for end.
if (LastError == ERROR_NO_MORE_FILES)
- return detail::directory_iterator_destruct(it);
+ return detail::directory_iterator_destruct(IT);
return mapWindowsError(LastError);
}
@@ -980,16 +982,18 @@ std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
if ((FilenameLen == 1 && FindData.cFileName[0] == L'.') ||
(FilenameLen == 2 && FindData.cFileName[0] == L'.' &&
FindData.cFileName[1] == L'.'))
- return directory_iterator_increment(it);
+ return directory_iterator_increment(IT);
- SmallString<128> directory_entry_path_utf8;
- if (std::error_code ec =
+ SmallString<128> DirectoryEntryPathUTF8;
+ if (std::error_code EC =
UTF16ToUTF8(FindData.cFileName, ::wcslen(FindData.cFileName),
- directory_entry_path_utf8))
- return ec;
+ DirectoryEntryPathUTF8))
+ return EC;
- it.CurrentEntry.replace_filename(Twine(directory_entry_path_utf8),
- status_from_find_data(&FindData));
+ IT.CurrentEntry.replace_filename(
+ Twine(DirectoryEntryPathUTF8),
+ file_type_from_attrs(FindData.dwFileAttributes),
+ status_from_find_data(&FindData));
return std::error_code();
}
OpenPOWER on IntegriCloud