Skip to content

Commit

Permalink
Don't block "hidden files" for wildcard expansions that aren't files …
Browse files Browse the repository at this point in the history
…(like case)

#667
  • Loading branch information
ridiculousfish committed Apr 20, 2013
1 parent e285d29 commit b65f8d8
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 27 deletions.
47 changes: 21 additions & 26 deletions wildcard.cpp
Expand Up @@ -143,15 +143,13 @@ int wildcard_has(const wchar_t *str, int internal)
\param wc The wildcard.
\param is_first Whether files beginning with dots should not be matched against wildcards.
*/
static bool wildcard_match2(const wchar_t *str,
const wchar_t *wc,
bool is_first)
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 (is_first && contains(str, L".", L".."))
/* 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);
Expand All @@ -160,15 +158,15 @@ static bool wildcard_match2(const wchar_t *str,
if (*wc == ANY_STRING || *wc == ANY_STRING_RECURSIVE)
{
/* Ignore hidden file */
if (is_first && *str == L'.')
if (leading_dots_fail_to_match && is_first && *str == L'.')
{
return false;
}

/* Try all submatches */
do
{
if (wildcard_match2(str, wc+1, false))
if (wildcard_match_internal(str, wc+1, leading_dots_fail_to_match, false))
return true;
}
while (*(str++) != 0);
Expand All @@ -190,11 +188,11 @@ static bool wildcard_match2(const wchar_t *str,
return false;
}

return wildcard_match2(str+1, wc+1, false);
return wildcard_match_internal(str+1, wc+1, leading_dots_fail_to_match, false);
}

if (*wc == *str)
return wildcard_match2(str+1, wc+1, false);
return wildcard_match_internal(str+1, wc+1, leading_dots_fail_to_match, false);

return false;
}
Expand Down Expand Up @@ -310,9 +308,9 @@ bool wildcard_complete(const wcstring &str,
}


bool wildcard_match(const wcstring &str, const wcstring &wc)
bool wildcard_match(const wcstring &str, const wcstring &wc, bool leading_dots_fail_to_match)
{
return wildcard_match2(str.c_str(), wc.c_str(), true);
return wildcard_match_internal(str.c_str(), wc.c_str(), leading_dots_fail_to_match, true /* first */);
}

/**
Expand Down Expand Up @@ -821,20 +819,19 @@ static int wildcard_expand_internal(const wchar_t *wc,
/*
This is the last wildcard segment, and it is not empty. Match files/directories.
*/
wcstring next;
while (wreaddir(dir, next))
wcstring name_str;
while (wreaddir(dir, name_str))
{
const wchar_t * const name = next.c_str();
if (flags & ACCEPT_INCOMPLETE)
{

const wcstring long_name = make_path(base_dir, next);
const wcstring long_name = make_path(base_dir, name_str);

/*
Test for matches before stating file, so as to minimize the number of calls to the much slower stat function
*/
std::vector<completion_t> test;
if (wildcard_complete(name,
if (wildcard_complete(name_str,
wc,
L"",
0,
Expand All @@ -845,7 +842,7 @@ static int wildcard_expand_internal(const wchar_t *wc,
{
wildcard_completion_allocate(out,
long_name,
name,
name_str,
wc,
flags);

Expand All @@ -854,9 +851,9 @@ static int wildcard_expand_internal(const wchar_t *wc,
}
else
{
if (wildcard_match2(name, wc, true))
if (wildcard_match(name_str, wc, true /* skip files with leading dots */))
{
const wcstring long_name = make_path(base_dir, next);
const wcstring long_name = make_path(base_dir, name_str);
int skip = 0;

if (is_recursive)
Expand Down Expand Up @@ -940,16 +937,14 @@ static int wildcard_expand_internal(const wchar_t *wc,

wcscpy(new_dir, base_dir);

wcstring next;
while (wreaddir(dir, next))
wcstring name_str;
while (wreaddir(dir, name_str))
{
const wchar_t *name = next.c_str();

/*
Test if the file/directory name matches the whole
wildcard element, i.e. regular matching.
*/
int whole_match = wildcard_match2(name, wc_str, true);
int whole_match = wildcard_match(name_str, wc_str, true /* ignore leading dots */);
int partial_match = 0;

/*
Expand All @@ -962,7 +957,7 @@ static int wildcard_expand_internal(const wchar_t *wc,
{
const wchar_t *end = wcschr(wc, ANY_STRING_RECURSIVE);
wchar_t *wc_sub = wcsndup(wc, end-wc+1);
partial_match = wildcard_match2(name, wc_sub, true);
partial_match = wildcard_match(name_str, wc_sub, true /* ignore leading dots */);
free(wc_sub);
}

Expand All @@ -973,7 +968,7 @@ static int wildcard_expand_internal(const wchar_t *wc,
int stat_res;
int new_res;

wcscpy(&new_dir[base_len], name);
wcscpy(&new_dir[base_len], name_str.c_str());
dir_str = wcs2str(new_dir);

if (dir_str)
Expand Down
3 changes: 2 additions & 1 deletion wildcard.h
Expand Up @@ -73,9 +73,10 @@ int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, expand_
\param str The string to test
\param wc The wildcard to test against
\param leading_dots_fail_to_match if set, strings with leading dots are assumed to be hidden files and are not matched
\return true if the wildcard matched
*/
bool wildcard_match(const wcstring &str, const wcstring &wc);
bool wildcard_match(const wcstring &str, const wcstring &wc, bool leading_dots_fail_to_match = false);


/**
Expand Down

0 comments on commit b65f8d8

Please sign in to comment.