Merge branch 'msw-fnmatch-all'
Fix using *.* and similar patterns in wxDir under MSW: they're supposed to match all files and not only files with extensions. See #23910.
This commit is contained in:
commit
a4d2e36cec
2 changed files with 77 additions and 31 deletions
|
|
@ -27,8 +27,11 @@
|
|||
|
||||
#include "wx/dir.h"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/private.h"
|
||||
#include <shlwapi.h>
|
||||
|
||||
#ifdef __VISUALC__
|
||||
#pragma comment(lib, "shlwapi")
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -60,11 +63,6 @@ inline void FreeFindData(FIND_DATA fd)
|
|||
}
|
||||
}
|
||||
|
||||
const wxChar *GetNameFromFindData(const FIND_STRUCT *finddata)
|
||||
{
|
||||
return finddata->cFileName;
|
||||
}
|
||||
|
||||
// Helper function checking that the contents of the given FIND_STRUCT really
|
||||
// match our filter. We need to do it ourselves as native Windows functions
|
||||
// apply the filter to both the long and the short names of the file, so
|
||||
|
|
@ -78,17 +76,7 @@ CheckFoundMatch(const FIND_STRUCT* finddata, const wxString& filter)
|
|||
if ( filter.empty() )
|
||||
return true;
|
||||
|
||||
// Otherwise do check the match validity. Notice that we must do it
|
||||
// case-insensitively because the case of the file names is not supposed to
|
||||
// matter under Windows.
|
||||
wxString fn(GetNameFromFindData(finddata));
|
||||
|
||||
// However if the filter contains only special characters (which is a
|
||||
// common case), we can skip the case conversion.
|
||||
if ( filter.find_first_not_of(wxS("*?.")) == wxString::npos )
|
||||
return fn.Matches(filter);
|
||||
|
||||
return fn.MakeUpper().Matches(filter.Upper());
|
||||
return ::PathMatchSpec(finddata->cFileName, filter) == TRUE;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
|
@ -130,11 +118,6 @@ FindFirst(const wxString& spec,
|
|||
return fd;
|
||||
}
|
||||
|
||||
inline FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
|
||||
{
|
||||
return finddata->dwFileAttributes;
|
||||
}
|
||||
|
||||
inline bool IsDir(FIND_ATTR attr)
|
||||
{
|
||||
return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
|
|
@ -231,7 +214,6 @@ bool wxDirData::Read(wxString *filename)
|
|||
bool first = false;
|
||||
|
||||
WIN32_FIND_DATA finddata;
|
||||
#define PTR_TO_FINDDATA (&finddata)
|
||||
|
||||
if ( !IsFindDataOk(m_finddata) )
|
||||
{
|
||||
|
|
@ -246,7 +228,7 @@ bool wxDirData::Read(wxString *filename)
|
|||
else
|
||||
filespec += m_filespec;
|
||||
|
||||
m_finddata = FindFirst(filespec, m_filespec, PTR_TO_FINDDATA);
|
||||
m_finddata = FindFirst(filespec, m_filespec, &finddata);
|
||||
|
||||
first = true;
|
||||
}
|
||||
|
|
@ -265,9 +247,6 @@ bool wxDirData::Read(wxString *filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
const wxChar *name;
|
||||
FIND_ATTR attr;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( first )
|
||||
|
|
@ -276,7 +255,7 @@ bool wxDirData::Read(wxString *filename)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( !FindNext(m_finddata, m_filespec, PTR_TO_FINDDATA) )
|
||||
if ( !FindNext(m_finddata, m_filespec, &finddata) )
|
||||
{
|
||||
DWORD err = ::GetLastError();
|
||||
|
||||
|
|
@ -290,8 +269,8 @@ bool wxDirData::Read(wxString *filename)
|
|||
}
|
||||
}
|
||||
|
||||
name = GetNameFromFindData(PTR_TO_FINDDATA);
|
||||
attr = GetAttrFromFindData(PTR_TO_FINDDATA);
|
||||
const wxChar* const name = finddata.cFileName;
|
||||
const FIND_ATTR attr = finddata.dwFileAttributes;
|
||||
|
||||
// don't return "." and ".." unless asked for
|
||||
if ( name[0] == wxT('.') &&
|
||||
|
|
|
|||
|
|
@ -20,6 +20,16 @@
|
|||
#define DIRTEST_FOLDER wxString("dirTest_folder")
|
||||
#define SEP wxFileName::GetPathSeparator()
|
||||
|
||||
// We can't use wxFileSelectorDefaultWildcardStr from wxCore here, so define
|
||||
// our own.
|
||||
const wxString WILDCARD_ALL =
|
||||
#if defined(__WXMSW__)
|
||||
"*.*"
|
||||
#else // Unix/Mac
|
||||
"*"
|
||||
#endif
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test fixture
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -145,6 +155,21 @@ TEST_CASE_METHOD(DirTestCase, "Dir::Traverse", "[dir]")
|
|||
wxArrayString files;
|
||||
CHECK( wxDir::GetAllFiles(DIRTEST_FOLDER, &files) == 4 );
|
||||
|
||||
// enum all files using an explicit wildcard
|
||||
CHECK(wxDir::GetAllFiles(DIRTEST_FOLDER, &files, WILDCARD_ALL) == 4);
|
||||
|
||||
// enum all files using an explicit wildcard different from WILDCARD_ALL
|
||||
//
|
||||
// broken under Wine, see https://bugs.winehq.org/show_bug.cgi?id=55677
|
||||
if ( !wxIsRunningUnderWine() )
|
||||
{
|
||||
CHECK(wxDir::GetAllFiles(DIRTEST_FOLDER, &files, "d" + WILDCARD_ALL) == 4);
|
||||
}
|
||||
else if (wxDir::GetAllFiles(DIRTEST_FOLDER, &files, "d" + WILDCARD_ALL) == 4)
|
||||
{
|
||||
WARN("PathMatchSpec() seems to work under Wine now");
|
||||
}
|
||||
|
||||
// enum all files according to the filter
|
||||
CHECK( wxDir::GetAllFiles(DIRTEST_FOLDER, &files, "*.foo") == 1 );
|
||||
|
||||
|
|
@ -232,3 +257,45 @@ TEST_CASE_METHOD(DirTestCase, "Dir::GetName", "[dir]")
|
|||
CHECK( d.GetNameWithSep() == "/" );
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disabled by default test allowing to check the result of matching against
|
||||
// the given filter.
|
||||
#ifdef __WXMSW__
|
||||
|
||||
#include "wx/msw/wrapwin.h"
|
||||
#include <shlwapi.h>
|
||||
#ifdef __VISUALC__
|
||||
#pragma comment(lib, "shlwapi")
|
||||
#endif
|
||||
|
||||
#include "wx/crt.h"
|
||||
#include "wx/filefn.h"
|
||||
|
||||
TEST_CASE("Dir::Match", "[.]")
|
||||
{
|
||||
wxString filter;
|
||||
REQUIRE( wxGetEnv("WX_TEST_DIR_FILTER", &filter) );
|
||||
|
||||
static const wxString filenames[] =
|
||||
{
|
||||
"foo",
|
||||
"foo.bar",
|
||||
"foo.bar.baz",
|
||||
".hidden",
|
||||
".hidden.ext",
|
||||
};
|
||||
|
||||
// Show the results of matching the pattern using various functions.
|
||||
wxPrintf("%-15s %20s %20s %20s\n",
|
||||
"File", "wxString::Matches", "wxMatchWild", "PathMatchSpec");
|
||||
for ( const auto& fn : filenames )
|
||||
{
|
||||
wxPrintf("%-15s %20d %20d %20d\n",
|
||||
fn,
|
||||
fn.Matches(filter),
|
||||
wxMatchWild(filter, fn),
|
||||
PathMatchSpec(fn.wc_str(), filter.wc_str()) == TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __WXMSW__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue