[comp.bugs.4bsd] another bug in vi + fix

greim@sbsvax.UUCP (Michael Greim) (07/27/88)

In <1244@potpourri.UUCP> Burch Seymour writes about a bug :

>I noticed the following strange behavior of vi and, while it's not exactly
>a critical problem, I am curious as to whether vi is flawed, or my 
>understanding of the way vi does searches is flawed.
>
>Consider the following three lines of text:
>
>loog loog loog loog loog loog
>loog loog loog loog loog loog
>loog loog loog loog loog loog
>
>Now search for loog using '/loog<cr>' followed by 'n' as required. Vi will
>stop the cursor on each word in the three lines. Fine so far. Now search
>using '/l.*g<cr>' and 'n'. Vi will stop at the first position of each line.
>This, or so I am told, is because vi matches the longest possible pattern,
>and the whole line matches, so the next match is on the next line. Fair
>enough. Now the buggy part.  Position the cursor on some character other
>than the first one on any of those lines. Then do the '/l.*g<cr>'. I would
>expect it to stop at the next occurance of 'l' on that line. It does not.
>It will stop at the first position of the next line. Anyone care to 
>speculate why? And is that a correct thing for it to do?

Here I present a fix. If the fix breaks something else please let me know.
I tried it only with a few commands, of course.

Diagnosis:
	Vi executes a loop to find the next match on the line if the cursor
	stands somewhere on the line. First it looks, if there is a match
	on the line, then it tries matches until it finds the first match
	after the current position.
	This is rather strange for forward search, but it makes sense
	for backward search (inverted of course).

Therapy:
	Omit the loop. We already know where we are in the line.
	Apply the following fix.

*** ex_addr.c.old	Wed Jul 27 15:32:04 1988
--- ex_addr.c	Wed Jul 27 15:18:35 1988
***************
*** 193,204 ****
  			addr = dot;
  			if (inline && execute(0, dot)) {
  				if (c == '/') {
! 					while (loc1 <= inline) {
! 						if (loc1 == loc2)
! 							loc2++;
! 						if (!execute(1))
! 							goto nope;
! 					}
  					break;
  				} else if (loc1 < inline) {
  					char *last;
--- 193,201 ----
  			addr = dot;
  			if (inline && execute(0, dot)) {
  				if (c == '/') {
! 					loc2 = inline + 1;
! 					if (!execute(1))
! 						goto nope;
  					break;
  				} else if (loc1 < inline) {
  					char *last;


Absorb, apply and enjoy,

	-mg
-- 
+------------------------------------------------------------------------------+
| UUCP:  ...!uunet!unido!sbsvax!greim   | Michael T. Greim                     |
|        or greim@sbsvax.UUCP           | Universitaet des Saarlandes          |
| CSNET: greim%sbsvax.uucp@Germany.CSnet| FB 10 - Informatik (Dept. of CS)     |
| ARPA:  greim%sbsvax.uucp@uunet.UU.NET | Bau 36, Im Stadtwald 15              |
| Phone: +49 681 302 2434               | D-6600 Saarbruecken 11, West Germany |
+------------------------------------------------------------------------------+
| # include <disclaimers/std.h>                                                |
+------------------------------------------------------------------------------+