Commit dfc4d618dd
Changed files (1)
lib
std
lib/std/debug.zig
@@ -104,6 +104,63 @@ pub fn getSelfDebugInfo() !*DebugInfo {
}
}
+/// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.
+pub fn hexdump(bytes: []const u8) void {
+ hexdump_internal(bytes) catch {};
+}
+
+fn hexdump_internal(bytes: []const u8) !void {
+ const stderr = std.io.getStdErr();
+ const ttyconf = std.io.tty.detectConfig(stderr);
+ const writer = stderr.writer();
+ var chunks = mem.window(u8, bytes, 16, 16);
+ while (chunks.next()) |window| {
+ // 1. Print the address.
+ const address = (@intFromPtr(bytes.ptr) + 0x10 * (chunks.index orelse 0) / 16) - 0x10;
+ try ttyconf.setColor(writer, .dim);
+ // We print the address in lowercase and the bytes in uppercase hexadecimal to distinguish them more.
+ // Also, make sure all lines are aligned by padding the address.
+ try writer.print("{x:0>[1]} ", .{ address, @sizeOf(usize) * 2 });
+ try ttyconf.setColor(writer, .reset);
+
+ // 2. Print the bytes.
+ for (window, 0..) |byte, index| {
+ try writer.print("{X:0>2} ", .{byte});
+ if (index == 7) try writer.writeByte(' ');
+ }
+ try writer.writeByte(' ');
+ if (window.len < 16) {
+ var missing_columns = (16 - window.len) * 3;
+ if (window.len < 8) missing_columns += 1;
+ try writer.writeByteNTimes(' ', missing_columns);
+ }
+
+ // 3. Print the characters.
+ for (window) |byte| {
+ if (std.ascii.isPrint(byte)) {
+ try writer.writeByte(byte);
+ } else {
+ // TODO: remove this `if` when https://github.com/ziglang/zig/issues/7600 is fixed
+ if (ttyconf == .windows_api) {
+ try writer.writeByte('.');
+ continue;
+ }
+
+ // Let's print some common control codes as graphical Unicode symbols.
+ // We don't want to do this for all control codes because most control codes apart from
+ // the ones that Zig has escape sequences for are likely not very useful to print as symbols.
+ switch (byte) {
+ '\n' => try writer.writeAll("โ"),
+ '\r' => try writer.writeAll("โ"),
+ '\t' => try writer.writeAll("โ"),
+ else => try writer.writeByte('.'),
+ }
+ }
+ }
+ try writer.writeByte('\n');
+ }
+}
+
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {