summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>2008-08-22 19:12:18 +0000
committerw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>2008-08-22 19:12:18 +0000
commit9582002171b47c49f5de3cb6ae6f7ece788b233b (patch)
tree2fd4221b850da300dc04efd892df622ba39be1f0
parentcb6917c48eceeaa0f9980d8efbec8b23fc91d3bf (diff)
Actually, we did manage to make a faster match than znc, when casemapping is taken into account. Hooray.
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@10222 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--src/wildcard.cpp79
1 files changed, 44 insertions, 35 deletions
diff --git a/src/wildcard.cpp b/src/wildcard.cpp
index 4b00e7261..074a91eed 100644
--- a/src/wildcard.cpp
+++ b/src/wildcard.cpp
@@ -18,63 +18,72 @@
#include "inspstring.h"
/*
- * Wildcard matching, the third (and probably final) iteration!
+ * Wildcard matching!
+ *
+ * Iteration 1)
+ * Slow, horrible, etc.
+ * Iteration 2)
+ * The vastly available 'public domain' one
+ * Iteration 3)
+ * ZNC's, thought to be faster than ours, but it turned out that we could do better ;-)
+ * Iteration 4)
+ * Largely from work by peavey and myself (w00t) :)
*
*/
-static bool match_internal(const unsigned char *mask, const unsigned char *str, unsigned const char *map)
+static bool match_internal(const unsigned char *string, const unsigned char *wild, unsigned const char *map)
{
- const unsigned char *wild = str;
- const unsigned char *string = mask;
- const unsigned char *cp = NULL;
- const unsigned char *mp = NULL;
+ const unsigned char* s;
if (!map)
- map = lowermap; // default to case insensitive search
-
- while ((*string) && (*wild != '*'))
- {
- if ((map[*wild] != map[*string]) && (*wild != '?'))
- {
- return false;
- }
-
- ++wild;
- ++string;
- }
+ map = lowermap;
while (*string)
{
if (*wild == '*')
{
- if (!*++wild)
- {
+ while (*wild && *wild == '*')
+ wild++;
+
+ if (!*wild)
return true;
+ else if (*wild != '?')
+ {
+ s = string;
+ while (*s)
+ {
+ if ((map[*wild] == map[*s]))
+ {
+ string = s;
+ if (*(wild+1) || !*(s+1))
+ {
+ wild++;
+ break;
+ }
+ }
+ s++;
+ }
}
-
- mp = wild;
- cp = string+1;
}
- // if mapped char == mapped wild OR wild is ?
- else if ((map[*wild] == map[*string]) || (*wild == '?'))
+ else if ( (map[*wild] != map[*string]) && (*wild != '?') )
{
- ++wild;
- ++string;
+ return false;
}
else
- {
- wild = mp;
- string = cp++;
- }
+ wild++;
+
+ string++;
}
- while (*wild == '*')
- {
+ while (*wild && *wild == '*')
wild++;
- }
- return (*wild == 0);
+ return !*wild;
}
+/********************************************************************
+ * Below here is all wrappers around match_internal
+ ********************************************************************/
+
CoreExport bool InspIRCd::Match(const std::string &str, const std::string &mask, unsigned const char *map)
{
return match_internal((const unsigned char *)str.c_str(), (const unsigned char *)mask.c_str(), map);