static int my_wildcmp_unicode_impl()

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);
}