/** Check whether the string str matches the wildcard string wc. \param str String to be matched. \param wc The wildcard. \param is_first Whether files beginning with dots should not be matched against wildcards. */ static bool wildcard_match_internal(const wchar_t *str, const wchar_t *wc, bool leading_dots_fail_to_match, bool is_first) { if (*str == 0 && *wc==0) return true; /* Hackish fix for https://github.com/fish-shell/fish-shell/issues/270 . Prevent wildcards from matching . or .., but we must still allow literal matches. */ if (leading_dots_fail_to_match && is_first && contains(str, L".", L"..")) { /* The string is '.' or '..'. Return true if the wildcard exactly matches. */ return ! wcscmp(str, wc); } if (*wc == ANY_STRING || *wc == ANY_STRING_RECURSIVE) { /* Ignore hidden file */ if (leading_dots_fail_to_match && is_first && *str == L'.') { return false; } /* Try all submatches */ do { if (wildcard_match_internal(str, wc+1, leading_dots_fail_to_match, false)) return true; } while (*(str++) != 0); return false; } else if (*str == 0) { /* End of string, but not end of wildcard, and the next wildcard element is not a '*', so this is not a match. */ return false; } if (*wc == ANY_CHAR) { if (is_first && *str == L'.') { return false; } return wildcard_match_internal(str+1, wc+1, leading_dots_fail_to_match, false); } if (*wc == *str) return wildcard_match_internal(str+1, wc+1, leading_dots_fail_to_match, false); return false; }
bool wildcard_match(const wcstring &str, const wcstring &wc, bool leading_dots_fail_to_match) { return wildcard_match_internal(str.c_str(), wc.c_str(), leading_dots_fail_to_match, true /* first */); }
bool wildcard_match(const wcstring &str, const wcstring &wc, bool leading_dots_fail_to_match) { enum fuzzy_match_type_t match = wildcard_match_internal(str.c_str(), wc.c_str(), leading_dots_fail_to_match); return match != fuzzy_match_none; }