From 12badb9a44b61ecf7491ce825a3278f8ebc6653c Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 25 Mar 2022 01:12:56 +0000 Subject: [PATCH 1/1] multiprogress.c: Fix `split_string' to overestimate. Doing the right thing in `advance_measure' is much harder if `split_string' sometimes falls short of the requested bound because of wide characters. On the other hand, overestimating is a little tricky because we must remember to include all of the following zero- width (e.g., combining) characters or the prefix will just be wrong. But it's better to do this than come up with some kludge to make `advance_measure' sometimes advance the state even when we've not actually reached the right position. --- multiprogress.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/multiprogress.c b/multiprogress.c index f63eaa6..6945620 100644 --- a/multiprogress.c +++ b/multiprogress.c @@ -254,16 +254,22 @@ static size_t split_string(const char *p, size_t sz, unsigned *wd_out, unsigned maxwd) { struct measure m; - size_t lasti; unsigned lastwd; + size_t i; unsigned wd; int more; init_measure(&m, p, sz); for (;;) { - lasti = m.i; lastwd = m.wd; + if (!advance_measure(&m)) { *wd_out = m.wd; return (sz); } + if (m.wd >= maxwd) break; + } + wd = m.wd; i = m.i; + for (;;) { more = advance_measure(&m); - if (m.wd > maxwd) { *wd_out = lastwd; return (lasti); } - else if (!more) { *wd_out = m.wd; return (sz); } + if (m.wd > wd) break; + i = m.i; + if (!more) break; } + *wd_out = wd; return (i); } static int grow_linebuf(struct progress_render_state *render, size_t want) @@ -488,7 +494,7 @@ static void advance_bar_state(struct bar_state *bar) const struct progress_ttyinfo *tty = render->tty; size_t here = bar->nextpos; - while (bar->nextpos == here) { + while (bar->nextpos <= here) { switch (bar->state) { case LEFT_COLOUR: set_bgcolour(tty, 3); goto right; case LEFT_MONO: put_sequence(tty, tty->cap.me, 1); goto right; -- 2.11.0