From 8ed792b640ef3601dfb773d670915d74fbbbad13 Mon Sep 17 00:00:00 2001 From: erikarvstedt <36110478+erikarvstedt@users.noreply.github.com> Date: Mon, 14 Feb 2022 11:14:50 +0100 Subject: [PATCH] std.Progress: fix suffix printing Previously, `suffix` was copied to `output_buffer` at position `max_end`, thereby writing into reserved space after `max_end`. This only worked because `suffix` was not larger than `bytes_needed_for_esc_codes_at_end` (otherwise there'd be a potential buffer overrun) and no escape codes at end are actually written. Since 2d5b2bf1c986d037ef965bf8c9b4d8dfd5967478, escape codes are no longer written to the end of the buffer. They are now written exclusively to the front of the buffer. This allows removing `bytes_needed_for_esc_codes_at_end` and simplifying the suffix printing logic. This also fixes the bug that the ellipse suffix was not printed in Windows terminals because `end.* > max_end` was never true. --- lib/std/Progress.zig | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index ecef04c600..07f9077844 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -312,16 +312,10 @@ fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: any error.NoSpaceLeft => { self.columns_written += self.output_buffer.len - end.*; end.* = self.output_buffer.len; + const suffix = "... "; + std.mem.copy(u8, self.output_buffer[self.output_buffer.len - suffix.len ..], suffix); }, } - const bytes_needed_for_esc_codes_at_end: u8 = if (self.is_windows_terminal) 0 else 11; - const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end; - if (end.* > max_end) { - const suffix = "... "; - self.columns_written = self.columns_written - (end.* - max_end) + suffix.len; - std.mem.copy(u8, self.output_buffer[max_end..], suffix); - end.* = max_end + suffix.len; - } } test "basic functionality" { @@ -335,6 +329,8 @@ test "basic functionality" { const root_node = progress.start("", 100); defer root_node.end(); + const speed_factor = std.time.ns_per_ms; + const sub_task_names = [_][]const u8{ "reticulating splines", "adjusting shoes", @@ -350,24 +346,24 @@ test "basic functionality" { next_sub_task = (next_sub_task + 1) % sub_task_names.len; node.completeOne(); - std.time.sleep(5 * std.time.ns_per_ms); + std.time.sleep(5 * speed_factor); node.completeOne(); node.completeOne(); - std.time.sleep(5 * std.time.ns_per_ms); + std.time.sleep(5 * speed_factor); node.completeOne(); node.completeOne(); - std.time.sleep(5 * std.time.ns_per_ms); + std.time.sleep(5 * speed_factor); node.end(); - std.time.sleep(5 * std.time.ns_per_ms); + std.time.sleep(5 * speed_factor); } { var node = root_node.start("this is a really long name designed to activate the truncation code. let's find out if it works", 0); node.activate(); - std.time.sleep(10 * std.time.ns_per_ms); + std.time.sleep(10 * speed_factor); progress.refresh(); - std.time.sleep(10 * std.time.ns_per_ms); + std.time.sleep(10 * speed_factor); node.end(); } }