authorgravatar for 36110478+erikarvstedt@users.noreply.github.comerikarvstedt <36110478+erikarvstedt@users.noreply.github.com> 2022-02-14 11:14:50+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-14 12:14:50+02:00
log8ed792b640ef3601dfb773d670915d74fbbbad13
tree8f5060f3d06d23275ebb2852a25bdf9dc3defb81
parent9ca3c897ec546bc08eefe53471c995deefc9f36d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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.

1 files changed, 10 insertions(+), 14 deletions(-)

lib/std/Progress.zig+10-14
......@@ -312,16 +312,10 @@ fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: any
312312 error.NoSpaceLeft => {
313313 self.columns_written += self.output_buffer.len - end.*;
314314 end.* = self.output_buffer.len;
315 const suffix = "... ";
316 std.mem.copy(u8, self.output_buffer[self.output_buffer.len - suffix.len ..], suffix);
315317 },
316318 }
317 const bytes_needed_for_esc_codes_at_end: u8 = if (self.is_windows_terminal) 0 else 11;
318 const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end;
319 if (end.* > max_end) {
320 const suffix = "... ";
321 self.columns_written = self.columns_written - (end.* - max_end) + suffix.len;
322 std.mem.copy(u8, self.output_buffer[max_end..], suffix);
323 end.* = max_end + suffix.len;
324 }
325319}
326320
327321test "basic functionality" {
......@@ -335,6 +329,8 @@ test "basic functionality" {
335329 const root_node = progress.start("", 100);
336330 defer root_node.end();
337331
332 const speed_factor = std.time.ns_per_ms;
333
338334 const sub_task_names = [_][]const u8{
339335 "reticulating splines",
340336 "adjusting shoes",
......@@ -350,24 +346,24 @@ test "basic functionality" {
350346 next_sub_task = (next_sub_task + 1) % sub_task_names.len;
351347
352348 node.completeOne();
353 std.time.sleep(5 * std.time.ns_per_ms);
349 std.time.sleep(5 * speed_factor);
354350 node.completeOne();
355351 node.completeOne();
356 std.time.sleep(5 * std.time.ns_per_ms);
352 std.time.sleep(5 * speed_factor);
357353 node.completeOne();
358354 node.completeOne();
359 std.time.sleep(5 * std.time.ns_per_ms);
355 std.time.sleep(5 * speed_factor);
360356
361357 node.end();
362358
363 std.time.sleep(5 * std.time.ns_per_ms);
359 std.time.sleep(5 * speed_factor);
364360 }
365361 {
366362 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);
367363 node.activate();
368 std.time.sleep(10 * std.time.ns_per_ms);
364 std.time.sleep(10 * speed_factor);
369365 progress.refresh();
370 std.time.sleep(10 * std.time.ns_per_ms);
366 std.time.sleep(10 * speed_factor);
371367 node.end();
372368 }
373369}