mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
New wildcmp() function in CHARSET_INFO structure
This commit is contained in:
@ -138,4 +138,142 @@ int my_strncasecmp_mb(CHARSET_INFO * cs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Compare string against string with wildcard
|
||||
** 0 if matched
|
||||
** -1 if not matched with wildcard
|
||||
** 1 if matched with wildcard
|
||||
*/
|
||||
|
||||
#define INC_PTR(cs,A,B) A+=((use_mb_flag && \
|
||||
my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1)
|
||||
|
||||
#ifdef LIKE_CMP_TOUPPER
|
||||
#define likeconv(s,A) (uchar) my_toupper(s,A)
|
||||
#else
|
||||
#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)]
|
||||
#endif
|
||||
|
||||
int my_wildcmp_mb(CHARSET_INFO *cs,
|
||||
const char *str,const char *str_end,
|
||||
const char *wildstr,const char *wildend,
|
||||
int escape, int w_one, int w_many)
|
||||
{
|
||||
int result= -1; // Not found, using wildcards
|
||||
|
||||
bool use_mb_flag=use_mb(cs);
|
||||
|
||||
while (wildstr != wildend)
|
||||
{
|
||||
while (*wildstr != w_many && *wildstr != w_one)
|
||||
{
|
||||
int l;
|
||||
if (*wildstr == escape && wildstr+1 != wildend)
|
||||
wildstr++;
|
||||
if (use_mb_flag &&
|
||||
(l = my_ismbchar(cs, wildstr, wildend)))
|
||||
{
|
||||
if (str+l > str_end || memcmp(str, wildstr, l) != 0)
|
||||
return 1;
|
||||
str += l;
|
||||
wildstr += l;
|
||||
}
|
||||
else
|
||||
if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
|
||||
return(1); // No match
|
||||
if (wildstr == wildend)
|
||||
return (str != str_end); // Match if both are at end
|
||||
result=1; // Found an anchor char
|
||||
}
|
||||
if (*wildstr == w_one)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (str == str_end) // Skip one char if possible
|
||||
return (result);
|
||||
INC_PTR(cs,str,str_end);
|
||||
} while (++wildstr < wildend && *wildstr == w_one);
|
||||
if (wildstr == wildend)
|
||||
break;
|
||||
}
|
||||
if (*wildstr == w_many)
|
||||
{ // Found w_many
|
||||
uchar cmp;
|
||||
const char* mb = wildstr;
|
||||
int mblen;
|
||||
|
||||
wildstr++;
|
||||
/* Remove any '%' and '_' from the wild search string */
|
||||
for (; wildstr != wildend ; wildstr++)
|
||||
{
|
||||
if (*wildstr == w_many)
|
||||
continue;
|
||||
if (*wildstr == w_one)
|
||||
{
|
||||
if (str == str_end)
|
||||
return (-1);
|
||||
INC_PTR(cs,str,str_end);
|
||||
continue;
|
||||
}
|
||||
break; // Not a wild character
|
||||
}
|
||||
if (wildstr == wildend)
|
||||
return(0); // Ok if w_many is last
|
||||
if (str == str_end)
|
||||
return -1;
|
||||
|
||||
if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
|
||||
cmp= *++wildstr;
|
||||
|
||||
mb=wildstr;
|
||||
LINT_INIT(mblen);
|
||||
if (use_mb_flag)
|
||||
mblen = my_ismbchar(cs, wildstr, wildend);
|
||||
INC_PTR(cs,wildstr,wildend); // This is compared trough cmp
|
||||
cmp=likeconv(cs,cmp);
|
||||
do
|
||||
{
|
||||
if (use_mb_flag)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (str >= str_end)
|
||||
return -1;
|
||||
if (mblen)
|
||||
{
|
||||
if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0)
|
||||
{
|
||||
str += mblen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!my_ismbchar(cs, str, str_end) &&
|
||||
likeconv(cs,*str) == cmp)
|
||||
{
|
||||
str++;
|
||||
break;
|
||||
}
|
||||
INC_PTR(cs,str, str_end);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (str != str_end && likeconv(cs,*str) != cmp)
|
||||
str++;
|
||||
if (str++ == str_end) return (-1);
|
||||
}
|
||||
{
|
||||
int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);
|
||||
if (tmp <= 0)
|
||||
return (tmp);
|
||||
}
|
||||
} while (str != str_end && wildstr[0] != w_many);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
return (str != str_end ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user