Add visible terminal control debug helpers

This commit is contained in:
slhx agent
2026-06-21 16:41:15 +02:00
parent f88f688726
commit 8c4d09f709
2 changed files with 41 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
const std = @import("std");
/// Materialize terminal control characters as visible glyphs for failure output.
/// This is test/debug support only: product rendering still writes real CR/LF/ESC.
pub fn visibleControlsAlloc(allocator: std.mem.Allocator, bytes: []const u8) ![]u8 {
var out = std.ArrayList(u8).empty;
errdefer out.deinit(allocator);
for (bytes) |byte| switch (byte) {
'\r' => try out.appendSlice(allocator, ""),
'\n' => try out.appendSlice(allocator, "\n"),
0x1b => try out.appendSlice(allocator, ""),
'\t' => try out.appendSlice(allocator, ""),
else => if (byte < 0x20) {
try out.appendSlice(allocator, "");
} else try out.append(allocator, byte),
};
return out.toOwnedSlice(allocator);
}
pub fn hasBareLf(bytes: []const u8) bool {
for (bytes, 0..) |byte, i| {
if (byte == '\n' and (i == 0 or bytes[i - 1] != '\r')) return true;
}
return false;
}
test "regular: visible terminal controls expose newline and escape bytes" {
const debug = try visibleControlsAlloc(std.testing.allocator, "a\nb\r\n\x1b[31m");
defer std.testing.allocator.free(debug);
try std.testing.expectEqualStrings("a␊\nb␍␊\n␛[31m", debug);
}
test "adversarial: bare LF detector catches raw-mode skew risk" {
try std.testing.expect(hasBareLf("a\nb"));
try std.testing.expect(!hasBareLf("a\r\nb"));
}