Merge branch 'sg/progress-off-by-one-fix'
authorJunio C Hamano <gitster@pobox.com>
Thu, 30 May 2019 17:50:45 +0000 (10:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 30 May 2019 17:50:45 +0000 (10:50 -0700)
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

1  2 
progress.c
diff --combined progress.c
index 0318bdd41b2f40b6f3cedeb8ca72ead677038d6e,a4da26c2aadac239098578ef4d82956a164ef00d..a2e8cf64a8d1aa2f94c745bbb5098b9c771f3a05
@@@ -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);
  
  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"));
  }