[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox-cvs
Subject:    [git commit] vi: allow delimiter in ':s' to be escaped
From:       Denys Vlasenko <vda.linux () googlemail ! com>
Date:       2021-07-13 12:42:20
Message-ID: 20210713120945.C1F5B95519 () busybox ! osuosl ! org
[Download RAW message or body]

commit: https://git.busybox.net/busybox/commit/?id=2759201401cf87a9a8621edd9e5f44dfe838407c
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

When regular expressions are allowed in search commands it becomes
possible to escape the delimiter in search/replace commands.  For
example, this command will replace '/abc' with '/abc/':

   :s/\/abc/\/abc\//g

The code to split the command into 'find' and 'replace' strings
should allow for this possibility.

VI_REGEX_SEARCH isn't enabled by default.  When it is:

function                                             old     new   delta
strchr_backslash                                       -      38     +38
colon                                               4378    4373      -5
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/1 up/down: 38/-5)              Total: 33 bytes

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

diff --git a/editors/vi.c b/editors/vi.c
index 070e0f55a..c6bb74cfb 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2680,6 +2680,19 @@ static char *expand_args(char *args)
 #if ENABLE_FEATURE_VI_REGEX_SEARCH
 # define MAX_SUBPATTERN 10	// subpatterns \0 .. \9
 
+// Like strchr() but skipping backslash-escaped characters
+static char *strchr_backslash(const char *s, int c)
+{
+	for (; *s; ++s) {
+		if (*s == c) {
+			return (char *)s;
+		} else if (*s == '\\' && *++s == '\0') {
+			break;
+		}
+	}
+	return NULL;
+}
+
 // If the return value is not NULL the caller should free R
 static char *regex_search(char *q, regex_t *preg, const char *Rorig,
 				size_t *len_F, size_t *len_R, char **R)
@@ -2728,6 +2741,8 @@ static char *regex_search(char *q, regex_t *preg, const char *Rorig,
 
 	return found;
 }
+#else /* !ENABLE_FEATURE_VI_REGEX_SEARCH */
+# define strchr_backslash(s, c) strchr(s, c)
 #endif /* ENABLE_FEATURE_VI_REGEX_SEARCH */
 
 // buf must be no longer than MAX_INPUT_LEN!
@@ -3151,12 +3166,12 @@ static void colon(char *buf)
 		// replace the cmd line delimiters "/" with NULs
 		c = buf[1];	// what is the delimiter
 		F = buf + 2;	// start of "find"
-		R = strchr(F, c);	// middle delimiter
+		R = strchr_backslash(F, c);	// middle delimiter
 		if (!R)
 			goto colon_s_fail;
 		len_F = R - F;
 		*R++ = '\0';	// terminate "find"
-		flags = strchr(R, c);
+		flags = strchr_backslash(R, c);
 		if (flags) {
 			*flags++ = '\0';	// terminate "replace"
 			gflag = *flags;
_______________________________________________
busybox-cvs mailing list
busybox-cvs@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox-cvs
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic