From 28a22fc07f50bc097a6bd0ad1d5f8c2e463a77bb Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 20 Jun 2023 09:24:07 -0700 Subject: [PATCH] various tests to ensure we parse curly underlines correctly --- src/terminal/Parser.zig | 55 +++++++++++++++++++++++++++++++++++++++++ src/terminal/sgr.zig | 6 +++++ src/terminal/stream.zig | 5 +++- src/termio/Exec.zig | 2 +- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/terminal/Parser.zig b/src/terminal/Parser.zig index 8e55ba564..0c3d8ca73 100644 --- a/src/terminal/Parser.zig +++ b/src/terminal/Parser.zig @@ -524,12 +524,67 @@ test "csi: SGR ESC [ 38 : 2 m" { const d = a[1].?.csi_dispatch; try testing.expect(d.final == 'm'); + try testing.expect(d.sep == .colon); try testing.expect(d.params.len == 2); try testing.expectEqual(@as(u16, 38), d.params[0]); try testing.expectEqual(@as(u16, 2), d.params[1]); } } +test "csi: SGR ESC [4:3m colon" { + var p = init(); + _ = p.next(0x1B); + _ = p.next('['); + _ = p.next('4'); + _ = p.next(':'); + _ = p.next('3'); + + { + const a = p.next('m'); + try testing.expect(p.state == .ground); + try testing.expect(a[0] == null); + try testing.expect(a[1].? == .csi_dispatch); + try testing.expect(a[2] == null); + + const d = a[1].?.csi_dispatch; + try testing.expect(d.final == 'm'); + try testing.expect(d.sep == .colon); + try testing.expect(d.params.len == 2); + try testing.expectEqual(@as(u16, 4), d.params[0]); + try testing.expectEqual(@as(u16, 3), d.params[1]); + } +} + +test "csi: SGR with many blank and colon" { + var p = init(); + _ = p.next(0x1B); + for ("[58:2::240:143:104") |c| { + const a = p.next(c); + try testing.expect(a[0] == null); + try testing.expect(a[1] == null); + try testing.expect(a[2] == null); + } + + { + const a = p.next('m'); + try testing.expect(p.state == .ground); + try testing.expect(a[0] == null); + try testing.expect(a[1].? == .csi_dispatch); + try testing.expect(a[2] == null); + + const d = a[1].?.csi_dispatch; + try testing.expect(d.final == 'm'); + try testing.expect(d.sep == .colon); + try testing.expect(d.params.len == 6); + try testing.expectEqual(@as(u16, 58), d.params[0]); + try testing.expectEqual(@as(u16, 2), d.params[1]); + try testing.expectEqual(@as(u16, 0), d.params[2]); + try testing.expectEqual(@as(u16, 240), d.params[3]); + try testing.expectEqual(@as(u16, 143), d.params[4]); + try testing.expectEqual(@as(u16, 104), d.params[5]); + } +} + test "csi: mixing semicolon/colon" { var p = init(); _ = p.next(0x1B); diff --git a/src/terminal/sgr.zig b/src/terminal/sgr.zig index eda08ac8c..5d57162e8 100644 --- a/src/terminal/sgr.zig +++ b/src/terminal/sgr.zig @@ -344,6 +344,12 @@ test "sgr: underline styles" { try testing.expect(v.underline == .single); } + { + const v = testParseColon(&[_]u16{ 4, 3 }); + try testing.expect(v == .underline); + try testing.expect(v.underline == .curly); + } + { const v = testParseColon(&[_]u16{ 4, 4 }); try testing.expect(v == .underline); diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index f36fa6315..b121f123e 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -385,7 +385,10 @@ pub fn Stream(comptime Handler: type) type { // SGR - Select Graphic Rendition 'm' => if (@hasDecl(T, "setAttribute")) { var p: sgr.Parser = .{ .params = action.params, .colon = action.sep == .colon }; - while (p.next()) |attr| try self.handler.setAttribute(attr); + while (p.next()) |attr| { + //log.info("SGR attribute: {}", .{attr}); + try self.handler.setAttribute(attr); + } } else log.warn("unimplemented CSI callback: {}", .{action}), // CPR - Request Cursor Postion Report diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 0f513c0ba..80ea35348 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -1081,7 +1081,7 @@ const StreamHandler = struct { pub fn setAttribute(self: *StreamHandler, attr: terminal.Attribute) !void { switch (attr) { - .unknown => |unk| log.warn("unimplemented or unknown attribute: {any}", .{unk}), + .unknown => |unk| log.warn("unimplemented or unknown SGR attribute: {any}", .{unk}), else => self.terminal.setAttribute(attr) catch |err| log.warn("error setting attribute {}: {}", .{ attr, err }),