commit 2732217a407c03900145e6f4191936ff6a33945a
Author:     Roberto E. Vargas Caballero <k...@shike2.com>
AuthorDate: Fri Dec 29 20:27:23 2023 +0100
Commit:     Roberto E. Vargas Caballero <k...@shike2.com>
CommitDate: Fri Dec 29 20:27:23 2023 +0100

    ed: Handle correctly lines in substitutions
    
    The s command can apply a replace pattern with embedded newlines
    which modifies the line/index assignament. Using a range in  the
    address fail because afther the call to subline() the next  line
    has to be searched based in the index because the replace  could
    insert newlines.

diff --git a/TODO b/TODO
index 94b025f..3432591 100644
--- a/TODO
+++ b/TODO
@@ -50,14 +50,6 @@ ed
     line
     .
     1g/^$/p
-* cat <<EOF | ed
-i
-foobar1
-foobar2
-.
-1,2s/foo/&\
-&/
-,n
 
 * Editing huge files doesn't work well.
 
diff --git a/ed.c b/ed.c
index 4cba483..bec9b2d 100644
--- a/ed.c
+++ b/ed.c
@@ -1226,11 +1226,23 @@ subline(int num, int nth)
 static void
 subst(int nth)
 {
-       int i;
+       int i, line, next;
 
-       for (i = line1; i <= line2; ++i) {
+       line = line1;
+       for (i = 0; i < line2 - line1 + 1; i++) {
                chksignals();
-               subline(i, nth);
+
+               next = getindex(nextln(line));
+               subline(line, nth);
+
+               /*
+                * The substitution command can add lines, so
+                * we have to skip lines until we find the
+                * index that we saved before the substitution
+                */
+               do
+                       line = nextln(line);
+               while (getindex(line) != next);
        }
 }
 

Reply via email to