From ef33ec2f627dfe9e52acc82243e73113b9b9843a Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Sat, 20 Nov 2021 20:00:55 +0100 Subject: [PATCH] Keep narrow directory name around some more What this did was 1. Find directory 2. Turn name into wcstring and return it 3. Turn name back into string for some operations Instead, let's unglue the wcstringing from this, return the narrow string and then widen it when we need. --- src/wildcard.cpp | 13 +++++++------ src/wutil.cpp | 4 ++-- src/wutil.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/wildcard.cpp b/src/wildcard.cpp index a72588edb..899f95ab9 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -736,16 +736,16 @@ void wildcard_expander_t::expand_intermediate_segment(const wcstring &base_dir, const wcstring &wc_segment, const wchar_t *wc_remainder, const wcstring &prefix) { - wcstring name_str; + std::string narrow; int dir_fd = dirfd(base_dir_fp); - while (!interrupted_or_overflowed() && wreaddir_for_dirs(base_dir_fp, &name_str)) { + while (!interrupted_or_overflowed() && readdir_for_dirs(base_dir_fp, &narrow)) { + wcstring name_str = str2wcstring(narrow); // Note that it's critical we ignore leading dots here, else we may descend into . and .. if (!wildcard_match(name_str, wc_segment, true)) { // Doesn't match the wildcard for this segment, skip it. continue; } - std::string narrow = wcs2string(name_str); struct stat buf; if (0 != fstatat(dir_fd, narrow.c_str(), &buf, 0) || !S_ISDIR(buf.st_mode)) { // We either can't stat it, or we did but it's not a directory. @@ -776,18 +776,19 @@ void wildcard_expander_t::expand_literal_intermediate_segment_with_fuzz(const wc const wchar_t *wc_remainder, const wcstring &prefix) { // This only works with tab completions. Ordinary wildcard expansion should never go fuzzy. - wcstring name_str; + std::string narrow; // Mark that we are fuzzy for the duration of this function const scoped_push scoped_fuzzy(&this->has_fuzzy_ancestor, true); int dir_fd = dirfd(base_dir_fp); - while (!interrupted_or_overflowed() && wreaddir_for_dirs(base_dir_fp, &name_str)) { + while (!interrupted_or_overflowed() && readdir_for_dirs(base_dir_fp, &narrow)) { // Don't bother with . and .. - if (name_str == L"." || name_str == L"..") { + if (narrow == "." || narrow == "..") { continue; } + wcstring name_str = str2wcstring(narrow); // Skip cases that don't match or match exactly. The match-exactly case was handled directly // in expand(). const maybe_t match = string_fuzzy_match_string(wc_segment, name_str); diff --git a/src/wutil.cpp b/src/wutil.cpp index dc11469d5..55c8affef 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -94,7 +94,7 @@ bool wreaddir(DIR *dir, wcstring &out_name) { return true; } -bool wreaddir_for_dirs(DIR *dir, wcstring *out_name) { +bool readdir_for_dirs(DIR *dir, std::string *out_name) { struct dirent *result = nullptr; while (!result) { result = readdir(dir); @@ -118,7 +118,7 @@ bool wreaddir_for_dirs(DIR *dir, wcstring *out_name) { } if (result && out_name) { - *out_name = str2wcstring(result->d_name); + *out_name = result->d_name; } return result != nullptr; } diff --git a/src/wutil.h b/src/wutil.h index 07be9b8ef..139f5c8aa 100644 --- a/src/wutil.h +++ b/src/wutil.h @@ -71,7 +71,7 @@ bool wreaddir_resolving(DIR *dir, const std::wstring &dir_path, wcstring &out_na /// (i.e. the file is a symlink), then return it. Note that this does not guarantee that everything /// returned is a directory, it's just an optimization for cases where we would check for /// directories anyways. -bool wreaddir_for_dirs(DIR *dir, wcstring *out_name); +bool readdir_for_dirs(DIR *dir, std::string *out_name); /// Wide character version of dirname(). std::wstring wdirname(std::wstring path);