diff --git a/include/znc/ZNCString.h b/include/znc/ZNCString.h
index 32f9b3d6..97f5ecc1 100644
--- a/include/znc/ZNCString.h
+++ b/include/znc/ZNCString.h
@@ -169,20 +169,26 @@ public:
*/
bool Equals(const CString& s, bool bCaseSensitive, CString::size_type uLen = CString::npos) const;
/**
- * Do a wildcard comparision between two strings.
+ * Do a wildcard comparison between two strings.
* For example, the following returns true:
* WildCmp("*!?bar@foo", "I_am!~bar@foo");
* @param sWild The wildcards used for the comparison.
* @param sString The string that is used for comparing.
+ * @param cs CaseSensitive (default) if you want the comparison
+ * to be case sensitive, CaseInsensitive otherwise.
+ * @todo Make cs CaseInsensitive by default.
* @return true if the wildcard matches.
*/
- static bool WildCmp(const CString& sWild, const CString& sString);
+ static bool WildCmp(const CString& sWild, const CString& sString, CaseSensitivity cs = CaseSensitive);
/**
* Do a wild compare on this string.
* @param sWild The wildcards used to for the comparison.
+ * @param cs CaseSensitive (default) if you want the comparison
+ * to be case sensitive, CaseInsensitive otherwise.
+ * @todo Make cs CaseInsensitive by default.
* @return The result of this->WildCmp(sWild, *this);.
*/
- bool WildCmp(const CString& sWild) const;
+ bool WildCmp(const CString& sWild, CaseSensitivity cs = CaseSensitive) const;
/**
* Turn all characters in this string into their upper-case equivalent.
diff --git a/src/ZNCString.cpp b/src/ZNCString.cpp
index 8b1ffff6..550a3e8b 100644
--- a/src/ZNCString.cpp
+++ b/src/ZNCString.cpp
@@ -95,9 +95,15 @@ bool CString::Equals(const CString& s, bool bCaseSensitive, CString::size_type u
}
}
-bool CString::WildCmp(const CString& sWild, const CString& sString) {
+bool CString::WildCmp(const CString& sWild, const CString& sString, CaseSensitivity cs) {
+ // avoid a copy when cs == CaseSensitive (C++ deliberately specifies that binding
+ // a temporary object to a reference to const on the stack lengthens the lifetime
+ // of the temporary to the lifetime of the reference itself)
+ const CString& sWld = (cs == CaseSensitive ? sWild : sWild.AsLower());
+ const CString& sStr = (cs == CaseSensitive ? sString : sString.AsLower());
+
// Written by Jack Handy - jakkhandy@hotmail.com
- const char *wild = sWild.c_str(), *CString = sString.c_str();
+ const char *wild = sWld.c_str(), *CString = sStr.c_str();
const char *cp = NULL, *mp = NULL;
while ((*CString) && (*wild != '*')) {
@@ -133,8 +139,8 @@ bool CString::WildCmp(const CString& sWild, const CString& sString) {
return (*wild == 0);
}
-bool CString::WildCmp(const CString& sWild) const {
- return CString::WildCmp(sWild, *this);
+bool CString::WildCmp(const CString& sWild, CaseSensitivity cs) const {
+ return CString::WildCmp(sWild, *this, cs);
}
CString& CString::MakeUpper() {
diff --git a/test/StringTest.cpp b/test/StringTest.cpp
index ee20786b..5261c3fd 100644
--- a/test/StringTest.cpp
+++ b/test/StringTest.cpp
@@ -85,11 +85,32 @@ TEST(StringTest, Cmp) {
}
TEST(StringTest, Wild) {
- EXPECT_TRUE(CString::WildCmp("*!?bar@foo", "I_am!~bar@foo"));
- EXPECT_TRUE(CString::WildCmp("", ""));
- EXPECT_TRUE(CString::WildCmp("*a*b*c*", "abc"));
- EXPECT_TRUE(CString::WildCmp("*a*b*c*", "axbyc"));
- EXPECT_FALSE(CString::WildCmp("*a*b*c*", "xy"));
+ EXPECT_TRUE(CString::WildCmp("", "", CString::CaseSensitive));
+ EXPECT_TRUE(CString::WildCmp("", "", CString::CaseInsensitive));
+
+ EXPECT_FALSE(CString::WildCmp("*a*b*c*", "xy", CString::CaseSensitive));
+ EXPECT_FALSE(CString::WildCmp("*a*b*c*", "xy", CString::CaseInsensitive));
+
+ EXPECT_TRUE(CString::WildCmp("*!?bar@foo", "I_am!~bar@foo", CString::CaseSensitive));
+ EXPECT_TRUE(CString::WildCmp("*!?bar@foo", "I_am!~bar@foo", CString::CaseInsensitive));
+
+ EXPECT_FALSE(CString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", CString::CaseSensitive));
+ EXPECT_TRUE (CString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", CString::CaseInsensitive));
+
+ EXPECT_TRUE(CString::WildCmp("*a*b*c*", "abc", CString::CaseSensitive));
+ EXPECT_TRUE(CString::WildCmp("*a*b*c*", "abc", CString::CaseInsensitive));
+
+ EXPECT_FALSE(CString::WildCmp("*A*b*c*", "abc", CString::CaseSensitive));
+ EXPECT_TRUE (CString::WildCmp("*A*b*c*", "abc", CString::CaseInsensitive));
+
+ EXPECT_FALSE(CString::WildCmp("*a*b*c*", "Abc", CString::CaseSensitive));
+ EXPECT_TRUE (CString::WildCmp("*a*b*c*", "Abc", CString::CaseInsensitive));
+
+ EXPECT_TRUE(CString::WildCmp("*a*b*c*", "axbyc", CString::CaseSensitive));
+ EXPECT_TRUE(CString::WildCmp("*a*b*c*", "axbyc", CString::CaseInsensitive));
+
+ EXPECT_FALSE(CString::WildCmp("*a*B*c*", "AxByC", CString::CaseSensitive));
+ EXPECT_TRUE (CString::WildCmp("*a*B*c*", "AxByC", CString::CaseInsensitive));
}
TEST(StringTest, Case) {