All of lore.kernel.org
 help / color / mirror / Atom feed
From: Saul Wold <sgw@linux.intel.com>
To: Li Zhijian <lizhijian@cn.fujitsu.com>
Cc: openembedded-core@lists.openembedded.org
Subject: Re: [PATCH] grep-2.5.1a: fix grep for LSB compliance
Date: Mon, 26 Aug 2013 18:00:26 -0700	[thread overview]
Message-ID: <521BFA2A.4090508@linux.intel.com> (raw)
In-Reply-To: <1377596639-26980-1-git-send-email-lizhijian@cn.fujitsu.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=windows-1252; format=flowed, Size: 67391 bytes --]

On 08/27/2013 02:43 AM, Li Zhijian wrote:
> add patch from grep-2.5.1-55.el5.src.rpm and
> enable configration option of --without-include-regex
>
> LSB core-tests failed at /tset/LI18NUX2K.L1/utils/grep-tp/T.grep-tp 5,T.egrep-tp 5
> which is intend to verify this utility can perform pattern matching in searches
> without regard to case if -i option is specified.
>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> ---
>   .../grep/grep-2.5.1a/grep-2.5-i18n.patch           |  303 +++++++
>   .../grep/grep-2.5.1a/grep-2.5.1-bracket.patch      |   11 +
>   .../grep/grep-2.5.1a/grep-2.5.1-color.patch        |   10 +
>   .../grep/grep-2.5.1a/grep-2.5.1-dfa-optional.patch |   67 ++
>   .../grep/grep-2.5.1a/grep-2.5.1-egf-speedup.patch  |  823 ++++++++++++++++++++
>   .../grep/grep-2.5.1a/grep-2.5.1-fgrep.patch        |  145 ++++
>   .../grep/grep-2.5.1a/grep-2.5.1-icolor.patch       |   36 +
>   .../grep/grep-2.5.1a/grep-2.5.1-manpage.patch      |   19 +
>   .../grep/grep-2.5.1a/grep-2.5.1-oi.patch           |   48 ++
>   .../grep/grep-2.5.1a/grep-2.5.1-tests.patch        |  138 ++++
>   .../grep/grep-2.5.1a/grep-2.5.1-w.patch            |  121 +++
>   .../recipes-extended/grep/grep-2.5.1a/grep-P.patch |   14 +
>   .../grep/grep-2.5.1a/grep-bz434934.patch           |   17 +
>   .../grep/grep-2.5.1a/grep-bz460641.patch           |   11 +
>   .../grep/grep-2.5.1a/grep-empty-pattern.patch      |   36 +
>   .../grep/grep-2.5.1a/grep-man-label.patch          |   22 +
>   .../grep/grep-2.5.1a/grep-skip.patch               |   42 +
>   meta/recipes-extended/grep/grep_2.5.1a.bb          |   23 +-
>   18 files changed, 1883 insertions(+), 3 deletions(-)
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5-i18n.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-bracket.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-color.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-dfa-optional.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-egf-speedup.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-fgrep.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-icolor.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-manpage.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-oi.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-tests.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-w.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-P.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-bz434934.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-bz460641.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-empty-pattern.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-man-label.patch
>   create mode 100644 meta/recipes-extended/grep/grep-2.5.1a/grep-skip.patch
>
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5-i18n.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5-i18n.patch
> new file mode 100644
> index 0000000..8dc3dfe
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5-i18n.patch
> @@ -0,0 +1,303 @@
> +--- grep-2.5.1/src/dfa.c	2004-02-26 13:09:54.000000000 +0000
> ++++ grep-2.5.1/src/dfa.c	2004-05-18 16:43:31.189200479 +0100
> +@@ -414,7 +414,7 @@
> +
> + /* This function fetch a wide character, and update cur_mb_len,
> +    used only if the current locale is a multibyte environment.  */
> +-static wchar_t
> ++static wint_t
> + fetch_wc (char const *eoferr)
> + {
> +   wchar_t wc;
> +@@ -423,7 +423,7 @@
> +       if (eoferr != 0)
> + 	dfaerror (eoferr);
> +       else
> +-	return -1;
> ++	return WEOF;
> +     }
> +
> +   cur_mb_len = mbrtowc(&wc, lexptr, lexleft, &mbs);
> +@@ -459,7 +459,7 @@
> + static void
> + parse_bracket_exp_mb ()
> + {
> +-  wchar_t wc, wc1, wc2;
> ++  wint_t wc, wc1, wc2;
> +
> +   /* Work area to build a mb_char_classes.  */
> +   struct mb_char_classes *work_mbc;
> +@@ -496,7 +496,7 @@
> +     work_mbc->invert = 0;
> +   do
> +     {
> +-      wc1 = -1; /* mark wc1 is not initialized".  */
> ++      wc1 = WEOF; /* mark wc1 is not initialized".  */
> +
> +       /* Note that if we're looking at some other [:...:] construct,
> + 	 we just treat it as a bunch of ordinary characters.  We can do
> +@@ -586,7 +586,7 @@
> + 		      work_mbc->coll_elems[work_mbc->ncoll_elems++] = elem;
> + 		    }
> +  		}
> +-	      wc1 = wc = -1;
> ++	      wc1 = wc = WEOF;
> + 	    }
> + 	  else
> + 	    /* We treat '[' as a normal character here.  */
> +@@ -600,7 +600,7 @@
> + 	    wc = fetch_wc(("Unbalanced ["));
> + 	}
> +
> +-      if (wc1 == -1)
> ++      if (wc1 == WEOF)
> + 	wc1 = fetch_wc(_("Unbalanced ["));
> +
> +       if (wc1 == L'-')
> +@@ -630,17 +630,17 @@
> + 	    }
> + 	  REALLOC_IF_NECESSARY(work_mbc->range_sts, wchar_t,
> + 			       range_sts_al, work_mbc->nranges + 1);
> +-	  work_mbc->range_sts[work_mbc->nranges] = wc;
> ++	  work_mbc->range_sts[work_mbc->nranges] = (wchar_t)wc;
> + 	  REALLOC_IF_NECESSARY(work_mbc->range_ends, wchar_t,
> + 			       range_ends_al, work_mbc->nranges + 1);
> +-	  work_mbc->range_ends[work_mbc->nranges++] = wc2;
> ++	  work_mbc->range_ends[work_mbc->nranges++] = (wchar_t)wc2;
> + 	}
> +-      else if (wc != -1)
> ++      else if (wc != WEOF)
> + 	/* build normal characters.  */
> + 	{
> + 	  REALLOC_IF_NECESSARY(work_mbc->chars, wchar_t, chars_al,
> + 			       work_mbc->nchars + 1);
> +-	  work_mbc->chars[work_mbc->nchars++] = wc;
> ++	  work_mbc->chars[work_mbc->nchars++] = (wchar_t)wc;
> + 	}
> +     }
> +   while ((wc = wc1) != L']');
> +@@ -2552,6 +2552,8 @@
> +     }
> +
> +   /* match with a character?  */
> ++  if (case_fold)
> ++    wc = towlower (wc);
> +   for (i = 0; i<work_mbc->nchars; i++)
> +     {
> +       if (wc == work_mbc->chars[i])
> +--- grep-2.5.1/src/grep.c.i18n	2002-03-26 15:54:12.000000000 +0000
> ++++ grep-2.5.1/src/grep.c	2004-02-26 13:09:54.000000000 +0000
> +@@ -30,6 +30,12 @@
> + # include <sys/time.h>
> + # include <sys/resource.h>
> + #endif
> ++#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC
> ++/* We can handle multibyte string.  */
> ++# define MBS_SUPPORT
> ++# include <wchar.h>
> ++# include <wctype.h>
> ++#endif
> + #include <stdio.h>
> + #include "system.h"
> + #include "getopt.h"
> +@@ -1697,6 +1703,37 @@
> +   if (!install_matcher (matcher) && !install_matcher ("default"))
> +     abort ();
> +
> ++#ifdef MBS_SUPPORT
> ++  if (MB_CUR_MAX != 1 && match_icase)
> ++    {
> ++      wchar_t wc;
> ++      mbstate_t cur_state, prev_state;
> ++      int i, len = strlen(keys);
> ++
> ++      memset(&cur_state, 0, sizeof(mbstate_t));
> ++      for (i = 0; i <= len ;)
> ++	{
> ++	  size_t mbclen;
> ++	  mbclen = mbrtowc(&wc, keys + i, len - i, &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 singlebyte character.  */
> ++	      mbclen = 1;
> ++	    }
> ++	  else
> ++	    {
> ++	      if (iswupper((wint_t)wc))
> ++		{
> ++		  wc = towlower((wint_t)wc);
> ++		  wcrtomb(keys + i, wc, &cur_state);
> ++		}
> ++	    }
> ++	  i += mbclen;
> ++	}
> ++    }
> ++#endif /* MBS_SUPPORT */
> ++
> +   (*compile)(keys, keycc);
> +
> +   if ((argc - optind > 1 && !no_filenames) || with_filenames)
> +--- grep-2.5.1/src/search.c.i18n	2004-02-26 13:09:54.000000000 +0000
> ++++ grep-2.5.1/src/search.c	2004-02-26 13:17:12.000000000 +0000
> +@@ -149,15 +149,16 @@
> + static char*
> + check_multibyte_string(char const *buf, size_t size)
> + {
> +-  char *mb_properties = malloc(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 = mbrlen(buf + i, size - i, &cur_state);
> ++      mbclen = mbrtowc(&wc, buf + i, size - i, &cur_state);
> +
> +       if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
> + 	{
> +@@ -165,6 +166,14 @@
> + 	     We treat it as a singlebyte 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;
> +     }
> +@@ -233,7 +242,7 @@
> +       static char const line_end[] = "\\)$";
> +       static char const word_beg[] = "\\(^\\|[^[:alnum:]_]\\)\\(";
> +       static char const word_end[] = "\\)\\([^[:alnum:]_]\\|$\\)";
> +-      char *n = malloc (sizeof word_beg - 1 + size + sizeof word_end);
> ++      char *n = xmalloc (sizeof word_beg - 1 + size + sizeof word_end);
> +       size_t i;
> +       strcpy (n, match_lines ? line_beg : word_beg);
> +       i = strlen (n);
> +@@ -316,7 +325,7 @@
> +       static char const line_end[] = ")$";
> +       static char const word_beg[] = "(^|[^[:alnum:]_])(";
> +       static char const word_end[] = ")([^[:alnum:]_]|$)";
> +-      char *n = malloc (sizeof word_beg - 1 + size + sizeof word_end);
> ++      char *n = xmalloc (sizeof word_beg - 1 + size + sizeof word_end);
> +       size_t i;
> +       strcpy (n, match_lines ? line_beg : word_beg);
> +       i = strlen(n);
> +@@ -339,14 +348,20 @@
> +   char eol = eolbyte;
> +   int backref, start, len;
> +   struct kwsmatch kwsm;
> +-  size_t i;
> ++  size_t i, ret_val;
> + #ifdef MBS_SUPPORT
> +   char *mb_properties = NULL;
> +-#endif /* MBS_SUPPORT */
> +-
> +-#ifdef MBS_SUPPORT
> +-  if (MB_CUR_MAX > 1 && kwset)
> +-    mb_properties = check_multibyte_string(buf, size);
> ++  if (MB_CUR_MAX > 1)
> ++    {
> ++      if (match_icase)
> ++        {
> ++          char *case_buf = xmalloc(size);
> ++          memcpy(case_buf, buf, size);
> ++          buf = case_buf;
> ++        }
> ++      if (kwset)
> ++        mb_properties = check_multibyte_string(buf, size);
> ++    }
> + #endif /* MBS_SUPPORT */
> +
> +   buflim = buf + size;
> +@@ -455,8 +470,13 @@
> +
> +  failure:
> + #ifdef MBS_SUPPORT
> +-  if (MB_CUR_MAX > 1 && mb_properties)
> +-    free (mb_properties);
> ++  if (MB_CUR_MAX > 1)
> ++    {
> ++      if (mb_properties)
> ++	free (mb_properties);
> ++      if (match_icase)
> ++	free ((char *) buf);
> ++    }
> + #endif /* MBS_SUPPORT */
> +   return (size_t) -1;
> +
> +@@ -467,8 +487,13 @@
> +
> +  success_in_start_and_len:
> + #ifdef MBS_SUPPORT
> +-  if (MB_CUR_MAX > 1 && mb_properties)
> +-    free (mb_properties);
> ++  if (MB_CUR_MAX > 1)
> ++    {
> ++      if (mb_properties)
> ++	free (mb_properties);
> ++      if (match_icase)
> ++	free ((char *) buf);
> ++    }
> + #endif /* MBS_SUPPORT */
> +   *match_size = len;
> +   return start;
> +@@ -504,10 +529,19 @@
> +   register size_t len;
> +   char eol = eolbyte;
> +   struct kwsmatch kwsmatch;
> ++  size_t ret_val;
> + #ifdef MBS_SUPPORT
> +-  char *mb_properties;
> ++  char *mb_properties = NULL;
> +   if (MB_CUR_MAX > 1)
> +-    mb_properties = check_multibyte_string (buf, size);
> ++    {
> ++      if (match_icase)
> ++        {
> ++          char *case_buf = xmalloc(size);
> ++          memcpy(case_buf, buf, size);
> ++          buf = case_buf;
> ++        }
> ++      mb_properties = check_multibyte_string(buf, size);
> ++    }
> + #endif /* MBS_SUPPORT */
> +
> +   for (beg = buf; beg <= buf + size; ++beg)
> +@@ -565,7 +599,12 @@
> +  failure:
> + #ifdef MBS_SUPPORT
> +   if (MB_CUR_MAX > 1)
> +-    free (mb_properties);
> ++    {
> ++      if (match_icase)
> ++        free((char *) buf);
> ++      if (mb_properties)
> ++        free(mb_properties);
> ++    }
> + #endif /* MBS_SUPPORT */
> +   return -1;
> +
> +@@ -581,7 +620,12 @@
> +   *match_size = len;
> + #ifdef MBS_SUPPORT
> +   if (MB_CUR_MAX > 1)
> +-    free (mb_properties);
> ++    {
> ++      if (mb_properties)
> ++	free (mb_properties);
> ++      if (match_icase)
> ++	free ((char *) buf);
> ++    }
> + #endif /* MBS_SUPPORT */
> +   return beg - buf;
> + }
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-bracket.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-bracket.patch
> new file mode 100644
> index 0000000..f99571c
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-bracket.patch
> @@ -0,0 +1,11 @@
> +--- grep-2.5.1/src/dfa.c.bracket	2003-10-30 16:21:14.000000000 +0000
> ++++ grep-2.5.1/src/dfa.c	2003-10-30 16:22:38.000000000 +0000
> +@@ -586,7 +586,7 @@
> + 		      work_mbc->coll_elems[work_mbc->ncoll_elems++] = elem;
> + 		    }
> +  		}
> +-	      wc = -1;
> ++	      wc1 = wc = -1;
> + 	    }
> + 	  else
> + 	    /* We treat '[' as a normal character here.  */
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-color.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-color.patch
> new file mode 100644
> index 0000000..f54c258
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-color.patch
> @@ -0,0 +1,10 @@
> +--- grep-2.5.1/src/grep.c.color	2004-11-16 16:46:22.845505847 +0000
> ++++ grep-2.5.1/src/grep.c	2004-11-16 16:46:27.961530537 +0000
> +@@ -607,6 +607,7 @@
> + 	  fputs ("\33[00m", stdout);
> + 	  beg = b + match_size;
> + 	}
> ++      fputs ("\33[K", stdout);
> +     }
> +   fwrite (beg, 1, lim - beg, stdout);
> +   if (ferror (stdout))
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-dfa-optional.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-dfa-optional.patch
> new file mode 100644
> index 0000000..784eba9
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-dfa-optional.patch
> @@ -0,0 +1,67 @@
> +--- grep-2.5.1a/src/search.c.dfa-optional	2005-01-07 14:58:45.714869815 +0000
> ++++ grep-2.5.1a/src/search.c	2005-01-07 14:58:45.725867716 +0000
> +@@ -327,12 +327,34 @@
> +   int backref, start, len;
> +   struct kwsmatch kwsm;
> +   size_t i, ret_val;
> ++  static int use_dfa;
> ++  static int use_dfa_checked = 0;
> + #ifdef MBS_SUPPORT
> +   int mb_cur_max = MB_CUR_MAX;
> +   mbstate_t mbs;
> +   memset (&mbs, '\0', sizeof (mbstate_t));
> + #endif /* MBS_SUPPORT */
> +
> ++  if (!use_dfa_checked)
> ++    {
> ++      char *grep_use_dfa = getenv ("GREP_USE_DFA");
> ++      if (!grep_use_dfa)
> ++	{
> ++#ifdef MBS_SUPPORT
> ++	  /* Turn off DFA when processing multibyte input. */
> ++	  use_dfa = (MB_CUR_MAX == 1);
> ++#else
> ++	  use_dfa = 1;
> ++#endif /* MBS_SUPPORT */
> ++	}
> ++      else
> ++	{
> ++	  use_dfa = atoi (grep_use_dfa);
> ++	}
> ++
> ++      use_dfa_checked = 1;
> ++    }
> ++
> +   buflim = buf + size;
> +
> +   for (beg = end = buf; end < buflim; beg = end)
> +@@ -400,7 +422,8 @@
> + #endif /* MBS_SUPPORT */
> + 		  (kwsm.index < kwset_exact_matches))
> + 		goto success_in_beg_and_end;
> +-	      if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
> ++	      if (use_dfa &&
> ++		  dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
> + 		continue;
> + 	    }
> + 	  else
> +@@ -409,7 +432,9 @@
> + #ifdef MBS_SUPPORT
> + 	      size_t bytes_left = 0;
> + #endif /* MBS_SUPPORT */
> +-	      size_t offset = dfaexec (&dfa, beg, buflim - beg, &backref);
> ++	      size_t offset = 0;
> ++	      if (use_dfa)
> ++		offset = dfaexec (&dfa, beg, buflim - beg, &backref);
> + 	      if (offset == (size_t) -1)
> + 		break;
> + 	      /* Narrow down to the line we've found. */
> +@@ -451,7 +476,7 @@
> + 		--beg;
> + 	    }
> + 	  /* Successful, no backreferences encountered! */
> +-	  if (!backref)
> ++	  if (use_dfa && !backref)
> + 	    goto success_in_beg_and_end;
> + 	}
> +       else
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-egf-speedup.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-egf-speedup.patch
> new file mode 100644
> index 0000000..08e92c7
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-egf-speedup.patch
> @@ -0,0 +1,823 @@
> +--- grep-2.5.1/src/search.c	2004-12-31 15:28:35.720391036 +0000
> ++++ grep-2.5.1a/src/search.c	2005-01-07 14:53:10.308860193 +0000
> +@@ -18,9 +18,13 @@
> +
> + /* Written August 1992 by Mike Haertel. */
> +
> ++#ifndef _GNU_SOURCE
> ++# define _GNU_SOURCE 1
> ++#endif
> + #ifdef HAVE_CONFIG_H
> + # include <config.h>
> + #endif
> ++#include <assert.h>
> + #include <sys/types.h>
> + #if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC
> + /* We can handle multibyte string.  */
> +@@ -39,6 +43,9 @@
> + #ifdef HAVE_LIBPCRE
> + # include <pcre.h>
> + #endif
> ++#ifdef HAVE_LANGINFO_CODESET
> ++# include <langinfo.h>
> ++#endif
> +
> + #define NCHAR (UCHAR_MAX + 1)
> +
> +@@ -70,9 +77,10 @@
> +    call the regexp matcher at all. */
> + static int kwset_exact_matches;
> +
> +-#if defined(MBS_SUPPORT)
> +-static char* check_multibyte_string PARAMS ((char const *buf, size_t size));
> +-#endif
> ++/* UTF-8 encoding allows some optimizations that we can't otherwise
> ++   assume in a multibyte encoding. */
> ++static int using_utf8;
> ++
> + static void kwsinit PARAMS ((void));
> + static void kwsmusts PARAMS ((void));
> + static void Gcompile PARAMS ((char const *, size_t));
> +@@ -84,6 +92,15 @@
> + static size_t Pexecute PARAMS ((char const *, size_t, size_t *, int));
> +
> + void
> ++check_utf8 (void)
> ++{
> ++#ifdef HAVE_LANGINFO_CODESET
> ++  if (strcmp (nl_langinfo (CODESET), "UTF-8") == 0)
> ++    using_utf8 = 1;
> ++#endif
> ++}
> ++
> ++void
> + dfaerror (char const *mesg)
> + {
> +   error (2, 0, mesg);
> +@@ -141,47 +158,6 @@
> +     }
> + }
> +
> +-#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 singlebyte 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)
> +-	{
> +-	  /* An invalid sequence, or a truncated multibyte character.
> +-	     We treat it as a singlebyte 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
> +-
> + static void
> + Gcompile (char const *pattern, size_t size)
> + {
> +@@ -190,6 +166,7 @@
> +   size_t total = size;
> +   char const *motif = pattern;
> +
> ++  check_utf8 ();
> +   re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE | (match_icase ? RE_ICASE : 0));
> +   dfasyntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE, match_icase, eolbyte);
> +
> +@@ -266,6 +243,7 @@
> +   size_t total = size;
> +   char const *motif = pattern;
> +
> ++  check_utf8 ();
> +   if (strcmp (matcher, "awk") == 0)
> +     {
> +       re_set_syntax (RE_SYNTAX_AWK | (match_icase ? RE_ICASE : 0));
> +@@ -350,18 +328,9 @@
> +   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);
> +-          buf = case_buf;
> +-        }
> +-      if (kwset)
> +-        mb_properties = check_multibyte_string(buf, size);
> +-    }
> ++  int mb_cur_max = MB_CUR_MAX;
> ++  mbstate_t mbs;
> ++  memset (&mbs, '\0', sizeof (mbstate_t));
> + #endif /* MBS_SUPPORT */
> +
> +   buflim = buf + size;
> +@@ -373,21 +342,63 @@
> + 	  if (kwset)
> + 	    {
> + 	      /* Find a possible match using the KWset matcher. */
> +-	      size_t offset = kwsexec (kwset, beg, buflim - beg, &kwsm);
> ++#ifdef MBS_SUPPORT
> ++	      size_t bytes_left = 0;
> ++#endif /* MBS_SUPPORT */
> ++	      size_t offset;
> ++#ifdef MBS_SUPPORT
> ++	      /* kwsexec doesn't work with match_icase and multibyte input. */
> ++	      if (match_icase && mb_cur_max > 1)
> ++		/* Avoid kwset */
> ++		offset = 0;
> ++	      else
> ++#endif /* MBS_SUPPORT */
> ++	      offset = kwsexec (kwset, beg, buflim - beg, &kwsm);
> + 	      if (offset == (size_t) -1)
> + 	        goto failure;
> ++#ifdef MBS_SUPPORT
> ++	      if (mb_cur_max > 1 && !using_utf8)
> ++		{
> ++		  bytes_left = offset;
> ++		  while (bytes_left)
> ++		    {
> ++		      size_t mlen = mbrlen (beg, bytes_left, &mbs);
> ++		      if (mlen == (size_t) -1 || mlen == 0)
> ++			{
> ++			  /* Incomplete character: treat as single-byte. */
> ++			  memset (&mbs, '\0', sizeof (mbstate_t));
> ++			  beg++;
> ++			  bytes_left--;
> ++			  continue;
> ++			}
> ++
> ++		      if (mlen == (size_t) -2)
> ++			/* Offset points inside multibyte character:
> ++			 * no good. */
> ++			break;
> ++
> ++		      beg += mlen;
> ++		      bytes_left -= mlen;
> ++		    }
> ++		}
> ++	      else
> ++#endif /* MBS_SUPPORT */
> + 	      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)
> ++	      if (mb_cur_max > 1 && bytes_left)
> + 		continue;
> +-#endif
> ++#endif /* MBS_SUPPORT */
> + 	      while (beg > buf && beg[-1] != eol)
> + 		--beg;
> +-	      if (kwsm.index < kwset_exact_matches)
> ++	      if (
> ++#ifdef MBS_SUPPORT
> ++		  !(match_icase && mb_cur_max > 1) &&
> ++#endif /* MBS_SUPPORT */
> ++		  (kwsm.index < kwset_exact_matches))
> + 		goto success_in_beg_and_end;
> + 	      if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
> + 		continue;
> +@@ -395,13 +406,47 @@
> + 	  else
> + 	    {
> + 	      /* No good fixed strings; start with DFA. */
> ++#ifdef MBS_SUPPORT
> ++	      size_t bytes_left = 0;
> ++#endif /* MBS_SUPPORT */
> + 	      size_t offset = dfaexec (&dfa, beg, buflim - beg, &backref);
> + 	      if (offset == (size_t) -1)
> + 		break;
> + 	      /* Narrow down to the line we've found. */
> ++#ifdef MBS_SUPPORT
> ++	      if (mb_cur_max > 1 && !using_utf8)
> ++		{
> ++		  bytes_left = offset;
> ++		  while (bytes_left)
> ++		    {
> ++		      size_t mlen = mbrlen (beg, bytes_left, &mbs);
> ++		      if (mlen == (size_t) -1 || mlen == 0)
> ++			{
> ++			  /* Incomplete character: treat as single-byte. */
> ++			  memset (&mbs, '\0', sizeof (mbstate_t));
> ++			  beg++;
> ++			  bytes_left--;
> ++			  continue;
> ++			}
> ++
> ++		      if (mlen == (size_t) -2)
> ++			/* Offset points inside multibyte character:
> ++			 * no good. */
> ++			break;
> ++
> ++		      beg += mlen;
> ++		      bytes_left -= mlen;
> ++		    }
> ++		}
> ++	      else
> ++#endif /* MBS_SUPPORT */
> + 	      beg += offset;
> + 	      end = memchr (beg, eol, buflim - beg);
> + 	      end++;
> ++#ifdef MBS_SUPPORT
> ++	      if (mb_cur_max > 1 && bytes_left)
> ++		continue;
> ++#endif /* MBS_SUPPORT */
> + 	      while (beg > buf && beg[-1] != eol)
> + 		--beg;
> + 	    }
> +@@ -469,15 +514,6 @@
> +     } /* for (beg = end ..) */
> +
> +  failure:
> +-#ifdef MBS_SUPPORT
> +-  if (MB_CUR_MAX > 1)
> +-    {
> +-      if (mb_properties)
> +-	free (mb_properties);
> +-      if (match_icase)
> +-	free ((char *) buf);
> +-    }
> +-#endif /* MBS_SUPPORT */
> +   return (size_t) -1;
> +
> +  success_in_beg_and_end:
> +@@ -486,24 +522,144 @@
> +   /* FALLTHROUGH */
> +
> +  success_in_start_and_len:
> +-#ifdef MBS_SUPPORT
> +-  if (MB_CUR_MAX > 1)
> +-    {
> +-      if (mb_properties)
> +-	free (mb_properties);
> +-      if (match_icase)
> +-	free ((char *) buf);
> +-    }
> +-#endif /* MBS_SUPPORT */
> +   *match_size = len;
> +   return start;
> + }
> +
> ++#ifdef MBS_SUPPORT
> ++static int f_i_multibyte; /* whether we're using the new -Fi MB method */
> ++static struct
> ++{
> ++  wchar_t **patterns;
> ++  size_t count, maxlen;
> ++  unsigned char *match;
> ++} Fimb;
> ++#endif
> ++
> + static void
> + Fcompile (char const *pattern, size_t size)
> + {
> ++  int mb_cur_max = MB_CUR_MAX;
> +   char const *beg, *lim, *err;
> +
> ++  check_utf8 ();
> ++#ifdef MBS_SUPPORT
> ++  /* Support -F -i for UTF-8 input. */
> ++  if (match_icase && mb_cur_max > 1)
> ++    {
> ++      mbstate_t mbs;
> ++      wchar_t *wcpattern = xmalloc ((size + 1) * sizeof (wchar_t));
> ++      const char *patternend = pattern;
> ++      size_t wcsize;
> ++      kwset_t fimb_kwset = NULL;
> ++      char *starts = NULL;
> ++      wchar_t *wcbeg, *wclim;
> ++      size_t allocated = 0;
> ++
> ++      memset (&mbs, '\0', sizeof (mbs));
> ++# ifdef __GNU_LIBRARY__
> ++      wcsize = mbsnrtowcs (wcpattern, &patternend, size, size, &mbs);
> ++      if (patternend != pattern + size)
> ++	wcsize = (size_t) -1;
> ++# else
> ++      {
> ++	char *patterncopy = xmalloc (size + 1);
> ++
> ++	memcpy (patterncopy, pattern, size);
> ++	patterncopy[size] = '\0';
> ++	patternend = patterncopy;
> ++	wcsize = mbsrtowcs (wcpattern, &patternend, size, &mbs);
> ++	if (patternend != patterncopy + size)
> ++	  wcsize = (size_t) -1;
> ++	free (patterncopy);
> ++      }
> ++# endif
> ++      if (wcsize + 2 <= 2)
> ++	{
> ++fimb_fail:
> ++	  free (wcpattern);
> ++	  free (starts);
> ++	  if (fimb_kwset)
> ++	    kwsfree (fimb_kwset);
> ++	  free (Fimb.patterns);
> ++	  Fimb.patterns = NULL;
> ++	}
> ++      else
> ++	{
> ++	  if (!(fimb_kwset = kwsalloc (NULL)))
> ++	    error (2, 0, _("memory exhausted"));
> ++
> ++	  starts = xmalloc (mb_cur_max * 3);
> ++	  wcbeg = wcpattern;
> ++	  do
> ++	    {
> ++	      int i;
> ++	      size_t wclen;
> ++
> ++	      if (Fimb.count >= allocated)
> ++		{
> ++		  if (allocated == 0)
> ++		    allocated = 128;
> ++		  else
> ++		    allocated *= 2;
> ++		  Fimb.patterns = xrealloc (Fimb.patterns,
> ++					    sizeof (wchar_t *) * allocated);
> ++		}
> ++	      Fimb.patterns[Fimb.count++] = wcbeg;
> ++	      for (wclim = wcbeg;
> ++		   wclim < wcpattern + wcsize && *wclim != L'\n'; ++wclim)
> ++		*wclim = towlower (*wclim);
> ++	      *wclim = L'\0';
> ++	      wclen = wclim - wcbeg;
> ++	      if (wclen > Fimb.maxlen)
> ++		Fimb.maxlen = wclen;
> ++	      if (wclen > 3)
> ++		wclen = 3;
> ++	      if (wclen == 0)
> ++		{
> ++		  if ((err = kwsincr (fimb_kwset, "", 0)) != 0)
> ++		    error (2, 0, err);
> ++		}
> ++	      else
> ++		for (i = 0; i < (1 << wclen); i++)
> ++		  {
> ++		    char *p = starts;
> ++		    int j, k;
> ++
> ++		    for (j = 0; j < wclen; ++j)
> ++		      {
> ++			wchar_t wc = wcbeg[j];
> ++			if (i & (1 << j))
> ++			  {
> ++			    wc = towupper (wc);
> ++			    if (wc == wcbeg[j])
> ++			      continue;
> ++			  }
> ++			k = wctomb (p, wc);
> ++			if (k <= 0)
> ++			  goto fimb_fail;
> ++			p += k;
> ++		      }
> ++		    if ((err = kwsincr (fimb_kwset, starts, p - starts)) != 0)
> ++		      error (2, 0, err);
> ++		  }
> ++	      if (wclim < wcpattern + wcsize)
> ++		++wclim;
> ++	      wcbeg = wclim;
> ++	    }
> ++	  while (wcbeg < wcpattern + wcsize);
> ++	  f_i_multibyte = 1;
> ++	  kwset = fimb_kwset;
> ++	  free (starts);
> ++	  Fimb.match = xmalloc (Fimb.count);
> ++	  if ((err = kwsprep (kwset)) != 0)
> ++	    error (2, 0, err);
> ++	  return;
> ++	}
> ++    }
> ++#endif /* MBS_SUPPORT */
> ++
> ++
> +   kwsinit ();
> +   beg = pattern;
> +   do
> +@@ -522,6 +678,76 @@
> +     error (2, 0, err);
> + }
> +
> ++#ifdef MBS_SUPPORT
> ++static int
> ++Fimbexec (const char *buf, size_t size, size_t *plen, int exact)
> ++{
> ++  size_t len, letter, i;
> ++  int ret = -1;
> ++  mbstate_t mbs;
> ++  wchar_t wc;
> ++  int patterns_left;
> ++
> ++  assert (match_icase && f_i_multibyte == 1);
> ++  assert (MB_CUR_MAX > 1);
> ++
> ++  memset (&mbs, '\0', sizeof (mbs));
> ++  memset (Fimb.match, '\1', Fimb.count);
> ++  letter = len = 0;
> ++  patterns_left = 1;
> ++  while (patterns_left && len <= size)
> ++    {
> ++      size_t c;
> ++
> ++      patterns_left = 0;
> ++      if (len < size)
> ++	{
> ++	  c = mbrtowc (&wc, buf + len, size - len, &mbs);
> ++	  if (c + 2 <= 2)
> ++	    return ret;
> ++
> ++	  wc = towlower (wc);
> ++	}
> ++      else
> ++	{
> ++	  c = 1;
> ++	  wc = L'\0';
> ++	}
> ++
> ++      for (i = 0; i < Fimb.count; i++)
> ++	{
> ++	  if (Fimb.match[i])
> ++	    {
> ++	      if (Fimb.patterns[i][letter] == L'\0')
> ++		{
> ++		  /* Found a match. */
> ++		  *plen = len;
> ++		  if (!exact && !match_words)
> ++		    return 0;
> ++		  else
> ++		    {
> ++		      /* For -w or exact look for longest match.  */
> ++		      ret = 0;
> ++		      Fimb.match[i] = '\0';
> ++		      continue;
> ++		    }
> ++		}
> ++
> ++	      if (Fimb.patterns[i][letter] == wc)
> ++		patterns_left = 1;
> ++	      else
> ++		Fimb.match[i] = '\0';
> ++	    }
> ++	}
> ++
> ++      len += c;
> ++      letter++;
> ++    }
> ++
> ++  return ret;
> ++}
> ++#endif /* MBS_SUPPORT */
> ++
> + static size_t
> + Fexecute (char const *buf, size_t size, size_t *match_size, int exact)
> + {
> +@@ -531,80 +757,258 @@
> +   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);
> +-          buf = case_buf;
> +-        }
> +-      mb_properties = check_multibyte_string(buf, size);
> +-    }
> ++  int mb_cur_max = MB_CUR_MAX;
> ++  mbstate_t mbs;
> ++  memset (&mbs, '\0', sizeof (mbstate_t));
> ++  const char *last_char = NULL;
> + #endif /* MBS_SUPPORT */
> +
> +   for (beg = buf; beg <= buf + size; ++beg)
> +     {
> +-      size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
> ++      size_t offset;
> ++      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.  */
> ++      if (mb_cur_max > 1 && !using_utf8)
> ++	{
> ++	  size_t bytes_left = offset;
> ++	  while (bytes_left)
> ++	    {
> ++	      size_t mlen = mbrlen (beg, bytes_left, &mbs);
> ++
> ++	      last_char = beg;
> ++	      if (mlen == (size_t) -1 || mlen == 0)
> ++		{
> ++		  /* Incomplete character: treat as single-byte. */
> ++		  memset (&mbs, '\0', sizeof (mbstate_t));
> ++		  beg++;
> ++		  bytes_left--;
> ++		  continue;
> ++		}
> ++
> ++	      if (mlen == (size_t) -2)
> ++		/* Offset points inside multibyte character: no good. */
> ++		break;
> ++
> ++	      beg += mlen;
> ++	      bytes_left -= mlen;
> ++	    }
> ++
> ++	  if (bytes_left)
> ++	    continue;
> ++	}
> ++      else
> + #endif /* MBS_SUPPORT */
> +       beg += offset;
> ++#ifdef MBS_SUPPORT
> ++      /* For f_i_multibyte, the string at beg now matches first 3 chars of
> ++	 one of the search strings (less if there are shorter search strings).
> ++	 See if this is a real match.  */
> ++      if (f_i_multibyte
> ++	  && Fimbexec (beg, buf + size - beg, &kwsmatch.size[0], exact))
> ++	goto next_char;
> ++#endif /* MBS_SUPPORT */
> +       len = kwsmatch.size[0];
> +       if (exact && !match_words)
> + 	goto success_in_beg_and_len;
> +       if (match_lines)
> + 	{
> + 	  if (beg > buf && beg[-1] != eol)
> +-	    continue;
> ++	    goto next_char;
> + 	  if (beg + len < buf + size && beg[len] != eol)
> +-	    continue;
> ++	    goto next_char;
> + 	  goto success;
> + 	}
> +       else if (match_words)
> +-	for (try = beg; len; )
> +-	  {
> +-	    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)
> +-		  {
> ++	{
> ++	  while (len)
> ++	    {
> ++	      int word_match = 0;
> ++	      if (beg > buf)
> ++		{
> + #ifdef MBS_SUPPORT
> +-		    if (MB_CUR_MAX > 1)
> +-		      free (mb_properties);
> ++		  if (mb_cur_max > 1)
> ++		    {
> ++		      const char *s;
> ++		      int mr;
> ++		      wchar_t pwc;
> ++
> ++		      if (using_utf8)
> ++			{
> ++			  s = beg - 1;
> ++			  while (s > buf
> ++				 && (unsigned char) *s >= 0x80
> ++				 && (unsigned char) *s <= 0xbf)
> ++			    --s;
> ++			}
> ++		      else
> ++			s = last_char;
> ++		      mr = mbtowc (&pwc, s, beg - s);
> ++		      if (mr <= 0)
> ++			memset (&mbs, '\0', sizeof (mbstate_t));
> ++		      else if ((iswalnum (pwc) || pwc == L'_')
> ++			       && mr == (int) (beg - s))
> ++			goto next_char;
> ++		    }
> ++		  else
> + #endif /* MBS_SUPPORT */
> +-		    return offset;
> +-		  }
> +-		try = beg + offset;
> +-		len = kwsmatch.size[0];
> +-	      }
> +-	    else
> +-	      goto success;
> +-	  }
> ++		  if (WCHAR ((unsigned char) beg[-1]))
> ++		    goto next_char;
> ++		}
> ++#ifdef MBS_SUPPORT
> ++	      if (mb_cur_max > 1)
> ++		{
> ++		  wchar_t nwc;
> ++		  int mr;
> ++
> ++		  mr = mbtowc (&nwc, beg + len, buf + size - beg - len);
> ++		  if (mr <= 0)
> ++		    {
> ++		      memset (&mbs, '\0', sizeof (mbstate_t));
> ++		      word_match = 1;
> ++		    }
> ++		  else if (!iswalnum (nwc) && nwc != L'_')
> ++		    word_match = 1;
> ++		}
> ++	      else
> ++#endif /* MBS_SUPPORT */
> ++		if (beg + len >= buf + size || !WCHAR ((unsigned char) beg[len]))
> ++		  word_match = 1;
> ++	      if (word_match)
> ++		{
> ++		  if (!exact)
> ++		    /* Returns the whole line now we know there's a word match. */
> ++		    goto success;
> ++		  else
> ++		    /* Returns just this word match. */
> ++		    goto success_in_beg_and_len;
> ++		}
> ++	      if (len > 0)
> ++		{
> ++		  /* Try a shorter length anchored at the same place. */
> ++		  --len;
> ++		  offset = kwsexec (kwset, beg, len, &kwsmatch);
> ++
> ++		  if (offset == -1)
> ++		    goto next_char; /* Try a different anchor. */
> ++#ifdef MBS_SUPPORT
> ++		  if (mb_cur_max > 1 && !using_utf8)
> ++		    {
> ++		      size_t bytes_left = offset;
> ++		      while (bytes_left)
> ++			{
> ++			  size_t mlen = mbrlen (beg, bytes_left, &mbs);
> ++
> ++			  last_char = beg;
> ++			  if (mlen == (size_t) -1 || mlen == 0)
> ++			    {
> ++			      /* Incomplete character: treat as single-byte. */
> ++			      memset (&mbs, '\0', sizeof (mbstate_t));
> ++			      beg++;
> ++			      bytes_left--;
> ++			      continue;
> ++			    }
> ++
> ++			  if (mlen == (size_t) -2)
> ++			    {
> ++			      /* Offset points inside multibyte character:
> ++			       * no good. */
> ++			      break;
> ++			    }
> ++
> ++			  beg += mlen;
> ++			  bytes_left -= mlen;
> ++			}
> ++
> ++		      if (bytes_left)
> ++			{
> ++			  memset (&mbs, '\0', sizeof (mbstate_t));
> ++			  goto next_char; /* Try a different anchor. */
> ++			}
> ++		    }
> ++		  else
> ++#endif /* MBS_SUPPORT */
> ++		  beg += offset;
> ++#ifdef MBS_SUPPORT
> ++		  /* The string at beg now matches first 3 chars of one of
> ++		     the search strings (less if there are shorter search
> ++		     strings).  See if this is a real match.  */
> ++		  if (f_i_multibyte
> ++		      && Fimbexec (beg, len - offset, &kwsmatch.size[0],
> ++				   exact))
> ++		    goto next_char;
> ++#endif /* MBS_SUPPORT */
> ++		  len = kwsmatch.size[0];
> ++		}
> ++	    }
> ++	}
> +       else
> + 	goto success;
> ++next_char:;
> ++#ifdef MBS_SUPPORT
> ++      /* Advance to next character.  For MB_CUR_MAX == 1 case this is handled
> ++	 by ++beg above.  */
> ++      if (mb_cur_max > 1)
> ++	{
> ++	  if (using_utf8)
> ++	    {
> ++	      unsigned char c = *beg;
> ++	      if (c >= 0xc2)
> ++		{
> ++		  if (c < 0xe0)
> ++		    ++beg;
> ++		  else if (c < 0xf0)
> ++		    beg += 2;
> ++		  else if (c < 0xf8)
> ++		    beg += 3;
> ++		  else if (c < 0xfc)
> ++		    beg += 4;
> ++		  else if (c < 0xfe)
> ++		    beg += 5;
> ++		}
> ++	    }
> ++	  else
> ++	    {
> ++	      size_t l = mbrlen (beg, buf + size - beg, &mbs);
> ++
> ++	      last_char = beg;
> ++	      if (l + 2 >= 2)
> ++		beg += l - 1;
> ++	      else
> ++		memset (&mbs, '\0', sizeof (mbstate_t));
> ++	    }
> ++	}
> ++#endif /* MBS_SUPPORT */
> +     }
> +
> +  failure:
> ++  return -1;
> ++
> ++ success:
> + #ifdef MBS_SUPPORT
> +-  if (MB_CUR_MAX > 1)
> ++  if (mb_cur_max > 1 && !using_utf8)
> +     {
> +-      if (match_icase)
> +-        free((char *) buf);
> +-      if (mb_properties)
> +-        free(mb_properties);
> ++      end = beg + len;
> ++      while (end < buf + size)
> ++	{
> ++	  size_t mlen = mbrlen (end, buf + size - end, &mbs);
> ++	  if (mlen == (size_t) -1 || mlen == (size_t) -2 || mlen == 0)
> ++	    {
> ++	      memset (&mbs, '\0', sizeof (mbstate_t));
> ++	      mlen = 1;
> ++	    }
> ++	  if (mlen == 1 && *end == eol)
> ++	    break;
> ++
> ++	  end += mlen;
> ++	}
> +     }
> ++  else
> + #endif /* MBS_SUPPORT */
> +-  return -1;
> +-
> +- success:
> +   end = memchr (beg + len, eol, (buf + size) - (beg + len));
> ++
> +   end++;
> +   while (buf < beg && beg[-1] != eol)
> +     --beg;
> +@@ -613,15 +1017,6 @@
> +
> +  success_in_beg_and_len:
> +   *match_size = len;
> +-#ifdef MBS_SUPPORT
> +-  if (MB_CUR_MAX > 1)
> +-    {
> +-      if (mb_properties)
> +-	free (mb_properties);
> +-      if (match_icase)
> +-	free ((char *) buf);
> +-    }
> +-#endif /* MBS_SUPPORT */
> +   return beg - buf;
> + }
> +
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-fgrep.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-fgrep.patch
> new file mode 100644
> index 0000000..c7f8f96
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-fgrep.patch
> @@ -0,0 +1,145 @@
> +--- grep-2.5.1/src/search.c.fgrep	2001-04-19 04:42:14.000000000 +0100
> ++++ grep-2.5.1/src/search.c	2004-02-26 13:09:32.000000000 +0000
> +@@ -360,13 +360,7 @@
> + 	      /* Find a possible match using the KWset matcher. */
> + 	      size_t offset = kwsexec (kwset, beg, buflim - beg, &kwsm);
> + 	      if (offset == (size_t) -1)
> +-		{
> +-#ifdef MBS_SUPPORT
> +-		  if (MB_CUR_MAX > 1)
> +-		    free(mb_properties);
> +-#endif
> +-		  return (size_t)-1;
> +-		}
> ++	        goto failure;
> + 	      beg += offset;
> + 	      /* Narrow down to the line containing the candidate, and
> + 		 run it through DFA. */
> +@@ -379,7 +373,7 @@
> + 	      while (beg > buf && beg[-1] != eol)
> + 		--beg;
> + 	      if (kwsm.index < kwset_exact_matches)
> +-		goto success;
> ++		goto success_in_beg_and_end;
> + 	      if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
> + 		continue;
> + 	    }
> +@@ -398,7 +392,7 @@
> + 	    }
> + 	  /* Successful, no backreferences encountered! */
> + 	  if (!backref)
> +-	    goto success;
> ++	    goto success_in_beg_and_end;
> + 	}
> +       else
> + 	end = beg + size;
> +@@ -413,14 +407,11 @@
> + 				       end - beg - 1, &(patterns[i].regs))))
> + 	    {
> + 	      len = patterns[i].regs.end[0] - start;
> +-	      if (exact)
> +-		{
> +-		  *match_size = len;
> +-		  return start;
> +-		}
> ++	      if (exact && !match_words)
> ++	        goto success_in_start_and_len;
> + 	      if ((!match_lines && !match_words)
> + 		  || (match_lines && len == end - beg - 1))
> +-		goto success;
> ++		goto success_in_beg_and_end;
> + 	      /* If -w, check if the match aligns with word boundaries.
> + 		 We do this iteratively because:
> + 		 (a) the line may contain more than one occurence of the
> +@@ -434,7 +425,7 @@
> + 		    if ((start == 0 || !WCHAR ((unsigned char) beg[start - 1]))
> + 			&& (len == end - beg - 1
> + 			    || !WCHAR ((unsigned char) beg[start + len])))
> +-		      goto success;
> ++		      goto success_in_beg_and_end;
> + 		    if (len > 0)
> + 		      {
> + 			/* Try a shorter length anchored at the same place. */
> +@@ -461,19 +452,26 @@
> + 	    }
> + 	} /* for Regex patterns.  */
> +     } /* for (beg = end ..) */
> ++
> ++ failure:
> + #ifdef MBS_SUPPORT
> +   if (MB_CUR_MAX > 1 && mb_properties)
> +     free (mb_properties);
> + #endif /* MBS_SUPPORT */
> +   return (size_t) -1;
> +
> +- success:
> ++ success_in_beg_and_end:
> ++  len = end - beg;
> ++  start = beg - buf;
> ++  /* FALLTHROUGH */
> ++
> ++ success_in_start_and_len:
> + #ifdef MBS_SUPPORT
> +   if (MB_CUR_MAX > 1 && mb_properties)
> +     free (mb_properties);
> + #endif /* MBS_SUPPORT */
> +-  *match_size = end - beg;
> +-  return beg - buf;
> ++  *match_size = len;
> ++  return start;
> + }
> +
> + static void
> +@@ -516,28 +514,15 @@
> +     {
> +       size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
> +       if (offset == (size_t) -1)
> +-	{
> +-#ifdef MBS_SUPPORT
> +-	  if (MB_CUR_MAX > 1)
> +-	    free(mb_properties);
> +-#endif /* MBS_SUPPORT */
> +-	  return offset;
> +-	}
> ++	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 (exact)
> +-	{
> +-	  *match_size = len;
> +-#ifdef MBS_SUPPORT
> +-	  if (MB_CUR_MAX > 1)
> +-	    free (mb_properties);
> +-#endif /* MBS_SUPPORT */
> +-	  return beg - buf;
> +-	}
> ++      if (exact && !match_words)
> ++	goto success_in_beg_and_len;
> +       if (match_lines)
> + 	{
> + 	  if (beg > buf && beg[-1] != eol)
> +@@ -551,6 +536,7 @@
> + 	goto success;
> +     }
> +
> ++ failure:
> + #ifdef MBS_SUPPORT
> +   if (MB_CUR_MAX > 1)
> +     free (mb_properties);
> +@@ -583,7 +569,11 @@
> +   end++;
> +   while (buf < beg && beg[-1] != eol)
> +     --beg;
> +-  *match_size = end - beg;
> ++  len = end - beg;
> ++  /* FALLTHROUGH */
> ++
> ++ success_in_beg_and_len:
> ++  *match_size = len;
> + #ifdef MBS_SUPPORT
> +   if (MB_CUR_MAX > 1)
> +     free (mb_properties);
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-icolor.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-icolor.patch
> new file mode 100644
> index 0000000..14b2617
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-icolor.patch
> @@ -0,0 +1,36 @@
> +--- grep-2.5.1a/src/grep.c.icolor	2005-01-07 12:05:20.877785250 +0000
> ++++ grep-2.5.1a/src/grep.c	2005-01-07 12:05:44.690194388 +0000
> +@@ -564,33 +564,6 @@
> +     {
> +       size_t match_size;
> +       size_t match_offset;
> +-      if(match_icase)
> +-        {
> +-	  /* Yuck, this is tricky */
> +-          char *buf = (char*) xmalloc (lim - beg);
> +-	  char *ibeg = buf;
> +-	  char *ilim = ibeg + (lim - beg);
> +-	  int i;
> +-	  for (i = 0; i < lim - beg; i++)
> +-	    ibeg[i] = tolower (beg[i]);
> +-	  while ((match_offset = (*execute) (ibeg, ilim-ibeg, &match_size, 1))
> +-		 != (size_t) -1)
> +-	    {
> +-	      char const *b = beg + match_offset;
> +-	      if (b == lim)
> +-		break;
> +-	      fwrite (beg, sizeof (char), match_offset, stdout);
> +-	      printf ("\33[%sm", grep_color);
> +-	      fwrite (b, sizeof (char), match_size, stdout);
> +-	      fputs ("\33[00m", stdout);
> +-	      beg = b + match_size;
> +-	      ibeg = ibeg + match_offset + match_size;
> +-	    }
> +-	  fwrite (beg, 1, lim - beg, stdout);
> +-	  free (buf);
> +-	  lastout = lim;
> +-	  return;
> +-	}
> +       while (lim-beg && (match_offset = (*execute) (beg, lim - beg, &match_size, 1))
> + 	     != (size_t) -1)
> + 	{
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-manpage.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-manpage.patch
> new file mode 100644
> index 0000000..284f0c4
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-manpage.patch
> @@ -0,0 +1,19 @@
> +--- grep-2.5.1/doc/grep.1.manpage	2002-01-22 13:20:04.000000000 +0000
> ++++ grep-2.5.1/doc/grep.1	2003-10-08 09:37:32.000000000 +0100
> +@@ -191,6 +191,7 @@
> + .I PATTERN
> + as a list of fixed strings, separated by newlines,
> + any of which is to be matched.
> ++.TP
> + .BR \-P ", " \-\^\-perl-regexp
> + Interpret
> + .I PATTERN
> +@@ -302,7 +303,7 @@
> + This is especially useful for tools like zgrep, e.g.
> + .B "gzip -cd foo.gz |grep --label=foo something"
> + .TP
> +-.BR \-\^\-line-buffering
> ++.BR \-\^\-line-buffered
> + Use line buffering, it can be a performance penality.
> + .TP
> + .BR \-q ", " \-\^\-quiet ", " \-\^\-silent
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-oi.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-oi.patch
> new file mode 100644
> index 0000000..eb997ad
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-oi.patch
> @@ -0,0 +1,48 @@
> +--- grep-2.5.1/lib/posix/regex.h.oi	2004-01-05 12:09:12.984391131 +0000
> ++++ grep-2.5.1/lib/posix/regex.h	2004-01-05 12:09:24.717990622 +0000
> +@@ -109,6 +109,10 @@
> +    If not set, \{, \}, {, and } are literals.  */
> + #define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
> +
> ++/* If this bit is set, then ignore case when matching.
> ++   If not set, then case is significant.  */
> ++#define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
> ++
> + /* If this bit is set, +, ? and | aren't recognized as operators.
> +    If not set, they are.  */
> + #define RE_LIMITED_OPS (RE_INTERVALS << 1)
> +--- grep-2.5.1/src/search.c.oi	2004-01-05 12:07:00.550199415 +0000
> ++++ grep-2.5.1/src/search.c	2004-01-05 12:07:00.566197505 +0000
> +@@ -31,7 +31,7 @@
> +
> + #include "system.h"
> + #include "grep.h"
> +-#include "regex.h"
> ++#include <regex.h>
> + #include "dfa.h"
> + #include "kwset.h"
> + #include "error.h"
> +@@ -190,7 +190,7 @@
> +   size_t total = size;
> +   char const *motif = pattern;
> +
> +-  re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE);
> ++  re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE | (match_icase ? RE_ICASE : 0));
> +   dfasyntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE, match_icase, eolbyte);
> +
> +   /* For GNU regex compiler we have to pass the patterns separately to detect
> +@@ -268,12 +268,12 @@
> +
> +   if (strcmp (matcher, "awk") == 0)
> +     {
> +-      re_set_syntax (RE_SYNTAX_AWK);
> ++      re_set_syntax (RE_SYNTAX_AWK | (match_icase ? RE_ICASE : 0));
> +       dfasyntax (RE_SYNTAX_AWK, match_icase, eolbyte);
> +     }
> +   else
> +     {
> +-      re_set_syntax (RE_SYNTAX_POSIX_EGREP);
> ++      re_set_syntax (RE_SYNTAX_POSIX_EGREP | (match_icase ? RE_ICASE : 0));
> +       dfasyntax (RE_SYNTAX_POSIX_EGREP, match_icase, eolbyte);
> +     }
> +
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-tests.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-tests.patch
> new file mode 100644
> index 0000000..2934a21
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-tests.patch
> @@ -0,0 +1,138 @@
> +--- grep-2.5.1/tests/Makefile.am.jj	2001-03-07 05:11:27.000000000 +0100
> ++++ grep-2.5.1/tests/Makefile.am	2004-12-31 11:42:41.595492300 +0100
> +@@ -3,7 +3,8 @@
> + AWK=@AWK@
> +
> + TESTS = warning.sh khadafy.sh spencer1.sh bre.sh ere.sh \
> +-        status.sh empty.sh options.sh backref.sh file.sh
> ++        status.sh empty.sh options.sh backref.sh file.sh \
> ++        fmbtest.sh
> + EXTRA_DIST = $(TESTS) \
> +              khadafy.lines khadafy.regexp \
> +              spencer1.awk spencer1.tests \
> +--- grep-2.5.1/tests/fmbtest.sh	2004-12-31 13:30:23.942871250 +0100
> ++++ grep-2.5.1/tests/fmbtest.sh	2004-12-31 14:09:13.219463855 +0100
> +@@ -0,0 +1,111 @@
> ++#!/bin/sh
> ++
> ++: ${srcdir=.}
> ++
> ++# If cs_CZ.UTF-8 locale doesn't work, skip this test silently
> ++LC_ALL=cs_CZ.UTF-8 locale -k LC_CTYPE 2>/dev/null | ${GREP} -q charmap.*UTF-8 \
> ++  || exit 77
> ++
> ++failures=0
> ++
> ++cat > csinput <<EOF
> ++01 Žluťoučká číše
> ++ČíŠE 02
> ++03 Z číší Čiší cosi
> ++04 Čí
> ++Å e 05
> ++06 ČČČČČČČíšČÍŠčíš
> ++07 ČČČ ČČČČíšČÍŠčíšEEEE
> ++čAs 08
> ++09ÄŒapka
> ++10ČaSy se měnÍ
> ++ČÍšE11
> ++ÄŒas12
> ++𝇕ČÍšE𝇓13
> ++ŽČÍšE𝇓14
> ++𝇕ČÍšEŽ15
> ++ŽČÍšEŽ16
> ++ČÍšE𝇓17
> ++ČÍšEŽ18
> ++19𝇕ČÍše
> ++20ŽČÍše
> ++EOF
> ++cat > cspatfile <<EOF
> ++ČÍšE
> ++ÄŒas
> ++EOF
> ++
> ++for mode in F G E; do
> ++
> ++test1="$(echo `LC_ALL=cs_CZ.UTF-8 ${GREP} -${mode} -f cspatfile csinput \
> ++	       | LC_ALL=C sed 's/^.*\([0-9][0-9]\).*$/\1/'`)"
> ++if test "$test1" != "11 12 13 14 15 16 17 18"; then
> ++  echo "Test #1 ${mode} failed: $test1"
> ++  failures=1
> ++fi
> ++
> ++test2="$(echo `LC_ALL=cs_CZ.UTF-8 ${GREP} -${mode}i -f cspatfile csinput \
> ++	       | LC_ALL=C sed 's/^.*\([0-9][0-9]\).*$/\1/'`)"
> ++if test "$test2" != "01 02 07 08 10 11 12 13 14 15 16 17 18 19 20"; then
> ++  echo "Test #2 ${mode} failed: $test2"
> ++  failures=1
> ++fi
> ++
> ++test3="$(echo `LC_ALL=cs_CZ.UTF-8 ${GREP} -${mode}i -e 'ČÍšE' -e 'Čas' csinput \
> ++	       | LC_ALL=C sed 's/^.*\([0-9][0-9]\).*$/\1/'`)"
> ++if test "$test3" != "01 02 07 08 10 11 12 13 14 15 16 17 18 19 20"; then
> ++  echo "Test #3 ${mode} failed: $test3"
> ++  failures=1
> ++fi
> ++
> ++test4="$(echo `LC_ALL=cs_CZ.UTF-8 ${GREP} -${mode}iw -f cspatfile csinput \
> ++	       | LC_ALL=C sed 's/^.*\([0-9][0-9]\).*$/\1/'`)"
> ++if test "$test4" != "01 02 08 13 17 19"; then
> ++  echo "Test #4 ${mode} failed: $test4"
> ++  failures=1
> ++fi
> ++
> ++done
> ++
> ++# Test that -F --color=always prefers longer matches.
> ++test5="`echo 'Cosi tu ČišÍ...' \
> ++	| LC_ALL=cs_CZ.UTF-8 ${GREP} --color=always -Fi -e 'čiš' -e 'čiší'`"
> ++if echo "$test5" | LC_ALL=C ${GREP} -q 'Cosi tu .*\[.*mČišÍ.*\[.*m\(.\[K\)\?\.\.\.'; then
> ++  :
> ++else
> ++  echo "Test #5 F failed: $test5"
> ++  failures=1
> ++fi
> ++
> ++for mode in G E; do
> ++
> ++# Test that -{G,E} --color=always prefers earlier pattern matches.
> ++test6="`echo 'Cosi tu ČišÍ...' \
> ++	| LC_ALL=cs_CZ.UTF-8 ${GREP} --color=always -${mode}i -e 'čiš' -e 'čiší'`"
> ++if echo "$test6" | LC_ALL=C ${GREP} -q 'Cosi tu .*\[.*mČiš.*\[.*m\(.\[K\)\?Í\.\.\.'; then
> ++  :
> ++else
> ++  echo "Test #6 ${mode} failed: $test6"
> ++  failures=1
> ++fi
> ++
> ++# Test that -{G,E} --color=always prefers earlier pattern matches.
> ++test7="`echo 'Cosi tu ČišÍ...' \
> ++	| LC_ALL=cs_CZ.UTF-8 ${GREP} --color=always -${mode}i -e 'čiší' -e 'čiš'`"
> ++if echo "$test7" | LC_ALL=C ${GREP} -q 'Cosi tu .*\[.*mČišÍ.*\[.*m\(.\[K\)\?\.\.\.'; then
> ++  :
> ++else
> ++  echo "Test #7 ${mode} failed: $test7"
> ++  failures=1
> ++fi
> ++
> ++test8="$(echo `LC_ALL=cs_CZ.UTF-8 ${GREP} -${mode}i -e 'Č.šE' -e 'Č[a-f]s' csinput \
> ++	       | LC_ALL=C sed 's/^.*\([0-9][0-9]\).*$/\1/'`)"
> ++if test "$test8" != "01 02 07 08 10 11 12 13 14 15 16 17 18 19 20"; then
> ++  echo "Test #8 ${mode} failed: $test8"
> ++  failures=1
> ++fi
> ++
> ++done
> ++
> ++exit $failures
> +--- grep-2.5.1/tests/Makefile.in.jj	2004-12-31 11:42:53.000000000 +0100
> ++++ grep-2.5.1/tests/Makefile.in	2004-12-31 11:43:36.871514505 +0100
> +@@ -97,7 +97,8 @@ install_sh = @install_sh@
> + AWK = @AWK@
> +
> + TESTS = warning.sh khadafy.sh spencer1.sh bre.sh ere.sh \
> +-        status.sh empty.sh options.sh backref.sh file.sh
> ++        status.sh empty.sh options.sh backref.sh file.sh \
> ++	fmbtest.sh
> +
> + EXTRA_DIST = $(TESTS) \
> +              khadafy.lines khadafy.regexp \
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-w.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-w.patch
> new file mode 100644
> index 0000000..79ae2ae
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-2.5.1-w.patch
> @@ -0,0 +1,121 @@
> +--- grep-2.5.1a/src/search.c.w	2006-02-20 14:27:27.000000000 +0000
> ++++ grep-2.5.1a/src/search.c	2006-02-20 14:32:07.000000000 +0000
> +@@ -507,10 +507,114 @@
> + 	      if (match_words)
> + 		while (start >= 0)
> + 		  {
> +-		    if ((start == 0 || !WCHAR ((unsigned char) beg[start - 1]))
> +-			&& (len == end - beg - 1
> +-			    || !WCHAR ((unsigned char) beg[start + len])))
> +-		      goto success_in_beg_and_end;
> ++		    int lword_match = 0;
> ++		    if (start == 0)
> ++		      lword_match = 1;
> ++		    else
> ++		      {
> ++			assert (start > 0);
> ++#ifdef MBS_SUPPORT
> ++			if (mb_cur_max > 1)
> ++			  {
> ++			    const char *s;
> ++			    size_t mr;
> ++			    wchar_t pwc;
> ++
> ++			    /* Locate the start of the multibyte character
> ++			       before the match position (== beg + start). */
> ++			    if (using_utf8)
> ++			      {
> ++				/* UTF-8 is a special case: scan backwards
> ++				   until we find a 7-bit character or a
> ++				   lead byte. */
> ++				s = beg + start - 1;
> ++				while (s > buf
> ++				       && (unsigned char) *s >= 0x80
> ++				       && (unsigned char) *s <= 0xbf)
> ++				  --s;
> ++			      }
> ++			    else
> ++			      {
> ++				/* Scan forwards to find the start of the
> ++				   last complete character before the
> ++				   match position.  */
> ++				size_t bytes_left = start - 1;
> ++				s = beg;
> ++				while (bytes_left > 0)
> ++				  {
> ++				    mr = mbrlen (s, bytes_left, &mbs);
> ++				    if (mr == (size_t) -1 || mr == 0)
> ++				      {
> ++					memset (&mbs, '\0', sizeof (mbs));
> ++					s++;
> ++					bytes_left--;
> ++					continue;
> ++				      }
> ++				    if (mr == (size_t) -2)
> ++				      {
> ++					memset (&mbs, '\0', sizeof (mbs));
> ++					break;
> ++				      }
> ++				    s += mr;
> ++				    bytes_left -= mr;
> ++				  }
> ++			      }
> ++			    mr = mbrtowc (&pwc, s, beg + start - s, &mbs);
> ++			    if (mr == (size_t) -2 || mr == (size_t) -1 ||
> ++				mr == 0)
> ++			      {
> ++				memset (&mbs, '\0', sizeof (mbstate_t));
> ++				lword_match = 1;
> ++			      }
> ++			    else if (!(iswalnum (pwc) || pwc == L'_')
> ++				     && mr == beg + start - s)
> ++			      lword_match = 1;
> ++			  }
> ++			else
> ++#endif /* MBS_SUPPORT */
> ++			if (!WCHAR ((unsigned char) beg[start - 1]))
> ++			  lword_match = 1;
> ++		      }
> ++
> ++		    if (lword_match)
> ++		      {
> ++			int rword_match = 0;
> ++			if (start + len == end - beg - 1)
> ++			  rword_match = 1;
> ++			else
> ++			  {
> ++#ifdef MBS_SUPPORT
> ++			    if (mb_cur_max > 1)
> ++			      {
> ++				wchar_t nwc;
> ++				int mr;
> ++
> ++				mr = mbtowc (&nwc, beg + start + len,
> ++					     end - beg - start - len - 1);
> ++				if (mr <= 0)
> ++				  {
> ++				    memset (&mbs, '\0', sizeof (mbstate_t));
> ++				    rword_match = 1;
> ++				  }
> ++				else if (!iswalnum (nwc) && nwc != L'_')
> ++				  rword_match = 1;
> ++			      }
> ++			    else
> ++#endif /* MBS_SUPPORT */
> ++			    if (!WCHAR ((unsigned char) beg[start + len]))
> ++			      rword_match = 1;
> ++			  }
> ++
> ++			if (rword_match)
> ++			  {
> ++			    if (!exact)
> ++			      /* Returns the whole line. */
> ++			      goto success_in_beg_and_end;
> ++			    else
> ++			      /* Returns just this word match. */
> ++			      goto success_in_start_and_len;
> ++			  }
> ++		      }
> + 		    if (len > 0)
> + 		      {
> + 			/* Try a shorter length anchored at the same place. */
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-P.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-P.patch
> new file mode 100644
> index 0000000..9dca4ad
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-P.patch
> @@ -0,0 +1,14 @@
> +--- grep-2.5.1a/src/search.c.P	2006-02-03 14:08:00.000000000 +0000
> ++++ grep-2.5.1a/src/search.c	2006-02-03 14:11:20.000000000 +0000
> +@@ -1234,8 +1234,9 @@
> +       char eol = eolbyte;
> +       if (!exact)
> + 	{
> +-	  end = memchr (end, eol, buflim - end);
> +-	  end++;
> ++	  while (end < buflim)
> ++	    if (*end++ == eol)
> ++	      break;
> + 	  while (buf < beg && beg[-1] != eol)
> + 	    --beg;
> + 	}
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-bz434934.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-bz434934.patch
> new file mode 100644
> index 0000000..677e586
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-bz434934.patch
> @@ -0,0 +1,17 @@
> +2009-01-26  Stepan Kasal  <skasal@redhat.com>
> +
> +	* src/grep.c (prpending) fix off-by-one error in the execute call;
> +	also in upstream, see https://savannah.gnu.org/patch/?3840
> +
> +
> +--- grep-2.5.1/src/grep.c	2009-01-26 15:31:11.404091000 +0100
> ++++ grep-2.5.1/src/grep.c	2009-01-26 16:29:42.821903000 +0100
> +@@ -635,7 +635,7 @@
> +       size_t match_size;
> +       --pending;
> +       if (outleft
> +-	  || (((*execute) (lastout, nl - lastout, &match_size, 0) == (size_t) -1)
> ++	  || (((*execute) (lastout, nl + 1 - lastout, &match_size, 0) == (size_t) -1)
> + 	      == !out_invert))
> + 	prline (lastout, nl + 1, '-');
> +       else
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-bz460641.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-bz460641.patch
> new file mode 100644
> index 0000000..cd826f8
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-bz460641.patch
> @@ -0,0 +1,11 @@
> +--- grep-2.5.1a/src/search.c.bz460641	2009-01-26 15:17:19.227844000 +0100
> ++++ grep-2.5.1a/src/search.c	2009-01-26 15:29:34.585838000 +0100
> +@@ -900,7 +900,7 @@
> +   const char *last_char = NULL;
> + #endif /* MBS_SUPPORT */
> +
> +-  for (beg = buf; beg <= buf + size; ++beg)
> ++  for (beg = buf; beg < buf + size; ++beg)
> +     {
> +       size_t offset;
> +       offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-empty-pattern.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-empty-pattern.patch
> new file mode 100644
> index 0000000..acb702a
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-empty-pattern.patch
> @@ -0,0 +1,36 @@
> +--- grep-2.5.1a/src/grep.c.empty-pattern	2006-11-22 19:05:43.000000000 +0000
> ++++ grep-2.5.1a/src/grep.c	2006-11-22 19:22:04.000000000 +0000
> +@@ -1667,9 +1667,6 @@
> + 	  out_invert ^= 1;
> + 	  match_lines = match_words = 0;
> + 	}
> +-      else
> +-	/* Strip trailing newline. */
> +-        --keycc;
> +     }
> +   else
> +     if (optind < argc)
> +--- grep-2.5.1a/src/search.c.empty-pattern	2006-11-22 19:21:11.000000000 +0000
> ++++ grep-2.5.1a/src/search.c	2006-11-22 19:35:06.000000000 +0000
> +@@ -204,6 +204,10 @@
> +       motif = sep;
> +     } while (sep && total != 0);
> +
> ++  /* Strip trailing newline. */
> ++  if (size && pattern[size - 1] == '\n')
> ++    size--;
> ++
> +   /* In the match_words and match_lines cases, we use a different pattern
> +      for the DFA matcher that will quickly throw out cases that won't work.
> +      Then if DFA succeeds we do some hairy stuff using the regex matcher
> +@@ -288,6 +292,10 @@
> +       motif = sep;
> +     } while (sep && total != 0);
> +
> ++  /* Strip trailing newline. */
> ++  if (size && pattern[size - 1] == '\n')
> ++    size--;
> ++
> +   /* In the match_words and match_lines cases, we use a different pattern
> +      for the DFA matcher that will quickly throw out cases that won't work.
> +      Then if DFA succeeds we do some hairy stuff using the regex matcher
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-man-label.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-man-label.patch
> new file mode 100644
> index 0000000..316e577
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-man-label.patch
> @@ -0,0 +1,22 @@
> +--- grep-2.5.1a/doc/grep.texi.man-label	2004-11-12 12:26:48.000000000 +0100
> ++++ grep-2.5.1a/doc/grep.texi	2009-05-07 16:23:45.050654000 +0200
> +@@ -364,7 +364,7 @@
> + @cindex changing name of standard input
> + Displays input actually coming from standard input as input coming from file
> + @var{LABEL}. This is especially useful for tools like zgrep, e.g.
> +-@command{gzip -cd foo.gz |grep --label=foo something}
> ++@command{gzip -cd foo.gz |grep -H --label=foo something}
> +
> + @item -L
> + @itemx --files-without-match
> +--- grep-2.5.1a/doc/grep.1.man-label	2009-05-07 16:19:48.856815000 +0200
> ++++ grep-2.5.1a/doc/grep.1	2009-05-07 16:26:12.847116000 +0200
> +@@ -301,7 +301,7 @@
> + Displays input actually coming from standard input as input coming from file
> + .I LABEL.
> + This is especially useful for tools like zgrep, e.g.
> +-.B "gzip -cd foo.gz |grep --label=foo something"
> ++.B "gzip -cd foo.gz |grep -H --label=foo something"
> + .TP
> + .BR \-\^\-line-buffered
> + Use line buffering, it can be a performance penality.
> diff --git a/meta/recipes-extended/grep/grep-2.5.1a/grep-skip.patch b/meta/recipes-extended/grep/grep-2.5.1a/grep-skip.patch
> new file mode 100644
> index 0000000..fb6645f
> --- /dev/null
> +++ b/meta/recipes-extended/grep/grep-2.5.1a/grep-skip.patch
> @@ -0,0 +1,42 @@
> +--- grep-2.5.1a/src/grep.c.skip	2006-05-31 09:26:58.000000000 +0100
> ++++ grep-2.5.1a/src/grep.c	2006-05-31 09:28:24.000000000 +0100
> +@@ -261,19 +261,6 @@
> +   bufbeg[-1] = eolbyte;
> +   bufdesc = fd;
> +
> +-  if (fstat (fd, &stats->stat) != 0)
> +-    {
> +-      error (0, errno, "fstat");
> +-      return 0;
> +-    }
> +-  if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
> +-    return 0;
> +-#ifndef DJGPP
> +-  if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode)))
> +-#else
> +-  if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode)))
> +-#endif
> +-    return 0;
> +   if (S_ISREG (stats->stat.st_mode))
> +     {
> +       if (file)
> +@@ -875,6 +862,19 @@
> +     }
> +   else
> +     {
> ++      if (stat (file, &stats->stat) != 0)
> ++        {
> ++          suppressible_error (file, errno);
> ++          return 1;
> ++        }
> ++      if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
> ++        return 1;
> ++#ifndef DJGPP
> ++      if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode) || S_ISFIFO(stats->stat.st_mode)))
> ++#else
> ++      if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode)))
> ++#endif
> ++        return 1;
> +       while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)
> + 	continue;
> +
> diff --git a/meta/recipes-extended/grep/grep_2.5.1a.bb b/meta/recipes-extended/grep/grep_2.5.1a.bb
> index 088959c..d964d84 100644
> --- a/meta/recipes-extended/grep/grep_2.5.1a.bb
> +++ b/meta/recipes-extended/grep/grep_2.5.1a.bb
> @@ -5,7 +5,7 @@ SECTION = "console/utils"
>   LICENSE = "GPLv2"
>   LIC_FILES_CHKSUM = "file://COPYING;md5=0636e73ff0215e8d672dc4c32c317bb3"
>
> -PR = "r2"
> +PR = "r3"
>
>   SRC_URI = "${GNU_MIRROR}/grep/grep-${PV}.tar.bz2 \
>              file://uclibc-fix.patch \
> @@ -13,8 +13,25 @@ SRC_URI = "${GNU_MIRROR}/grep/grep-${PV}.tar.bz2 \
>              file://gettext.patch \
>              file://fix64-int-to-pointer.patch \
>              file://Makevars \
> -           file://grep-CVE-2012-5667.patch \

Why are you removing this patch?

Will an update to 2.5.3 accomplish the same thing as these patches?

Also all of your patches above are missing Upstream-Status and 
Signed-off-by:

See the Patch Guildlines on OE-Core:
http://www.openembedded.org/wiki/Commit_Patch_Message_Guidelines

Thanks

Sau!

>              file://fix-for-texinfo-5.1.patch \
> +           file://grep-2.5.1-fgrep.patch \
> +           file://grep-2.5.1-bracket.patch \
> +           file://grep-2.5-i18n.patch \
> +           file://grep-2.5.1-oi.patch \
> +           file://grep-2.5.1-manpage.patch \
> +           file://grep-2.5.1-color.patch \
> +           file://grep-2.5.1-icolor.patch \
> +           file://grep-skip.patch \
> +           file://grep-2.5.1-egf-speedup.patch \
> +           file://grep-2.5.1-dfa-optional.patch \
> +           file://grep-2.5.1-tests.patch \
> +           file://grep-2.5.1-w.patch \
> +           file://grep-P.patch \
> +           file://grep-CVE-2012-5667.patch \
> +           file://grep-empty-pattern.patch \
> +           file://grep-bz460641.patch \
> +           file://grep-bz434934.patch \
> +           file://grep-man-label.patch \
>             "
>
>   SRC_URI[md5sum] = "52202fe462770fa6be1bb667bd6cf30c"
> @@ -22,7 +39,7 @@ SRC_URI[sha256sum] = "38c8a2bb9223d1fb1b10bdd607cf44830afc92fd451ac4cd07619bf92b
>
>   inherit autotools gettext
>
> -EXTRA_OECONF = "--disable-perl-regexp --disable-ncurses"
> +EXTRA_OECONF = "--disable-perl-regexp --disable-ncurses --without-included-regex"
>
>   CFLAGS += "-D PROTOTYPES"
>   do_configure_prepend () {
>
>
>
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.openembedded.org/mailman/listinfo/openembedded-core
>


  reply	other threads:[~2013-08-27  1:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-27  9:43 [PATCH] grep-2.5.1a: fix grep for LSB compliance Li Zhijian
2013-08-27  1:00 ` Saul Wold [this message]
2013-08-27  4:32   ` Li Zhijian
2013-08-27  6:52     ` Saul Wold
2013-08-28  6:16       ` Li Zhijian
2013-08-27 10:43   ` Phil Blundell
2013-08-28  5:47     ` Li Zhijian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=521BFA2A.4090508@linux.intel.com \
    --to=sgw@linux.intel.com \
    --cc=lizhijian@cn.fujitsu.com \
    --cc=openembedded-core@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.