f416c42
--- grep-2.5.1a/src/search.c.w	2005-01-07 15:04:18.766280754 +0000
f416c42
+++ grep-2.5.1a/src/search.c	2005-01-07 16:59:19.287275172 +0000
f416c42
@@ -330,6 +330,7 @@
f416c42
   static int use_dfa;
f416c42
   static int use_dfa_checked = 0;
f416c42
 #ifdef MBS_SUPPORT
f416c42
+  const char *last_char = NULL;
f416c42
   int mb_cur_max = MB_CUR_MAX;
f416c42
   mbstate_t mbs;
f416c42
   memset (&mbs, '\0', sizeof (mbstate_t));
f416c42
@@ -385,6 +386,8 @@
f416c42
 		  while (bytes_left)
f416c42
 		    {
f416c42
 		      size_t mlen = mbrlen (beg, bytes_left, &mbs);
f416c42
+
f416c42
+		      last_char = beg;
f416c42
 		      if (mlen == (size_t) -1 || mlen == 0)
f416c42
 			{
f416c42
 			  /* Incomplete character: treat as single-byte. */
f416c42
@@ -445,6 +448,8 @@
f416c42
 		  while (bytes_left)
f416c42
 		    {
f416c42
 		      size_t mlen = mbrlen (beg, bytes_left, &mbs);
f416c42
+
f416c42
+		      last_char = beg;
f416c42
 		      if (mlen == (size_t) -1 || mlen == 0)
f416c42
 			{
f416c42
 			  /* Incomplete character: treat as single-byte. */
f416c42
@@ -507,10 +512,84 @@
f416c42
 	      if (match_words)
f416c42
 		while (start >= 0)
f416c42
 		  {
f416c42
-		    if ((start == 0 || !WCHAR ((unsigned char) beg[start - 1]))
f416c42
-			&& (len == end - beg - 1
f416c42
-			    || !WCHAR ((unsigned char) beg[start + len])))
f416c42
-		      goto success_in_beg_and_end;
f416c42
+		    int lword_match = 0;
f416c42
+		    if (start == 0)
f416c42
+		      lword_match = 1;
f416c42
+		    else
f416c42
+		      {
f416c42
+			assert (start > 0);
f416c42
+#ifdef MBS_SUPPORT
f416c42
+			if (mb_cur_max > 1)
f416c42
+			  {
f416c42
+			    const char *s;
f416c42
+			    int mr;
f416c42
+			    wchar_t pwc;
f416c42
+
f416c42
+			    if (using_utf8)
f416c42
+			      {
f416c42
+				s = beg + start - 1;
f416c42
+				while (s > buf
f416c42
+				       && (unsigned char) *s >= 0x80
f416c42
+				       && (unsigned char) *s <= 0xbf)
f416c42
+				  --s;
f416c42
+			      }
f416c42
+			    else
f416c42
+			      s = last_char;
f416c42
+			    mr = mbtowc (&pwc, s, beg + start - s);
f416c42
+			    if (mr <= 0)
f416c42
+			      {
f416c42
+				memset (&mbs, '\0', sizeof (mbstate_t));
f416c42
+				lword_match = 1;
f416c42
+			      }
f416c42
+			    else if (!(iswalnum (pwc) || pwc == L'_')
f416c42
+				     && mr == (int) (beg + start - s))
f416c42
+			      lword_match = 1;
f416c42
+			  }
f416c42
+			else
f416c42
+#endif /* MBS_SUPPORT */
f416c42
+			if (!WCHAR ((unsigned char) beg[start - 1]))
f416c42
+			  lword_match = 1;
f416c42
+		      }
f416c42
+
f416c42
+		    if (lword_match)
f416c42
+		      {
f416c42
+			int rword_match = 0;
f416c42
+			if (start + len == end - beg - 1)
f416c42
+			  rword_match = 1;
f416c42
+			else
f416c42
+			  {
f416c42
+#ifdef MBS_SUPPORT
f416c42
+			    if (mb_cur_max > 1)
f416c42
+			      {
f416c42
+				wchar_t nwc;
f416c42
+				int mr;
f416c42
+
f416c42
+				mr = mbtowc (&nwc, beg + start + len,
f416c42
+					     end - beg - start - len - 1);
f416c42
+				if (mr <= 0)
f416c42
+				  {
f416c42
+				    memset (&mbs, '\0', sizeof (mbstate_t));
f416c42
+				    rword_match = 1;
f416c42
+				  }
f416c42
+				else if (!iswalnum (nwc) && nwc != L'_')
f416c42
+				  rword_match = 1;
f416c42
+			      }
f416c42
+			    else
f416c42
+#endif /* MBS_SUPPORT */
f416c42
+			    if (!WCHAR ((unsigned char) beg[start + len]))
f416c42
+			      rword_match = 1;
f416c42
+			  }
f416c42
+
f416c42
+			if (rword_match)
f416c42
+			  {
f416c42
+			    if (!exact)
f416c42
+			      /* Returns the whole line. */
f416c42
+			      goto success_in_beg_and_end;
f416c42
+			    else
f416c42
+			      /* Returns just this word match. */
f416c42
+			      goto success_in_start_and_len;
f416c42
+			  }
f416c42
+		      }
f416c42
 		    if (len > 0)
f416c42
 		      {
f416c42
 			/* Try a shorter length anchored at the same place. */