#include "lib.h"
#include "wildcard-match.h"
#include <ctype.h>
#define WILDS '*'
#define WILDQ '?'
#define NOMATCH 0
#define MATCH (match+sofar)
static int wildcard_match_int(const char *data, const char *mask, int icase)
{
const char *ma = mask, *na = data, *lsm = 0, *lsn = 0;
int match = 1;
int sofar = 0;
if ((ma == 0) || (na == 0) || (!*ma) || (!*na))
return NOMATCH;
while (*(++mask));
mask--;
while (*(++data));
data--;
while (data >= na) {
if (mask < ma) {
if (lsm) {
data = --lsn;
mask = lsm;
if (data < na)
lsm = 0;
sofar = 0;
}
else
return NOMATCH;
}
switch (*mask) {
case WILDS:
do
mask--;
while ((mask >= ma) && (*mask == WILDS));
lsm = mask;
lsn = data;
match += sofar;
sofar = 0;
if (mask < ma)
return MATCH;
continue;
case WILDQ:
mask--;
data--;
continue;
}
if (icase ? (i_toupper(*mask) == i_toupper(*data)) :
(*mask == *data)) {
mask--;
data--;
sofar++;
continue;
}
if (lsm) {
data = --lsn;
mask = lsm;
if (data < na)
lsm = 0;
sofar = 0;
continue;
}
return NOMATCH;
}
while ((mask >= ma) && (*mask == WILDS))
mask--;
return (mask >= ma) ? NOMATCH : MATCH;
}
bool wildcard_match(const char *data, const char *mask)
{
return wildcard_match_int(data, mask, FALSE) != 0;
}
bool wildcard_match_icase(const char *data, const char *mask)
{
return wildcard_match_int(data, mask, TRUE) != 0;
}