in mysql_strings/ctype-utf8.cc [4816:4934]
static int my_wildcmp_unicode_impl(const CHARSET_INFO *cs, const char *str,
const char *str_end, const char *wildstr,
const char *wildend, int escape, int w_one,
int w_many, const MY_UNICASE_INFO *weights,
int recurse_level) {
int result = -1; /* Not found, using wildcards */
my_wc_t s_wc, w_wc;
int scan;
int (*mb_wc)(const CHARSET_INFO *, my_wc_t *, const uchar *, const uchar *);
mb_wc = cs->cset->mb_wc;
if (my_string_stack_guard && my_string_stack_guard(recurse_level)) return 1;
while (wildstr != wildend) {
while (true) {
bool escaped = false;
if ((scan = mb_wc(cs, &w_wc, (const uchar *)wildstr,
(const uchar *)wildend)) <= 0)
return 1;
if (w_wc == (my_wc_t)w_many) {
result = 1; /* Found an anchor char */
break;
}
wildstr += scan;
if (w_wc == (my_wc_t)escape && wildstr < wildend) {
if ((scan = mb_wc(cs, &w_wc, (const uchar *)wildstr,
(const uchar *)wildend)) <= 0)
return 1;
wildstr += scan;
escaped = true;
}
if ((scan = mb_wc(cs, &s_wc, (const uchar *)str,
(const uchar *)str_end)) <= 0)
return 1;
str += scan;
if (!escaped && w_wc == (my_wc_t)w_one) {
result = 1; /* Found an anchor char */
} else {
if (weights) {
my_tosort_unicode(weights, &s_wc, cs->state);
my_tosort_unicode(weights, &w_wc, cs->state);
}
if (s_wc != w_wc) return 1; /* No match */
}
if (wildstr == wildend)
return (str != str_end); /* Match if both are at end */
}
if (w_wc == (my_wc_t)w_many) { /* Found w_many */
/* Remove any '%' and '_' from the wild search string */
for (; wildstr != wildend;) {
if ((scan = mb_wc(cs, &w_wc, (const uchar *)wildstr,
(const uchar *)wildend)) <= 0)
return 1;
if (w_wc == (my_wc_t)w_many) {
wildstr += scan;
continue;
}
if (w_wc == (my_wc_t)w_one) {
wildstr += scan;
if ((scan = mb_wc(cs, &s_wc, (const uchar *)str,
(const uchar *)str_end)) <= 0)
return 1;
str += scan;
continue;
}
break; /* Not a wild character */
}
if (wildstr == wildend) return 0; /* Ok if w_many is last */
if (str == str_end) return -1;
if ((scan = mb_wc(cs, &w_wc, (const uchar *)wildstr,
(const uchar *)wildend)) <= 0)
return 1;
wildstr += scan;
if (w_wc == (my_wc_t)escape) {
if (wildstr < wildend) {
if ((scan = mb_wc(cs, &w_wc, (const uchar *)wildstr,
(const uchar *)wildend)) <= 0)
return 1;
wildstr += scan;
}
}
while (true) {
/* Skip until the first character from wildstr is found */
while (str != str_end) {
if ((scan = mb_wc(cs, &s_wc, (const uchar *)str,
(const uchar *)str_end)) <= 0)
return 1;
if (weights) {
my_tosort_unicode(weights, &s_wc, cs->state);
my_tosort_unicode(weights, &w_wc, cs->state);
}
if (s_wc == w_wc) break;
str += scan;
}
if (str == str_end) return -1;
str += scan;
result =
my_wildcmp_unicode_impl(cs, str, str_end, wildstr, wildend, escape,
w_one, w_many, weights, recurse_level + 1);
if (result <= 0) return result;
}
}
}
return (str != str_end ? 1 : 0);
}