Submitted By: Jim Gifford (patches at jg555 dot com)
Date: 2003-09-09
Initial Package Version: 2.5.1
Origin: http://savannah.gnu.org/patch/download.php?id=1834
Description: Fixes -w option
	* src/search.c: (EGexecute) fix missing free of
	  multibyte properties, correct returned offset
	  and match_length when -w is in effect.
	* src/grep.c: fix compiler warning.
 	* src/search.c: (Fexecute) fix match_word mode,
	  using code more similar to that in EGexecute
	  and taking into account the 'exact' parameter.


diff -Naur grep-2.5.1.orig/src/grep.c grep-2.5.1/src/grep.c
--- grep-2.5.1.orig/src/grep.c	2003-09-10 04:24:38.000000000 +0000
+++ grep-2.5.1/src/grep.c	2003-09-10 04:25:52.000000000 +0000
@@ -556,7 +556,7 @@
 	      if(color_option)
 		fputs("\33[00m", stdout);
 	      fputs("\n", stdout);
-	      ibeg = b + match_size;
+	      ibeg = (char*) (b + match_size);
 	    }
 	  free (buf);
 	  lastout = lim;
diff -Naur grep-2.5.1.orig/src/search.c grep-2.5.1/src/search.c
--- grep-2.5.1.orig/src/search.c	2001-04-19 03:42:14.000000000 +0000
+++ grep-2.5.1/src/search.c	2003-09-10 04:25:52.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_start_and_len;
 		    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)
@@ -547,31 +532,37 @@
 	  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)
-		  {
-#ifdef MBS_SUPPORT
-		    if (MB_CUR_MAX > 1)
-		      free (mb_properties);
-#endif /* MBS_SUPPORT */
-		    return offset;
-		  }
-		try = beg + offset;
-		len = kwsmatch.size[0];
-	      }
-	    else
-	      goto success;
-	  }
+	{
+	  while (offset >= 0)
+	    {
+	      if ((offset == 0 || !WCHAR ((unsigned char) beg[-1]))
+	          && (len == end - beg - 1 || !WCHAR ((unsigned char) beg[len])))
+	        {
+	          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) {
+	            break; /* Try a different anchor. */
+	          }
+	          beg += offset;
+	          len = kwsmatch.size[0];
+	        }
+	    }
+	}
       else
 	goto success;
     }
 
+ failure:
 #ifdef MBS_SUPPORT
   if (MB_CUR_MAX > 1)
     free (mb_properties);
@@ -583,7 +574,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);
