[git commit] vi: fixes to string search in colon commands, closes 10321

Denys Vlasenko vda.linux at googlemail.com
Wed Jan 29 13:01:50 UTC 2020


commit: https://git.busybox.net/busybox/commit/?id=16bcd504a32e6a7bf2015ffb241133f9ead6100b
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Handling of string searches in colon commands (e.g ':/pat1/,/pat2/cmd')
differ from standard vi:

- As reported in bug 10321 such searches can't be repeated using the
  'n' command.  This is because the last search pattern isn't updated.

- The search also can't be repeated using the command '://' because
  an empty search pattern doesn't imply the use of the last search
  pattern.

- Such searches should start on the line after the current line,
  otherwise '://' never moves to the next occurrence of the pattern.
  This can also affect other cases where line ranges are specified
  using search patterns.

Fix these various issues.

function                                             old     new   delta
get_one_address                                      325     342     +17

Signed-off-by: Ron Yorston <rmy at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/vi.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 51dfc1209..1dd0b6fb6 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2251,7 +2251,6 @@ static char *get_one_address(char *p, int *addr)	// get colon addr, if present
 	int st;
 	char *q;
 	IF_FEATURE_VI_YANKMARK(char c;)
-	IF_FEATURE_VI_SEARCH(char *pat;)
 
 	*addr = -1;			// assume no addr
 	if (*p == '.') {	// the current line
@@ -2276,16 +2275,20 @@ static char *get_one_address(char *p, int *addr)	// get colon addr, if present
 #endif
 #if ENABLE_FEATURE_VI_SEARCH
 	else if (*p == '/') {	// a search pattern
-		q = strchrnul(++p, '/');
-		pat = xstrndup(p, q - p); // save copy of pattern
+		q = strchrnul(p + 1, '/');
+		if (p + 1 != q) {
+			// save copy of new pattern
+			free(last_search_pattern);
+			last_search_pattern = xstrndup(p, q - p);
+		}
 		p = q;
 		if (*p == '/')
 			p++;
-		q = char_search(dot, pat, (FORWARD << 1) | FULL);
+		q = char_search(next_line(dot), last_search_pattern + 1,
+						(FORWARD << 1) | FULL);
 		if (q != NULL) {
 			*addr = count_lines(text, q);
 		}
-		free(pat);
 	}
 #endif
 	else if (*p == '$') {	// the last line in file


More information about the busybox-cvs mailing list