sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit 2732217a407c03900145e6f4191936ff6a33945a
parent e24228e0626e9f8ee89272f0f42d9ff9be078346
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 29 Dec 2023 20:27:23 +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.

Diffstat:
MTODO | 8--------
Med.c | 18+++++++++++++++---
2 files changed, 15 insertions(+), 11 deletions(-)

diff --git 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 @@ -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); } }