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

View File

@ -41,9 +41,11 @@ public:
/** /**
* @brief Match path against list of masks. * @brief Match path against list of masks.
* @param path Path to match. * @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. * @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: protected:

View File

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