*** src/grep.c.orig	2008-02-14 04:03:39.000000000 +0000
--- src/grep.c	2008-07-03 12:46:21.000000000 +0000
***************
*** 937,957 ****
  static void
  prpending (char const *lim)
  {
    if (!lastout)
      lastout = bufbeg;
!   while (pending > 0 && lastout < lim)
      {
!       char const *nl = memchr (lastout, eolbyte, lim - lastout);
        size_t match_size;
        --pending;
        if (outleft
! 	  || ((execute(lastout, nl + 1 - lastout,
  		       &match_size, NULL) == (size_t) -1)
  	      == !out_invert))
! 	prline (lastout, nl + 1, SEP_CHAR_REJECTED);
        else
  	pending = 0;
      }
  }
  
  /* Print the lines between BEG and LIM.  Deal with context crap.
--- 937,984 ----
  static void
  prpending (char const *lim)
  {
+   char *buf;
+   const char *beg, *ibeg;
+ 
    if (!lastout)
      lastout = bufbeg;
! 
!   beg = lastout;
! 
! #ifdef MBS_SUPPORT
!   if (MB_CUR_MAX > 1 && match_icase)
      {
!       char *buf;
!       ibeg = buf = (char *)xmalloc (lim - beg);
!       memcpy (buf, beg, lim - beg);
!     }
!   else
! #endif
!     {
!       buf = NULL;
!       ibeg = beg;
!     }
! 
!   while (pending > 0 && beg < lim)
!     {
!       char const *nl = memchr (ibeg, eolbyte, lim - beg);
        size_t match_size;
        --pending;
        if (outleft
! 	  || ((execute(beg, nl + 1 - beg,
  		       &match_size, NULL) == (size_t) -1)
  	      == !out_invert))
! {
! 	  prline (lastout, nl + 1, SEP_CHAR_REJECTED);
! 	  ibeg += lastout - beg;
! 	  beg = lastout;
! 	}
        else
  	pending = 0;
      }
+ 
+     if (buf)
+       free(buf);
  }
  
  /* Print the lines between BEG and LIM.  Deal with context crap.
***************
*** 1030,1046 ****
  grepbuf (char const *beg, char const *lim)
  {
    int nlines, n;
!   register char const *p;
    size_t match_offset;
    size_t match_size;
  
    nlines = 0;
    p = beg;
!   while ((match_offset = execute(p, lim - p, &match_size,
  				 NULL)) != (size_t) -1)
      {
        char const *b = p + match_offset;
!       char const *endp = b + match_size;
        /* Avoid matching the empty line at the end of the buffer. */
        if (b == lim)
  	break;
--- 1057,1089 ----
  grepbuf (char const *beg, char const *lim)
  {
    int nlines, n;
!   char *buf;
!   register const char *p, *q;
    size_t match_offset;
    size_t match_size;
  
    nlines = 0;
    p = beg;
! 
! #ifdef MBS_SUPPORT
!   if (MB_CUR_MAX > 1 && match_icase)
!     {
!       q = buf = (char *)xmalloc (lim - beg);
!       memcpy (buf, beg, lim - beg);
!     }
!   else
! #endif
!     {
!       buf = NULL;
!       q = beg;
!     }
! 
!   while ((match_offset = execute(q, lim - p, &match_size,
  				 NULL)) != (size_t) -1)
      {
        char const *b = p + match_offset;
!       char const *endp = p + match_offset + match_size;
!       char const *endq = q + match_offset + match_size;
        /* Avoid matching the empty line at the end of the buffer. */
        if (b == lim)
  	break;
***************
*** 1054,1059 ****
--- 1097,1104 ----
  	      if (exit_on_match)
  		exit (0);
  	      after_last_match = bufoffset - (buflim - endp);
+ 	      if (buf)
+ 		free (buf);
  	      return nlines;
  	    }
  	}
***************
*** 1063,1071 ****
  	  nlines += n;
            outleft -= n;
  	  if (!outleft)
! 	    return nlines;
  	}
        p = endp;
      }
    if (out_invert && p < lim)
      {
--- 1108,1121 ----
  	  nlines += n;
            outleft -= n;
  	  if (!outleft)
! 	    {
! 	      if (buf)
! 		free (buf);
! 	      return nlines;
! 	    }
  	}
        p = endp;
+       q = endq;
      }
    if (out_invert && p < lim)
      {
***************
*** 1073,1078 ****
--- 1123,1130 ----
        nlines += n;
        outleft -= n;
      }
+   if (buf)
+     free (buf);
    return nlines;
  }
  
*** src/search.c.orig	2007-06-28 19:10:46.000000000 +0000
--- src/search.c	2008-07-03 12:46:21.000000000 +0000
***************
*** 135,159 ****
  #endif /* !FGREP_PROGRAM */
  
  #ifdef MBS_SUPPORT
! /* 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)
  	{
--- 135,162 ----
  #endif /* !FGREP_PROGRAM */
  
  #ifdef MBS_SUPPORT
! /* This function checks multibyte string and check on the positions
!    which are not single byte character nor the first byte of a
!    multibyte character.  */
! static const char*
! check_multibyte_string(const char *mbr, const char *end, const char *buflim)
  {
    mbstate_t cur_state;
!   char eol = eolbyte;
!   const char *beg;
  
    memset(&cur_state, 0, sizeof(mbstate_t));
  
!   beg = end;
!   while (beg > mbr && beg[-1] != eolbyte)
!     beg--;
!   if (mbr < beg)
!     mbr = beg;
! 
!   while (mbr < end)
      {
        size_t mbclen;
!       mbclen = mbrlen(mbr, buflim - mbr, &cur_state);
  
        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 */
  
--- 164,204 ----
  	     We treat it as a single byte character.  */
  	  mbclen = 1;
  	}
!       mbr += mbclen;
      }
  
!   return mbr;
! }
! 
! /* This function is called to convert the strings "buf" points to lowercase
!    if MB_CUR_MAX is grater than 1 and match_icase is true.  */
! tolower_multibyte_string(char *mbr, const char *buflim)
! {
!   wchar_t wc;
!   mbstate_t cur_state;
! 
!   memset(&cur_state, 0, sizeof(mbstate_t));
! 
!   while (mbr < buflim)
!     {
!       size_t mbclen;
!       mbclen = mbrtowc(&wc, mbr, buflim - mbr, &cur_state);
! 
!       if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
!         {
!           /* An invalid sequence, or a truncated multibyte character.
!              We treat it as a single byte character.  */
!           mbclen = 1;
!         }
!       else if (iswupper((wint_t)wc))
!         {
!           wc = towlower((wint_t)wc);
!           wcrtomb(mbr, wc, &cur_state);
!         }
!       mbr += mbclen;
!     }
! 
!   return;
  }
  #endif /* MBS_SUPPORT */
  
***************
*** 303,345 ****
    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;
  
!   for (beg = end = buf; end < buflim; beg = end)
      {
        if (!start_ptr)
  	{
  	  /* We don't care about an exact match.  */
  	  if (kwset)
  	    {
  	      /* Find a possible match using the KWset matcher. */
! 	      size_t offset = kwsexec (kwset, beg, buflim - beg, &kwsm);
  	      if (offset == (size_t) -1)
! 		goto failure;
  	      beg += offset;
  	      /* Narrow down to the line containing the candidate, and
  		 run it through DFA. */
  	      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;
--- 328,378 ----
    struct kwsmatch kwsm;
    size_t i, ret_val;
  #ifdef MBS_SUPPORT
!   const char *mbr1, *mbr2;
!   mbr1 = mbr2 = buf;
  #endif /* MBS_SUPPORT */
    buflim = buf + size;
  
!   for (beg = end = buf; beg < buflim; beg = end)
      {
        if (!start_ptr)
  	{
  	  /* We don't care about an exact match.  */
  	  if (kwset)
  	    {
+ #ifdef MBS_SUPPORT
+ 	      if (MB_CUR_MAX > 1 && match_icase)
+ 		{
+ 		  end = memchr(beg, eol, buflim - beg);
+ 		  end++;
+ 		  if (mbr1 <= beg)
+ 		    {
+ 		      mbr1 = beg;
+ 		      while (mbr1 > buf && mbr1[-1] != eol)
+ 			mbr1--;
+ 		      tolower_multibyte_string((char *)mbr1, end);
+ 		      mbr1 = end;
+ 		    }
+ 		}
+ 	      else
+ #endif /* MBS_SUPPORT */
+ 		end = buflim;
  	      /* Find a possible match using the KWset matcher. */
! 	      size_t offset = kwsexec (kwset, beg, end - beg, &kwsm);
  	      if (offset == (size_t) -1)
! 		continue;
  	      beg += offset;
  	      /* Narrow down to the line containing the candidate, and
  		 run it through DFA. */
  	      end = memchr(beg, eol, buflim - beg);
  	      end++;
  #ifdef MBS_SUPPORT
! 	      if  (MB_CUR_MAX > 1)
! 		{
! 		  mbr2 = check_multibyte_string(mbr2, beg, buflim);
! 		  if (mbr2 > beg)
! 		    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) */
--- 508,513 ----
***************
*** 513,549 ****
  
  EXECUTE_FCT(Fexecute)
  {
!   register char const *beg, *try, *end;
    register size_t len;
    char eol = eolbyte;
    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++)
      {
!       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;
--- 537,580 ----
  
  EXECUTE_FCT(Fexecute)
  {
!   register char const *buflim, *beg, *try, *end;
    register size_t len;
    char eol = eolbyte;
    struct kwsmatch kwsmatch;
    size_t ret_val;
  #ifdef MBS_SUPPORT
!   const char *mbr1, *mbr2;
!   mbr1 = mbr2 = buf;
  #endif /* MBS_SUPPORT */
+   buflim = buf + size;
  
!   for (beg = start_ptr ? start_ptr : buf; beg <= buflim; beg++)
      {
! #ifdef MBS_SUPPORT
!       if (MB_CUR_MAX > 1 && match_icase)
! 	{
! 	  if (mbr1 <= beg)
! 	    {
! 	      mbr1 = beg;
! 	      while (mbr1 > buf && mbr1[-1] != eol)
! 	        mbr1--;
! 	      tolower_multibyte_string((char *)mbr1, buflim);
! 	      mbr1 = buflim;
! 	    }
! 	}
! #endif /* MBS_SUPPORT */
!       size_t offset = kwsexec (kwset, beg, buflim - beg, &kwsmatch);
        if (offset == (size_t) -1)
  	goto failure;
+       beg += offset;
  #ifdef MBS_SUPPORT
!       if (MB_CUR_MAX > 1)
! 	{
! 	  mbr2 = check_multibyte_string(mbr2, beg, buflim);
! 	  if (mbr2 > 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;
***************
*** 551,557 ****
  	{
  	  if (beg > buf && beg[-1] != eol)
  	    continue;
! 	  if (beg + len < buf + size && beg[len] != eol)
  	    continue;
  	  goto success;
  	}
--- 582,588 ----
  	{
  	  if (beg > buf && beg[-1] != eol)
  	    continue;
! 	  if (beg + len < buflim && beg[len] != eol)
  	    continue;
  	  goto success;
  	}
***************
*** 560,566 ****
  	  {
  	    if (try > buf && WCHAR((unsigned char) try[-1]))
  	      break;
! 	    if (try + len < buf + size && WCHAR((unsigned char) try[len]))
  	      {
  		offset = kwsexec (kwset, beg, --len, &kwsmatch);
  		if (offset == (size_t) -1)
--- 591,597 ----
  	  {
  	    if (try > buf && WCHAR((unsigned char) try[-1]))
  	      break;
! 	    if (try + len < buflim && WCHAR((unsigned char) try[len]))
  	      {
  		offset = kwsexec (kwset, beg, --len, &kwsmatch);
  		if (offset == (size_t) -1)
***************
*** 582,588 ****
    goto out;
  
   success:
!   end = memchr (beg + len, eol, (buf + size) - (beg + len));
    end++;
    while (buf < beg && beg[-1] != eol)
      --beg;
--- 613,619 ----
    goto out;
  
   success:
!   end = memchr (beg + len, eol, (buflim) - (beg + len));
    end++;
    while (buf < beg && beg[-1] != eol)
      --beg;
***************
*** 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) */
--- 622,627 ----
