commit 0b117ab6c0d9771c0556180bc47c1988576ae740
Author:     Roberto E. Vargas Caballero <k...@shike2.com>
AuthorDate: Thu Jan 7 11:44:49 2016 +0100
Commit:     sin <s...@2f30.org>
CommitDate: Mon Jan 11 15:37:58 2016 +0000

    Fix pattern substitution
    
    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.

diff --git a/ed.c b/ed.c
index 0fc07b1..67ffdb8 100644
--- a/ed.c
+++ b/ed.c
@@ -957,12 +957,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 '&':
@@ -970,7 +978,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';
@@ -986,24 +994,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;

Reply via email to