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:
M | TODO | | | 8 | -------- |
M | ed.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);
}
}