[PHP-users 7235] 7234番ML関連のMySQLのC++ソース

Sakamoto php-users@php.gr.jp
Tue, 30 Apr 2002 04:43:53 +0900


坂本です。

7234番ML関連のMySQLのC++ソース です。

/*
** Compare string against string with wildcard
** 0 if matched
** -1 if not matched with wildcard
**  1 if matched with wildcard
*/

#ifdef LIKE_CMP_TOUPPER
#define likeconv(A) (uchar) toupper(A)
#else
#define likeconv(A) (uchar) my_sort_order[(uchar) (A)]
#endif

static int wild_case_compare(const char *str,const char *str_end,
        const char *wildstr,const char *wildend,
        char escape)
{
  int result= -1;    // Not found, using wildcards
#ifdef USE_MB
  bool use_mb_flag=use_mb(default_charset_info);
#endif
  while (wildstr != wildend)
  {
    while (*wildstr != wild_many && *wildstr != wild_one)
    {
      if (*wildstr == escape && wildstr+1 != wildend)
 wildstr++;
#ifdef USE_MB
      int l;
      if (use_mb_flag &&
          (l = my_ismbchar(default_charset_info, wildstr, wildend)))
      {
   if (str+l > str_end || memcmp(str, wildstr, l) != 0)
       return 1;
   str += l;
   wildstr += l;
      }
      else
#endif
      if (str == str_end || likeconv(*wildstr++) != likeconv(*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 == wild_one)
    {
      do
      {
 if (str == str_end)   // Skipp one char if possible
   return (result);
 INC_PTR(str,str_end);
      } while (++wildstr < wildend && *wildstr == wild_one);
      if (wildstr == wildend)
 break;
    }
    if (*wildstr == wild_many)
    {      // Found wild_many
      wildstr++;
      /* Remove any '%' and '_' from the wild search string */
      for ( ; wildstr != wildend ; wildstr++)
      {
 if (*wildstr == wild_many)
   continue;
 if (*wildstr == wild_one)
 {
   if (str == str_end)
     return (-1);
   INC_PTR(str,str_end);
   continue;
 }
 break;     // Not a wild character
      }
      if (wildstr == wildend)
 return(0);    // Ok if wild_many is last
      if (str == str_end)
 return -1;

      uchar cmp;
      if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
 cmp= *++wildstr;
#ifdef USE_MB
      const char* mb = wildstr;
      int mblen;
      LINT_INIT(mblen);
      if (use_mb_flag)
        mblen = my_ismbchar(default_charset_info, wildstr, wildend);
#endif
      INC_PTR(wildstr,wildend);   // This is compared trough cmp
      cmp=likeconv(cmp);   
      do
      {
#ifdef USE_MB
        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(default_charset_info, str, str_end) &&
                     likeconv(*str) == cmp)
            {
              str++;
              break;
            }
            INC_PTR(str, str_end);
          }
 }
        else
        {
#endif /* USE_MB */
          while (str != str_end && likeconv(*str) != cmp)
            str++;
          if (str++ == str_end) return (-1);
#ifdef USE_MB
        }
#endif
 {
   int tmp=wild_case_compare(str,str_end,wildstr,wildend,escape);
   if (tmp <= 0)
     return (tmp);
 }
      } while (str != str_end && wildstr[0] != wild_many);
      return(-1);
    }
  }
  return (str != str_end ? 1 : 0);
}


int wild_case_compare(String &match,String &wild, char escape)
{
  return wild_case_compare(match.ptr(),match.ptr()+match.length(),
      wild.ptr(), wild.ptr()+wild.length(),escape);
}

/*
** The following is used when using LIKE on binary strings
*/

static int wild_compare(const char *str,const char *str_end,
   const char *wildstr,const char *wildend,char escape)
{
  int result= -1;    // Not found, using wildcards
  while (wildstr != wildend)
  {
    while (*wildstr != wild_many && *wildstr != wild_one)
    {
      if (*wildstr == escape && wildstr+1 != wildend)
 wildstr++;
      if (str == str_end || *wildstr++ != *str++)
 return(1);
      if (wildstr == wildend)
 return (str != str_end);  // Match if both are at end
      result=1;     // Found an anchor char
    }
    if (*wildstr == wild_one)
    {
      do
      {
 if (str == str_end)   // Skipp one char if possible
   return (result);
 str++;
      } while (*++wildstr == wild_one && wildstr != wildend);
      if (wildstr == wildend)
 break;
    }
    if (*wildstr == wild_many)
    {      // Found wild_many
      wildstr++;
      /* Remove any '%' and '_' from the wild search string */
      for ( ; wildstr != wildend ; wildstr++)
      {
 if (*wildstr == wild_many)
   continue;
 if (*wildstr == wild_one)
 {
   if (str == str_end)
     return (-1);
   str++;
   continue;
 }
 break;     // Not a wild character
      }
      if (wildstr == wildend)
 return(0);    // Ok if wild_many is last
      if (str == str_end)
 return -1;

      char cmp;
      if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
 cmp= *++wildstr;
      wildstr++;    // This is compared trough cmp
      do
      {
 while (str != str_end && *str != cmp)
   str++;
 if (str++ == str_end) return (-1);
 {
   int tmp=wild_compare(str,str_end,wildstr,wildend,escape);
   if (tmp <= 0)
     return (tmp);
 }
      } while (str != str_end && wildstr[0] != wild_many);
      return(-1);
    }
  }
  return (str != str_end ? 1 : 0);
}


int wild_compare(String &match,String &wild, char escape)
{
  return wild_compare(match.ptr(),match.ptr()+match.length(),
        wild.ptr(), wild.ptr()+wild.length(),escape);
}