2020-04-02 21:35:07 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
don't hide cursor but only redraw bar when it changes hiding the cursor is nice but it adds sensible complexity specially if we want to handle SIGINT gracefully we can prevent the cursor from jumping around by avoiding unnecessary redraws
diff --git a/mpb.c b/mpb.c index 9c4cd58..7fc23ed 100644 --- a/mpb.c +++ b/mpb.c @@ -1,60 +1,49 @@ #include <stdio.h> #include <stdlib.h> +#include <limits.h> static unsigned width; static char spinchars[] = "|/-\\"; static unsigned spinindex; static char line[(1 << 12) + 1]; - -void -hide_cursor() -{ - printf("\x1B[?25l"); - fflush(stdout); -} - -void -show_cursor() -{ - printf("\x1B[?25h"); - fflush(stdout); -} +static unsigned lastfill = UINT_MAX; void print_bar(unsigned long percent) { - unsigned i, n; - n = percent * width / 100; + unsigned i, fill; + fill = percent * width / 100; if (percent % 100 == 0) spinindex = 0; - printf("\r (%c) [", spinchars[spinindex++]); + printf(" (%c) [", spinchars[spinindex++]); spinindex %= sizeof(spinchars) - 1; - for (i = 0; i < n; i++) - putchar('#'); - for (; i < width; i++) - putchar('-'); - printf("] %3lu%%", percent); + if (fill != lastfill) { + for (i = 0; i < fill; i++) + putchar('#'); + for (; i < width; i++) + putchar('-'); + lastfill = fill; + } else { + printf("\x1B[%uC", width); + } + printf("] %3lu%%\r", percent); fflush(stdout); } int main(int argc, char *argv[]) { - int ret = 0; unsigned long count, total, percent; if (argc != 2) { fprintf(stderr, "usage:\n %s total\n", argv[0]); - ret = 1; - goto quit; + return 1; } total = (unsigned) atol(argv[1]); if (total == 0) { fprintf(stderr, "total must be nonzero\n"); - ret = 1; - goto quit; + return 1; } width = 32; - hide_cursor(); print_bar(0); count = 0; while (scanf("%s", line) != EOF) { @@ -64,8 +53,6 @@ main(int argc, char *argv[]) print_bar(percent); } print_bar(100); -quit: - show_cursor(); puts(""); - return ret; + return 0; }