summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sam_edit.zig12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/sam_edit.zig b/src/sam_edit.zig
index 40221628..e8e90b67 100644
--- a/src/sam_edit.zig
+++ b/src/sam_edit.zig
@@ -95,6 +95,8 @@ const Parser = struct {
i: usize = 0,
/// The last pattern given, for an empty one (edit.c:562, getregexp).
lastpat: []const u8 = "",
+ /// The last `parse` that answered null met a `}`, not the end.
+ braced: bool = false,
why: *Why,
fn getch(ps: *Parser) ?u8 {
@@ -326,12 +328,18 @@ const Parser = struct {
var last: ?*Cmd = null;
while (true) {
if (ps.skipbl() == '\n') ps.i += 1;
- const next = (try ps.parse(nest + 1)) orelse break;
+ ps.braced = false;
+ const next = (try ps.parse(nest + 1)) orelse {
+ // sam reads on for the `}`; an Edit has no more to read.
+ if (!ps.braced) return fail(ps.why, "unmatched `{{'", .{});
+ break;
+ };
if (last) |l| l.next = next else cmd.sub = next;
last = next;
}
},
'}' => {
+ ps.braced = true;
try ps.atnl();
if (nest == 0) return fail(ps.why, "right brace with no left brace", .{});
return null;
@@ -655,6 +663,8 @@ test "an Edit that fails halfway changes nothing, and says why in acme's words"
.{ "k", "unknown command k" },
.{ ",x/a/{\na/1/\ni/2/\n}", "changes out of sequence" },
.{ "}", "right brace with no left brace" },
+ .{ ",x/foo/{", "unmatched `{'" },
+ .{ ",x/foo/{\nd", "unmatched `{'" },
.{ "w /tmp/x", "w is not supported in pardes" },
.{ ",s/(a)/\\1/", "no \\1: mvzr keeps no submatches" },
.{ "1 m 1,2", "move overlaps itself" },