CLI: Add support for ignoring case in PathMatch.

In Windows (or in Windows code?) we want to ignore case in the
paths. This patch implements the case ignore for the PathMatch-
class.
This commit is contained in:
Kimmo Varis 2011-10-02 11:46:27 +03:00
parent 15078416e9
commit 4ef4cb26e9
3 changed files with 37 additions and 9 deletions

View File

@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include "pathmatch.h"
PathMatch::PathMatch(const std::vector<std::string> &masks)
@ -23,7 +24,7 @@ PathMatch::PathMatch(const std::vector<std::string> &masks)
{
}
bool PathMatch::Match(const std::string &path)
bool PathMatch::Match(const std::string &path, bool caseSensitive)
{
if (path.empty())
return false;
@ -31,34 +32,41 @@ bool PathMatch::Match(const std::string &path)
std::vector<std::string>::const_iterator iterMask;
for (iterMask = _masks.begin(); iterMask != _masks.end(); ++iterMask)
{
std::string mask(*iterMask);
if (!caseSensitive)
std::transform(mask.begin(), mask.end(), mask.begin(), ::tolower);
std::string findpath(path);
if (!caseSensitive)
std::transform(findpath.begin(), findpath.end(), findpath.begin(), ::tolower);
// Filtering directory name
if ((*iterMask)[(*iterMask).length() - 1] == '/')
if (mask[mask.length() - 1] == '/')
{
std::string findpath(path);
if (findpath[findpath.length() - 1] != '/')
findpath = RemoveFilename(findpath);
if ((*iterMask).length() > findpath.length())
if (mask.length() > findpath.length())
continue;
// Match relative paths starting with mask
// -isrc matches src/foo.cpp
if (findpath.compare(0, (*iterMask).size(), *iterMask) == 0)
if (findpath.compare(0, mask.size(), mask) == 0)
return true;
// Match only full directory name in middle or end of the path
// -isrc matches myproject/src/ but does not match
// myproject/srcfiles/ or myproject/mysrc/
if (findpath.find("/" + *iterMask) != std::string::npos)
if (findpath.find("/" + mask) != std::string::npos)
return true;
}
// Filtering filename
else
{
if ((*iterMask).length() > path.length())
if (mask.length() > findpath.length())
continue;
// Check if path ends with mask
// -ifoo.cpp matches (./)foo.c, src/foo.cpp and proj/src/foo.cpp
// -isrc/file.cpp matches src/foo.cpp and proj/src/foo.cpp
if (path.compare(path.size() - (*iterMask).size(), path.size(), *iterMask) == 0)
if (findpath.compare(findpath.size() - mask.size(), findpath.size(), mask) == 0)
return true;
}

View File

@ -41,9 +41,11 @@ public:
/**
* @brief Match path against list of masks.
* @param path Path to match.
* @param caseSensitive Match the case of the characters when
* matching paths?
* @return true if any of the masks match the path, false otherwise.
*/
bool Match(const std::string &path);
bool Match(const std::string &path, bool caseSensitive = true);
protected:

View File

@ -37,6 +37,7 @@ private:
TEST_CASE(emptymaskpath3);
TEST_CASE(onemaskemptypath);
TEST_CASE(onemasksamepath);
TEST_CASE(onemasksamepathdifferentcase);
TEST_CASE(onemasksamepathwithfile);
TEST_CASE(onemaskdifferentdir1);
TEST_CASE(onemaskdifferentdir2);
@ -46,6 +47,7 @@ private:
TEST_CASE(onemasklongerpath2);
TEST_CASE(onemasklongerpath3);
TEST_CASE(filemask1);
TEST_CASE(filemaskdifferentcase);
TEST_CASE(filemask2);
TEST_CASE(filemask3);
TEST_CASE(filemaskpath1);
@ -98,6 +100,14 @@ private:
ASSERT(match.Match("src/"));
}
void onemasksamepathdifferentcase()
{
std::vector<std::string> masks;
masks.push_back("sRc/");
PathMatch match(masks);
ASSERT(match.Match("srC/", false));
}
void onemasksamepathwithfile()
{
std::vector<std::string> masks;
@ -206,6 +216,14 @@ private:
ASSERT(match.Match("foo.cpp"));
}
void filemaskdifferentcase()
{
std::vector<std::string> masks;
masks.push_back("foo.cPp");
PathMatch match(masks);
ASSERT(match.Match("fOo.cpp", false));
}
void filemask2()
{
std::vector<std::string> masks;