[hackers] [sbase][PATCH v2] Fix pattern substitution

From: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
Date: Thu, 7 Jan 2016 11:44:49 +0100

Ed was falling doing substitution different of the first or all
(s//%/, s//%/\1, s//%/g), because it was not adding the matches
which were not going to be substituted.
---
 ed.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/ed.c b/ed.c
index 77aad19..69c7422 100644
--- a/ed.c
+++ b/ed.c
_AT_@ -959,12 +959,20 @@ addpost(char **s, size_t *cap, size_t *siz)
 	*s = addchar('\0', *s, cap, siz);
 }
 
-static void
-addsub(char **s, size_t *cap, size_t *siz)
+static int
+addsub(char **s, size_t *cap, size_t *siz, int nth, int nmatch)
 {
 	char *end, *q, *p, c;
 	int sub;
 
+	if (nth != nmatch && nth != -1) {
+		q   = lastmatch + matchs[0].rm_so;
+		end = lastmatch + matchs[0].rm_eo;
+		while (q < end)
+			*s = addchar(*q++, *s, cap, siz);
+		return 0;
+	}
+
 	for (p = rhs; (c = *p); ++p) {
 		switch (c) {
 		case '&':
_AT_@ -972,7 +980,7 @@ addsub(char **s, size_t *cap, size_t *siz)
 			goto copy_match;
 		case '\\':
 			if ((c = *++p) == '\0')
-				return;
+				return 1;
 			if (!isdigit(c))
 				goto copy_char;
 			sub = c - '0';
_AT_@ -988,24 +996,20 @@ addsub(char **s, size_t *cap, size_t *siz)
 			break;
 		}
 	}
+	return 1;
 }
 
 static void
 subline(int num, int nth)
 {
-	int m, changed;
+	int i, m, changed;
 	static char *s;
 	static size_t siz, cap;
 
-	siz = 0;
+	i = changed = siz = 0;
 	for (m = match(num); m; m = rematch(num)) {
 		addpre(&s, &cap, &siz);
-		if (--nth > 0)
-			continue;
-		changed = 1;
-		addsub(&s, &cap, &siz);
-		if (nth == 0)
-			break;
+		changed |= addsub(&s, &cap, &siz, nth, ++i);
 	}
 	if (!changed)
 		return;
-- 
2.1.4
Received on Thu Jan 07 2016 - 11:44:49 CET

This archive was generated by hypermail 2.3.0 : Thu Jan 07 2016 - 11:48:17 CET