From 9a4232dcb721e93ea4320ea6d87b4337761b8dd7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 2 Jul 2001 12:42:46 +0000 Subject: [PATCH] fixed bug in wxString::Matches() - backtrack now if \* mismatched git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10777 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- samples/console/console.cpp | 102 ++++++++++++++++++++++++------------ src/common/string.cpp | 38 ++++++++++++-- 2 files changed, 102 insertions(+), 38 deletions(-) diff --git a/samples/console/console.cpp b/samples/console/console.cpp index fe75234c25..59760cdb2b 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -35,38 +35,38 @@ // what to test (in alphabetic order)? -#define TEST_ARRAYS -#define TEST_CHARSET -#define TEST_CMDLINE -#define TEST_DATETIME -#define TEST_DIR -#define TEST_DLLLOADER -#define TEST_ENVIRON -#define TEST_EXECUTE -#define TEST_FILE -#define TEST_FILECONF -#define TEST_FILENAME -#define TEST_FTP -#define TEST_HASH -#define TEST_INFO_FUNCTIONS -#define TEST_LIST -#define TEST_LOCALE -#define TEST_LOG -#define TEST_LONGLONG -#define TEST_MIME -#define TEST_PATHLIST -#define TEST_REGCONF -#define TEST_REGISTRY -#define TEST_SNGLINST -#define TEST_SOCKETS -#define TEST_STREAMS +//#define TEST_ARRAYS +//#define TEST_CHARSET +//#define TEST_CMDLINE +//#define TEST_DATETIME +//#define TEST_DIR +//#define TEST_DLLLOADER +//#define TEST_ENVIRON +//#define TEST_EXECUTE +//#define TEST_FILE +//#define TEST_FILECONF +//#define TEST_FILENAME +//#define TEST_FTP +//#define TEST_HASH +//#define TEST_INFO_FUNCTIONS +//#define TEST_LIST +//#define TEST_LOCALE +//#define TEST_LOG +//#define TEST_LONGLONG +//#define TEST_MIME +//#define TEST_PATHLIST +//#define TEST_REGCONF +//#define TEST_REGISTRY +//#define TEST_SNGLINST +//#define TEST_SOCKETS +//#define TEST_STREAMS #define TEST_STRINGS -#define TEST_THREADS -#define TEST_TIMER +//#define TEST_THREADS +//#define TEST_TIMER //#define TEST_VCARD -- don't enable this (VZ) -#define TEST_WCHAR -#define TEST_ZIP -#define TEST_ZLIB +//#define TEST_WCHAR +//#define TEST_ZIP +//#define TEST_ZLIB #ifdef TEST_SNGLINST #include @@ -4547,6 +4547,44 @@ static void TestStringReplace() puts(""); } +static void TestStringMatch() +{ + wxPuts(_T("*** Testing wxString::Matches() ***")); + + static const struct StringMatchTestData + { + const wxChar *text; + const wxChar *wildcard; + bool matches; + } stringMatchTestData[] = + { + { _T("foobar"), _T("foo*"), 1 }, + { _T("foobar"), _T("*oo*"), 1 }, + { _T("foobar"), _T("*bar"), 1 }, + { _T("foobar"), _T("??????"), 1 }, + { _T("foobar"), _T("f??b*"), 1 }, + { _T("foobar"), _T("f?b*"), 0 }, + { _T("foobar"), _T("*goo*"), 0 }, + { _T("foobar"), _T("*foo"), 0 }, + { _T("foobarfoo"), _T("*foo"), 1 }, + { _T(""), _T("*"), 1 }, + { _T(""), _T("?"), 0 }, + }; + + for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ ) + { + const StringMatchTestData& data = stringMatchTestData[n]; + bool matches = wxString(data.text).Matches(data.wildcard); + wxPrintf(_T("'%s' %s '%s' (%s)\n"), + data.wildcard, + matches ? _T("matches") : _T("doesn't match"), + data.text, + matches == data.matches ? _T("ok") : _T("ERROR")); + } + + wxPuts(_T("")); +} + #endif // TEST_STRINGS // ---------------------------------------------------------------------------- @@ -4632,16 +4670,14 @@ int main(int argc, char **argv) { TestPChar(); TestString(); - } TestStringSub(); - if ( 0 ) - { TestStringConstruction(); TestStringFormat(); TestStringFind(); TestStringTokenizer(); TestStringReplace(); } + TestStringMatch(); #endif // TEST_STRINGS #ifdef TEST_ARRAYS diff --git a/src/common/string.cpp b/src/common/string.cpp index 38d6d28300..902b9a5af7 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1456,21 +1456,34 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) // of them) bool wxString::Matches(const wxChar *pszMask) const { - // check char by char - const wxChar *pszTxt; - for ( pszTxt = c_str(); *pszMask != wxT('\0'); pszMask++, pszTxt++ ) { + // TODO: this is, of course, awfully inefficient... + + // the char currently being checked + const wxChar *pszTxt = c_str(); + + // the last location where '*' matched + const wxChar *pszLastStarInText = NULL; + const wxChar *pszLastStarInMask = NULL; + +match: + for ( ; *pszMask != wxT('\0'); pszMask++, pszTxt++ ) { switch ( *pszMask ) { case wxT('?'): if ( *pszTxt == wxT('\0') ) return FALSE; - // pszText and pszMask will be incremented in the loop statement + // pszTxt and pszMask will be incremented in the loop statement break; case wxT('*'): { + // remember where we started to be able to backtrack later + pszLastStarInText = pszTxt; + pszLastStarInMask = pszMask; + // ignore special chars immediately following this one + // (should this be an error?) while ( *pszMask == wxT('*') || *pszMask == wxT('?') ) pszMask++; @@ -1510,7 +1523,22 @@ bool wxString::Matches(const wxChar *pszMask) const } // match only if nothing left - return *pszTxt == wxT('\0'); + if ( *pszTxt == wxT('\0') ) + return TRUE; + + // if we failed to match, backtrack if we can + if ( pszLastStarInText ) { + pszTxt = pszLastStarInText + 1; + pszMask = pszLastStarInMask; + + pszLastStarInText = NULL; + + // don't bother resetting pszLastStarInMask, it's unnecessary + + goto match; + } + + return FALSE; } // Count the number of chars -- 2.47.2