diff -rc grep-2.5.4.orig/src/search.c grep-2.5.4/src/search.c
*** grep-2.5.4.orig/src/search.c	2009-01-31 05:39:54.000000000 +0000
--- grep-2.5.4/src/search.c	2009-08-24 01:03:48.000000000 +0000
***************
*** 43,48 ****
--- 43,51 ----
  #ifdef HAVE_LIBPCRE
  # include <pcre.h>
  #endif
+ #ifdef HAVE_LANGINFO_CODESET
+ # include <langinfo.h>
+ #endif
  
  #define NCHAR (UCHAR_MAX + 1)
  
***************
*** 138,159 ****
  /* This function allocate the array which correspond to "buf".
     Then this check multibyte string and mark on the positions which
     are not single byte character nor the first byte of a multibyte
!    character.  Caller must free the array.  */
! static char*
! check_multibyte_string(char const *buf, size_t size)
  {
!   char *mb_properties = xmalloc(size);
!   mbstate_t cur_state;
!   wchar_t wc;
!   int i;
  
!   memset(&cur_state, 0, sizeof(mbstate_t));
!   memset(mb_properties, 0, sizeof(char)*size);
  
!   for (i = 0; i < size ;)
      {
!       size_t mbclen;
!       mbclen = mbrtowc(&wc, buf + i, size - i, &cur_state);
  
        if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
  	{
--- 141,170 ----
  /* This function allocate the array which correspond to "buf".
     Then this check multibyte string and mark on the positions which
     are not single byte character nor the first byte of a multibyte
!    character. */
! static char const*
! check_multibyte_string (char const *buf, char const *beg, char const *end,
! 			char const *buflim, mbstate_t *mbs)
  {
!   char const *p;
  
! #ifdef HAVE_LANGINFO_CODESET
!   if (!strcmp (nl_langinfo (CODESET), "UTF-8"))
!     return end; /* do nothing */
! #endif
! 
!   p = end;
!   while (p > buf && p[-1] != eolbyte)
!     p--;
!   if (p > beg || beg > end)
!     beg = p;
  
!   if (beg[-1] == eolbyte)
!     memset(mbs, 0, sizeof(mbstate_t));
! 
!   while (beg < end)
      {
!       size_t mbclen = mbrlen(beg, buflim - beg, mbs);
  
        if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
  	{
***************
*** 161,179 ****
  	     We treat it as a single byte character.  */
  	  mbclen = 1;
  	}
!       else if (match_icase)
! 	{
! 	  if (iswupper((wint_t)wc))
! 	    {
! 	      wc = towlower((wint_t)wc);
! 	      wcrtomb(buf + i, wc, &cur_state);
! 	    }
! 	}
!       mb_properties[i] = mbclen;
!       i += mbclen;
      }
  
!   return mb_properties;
  }
  #endif /* MBS_SUPPORT */
  
--- 172,181 ----
  	     We treat it as a single byte character.  */
  	  mbclen = 1;
  	}
!       beg += mbclen;
      }
  
!   return beg;
  }
  #endif /* MBS_SUPPORT */
  
***************
*** 270,276 ****
    else
      motif = NULL;
  
!   dfacomp (pattern, size, &dfa, 1);
    kwsmusts ();
  
    if (motif)
--- 272,283 ----
    else
      motif = NULL;
  
! #ifdef MBS_SUPPORT
!   if (MB_CUR_MAX > 1)
!     dfacomp (pattern, size, &dfa, 0);
!   else
! #endif
!     dfacomp (pattern, size, &dfa, 1);
    kwsmusts ();
  
    if (motif)
***************
*** 303,322 ****
    struct kwsmatch kwsm;
    size_t i, ret_val;
  #ifdef MBS_SUPPORT
!   char *mb_properties = NULL;
    if (MB_CUR_MAX > 1)
!     {
!       if (match_icase)
!         {
!           char *case_buf = xmalloc(size);
!           memcpy(case_buf, buf, size);
! 	  if (start_ptr)
! 	    start_ptr = case_buf + (start_ptr - buf);
!           buf = case_buf;
!         }
!       if (kwset)
!         mb_properties = check_multibyte_string(buf, size);
!     }
  #endif /* MBS_SUPPORT */
  
    buflim = buf + size;
--- 310,319 ----
    struct kwsmatch kwsm;
    size_t i, ret_val;
  #ifdef MBS_SUPPORT
!   register char const *mbr = buf;
!   mbstate_t cur_state;
    if (MB_CUR_MAX > 1)
!     memset (&cur_state, 0, sizeof (mbstate_t));
  #endif /* MBS_SUPPORT */
  
    buflim = buf + size;
***************
*** 338,363 ****
  	      end = memchr(beg, eol, buflim - beg);
  	      end++;
  #ifdef MBS_SUPPORT
! 	      if (MB_CUR_MAX > 1 && mb_properties[beg - buf] == 0)
! 		continue;
  #endif
  	      while (beg > buf && beg[-1] != eol)
  		--beg;
  	      if (kwsm.index < kwset_exact_matches)
  		goto success;
! 	      if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
! 		continue;
  	    }
  	  else
  	    {
  	      /* No good fixed strings; start with DFA. */
! 	      size_t offset = dfaexec (&dfa, beg, buflim - beg, &backref);
! 	      if (offset == (size_t) -1)
! 		break;
  	      /* Narrow down to the line we've found. */
  	      beg += offset;
  	      end = memchr (beg, eol, buflim - beg);
  	      end++;
  	      while (beg > buf && beg[-1] != eol)
  		--beg;
  	    }
--- 335,436 ----
  	      end = memchr(beg, eol, buflim - beg);
  	      end++;
  #ifdef MBS_SUPPORT
! 	      if (MB_CUR_MAX > 1)
! 		{
! 		  mbr = check_multibyte_string (buf, mbr, beg, buflim, &cur_state);
! 		  if (mbr > beg)
! 		    {
! 		      end = mbr;
! 		      continue;
! 		    }
! 		}
  #endif
  	      while (beg > buf && beg[-1] != eol)
  		--beg;
  	      if (kwsm.index < kwset_exact_matches)
  		goto success;
! 
! #ifdef MBS_SUPPORT
! 	      if (MB_CUR_MAX > 1)
! 		{
! 		  register char const *try;
! 
! 		  try = mbr = beg;
! 
! 		  while (try < end)
! 		    {
! 		      offset = dfaexec (&dfa, try, end - try, &backref);
! 		      if (offset == (size_t) -1)
! 			{
! 			  try++;
! 			  continue;
! 			}
! 
! 		      mbr = check_multibyte_string (buf, mbr, try, buflim, &cur_state);
! 		      if (mbr <= try)
! 			break;
! 
! 		      try++;
! 		    }
! 
! 		  if (try >= end)
! 		    continue;
! 		}
! 	      else
! #endif
! 		if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
! 		  continue;
  	    }
  	  else
  	    {
  	      /* No good fixed strings; start with DFA. */
! 	      size_t offset;
! #ifdef MBS_SUPPORT
! 	      if (MB_CUR_MAX > 1)
! 		{
! 		  while (beg < buflim)
! 		    {
! 		      mbr = beg;
! 
! 		      offset = dfaexec (&dfa, beg, buflim - beg, &backref);
! 		      if (offset == (size_t) -1)
! 			{
! 			  beg++;
! 			  continue;
! 			}
! 
! 		      mbr = check_multibyte_string (buf, mbr, beg, buflim, &cur_state);
! 		      if (mbr <= beg)
! 			break;
! 
! 		      beg++;
! 		    }
! 
! 		  if (beg >= buflim)
! 		    break;
! 		}
! 	      else
! #endif
! 		{
! 		   offset = dfaexec (&dfa, beg, buflim - beg, &backref);
! 		   if (offset == (size_t) -1)
! 		     break;
! 		}
  	      /* Narrow down to the line we've found. */
  	      beg += offset;
  	      end = memchr (beg, eol, buflim - beg);
  	      end++;
+ #ifdef MBS_SUPPORT
+ 	      if (MB_CUR_MAX > 1)
+ 		{
+ 		  mbr = check_multibyte_string (buf, mbr, beg, buflim, &cur_state);
+ 		  if (mbr > beg)
+ 		    {
+ 		      end = mbr;
+ 		      continue;
+ 		    }
+ 		}
+ #endif
  	      while (beg > buf && beg[-1] != eol)
  		--beg;
  	    }
***************
*** 475,489 ****
    *match_size = len;
    ret_val = beg - buf;
   out:
- #ifdef MBS_SUPPORT
-   if (MB_CUR_MAX > 1)
-     {
-       if (match_icase)
-         free((char*)buf);
-       if (mb_properties)
-         free(mb_properties);
-     }
- #endif /* MBS_SUPPORT */
    return ret_val;
  }
  #endif /* defined(GREP_PROGRAM) || defined(EGREP_PROGRAM) */
--- 548,553 ----
***************
*** 519,537 ****
    struct kwsmatch kwsmatch;
    size_t ret_val;
  #ifdef MBS_SUPPORT
!   char *mb_properties = NULL;
    if (MB_CUR_MAX > 1)
!     {
!       if (match_icase)
!         {
!           char *case_buf = xmalloc(size);
!           memcpy(case_buf, buf, size);
! 	  if (start_ptr)
! 	    start_ptr = case_buf + (start_ptr - buf);
!           buf = case_buf;
!         }
!       mb_properties = check_multibyte_string(buf, size);
!     }
  #endif /* MBS_SUPPORT */
  
    for (beg = start_ptr ? start_ptr : buf; beg <= buf + size; beg++)
--- 583,592 ----
    struct kwsmatch kwsmatch;
    size_t ret_val;
  #ifdef MBS_SUPPORT
!   register char const *mbr = buf;
!   mbstate_t cur_state;
    if (MB_CUR_MAX > 1)
!     memset (&cur_state, 0, sizeof (mbstate_t));
  #endif /* MBS_SUPPORT */
  
    for (beg = start_ptr ? start_ptr : buf; beg <= buf + size; beg++)
***************
*** 539,549 ****
        size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
        if (offset == (size_t) -1)
  	goto failure;
  #ifdef MBS_SUPPORT
!       if (MB_CUR_MAX > 1 && mb_properties[offset+beg-buf] == 0)
! 	continue; /* It is a part of multibyte character.  */
  #endif /* MBS_SUPPORT */
-       beg += offset;
        len = kwsmatch.size[0];
        if (start_ptr && !match_words)
  	goto success_in_beg_and_len;
--- 594,608 ----
        size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
        if (offset == (size_t) -1)
  	goto failure;
+       beg += offset;
  #ifdef MBS_SUPPORT
!       if (MB_CUR_MAX > 1)
! 	{
! 	  mbr = check_multibyte_string (buf, mbr, beg, buf + size, &cur_state);
! 	  if (mbr > beg)
! 	    continue; /* It is a part of multibyte character.  */
! 	}
  #endif /* MBS_SUPPORT */
        len = kwsmatch.size[0];
        if (start_ptr && !match_words)
  	goto success_in_beg_and_len;
***************
*** 591,605 ****
    *match_size = len;
    ret_val = beg - buf;
   out:
- #ifdef MBS_SUPPORT
-   if (MB_CUR_MAX > 1)
-     {
-       if (match_icase)
-         free((char*)buf);
-       if (mb_properties)
-         free(mb_properties);
-     }
- #endif /* MBS_SUPPORT */
    return ret_val;
  }
  #endif /* defined(GREP_PROGRAM) || defined(FGREP_PROGRAM) */
--- 650,655 ----
