diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2013-06-19 08:47:09 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2013-06-19 10:00:31 +0000 |
commit | adc5b0b16127049307283b9b59d7f0705ba8adc2 (patch) | |
tree | 55dd37153d8d5b8f1e9c88219f966e959cbfcdc0 /src/print.c | |
parent | 0c1a26f25c73710896d8666b2de11e5215eda366 (diff) | |
download | apk-tools-adc5b0b16127049307283b9b59d7f0705ba8adc2.tar.gz apk-tools-adc5b0b16127049307283b9b59d7f0705ba8adc2.tar.bz2 apk-tools-adc5b0b16127049307283b9b59d7f0705ba8adc2.tar.xz apk-tools-adc5b0b16127049307283b9b59d7f0705ba8adc2.zip |
print: move progress bar update logic to apk_print_progress
- let the apk_print functions deal with the forced print itself. We
avoid that the callbacks need to deal with the force flag. We can
also get rid of the APK_PRINT_PROGRESS_* defines.
- let the reader of --progress-fd decide how often things are updated
rather than having a fixed granularity off 1/100 (percent)
- avoid detect screen size and percent/bar calculations in case the
--no-progress was given
- track satistics for both the ascii bar and percent info and update bar
only if either percent or bar changes. This makes the bar go smoother
when width is wider than 100 chars and it makes the percent counter
go smooth when screen width is less thann 100 chars. It also
simplifies the callbacks as they no longer need to deal with update
granularity.
Diffstat (limited to 'src/print.c')
-rw-r--r-- | src/print.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/src/print.c b/src/print.c index d83bad2..6d00064 100644 --- a/src/print.c +++ b/src/print.c @@ -21,10 +21,12 @@ int apk_progress_fd; static int apk_screen_width = 0; +static int apk_progress_force = 1; void apk_reset_screen_width(void) { apk_screen_width = 0; + apk_progress_force = 1; } int apk_get_screen_width(void) @@ -41,35 +43,48 @@ int apk_get_screen_width(void) return apk_screen_width; } -void apk_print_progress(int percent_flags) +void apk_print_progress(size_t done, size_t total) { - static int last_written = 0; - const int bar_width = apk_get_screen_width() - 7; - char buf[8]; - int i, percent; + static size_t last_done = 0; + static int last_bar = 0, last_percent = 0; + int bar_width; + int bar = 0; + char buf[64]; /* enough for petabytes... */ + int i, percent = 0; + + if (last_done == done && !apk_progress_force) + return; - percent = percent_flags & APK_PRINT_PROGRESS_MASK; + if (apk_progress_fd != 0) { + i = snprintf(buf, sizeof(buf), "%zu/%zu\n", done, total); + write(apk_progress_fd, buf, i); + } + last_done = done; - if (last_written == percent && !(percent_flags & APK_PRINT_PROGRESS_FORCE)) + if (!(apk_flags & APK_PROGRESS)) return; - last_written = percent; - - if (apk_flags & APK_PROGRESS) { - fprintf(stderr, "\e7%3i%% [", percent); - for (i = 0; i < bar_width * percent / 100; i++) - fputc('#', stderr); - for (; i < bar_width; i++) - fputc(' ', stderr); - fputc(']', stderr); - fflush(stderr); - fputs("\e8\e[0K", stderr); + bar_width = apk_get_screen_width() - 7; + if (total > 0) { + bar = muldiv(bar_width, done, total); + percent = muldiv(100, done, total); } - if (apk_progress_fd != 0) { - i = snprintf(buf, sizeof(buf), "%i\n", percent); - write(apk_progress_fd, buf, i); - } + if (bar == last_bar && percent == last_percent && !apk_progress_force) + return; + + last_bar = bar; + last_percent = percent; + apk_progress_force = 0; + + fprintf(stderr, "\e7%3i%% [", percent); + for (i = 0; i < bar; i++) + fputc('#', stderr); + for (; i < bar_width; i++) + fputc(' ', stderr); + fputc(']', stderr); + fflush(stderr); + fputs("\e8\e[0K", stderr); } int apk_print_indented(struct apk_indent *i, apk_blob_t blob) @@ -80,6 +95,7 @@ int apk_print_indented(struct apk_indent *i, apk_blob_t blob) i->x += printf("%*s" BLOB_FMT, i->indent - i->x, "", BLOB_PRINTF(blob)); else i->x += printf(" " BLOB_FMT, BLOB_PRINTF(blob)); + apk_progress_force = 1; return 0; } @@ -133,5 +149,6 @@ void apk_log(const char *prefix, const char *format, ...) vfprintf(stderr, format, va); va_end(va); fprintf(stderr, "\n"); + apk_progress_force = 1; } |