diff options
Diffstat (limited to 'src/ninep')
| -rw-r--r-- | src/ninep/ctl.zig | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 06eb8cdd..697ef594 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -300,7 +300,7 @@ pub fn failureErrno(failure: []const u8) u16 { if (std.mem.indexOf(u8, failure, "no such") != null or std.mem.indexOf(u8, failure, "not found") != null) return E.NOENT; // A pattern refused (Edit's too) is malformed input, as 9ns reads it; // so is a word this build has not (`invalid: acme's Put ...`). - if (std.mem.indexOf(u8, failure, "bad regular expression") != null or std.mem.startsWith(u8, failure, "invalid") or + if (std.mem.indexOf(u8, failure, "bad regular expression") != null or std.mem.indexOf(u8, failure, "invalid") != null or std.mem.startsWith(u8, failure, "address out of range")) return E.INVAL; // A word's arguments wrong, or a dial that is no address: what 9ns // reads as EINVAL from the same words (`control message`, `bad `). @@ -997,7 +997,8 @@ pub fn writePane(p: *Pardes, req: Req, pane: *Pane) Reply { // else leaves it standing, and says what it takes. if (!std.mem.eql(u8, choice, "-") and (choice.len != 1 or std.mem.indexOfScalar(u8, choices, choice[0]) == null)) { var why: [96]u8 = undefined; - return refuse(p, req, std.fmt.bufPrint(&why, "answer takes {s} or -", .{choices}) catch "answer takes a choice or -", line); + // The choice refused is what is quoted: `answer takes a b or - "z"`. + return refuseQuoting(p, req, std.fmt.bufPrint(&why, "answer takes {s} or -", .{choices}) catch "answer takes a choice or -", choice); } if (apply) _ = p.answerQuestion(id, if (choice[0] == '-') null else choice[0]); } else if (!apply) { @@ -1032,6 +1033,9 @@ fn acmeCtl(p: *Pardes, req: Req, serial: u32, line: []const u8, apply: bool) Acm // name's first byte: a line's words are split at blanks. if (std.mem.eql(u8, word, "name") and rest.len > 0 and line[word.len + 1] == ' ') return .{ .refused = tree.failText(req.tag, E.INVAL, "bad character in file name: a blank at its start") }; + // `name` with nothing after it names nothing: said so, not an unknown word. + if (std.mem.eql(u8, word, "name") and rest.len == 0) + return .{ .refused = tree.failText(req.tag, E.INVAL, "invalid file name: name takes the name, and there is none") }; const into: ?Into = if (std.mem.eql(u8, word, "name") and rest.len > 0) .{ .file = .name, .data = line[word.len + 1 ..] } else if (std.mem.eql(u8, line, "clean")) @@ -2356,7 +2360,7 @@ test "a setting this frontend cannot show says GUI-only, and DumpDir reads back if (comptime !pardes.font_picker) { try testing.expectEqualStrings("Fonts is GUI-only, invalid here \"Fonts\"", wr(p, root_ctl, "Fonts\n").reply.ename); const ran = wr(p, root_exec, "Fonts\n"); - try testing.expectEqual(E.IO, ran.errno()); + try testing.expectEqual(E.INVAL, ran.errno()); try testing.expectEqualStrings("Fonts is GUI-only, invalid here", ran.reply.ename); } } @@ -3697,13 +3701,22 @@ test "size is monotonic: growing is never refused, and a size once taken is take try testing.expectStringStartsWith(bad.reply.ename, "invalid size"); } -test "Repl with no such language names a few whole, and where the rest are" { +test "Repl with no such language is invalid, EINVAL, and names a few whole and how many more" { const p = try th.withTerm(testing.allocator); defer p.deinit(); const refused = wr(p, Node.of(serialOf(p), .ctl), "Repl zzlang\n"); - try testing.expectEqual(Status.err, refused.reply.status); - try testing.expect(std.mem.indexOf(u8, refused.reply.ename, "Repl: no language \"zzlang\"; - or one like zig ada bash c c_sharp clojure (") != null); - try testing.expect(std.mem.indexOf(u8, refused.reply.ename, " more: docs/typ/reference.typ, REPLs)") != null); + try testing.expectEqual(E.INVAL, refused.errno()); + try testing.expect(std.mem.indexOf(u8, refused.reply.ename, "Repl: invalid language \"zzlang\"; - or one like zig ada bash c c_sharp clojure (") != null); + try testing.expect(std.mem.endsWith(u8, refused.reply.ename, " more)")); +} + +test "answer quotes the choice it refuses, and a bare name says it names nothing" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const node = Node.of(serialOf(p), .ctl); + const empty = wr(p, node, "name \n"); + try testing.expectEqual(E.INVAL, empty.errno()); + try testing.expectEqualStrings("invalid file name: name takes the name, and there is none", empty.reply.ename); } test "a 10k-line Edit text block is taken in linear time and memory" { |
