Esempio n. 1
0
void
progress_bar_set (struct progress_bar *bar,
                  uint64_t position, uint64_t total)
{
  size_t i, cols;
  int pulse_mode;
  double ratio;
  const char *s_open, *s_dot, *s_dash, *s_close;

  if (bar->machine_readable || bar->have_terminfo == 0) {
  dumb:
    printf ("%" PRIu64 "/%" PRIu64 "\n", position, total);
  } else {
    cols = tgetnum ((char *) "co");
    if (cols < 32) goto dumb;

    /* Update an existing progress bar just printed? */
    if (bar->count > 0)
      tputs (UP, 2, putchar);
    bar->count++;

    /* Find out if we're in "pulse mode". */
    pulse_mode = position == 0 && total == 1;

    ratio = (double) position / total;
    if (ratio < 0) ratio = 0; else if (ratio > 1) ratio = 1;

    if (pulse_mode) {
      printf ("%s --- ", spinner (bar, bar->count));
    }
    else if (ratio < 1) {
      int percent = 100.0 * ratio;
      printf ("%s%3d%% ", spinner (bar, bar->count), percent);
    }
    else {
      fputs (" 100% ", stdout);
    }

    if (bar->utf8_mode) {
      s_open = "\u27e6";
      s_dot = "\u2593";
      s_dash = "\u2550";
      s_close = "\u27e7";
    } else {
      s_open = "["; s_dot = "#"; s_dash = "-"; s_close = "]";
    }

    fputs (s_open, stdout);

    if (!pulse_mode) {
      size_t dots = ratio * (double) (cols - COLS_OVERHEAD);

      for (i = 0; i < dots; ++i)
        fputs (s_dot, stdout);
      for (i = dots; i < cols - COLS_OVERHEAD; ++i)
        fputs (s_dash, stdout);
    }
    else {           /* "Pulse mode": the progress bar just pulses. */
      for (i = 0; i < cols - COLS_OVERHEAD; ++i) {
        int cc = (bar->count * 3 - i) % (cols - COLS_OVERHEAD);
        if (cc >= 0 && cc <= 3)
          fputs (s_dot, stdout);
        else
          fputs (s_dash, stdout);
      }
    }

    fputs (s_close, stdout);
    fputc (' ', stdout);

    /* Time estimate. */
    double estimate = estimate_remaining_time (bar, ratio);
    if (estimate >= 100.0 * 60.0 * 60.0 /* >= 100 hours */) {
      /* Display hours<h> */
      estimate /= 60. * 60.;
      int hh = floor (estimate);
      printf (">%dh", hh);
    } else if (estimate >= 100.0 * 60.0 /* >= 100 minutes */) {
      /* Display hours<h>minutes */
      estimate /= 60. * 60.;
      int hh = floor (estimate);
      double ignore;
      int mm = floor (modf (estimate, &ignore) * 60.);
      printf ("%02dh%02d", hh, mm);
    } else if (estimate >= 0.0) {
      /* Display minutes:seconds */
      estimate /= 60.;
      int mm = floor (estimate);
      double ignore;
      int ss = floor (modf (estimate, &ignore) * 60.);
      printf ("%02d:%02d", mm, ss);
    }
    else /* < 0 means estimate was not meaningful */
      fputs ("--:--", stdout);

    fputc ('\n', stdout);
  }
  fflush (stdout);
}
Esempio n. 2
0
void
progress_bar_set (struct progress_bar *bar,
                  uint64_t position, uint64_t total)
{
  size_t i, cols;
  int pulse_mode;
  double ratio;
  const char *s_open, *s_dot, *s_dash, *s_close;
  FILE *fp;

  if (bar->machine_readable || bar->have_terminfo == 0) {
  dumb:
    printf ("%" PRIu64 "/%" PRIu64 "\n", position, total);
    fflush (stdout);
  } else {
    cols = tgetnum ((char *) "co");
    if (cols < 32) goto dumb;

    /* Send progress bar output to /dev/tty if we could open it, else stdout. */
    fp = bar->fp;
    if (!fp)
      fp = stdout;

    /* Update an existing progress bar just printed? */
    if (bar->count > 0) {
      /* XXX We should call tputs here, but (a) it's unlikely that any
       * modern terminal is so slow that it requires padding, and
       * (b) it's just not possible to use tputs in a sane way here.
       */
      /*tputs (UP, 2, putchar);*/
      fprintf (fp, "%s", UP);
    }
    bar->count++;

    /* Find out if we're in "pulse mode". */
    pulse_mode = position == 0 && total == 1;

    ratio = (double) position / total;
    if (ratio < 0) ratio = 0; else if (ratio > 1) ratio = 1;

    if (pulse_mode) {
      fprintf (fp, "%s --- ", spinner (bar, bar->count));
    }
    else if (ratio < 1) {
      int percent = 100.0 * ratio;
      fprintf (fp, "%s%3d%% ", spinner (bar, bar->count), percent);
    }
    else {
      fputs (" 100% ", fp);
    }

    if (bar->utf8_mode) {
      s_open = "\u27e6";
      s_dot = "\u2592";
      s_dash = "\u2550";
      s_close = "\u27e7";
    } else {
      s_open = "["; s_dot = "#"; s_dash = "-"; s_close = "]";
    }

    fputs (s_open, fp);

    if (!pulse_mode) {
      size_t dots = ratio * (double) (cols - COLS_OVERHEAD);

      for (i = 0; i < dots; ++i)
        fputs (s_dot, fp);
      for (i = dots; i < cols - COLS_OVERHEAD; ++i)
        fputs (s_dash, fp);
    }
    else {           /* "Pulse mode": the progress bar just pulses. */
      for (i = 0; i < cols - COLS_OVERHEAD; ++i) {
        int cc = (bar->count * 3 - i) % (cols - COLS_OVERHEAD);
        if (cc >= 0 && cc <= 3)
          fputs (s_dot, fp);
        else
          fputs (s_dash, fp);
      }
    }

    fputs (s_close, fp);
    fputc (' ', fp);

    /* Time estimate. */
    double estimate = estimate_remaining_time (bar, ratio);
    if (estimate >= 100.0 * 60.0 * 60.0 /* >= 100 hours */) {
      /* Display hours<h> */
      estimate /= 60. * 60.;
      int hh = floor (estimate);
      fprintf (fp, ">%dh", hh);
    } else if (estimate >= 100.0 * 60.0 /* >= 100 minutes */) {
      /* Display hours<h>minutes */
      estimate /= 60. * 60.;
      int hh = floor (estimate);
      double ignore;
      int mm = floor (modf (estimate, &ignore) * 60.);
      fprintf (fp, "%02dh%02d", hh, mm);
    } else if (estimate >= 0.0) {
      /* Display minutes:seconds */
      estimate /= 60.;
      int mm = floor (estimate);
      double ignore;
      int ss = floor (modf (estimate, &ignore) * 60.);
      fprintf (fp, "%02d:%02d", mm, ss);
    }
    else /* < 0 means estimate was not meaningful */
      fputs ("--:--", fp);

    fputc ('\n', fp);
    fflush (fp);
  }
}