diff -rc -N grep-2.5.4.orig/src/Makefile.am grep-2.5.4/src/Makefile.am
*** grep-2.5.4.orig/src/Makefile.am	2009-01-31 05:39:54.000000000 +0000
--- grep-2.5.4/src/Makefile.am	2009-08-24 01:25:04.000000000 +0000
***************
*** 20,31 ****
  LN = ln
  
  bin_PROGRAMS = grep egrep fgrep
! grep_SOURCES  =  grep.c  search.c kwset.c dfa.c
! egrep_SOURCES = egrep.c esearch.c kwset.c dfa.c
! fgrep_SOURCES = fgrep.c fsearch.c kwset.c
  noinst_HEADERS = grep.h dfa.h kwset.h getpagesize.h system.h mbsupport.h
  
! LDADD = @INTLLIBS@ ../lib/libgreputils.a
  datadir = $(prefix)/@DATADIRNAME@
  localedir = $(datadir)/locale
  INCLUDES = -I../intl -I$(top_srcdir)/lib -DLOCALEDIR=\"$(localedir)\"
--- 20,31 ----
  LN = ln
  
  bin_PROGRAMS = grep egrep fgrep
! grep_SOURCES  =  grep.c  search.c kwset.c kwsmb.c dfa.c
! egrep_SOURCES = egrep.c esearch.c kwset.c kwsmb.c dfa.c
! fgrep_SOURCES = fgrep.c fsearch.c kwset.c kwsmb.c
  noinst_HEADERS = grep.h dfa.h kwset.h getpagesize.h system.h mbsupport.h
  
! LDADD = ../lib/libgreputils.a @INTLLIBS@
  datadir = $(prefix)/@DATADIRNAME@
  localedir = $(datadir)/locale
  INCLUDES = -I../intl -I$(top_srcdir)/lib -DLOCALEDIR=\"$(localedir)\"
diff -rc -N grep-2.5.4.orig/src/Makefile.in grep-2.5.4/src/Makefile.in
*** grep-2.5.4.orig/src/Makefile.in	2009-02-10 04:35:28.000000000 +0000
--- grep-2.5.4/src/Makefile.in	2009-08-24 01:25:04.000000000 +0000
***************
*** 77,93 ****
  binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
  PROGRAMS = $(bin_PROGRAMS)
  am_egrep_OBJECTS = egrep$U.$(OBJEXT) esearch$U.$(OBJEXT) \
! 	kwset$U.$(OBJEXT) dfa$U.$(OBJEXT)
  egrep_OBJECTS = $(am_egrep_OBJECTS)
  egrep_LDADD = $(LDADD)
  egrep_DEPENDENCIES = ../lib/libgreputils.a
  am_fgrep_OBJECTS = fgrep$U.$(OBJEXT) fsearch$U.$(OBJEXT) \
! 	kwset$U.$(OBJEXT)
  fgrep_OBJECTS = $(am_fgrep_OBJECTS)
  fgrep_LDADD = $(LDADD)
  fgrep_DEPENDENCIES = ../lib/libgreputils.a
  am_grep_OBJECTS = grep$U.$(OBJEXT) search$U.$(OBJEXT) \
! 	kwset$U.$(OBJEXT) dfa$U.$(OBJEXT)
  grep_OBJECTS = $(am_grep_OBJECTS)
  grep_LDADD = $(LDADD)
  grep_DEPENDENCIES = ../lib/libgreputils.a
--- 77,93 ----
  binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
  PROGRAMS = $(bin_PROGRAMS)
  am_egrep_OBJECTS = egrep$U.$(OBJEXT) esearch$U.$(OBJEXT) \
! 	kwset$U.$(OBJEXT) kwsmb$U.$(OBJEXT) dfa$U.$(OBJEXT)
  egrep_OBJECTS = $(am_egrep_OBJECTS)
  egrep_LDADD = $(LDADD)
  egrep_DEPENDENCIES = ../lib/libgreputils.a
  am_fgrep_OBJECTS = fgrep$U.$(OBJEXT) fsearch$U.$(OBJEXT) \
! 	kwset$U.$(OBJEXT) kwsmb$U.$(OBJEXT)
  fgrep_OBJECTS = $(am_fgrep_OBJECTS)
  fgrep_LDADD = $(LDADD)
  fgrep_DEPENDENCIES = ../lib/libgreputils.a
  am_grep_OBJECTS = grep$U.$(OBJEXT) search$U.$(OBJEXT) \
! 	kwset$U.$(OBJEXT) kwsmb$U.$(OBJEXT) dfa$U.$(OBJEXT)
  grep_OBJECTS = $(am_grep_OBJECTS)
  grep_LDADD = $(LDADD)
  grep_DEPENDENCIES = ../lib/libgreputils.a
***************
*** 224,234 ****
  top_srcdir = @top_srcdir@
  AUTOMAKE_OPTIONS = ansi2knr
  LN = ln
! grep_SOURCES = grep.c  search.c kwset.c dfa.c
! egrep_SOURCES = egrep.c esearch.c kwset.c dfa.c
! fgrep_SOURCES = fgrep.c fsearch.c kwset.c
  noinst_HEADERS = grep.h dfa.h kwset.h getpagesize.h system.h mbsupport.h
! LDADD = @INTLLIBS@ ../lib/libgreputils.a
  INCLUDES = -I../intl -I$(top_srcdir)/lib -DLOCALEDIR=\"$(localedir)\"
  EXTRA_DIST = \
               dosbuf.c \
--- 224,234 ----
  top_srcdir = @top_srcdir@
  AUTOMAKE_OPTIONS = ansi2knr
  LN = ln
! grep_SOURCES = grep.c  search.c kwset.c kwsmb.c dfa.c
! egrep_SOURCES = egrep.c esearch.c kwset.c kwsmb.c dfa.c
! fgrep_SOURCES = fgrep.c fsearch.c kwset.c kwsmb.c
  noinst_HEADERS = grep.h dfa.h kwset.h getpagesize.h system.h mbsupport.h
! LDADD = ../lib/libgreputils.a @INTLLIBS@
  INCLUDES = -I../intl -I$(top_srcdir)/lib -DLOCALEDIR=\"$(localedir)\"
  EXTRA_DIST = \
               dosbuf.c \
***************
*** 322,327 ****
--- 322,328 ----
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsearch$U.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grep$U.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kwset$U.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kwsmb$U.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/search$U.Po@am__quote@
  
  .c.o:
***************
*** 351,361 ****
  	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/grep.c; then echo $(srcdir)/grep.c; else echo grep.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
  kwset_.c: kwset.c $(ANSI2KNR)
  	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/kwset.c; then echo $(srcdir)/kwset.c; else echo kwset.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
  search_.c: search.c $(ANSI2KNR)
  	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/search.c; then echo $(srcdir)/search.c; else echo search.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
  dfa_.$(OBJEXT) egrep_.$(OBJEXT) esearch_.$(OBJEXT) fgrep_.$(OBJEXT) \
! fsearch_.$(OBJEXT) grep_.$(OBJEXT) kwset_.$(OBJEXT) search_.$(OBJEXT) \
! : $(ANSI2KNR)
  
  ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
  	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
--- 352,364 ----
  	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/grep.c; then echo $(srcdir)/grep.c; else echo grep.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
  kwset_.c: kwset.c $(ANSI2KNR)
  	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/kwset.c; then echo $(srcdir)/kwset.c; else echo kwset.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+ kwsmb_.c: kwsmb.c $(ANSI2KNR)
+ 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/kwsmb.c; then echo $(srcdir)/kwsmb.c; else echo kwsmb.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
  search_.c: search.c $(ANSI2KNR)
  	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/search.c; then echo $(srcdir)/search.c; else echo search.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
  dfa_.$(OBJEXT) egrep_.$(OBJEXT) esearch_.$(OBJEXT) fgrep_.$(OBJEXT) \
! fsearch_.$(OBJEXT) grep_.$(OBJEXT) kwset_.$(OBJEXT) kwsmb_.$(OBJEXT) \
! search_.$(OBJEXT) : $(ANSI2KNR)
  
  ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
  	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
diff -rc -N grep-2.5.4.orig/src/kwsmb.c grep-2.5.4/src/kwsmb.c
*** grep-2.5.4.orig/src/kwsmb.c	1970-01-01 00:00:00.000000000 +0000
--- grep-2.5.4/src/kwsmb.c	2009-08-24 01:25:18.000000000 +0000
***************
*** 0 ****
--- 1,500 ----
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+ 
+ #include "mbsupport.h"
+ 
+ #ifdef MBS_SUPPORT
+ 
+ #include <sys/types.h>
+ #include "system.h"
+ #include "grep.h"
+ 
+ /* We can handle multibyte strings. */
+ # include <wchar.h>
+ # include <wctype.h>
+ 
+ #include "kwset.h"
+ #include "obstack.h"
+ 
+ #ifdef GREP
+ extern char *xmalloc ();
+ # undef malloc
+ # define malloc xmalloc
+ extern char *xrealloc ();
+ # undef realloc
+ # define realloc xrealloc
+ #endif
+ 
+ #define obstack_chunk_alloc malloc
+ #define obstack_chunk_free free
+ 
+ /* Balanced tree of edges and labels leaving a given trie node. */
+ struct tree
+ {
+   struct tree *llink;		/* Left link; MUST be first field. */
+   struct tree *rlink;		/* Right link (to larger labels). */
+   struct trie *trie;		/* Trie node pointed to by this edge. */
+   unsigned char label;		/* Label on this edge. */
+   char balance;			/* Difference in depths of subtrees. */
+ };
+ 
+ /* Node of a trie representing a set of reversed keywords. */
+ struct trie
+ {
+   unsigned int accepting;	/* Word index of accepted word, or zero. */
+   struct tree *links;		/* Tree of edges leaving this node. */
+ };
+ 
+ /* Structure returned opaquely to the caller, containing everything. */
+ struct kwsmb
+ {
+   struct obstack obstack;	/* Obstack for node allocation. */
+   int words;			/* Number of words in the trie. */
+   struct trie *trie;		/* The trie itself. */
+   kwset_t *kwset;
+ };
+ 
+ /* Free the components of the given keyword set. */
+ void
+ kmbfree (kwset_t kws)
+ {
+   struct kwsmb *kwsmb;
+ 
+   if (!(match_icase && MB_CUR_MAX > 1))
+     {
+       kwsfree (kws);
+       return;
+     }
+ 
+   kwsmb = (struct kwsmb *) kws;
+   obstack_free (&kwsmb->obstack, NULL);
+   free (kws);
+ }
+ 
+ /* Allocate and initialize a keyword set object, returning an opaque
+    pointer to it.  Return NULL if memory is not available. */
+ kwset_t
+ kmballoc (char const *trans)
+ {
+   struct kwsmb *kwsmb;
+ 
+   if (!(match_icase && MB_CUR_MAX > 1))
+     return kwsalloc (trans);
+ 
+   kwsmb = (struct kwsmb *) malloc (sizeof (struct kwsmb));
+   if (!kwsmb)
+     return NULL;
+ 
+   obstack_init (&kwsmb->obstack);
+   kwsmb->words = 0;
+   kwsmb->trie
+     = (struct trie *) obstack_alloc (&kwsmb->obstack, sizeof (struct trie));
+   if (!kwsmb->trie)
+     {
+       kmbfree ((kwset_t) kwsmb);
+       return NULL;
+     }
+   kwsmb->trie->accepting = 0;
+   kwsmb->trie->links = NULL;
+   kwsmb->kwset = kwsalloc ((char *) 0);
+ 
+   return (kwset_t) kwsmb;
+ }
+ 
+ /* This upper bound is valid for CHAR_BIT >= 4 and
+    exact for CHAR_BIT in { 4..11, 13, 15, 17, 19 }. */
+ #define DEPTH_SIZE (CHAR_BIT + CHAR_BIT/2)
+ 
+ /* Add the given string to the contents of the keyword set.  Return NULL
+    for success, an error message otherwise. */
+ 
+ static const char *
+ kmblink (kwset_t kws, register struct trie *trie, char const *text,
+ 	 size_t len, struct tree **cur_state)
+ {
+   struct kwsmb *kwsmb;
+   register unsigned char label;
+   struct tree *link;
+   register int depth;
+   struct tree *links[DEPTH_SIZE];
+   enum { L, R } dirs[DEPTH_SIZE];
+   struct tree *t, *r, *l, *rl, *lr;
+ 
+   kwsmb = (struct kwsmb *) kws;
+   link = NULL;
+ 
+   /* Descend the trie (built of reversed keywords) character-by-character,
+      installing new nodes when necessary. */
+   while (len--)
+     {
+       label = *text++;
+ 
+       /* Descend the tree of outgoing links for this trie node,
+          looking for the current character and keeping track
+          of the path followed. */
+       link = trie->links;
+       links[0] = (struct tree *) &trie->links;
+       dirs[0] = L;
+       depth = 1;
+ 
+       while (link && label != link->label)
+ 	{
+ 	  links[depth] = link;
+ 	  if (label < link->label)
+ 	    dirs[depth++] = L, link = link->llink;
+ 	  else
+ 	    dirs[depth++] = R, link = link->rlink;
+ 	}
+ 
+       /* The current character doesn't have an outgoing link at
+          this trie node, so build a new trie node and install
+          a link in the current trie node's tree. */
+       if (!link)
+ 	{
+ 	  link = (struct tree *) obstack_alloc (&kwsmb->obstack,
+ 						sizeof (struct tree));
+ 	  if (!link)
+ 	    return _("memory exhausted");
+ 	  link->llink = NULL;
+ 	  link->rlink = NULL;
+ 	  link->trie = (struct trie *) obstack_alloc (&kwsmb->obstack,
+ 						      sizeof (struct trie));
+ 	  if (!link->trie)
+ 	    {
+ 	      obstack_free (&kwsmb->obstack, link);
+ 	      return _("memory exhausted");
+ 	    }
+ 	  link->trie->accepting = 0;
+ 	  link->trie->links = NULL;
+ 	  link->label = label;
+ 	  link->balance = 0;
+ 
+ 	  /* Install the new tree node in its parent. */
+ 	  if (dirs[--depth] == L)
+ 	    links[depth]->llink = link;
+ 	  else
+ 	    links[depth]->rlink = link;
+ 
+ 	  /* Back up the tree fixing the balance flags. */
+ 	  while (depth && !links[depth]->balance)
+ 	    {
+ 	      if (dirs[depth] == L)
+ 		--links[depth]->balance;
+ 	      else
+ 		++links[depth]->balance;
+ 	      --depth;
+ 	    }
+ 
+ 	  /* Rebalance the tree by pointer rotations if necessary. */
+ 	  if (depth && ((dirs[depth] == L && --links[depth]->balance)
+ 			|| (dirs[depth] == R && ++links[depth]->balance)))
+ 	    {
+ 	      switch (links[depth]->balance)
+ 		{
+ 		case (char) -2:
+ 		  switch (dirs[depth + 1])
+ 		    {
+ 		    case L:
+ 		      r = links[depth], t = r->llink, rl = t->rlink;
+ 		      t->rlink = r, r->llink = rl;
+ 		      t->balance = r->balance = 0;
+ 		      break;
+ 		    case R:
+ 		      r = links[depth], l = r->llink, t = l->rlink;
+ 		      rl = t->rlink, lr = t->llink;
+ 		      t->llink = l, l->rlink = lr, t->rlink = r, r->llink = rl;
+ 		      l->balance = t->balance != 1 ? 0 : -1;
+ 		      r->balance = t->balance != (char) -1 ? 0 : 1;
+ 		      t->balance = 0;
+ 		      break;
+ 		    default:
+ 		      abort ();
+ 		    }
+ 		  break;
+ 		case 2:
+ 		  switch (dirs[depth + 1])
+ 		    {
+ 		    case R:
+ 		      l = links[depth], t = l->rlink, lr = t->llink;
+ 		      t->llink = l, l->rlink = lr;
+ 		      t->balance = l->balance = 0;
+ 		      break;
+ 		    case L:
+ 		      l = links[depth], r = l->rlink, t = r->llink;
+ 		      lr = t->llink, rl = t->rlink;
+ 		      t->llink = l, l->rlink = lr, t->rlink = r, r->llink = rl;
+ 		      l->balance = t->balance != 1 ? 0 : -1;
+ 		      r->balance = t->balance != (char) -1 ? 0 : 1;
+ 		      t->balance = 0;
+ 		      break;
+ 		    default:
+ 		      abort ();
+ 		    }
+ 		  break;
+ 		default:
+ 		  abort ();
+ 		}
+ 
+ 	      if (dirs[depth - 1] == L)
+ 		links[depth - 1]->llink = t;
+ 	      else
+ 		links[depth - 1]->rlink = t;
+ 	    }
+ 	}
+ 
+       trie = link->trie;
+     }
+ 
+   if (cur_state)
+     *cur_state = link;
+ 
+   return NULL;
+ }
+ 
+ /* Add the given string to the contents of the keyword set.  Return NULL
+    for success, an error message otherwise. */
+ 
+ char const *
+ kmbincr (kwset_t kws, char const *text, size_t len)
+ {
+   struct kwsmb *kwsmb;
+   struct trie *trie;
+   struct tree *link1, *link2;
+   char *buf, *beg2;
+   char const *beg1, *lim1, *lim2;
+   mbstate_t mbs1, mbs2;
+   size_t mbclen1, mbclen2;
+   wchar_t wc1, wc2;
+   int unmatches;
+   char const *err;
+ 
+   if (!(match_icase && MB_CUR_MAX > 1))
+     return kwsincr (kws, text, len);
+ 
+   kwsmb = (struct kwsmb *) kws;
+   trie = kwsmb->trie;
+   link1 = link2 = NULL;
+ 
+   beg1 = text;
+   lim1 = text + len;
+ 
+   beg2 = buf = (char *) malloc (sizeof (char) * (len));
+ 
+   if (!buf)
+     return _("_memory exhaust");
+ 
+   lim2 = buf + len;
+ 
+   memset (&mbs1, 0, sizeof (mbstate_t));
+   memset (&mbs2, 0, sizeof (mbstate_t));
+ 
+   unmatches = 0;
+   err = NULL;
+ 
+   while (beg1 < lim1)
+     {
+       mbclen1 = mbrtowc (&wc1, beg1, lim1 - beg1, &mbs1);
+ 
+       if (mbclen1 == (size_t) -1 || mbclen1 == (size_t) -2 || mbclen1 == 0)
+ 	{
+ 	  /* An invalid sequence, or a truncated multibyte character.
+ 	     We treat it as a single byte character.  */
+ 	  mbclen1 = 1;
+ 	}
+ 
+       if ((err = kmblink (kws, trie, beg1, mbclen1, &link1)))
+ 	goto out;
+ 
+       wc2 = wc1;
+ 
+       if (iswupper ((wint_t) wc1))
+ 	wc2 = towlower ((wint_t) wc1);
+       else if (iswlower ((wint_t) wc1))
+ 	wc2 = towupper ((wint_t) wc1);
+ 
+       if (lim2 - beg2 > MB_CUR_MAX)
+ 	{
+ 	  size_t offset, length;
+ 
+ 	  offset = beg2 - buf;
+ 	  length = lim2 - buf + MB_CUR_MAX;
+ 
+ 	  buf = (char *) realloc (buf, length);
+ 
+ 	  if (!buf)
+ 	    return _("_memory exhaust");
+ 
+ 	  beg2 = buf + offset;
+ 	  lim2 = buf + length;
+ 	}
+ 
+       mbclen2 = wcrtomb (beg2, wc2, &mbs2);
+ 
+       if (wc1 != wc2
+ 	  && !(mbclen2 == (size_t) -1 || mbclen2 == (size_t) -2 || mbclen2 == 0))
+ 	{
+ 	  unmatches++;
+ 
+ 	  if ((err = kmblink (kws, trie, beg2, mbclen2, &link2)))
+ 	    goto out;
+ 
+ 	  link2->trie = link1->trie;
+ 
+ 	  if (unmatches == 2)
+ 	    {
+ 	      if ((err = kwsincr (kwsmb->kwset, text, beg1 - text)))
+ 		goto out;
+ 	      if ((err = kwsincr (kwsmb->kwset, buf, beg2 - buf)))
+ 		goto out;
+ 	    }
+ 
+ 	  beg1 += mbclen1;
+ 
+ 	  if (unmatches < 2)
+ 	    beg2 += mbclen2;
+ 	}
+       else
+ 	{
+ 	  memcpy (beg2, beg1, mbclen1);
+ 
+ 	  beg1 += mbclen1;
+ 	  beg2 += mbclen1;
+ 	}
+ 
+       trie = link1->trie;
+     }
+ 
+   if ((err = kwsincr (kwsmb->kwset, text, len)))
+     goto out;
+ 
+   if (unmatches == 1)
+     {
+       if (lim2 - beg2 > lim1 - beg1)
+         {
+           size_t offset, length;
+ 
+           offset = beg2 - buf;
+           length = offset + (lim1 - beg1);
+ 
+           buf = (char *) realloc (buf, length);
+ 
+           if (!buf)
+             return _("_memory exhaust");
+ 
+           beg2 = buf + offset;
+           lim2 = buf + length;
+         }
+ 
+       memcpy (beg2, beg1, lim1 - beg1);
+       beg2 += lim1 - beg1;
+ 
+       if ((err = kwsincr (kwsmb->kwset, buf, beg2 - buf)))
+         goto out;
+     }
+ 
+   /* Mark the node we finally reached as accepting, encoding the
+      index number of this word in the keyword set so far. */
+   if (!trie->accepting)
+     trie->accepting = 1 + 2 * kwsmb->words;
+   ++kwsmb->words;
+ 
+  out:
+   free (buf);
+   return err;
+ }
+ 
+ /* Add both the upper and lower case of first multibyte character
+    of given string to the contents of the keyword set.  Return NULL
+    for success, an error message otherwise. */
+ 
+ char const *
+ kmbprep (kwset_t kws)
+ {
+   struct kwsmb const *kwsmb;
+ 
+   if (!(match_icase && MB_CUR_MAX > 1))
+     return kwsprep (kws);
+ 
+   kwsmb = (struct kwsmb *) kws;
+   return kwsprep (kwsmb->kwset);
+ }
+ 
+ /* Hairy multiple string search. */
+ size_t
+ kmbexec (kwset_t kws, char const *text, size_t len,
+ 	 struct kwsmatch *kwsmatch)
+ {
+   struct kwsmb const *kwsmb;
+   struct trie const *trie, *accept;
+   char const *beg, *lim, *try;
+   register unsigned char c;
+   register struct tree const *tree;
+   size_t offset, size, depth;
+ 
+   if (!(match_icase && MB_CUR_MAX > 1))
+     return kwsexec (kws, text, len, kwsmatch);
+ 
+   kwsmb = (struct kwsmb *) kws;
+   trie = NULL;
+   size = (size_t) -1;
+ 
+   beg = text;
+   lim = text + len;
+ 
+   while (beg < lim)
+     {
+       offset = kwsexec (kwsmb->kwset, beg, lim - beg, kwsmatch);
+ 
+       if (offset == (size_t) -1)
+ 	return -1;
+ 
+       beg += offset;
+ 
+       try = beg;
+       accept = NULL;
+       trie = kwsmb->trie;
+       depth = 0;
+ 
+       while (try < lim)
+ 	{
+ 	  c = *try++;
+ 	  tree = trie->links;
+ 
+ 	  while (tree && c != tree->label)
+ 	    if (c < tree->label)
+ 	      tree = tree->llink;
+ 	    else
+ 	      tree = tree->rlink;
+ 
+ 	  if (!tree)
+ 	    break;
+ 
+ 	  trie = tree->trie;
+ 	  depth++;
+ 
+ 	  if (trie->accepting)
+ 	    {
+ 	      accept = trie;
+ 	      size = depth;
+ 	    }
+ 	}
+ 
+       if (accept)
+ 	break;
+ 
+       beg++;
+     }
+ 
+   if (kwsmatch != NULL)
+     {
+       kwsmatch->index = trie->accepting / 2;
+       kwsmatch->offset[0] = beg - text;
+       kwsmatch->size[0] = size;
+     }
+ 
+   return beg - text;
+ }
+ 
+ #endif /* MBS_SUPPORT */
diff -rc -N grep-2.5.4.orig/src/kwsmb.h grep-2.5.4/src/kwsmb.h
*** grep-2.5.4.orig/src/kwsmb.h	1970-01-01 00:00:00.000000000 +0000
--- grep-2.5.4/src/kwsmb.h	2009-08-24 01:25:23.000000000 +0000
***************
*** 0 ****
--- 1,10 ----
+ 
+ #ifdef MBS_SUPPORT
+ 
+ #define kwsalloc kmballoc
+ #define kwsincr kmbincr
+ #define kwsprep kmbprep
+ #define kwsexec kmbexec
+ #define kwsfree kmbfree
+ 
+ #endif /* MBS_SUPPORT */
diff -rc -N 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:25:04.000000000 +0000
***************
*** 37,42 ****
--- 37,43 ----
  # include <regex.h>
  # include "dfa.h"
  #endif
+ #include "kwsmb.h"
  #include "kwset.h"
  #include "error.h"
  #include "xalloc.h"
