mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 16:34:13 +01:00
Use ratbox's match_esc(), this allows \s for space.
This commit is contained in:
parent
61b7e0d959
commit
7eecdd6894
1 changed files with 110 additions and 85 deletions
195
src/match.c
195
src/match.c
|
@ -178,11 +178,14 @@ int mask_match(const char *mask, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MATCH_MAX_CALLS 512 /* ACK! This dies when it's less that this
|
||||||
|
and we have long lines to parse */
|
||||||
/** Check a string against a mask.
|
/** Check a string against a mask.
|
||||||
* This test checks using traditional IRC wildcards only: '*' means
|
* This test checks using extended wildcards: '*' means match zero
|
||||||
* match zero or more characters of any type; '?' means match exactly
|
* or more characters of any type; '?' means match exactly one
|
||||||
* one character of any type; '#' means match exactly one character
|
* character of any type; '#' means match exactly one character that
|
||||||
* that is a number.
|
* is a number; '@' means match exactly one character that is a
|
||||||
|
* letter; '\s' means match a space.
|
||||||
*
|
*
|
||||||
* This function supports escaping, so that a wildcard may be matched
|
* This function supports escaping, so that a wildcard may be matched
|
||||||
* exactly.
|
* exactly.
|
||||||
|
@ -191,96 +194,118 @@ int mask_match(const char *mask, const char *name)
|
||||||
* @param[in] name String to check against \a mask.
|
* @param[in] name String to check against \a mask.
|
||||||
* @return Zero if \a mask matches \a name, non-zero if no match.
|
* @return Zero if \a mask matches \a name, non-zero if no match.
|
||||||
*/
|
*/
|
||||||
int match_esc(const char *mask, const char *name)
|
int
|
||||||
|
match_esc(const char *mask, const char *name)
|
||||||
{
|
{
|
||||||
const char *m = mask, *n = name;
|
const unsigned char *m = (const unsigned char *)mask;
|
||||||
const char *m_tmp = mask, *n_tmp = name;
|
const unsigned char *n = (const unsigned char *)name;
|
||||||
int star_p;
|
const unsigned char *ma = (const unsigned char *)mask;
|
||||||
|
const unsigned char *na = (const unsigned char *)name;
|
||||||
|
int wild = 0;
|
||||||
|
int calls = 0;
|
||||||
|
int quote = 0;
|
||||||
|
int match1 = 0;
|
||||||
|
|
||||||
s_assert(mask != NULL);
|
s_assert(mask != NULL);
|
||||||
s_assert(name != NULL);
|
s_assert(name != NULL);
|
||||||
|
|
||||||
for (;;)
|
if(!mask || !name)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* if the mask is "*", it matches everything */
|
||||||
|
if((*m == '*') && (*(m + 1) == '\0'))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
while(calls++ < MATCH_MAX_CALLS)
|
||||||
{
|
{
|
||||||
switch (*m)
|
if(quote)
|
||||||
|
quote++;
|
||||||
|
if(quote == 3)
|
||||||
|
quote = 0;
|
||||||
|
if(*m == '\\' && !quote)
|
||||||
{
|
{
|
||||||
case '\0':
|
m++;
|
||||||
if (!*n)
|
quote = 1;
|
||||||
return 1;
|
continue;
|
||||||
backtrack:
|
}
|
||||||
if (m_tmp == mask)
|
if(!quote && *m == '*')
|
||||||
return 0;
|
{
|
||||||
m = m_tmp;
|
/*
|
||||||
n = ++n_tmp;
|
* XXX - shouldn't need to spin here, the mask should have been
|
||||||
break;
|
* collapsed before match is called
|
||||||
case '\\':
|
*/
|
||||||
m++;
|
while(*m == '*')
|
||||||
/* allow escaping to force capitalization */
|
m++;
|
||||||
if (*m++ != *n++)
|
|
||||||
goto backtrack;
|
wild = 1;
|
||||||
break;
|
ma = m;
|
||||||
case '*':
|
na = n;
|
||||||
case '?':
|
|
||||||
for (star_p = 0;; m++)
|
if(*m == '\\')
|
||||||
{
|
{
|
||||||
if (*m == '*')
|
m++;
|
||||||
star_p = 1;
|
/* This means it is an invalid mask -A1kmm. */
|
||||||
else if (*m == '?')
|
if(!*m)
|
||||||
{
|
return 0;
|
||||||
if (!*n++)
|
quote++;
|
||||||
goto backtrack;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
break;
|
|
||||||
}
|
if(!*m)
|
||||||
if (star_p)
|
{
|
||||||
{
|
if(!*n)
|
||||||
if (!*m)
|
return 1;
|
||||||
return 1;
|
if(quote)
|
||||||
else if (*m == '\\')
|
return 0;
|
||||||
{
|
for(m--; (m > (const unsigned char *)mask) && (*m == '?'); m--);;
|
||||||
m_tmp = ++m;
|
|
||||||
if (!*m)
|
if(*m == '*' && (m > (const unsigned char *)mask))
|
||||||
return 0;
|
return 1;
|
||||||
for (n_tmp = n; *n && *n != *m; n++);
|
if(!wild)
|
||||||
}
|
return 0;
|
||||||
else if (*m == '#')
|
m = ma;
|
||||||
{
|
n = ++na;
|
||||||
m_tmp = m;
|
}
|
||||||
for (n_tmp = n; *n && !IsDigit(*n); n++);
|
else if(!*n)
|
||||||
}
|
{
|
||||||
else if (*m == '@')
|
/*
|
||||||
{
|
* XXX - shouldn't need to spin here, the mask should have been
|
||||||
m_tmp = m;
|
* collapsed before match is called
|
||||||
for (n_tmp = n; *n && !IsLetter(*n); n++);
|
*/
|
||||||
}
|
if(quote)
|
||||||
else
|
return 0;
|
||||||
{
|
while(*m == '*')
|
||||||
m_tmp = m;
|
m++;
|
||||||
for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++);
|
return (*m == 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* and fall through */
|
if(quote)
|
||||||
default:
|
match1 = *m == 's' ? *n == ' ' : ToLower(*m) == ToLower(*n);
|
||||||
if (!*n)
|
else if(*m == '?')
|
||||||
return (*m != '\0' ? 0 : 1);
|
match1 = 1;
|
||||||
if (*m == '#')
|
else if(*m == '@')
|
||||||
{
|
match1 = IsLetter(*n);
|
||||||
if (!IsDigit(*n))
|
else if(*m == '#')
|
||||||
goto backtrack;
|
match1 = IsDigit(*n);
|
||||||
}
|
else
|
||||||
else if (*m == '@')
|
match1 = ToLower(*m) == ToLower(*n);
|
||||||
{
|
if(match1)
|
||||||
if (!IsLetter(*n))
|
{
|
||||||
goto backtrack;
|
if(*m)
|
||||||
}
|
m++;
|
||||||
else if (ToLower(*m) != ToLower(*n))
|
if(*n)
|
||||||
goto backtrack;
|
n++;
|
||||||
m++;
|
}
|
||||||
n++;
|
else
|
||||||
break;
|
{
|
||||||
|
if(!wild)
|
||||||
|
return 0;
|
||||||
|
m = ma;
|
||||||
|
n = ++na;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int comp_with_mask(void *addr, void *dest, u_int mask)
|
int comp_with_mask(void *addr, void *dest, u_int mask)
|
||||||
|
|
Loading…
Reference in a new issue