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); } }