summaryrefslogtreecommitdiff
path: root/tools/source/fsys/wldcrd.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tools/source/fsys/wldcrd.cxx')
-rw-r--r--tools/source/fsys/wldcrd.cxx105
1 files changed, 58 insertions, 47 deletions
diff --git a/tools/source/fsys/wldcrd.cxx b/tools/source/fsys/wldcrd.cxx
index 6e0259696aca..e8199975c6e5 100644
--- a/tools/source/fsys/wldcrd.cxx
+++ b/tools/source/fsys/wldcrd.cxx
@@ -25,85 +25,96 @@
* '?' in pWild mean match exactly one character.
*
*/
-bool WildCard::ImpMatch( const sal_Unicode *pWild, const sal_Unicode *pStr )
+bool WildCard::ImpMatch( std::u16string_view aWild, std::u16string_view aStr )
{
- int pos=0;
- int flag=0;
+ const sal_Unicode* pPosAfterAsterisk = nullptr;
+ const sal_Unicode* pWild = aWild.data();
+ const sal_Unicode* pWildEnd = aWild.data() + aWild.size();
+ const sal_Unicode* pStr = aStr.data();
+ const sal_Unicode* pStrEnd = aStr.data() + aStr.size();
- while ( *pWild || flag )
+ while (pWild != pWildEnd)
{
switch (*pWild)
{
case '?':
- if ( *pStr == '\0' )
+ if ( pStr == pStrEnd )
return false;
- break;
-
- default:
- if ( (*pWild == '\\') && ((*(pWild+1)=='?') || (*(pWild+1) == '*')) )
+ break; // Match -> proceed to the next character
+ case '\\': // Escaping '?' and '*'; don't we need to escape '\\'?
+ if ((pWild + 1 != pWildEnd) && ((*(pWild + 1) == '?') || (*(pWild + 1) == '*')))
pWild++;
- if ( *pWild != *pStr )
- if ( !pos )
- return false;
- else
- pWild += pos;
- else
- break;
- // WARNING/TODO: may cause execution of next case in some
- // circumstances!
+ [[fallthrough]];
+ default: // No wildcard, literal match
+ if (pStr == pStrEnd)
+ return false;
+ if (*pWild == *pStr)
+ break; // Match -> proceed to the next character
+ if (!pPosAfterAsterisk)
+ return false;
+ pWild = pPosAfterAsterisk;
[[fallthrough]];
case '*':
- while ( *pWild == '*' )
+ while ( pWild != pWildEnd && *pWild == '*' )
pWild++;
- if ( *pWild == '\0' )
+ if ( pWild == pWildEnd )
return true;
- flag = 1;
- pos = 0;
- if ( *pStr == '\0' )
- return ( *pWild == '\0' );
- while ( *pStr && *pStr != *pWild )
+ // Consider strange things like "**?*?*"
+ while (*pWild == '?')
{
- if ( *pWild == '?' ) {
+ if (pStr == pStrEnd)
+ return false;
+ pWild++;
+ pStr++;
+ while (pWild != pWildEnd && *pWild == '*')
pWild++;
- while ( *pWild == '*' )
- pWild++;
- }
+ if (pWild == pWildEnd)
+ return true;
+ }
+ // At this point, we are past wildcards, and a literal match must follow
+ if ( pStr == pStrEnd )
+ return false;
+ pPosAfterAsterisk = pWild;
+ if ((*pWild == '\\') && (pWild + 1 != pWildEnd) && ((*(pWild + 1) == '?') || (*(pWild + 1) == '*')))
+ pWild++;
+ while (*pStr != *pWild)
+ {
pStr++;
- if ( *pStr == '\0' )
- return ( *pWild == '\0' );
+ if ( pStr == pStrEnd )
+ return false;
}
- break;
+ break; // Match -> proceed to the next character
}
- if ( *pWild != '\0' )
- pWild++;
- if ( *pStr != '\0' )
- pStr++;
- else
- flag = 0;
- if ( flag )
- pos--;
+ // We arrive here when the current characters in pWild and pStr match
+ assert(pWild != pWildEnd);
+ pWild++;
+ assert(pStr != pStrEnd);
+ pStr++;
+ if (pWild == pWildEnd && pPosAfterAsterisk && pStr != pStrEnd)
+ pWild = pPosAfterAsterisk; // Try again on the rest of pStr
}
- return ( *pStr == '\0' ) && ( *pWild == '\0' );
+ assert(pWild == pWildEnd);
+ return pStr == pStrEnd;
}
bool WildCard::Matches( std::u16string_view rString ) const
{
- OUString aTmpWild = aWildString;
+ std::u16string_view aTmpWild = aWildString;
- sal_Int32 nSepPos;
+ size_t nSepPos;
if ( cSepSymbol != '\0' )
{
- while ( (nSepPos = aTmpWild.indexOf(cSepSymbol)) != -1 )
+ while ( (nSepPos = aTmpWild.find(cSepSymbol)) != std::u16string_view::npos )
{
// Check all split wildcards
- if ( ImpMatch( aTmpWild.subView( 0, nSepPos ).data(), rString.data() ) )
+ if ( ImpMatch( aTmpWild.substr( 0, nSepPos ), rString ) )
return true;
- aTmpWild = aTmpWild.copy(nSepPos + 1); // remove separator
+ aTmpWild = aTmpWild.substr(nSepPos + 1); // remove separator
}
}
- return ImpMatch( aTmpWild.getStr(), rString.data() );
+ return ImpMatch( aTmpWild, rString );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */