From: Junio C Hamano Date: Thu, 30 May 2019 17:50:45 +0000 (-0700) Subject: Merge branch 'sg/progress-off-by-one-fix' X-Git-Tag: v2.22.0-rc2~5 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/fa03d9c6990aa0f0ca675e89bde1861988d0c517?ds=inline;hp=-c Merge branch 'sg/progress-off-by-one-fix' A brown-paper-bag bugfix to a change already in 'master'. * sg/progress-off-by-one-fix: progress: avoid empty line when breaking the progress line --- fa03d9c6990aa0f0ca675e89bde1861988d0c517 diff --combined progress.c index 0318bdd41b,a4da26c2aa..a2e8cf64a8 --- a/progress.c +++ b/progress.c @@@ -35,7 -35,6 +35,7 @@@ struct progress uint64_t total; unsigned last_percent; unsigned delay; + unsigned sparse; struct throughput *throughput; uint64_t start_ns; struct strbuf counters_sb; @@@ -128,7 -127,7 +128,7 @@@ static void display(struct progress *pr (int) clear_len, eol); } else if (!done && cols < progress_line_len) { clear_len = progress->title_len + 1 < cols ? - cols - progress->title_len : 0; + cols - progress->title_len - 1 : 0; fprintf(stderr, "%s:%*s\n %s%s", progress->title, (int) clear_len, "", counters_sb->buf, eol); @@@ -167,10 -166,12 +167,10 @@@ void display_throughput(struct progres now_ns = getnanotime(); if (!tp) { - progress->throughput = tp = calloc(1, sizeof(*tp)); - if (tp) { - tp->prev_total = tp->curr_total = total; - tp->prev_ns = now_ns; - strbuf_init(&tp->display, 0); - } + progress->throughput = tp = xcalloc(1, sizeof(*tp)); + tp->prev_total = tp->curr_total = total; + tp->prev_ns = now_ns; + strbuf_init(&tp->display, 0); return; } tp->curr_total = total; @@@ -221,15 -222,20 +221,15 @@@ void display_progress(struct progress * } static struct progress *start_progress_delay(const char *title, uint64_t total, - unsigned delay) + unsigned delay, unsigned sparse) { - struct progress *progress = malloc(sizeof(*progress)); - if (!progress) { - /* unlikely, but here's a good fallback */ - fprintf(stderr, "%s...\n", title); - fflush(stderr); - return NULL; - } + struct progress *progress = xmalloc(sizeof(*progress)); progress->title = title; progress->total = total; progress->last_value = -1; progress->last_percent = -1; progress->delay = delay; + progress->sparse = sparse; progress->throughput = NULL; progress->start_ns = getnanotime(); strbuf_init(&progress->counters_sb, 0); @@@ -241,46 -247,16 +241,46 @@@ struct progress *start_delayed_progress(const char *title, uint64_t total) { - return start_progress_delay(title, total, 2); + return start_progress_delay(title, total, 2, 0); } struct progress *start_progress(const char *title, uint64_t total) { - return start_progress_delay(title, total, 0); + return start_progress_delay(title, total, 0, 0); +} + +/* + * Here "sparse" means that the caller might use some sampling criteria to + * decide when to call display_progress() rather than calling it for every + * integer value in[0 .. total). In particular, the caller might not call + * display_progress() for the last value in the range. + * + * When "sparse" is set, stop_progress() will automatically force the done + * message to show 100%. + */ +struct progress *start_sparse_progress(const char *title, uint64_t total) +{ + return start_progress_delay(title, total, 0, 1); +} + +struct progress *start_delayed_sparse_progress(const char *title, + uint64_t total) +{ + return start_progress_delay(title, total, 2, 1); +} + +static void finish_if_sparse(struct progress *progress) +{ + if (progress && + progress->sparse && + progress->last_value != progress->total) + display_progress(progress, progress->total); } void stop_progress(struct progress **p_progress) { + finish_if_sparse(*p_progress); + stop_progress_msg(p_progress, _("done")); }