• Welcome to Valhalla Legends Archive.
 

Wildcard matching function

Started by SecretShop, April 01, 2006, 02:46 PM

Previous topic - Next topic

SecretShop

I just had to write this for one of my projects, matches a pattern where * matches 0 to many characters and ? matches exactly 1.


//Matches string against a pattern and returns
//true if the string matches. Returns false if
//the length of the pattern is > 1024.

bool AccessDatabase::wcMatch(const char *pattern, const char *string) {
char *p;
char *pString;
char buffer[1024];
memset(buffer, 0, 1024);

if (!strcmp(pattern, "*"))
return true;

if (strlen(pattern) > 1024)
return false;

//filter out repeat '*' from the pattern
p = buffer + 1;
buffer[0] = *pattern;
for (char *pTmp = (char *)(pattern + 1); *pTmp; ++pTmp) {
if (!(*pTmp == '*' && *(pTmp - 1) == '*'))
(*p++) = *pTmp;
}

p = buffer;
pString = (char *)string;
for (p = buffer; *p; ++p) {
if (*p == '?') {
if (!*pString) return false;
++pString;
}else if (*p == '*') {
char next = *(p + 1);
if (!next) {
return true;
}else if (next == '?') {
next = *(p + 2);
if (!next) return false;
}

while (*pString != next && *pString)
++pString;

if (!pString)
return false;
}else if (*p == *pString) {
++pString;
}else {
return false;
}
}

return true;
}


The whole 1024 thing is because I can safely assume that length due to the source of my patterns for this function.  If you wish to use this elsewhere id probably recommend allocating a properly sized buffer based on strlen() of the pattern.

Tell me if you see any bugs ;)

Kp

It's buggy. :)  You check for a NULL pointer instead of a pointer to a null, in the handler for *.  Also, it looks like it always returns false if you specfiy a pattern ending in "*?".  For example, input: "abcdef", pattern: "a*?".  Typical matchers would return true, letting a=a, *=bcde, ?=f.  From a cursory reading, yours appears to return false.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!