From 116d9a0ea7a5e903a344f7e6044dd019349bc01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sat, 19 Mar 2011 15:20:47 +0200 Subject: apk: improve progress bar * make it as wide as the screen * make sure it's drawn after package change * and draw it using ansi escapes in line buffered stderr --- src/apk.c | 20 +++++++++++++++++--- src/apk_defines.h | 1 + src/state.c | 20 +++++++++++--------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/apk.c b/src/apk.c index e8b8b12..55963b0 100644 --- a/src/apk.c +++ b/src/apk.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #ifndef OPENSSL_NO_ENGINE @@ -32,6 +33,7 @@ #include "apk_print.h" char **apk_argv; +int apk_screen_width; static struct apk_option generic_options[] = { { 'h', "help", "Show generic help or applet specific help" }, @@ -238,6 +240,20 @@ static void init_openssl(void) #endif } +static void setup_terminal(void) +{ + struct winsize w; + + setvbuf(stderr, NULL, _IOLBF, BUFSIZ); + if (ioctl(STDERR_FILENO,TIOCGWINSZ, &w) == 0) + apk_screen_width = w.ws_col; + else + apk_screen_width = 70; + if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) && isatty(STDIN_FILENO)) + apk_flags |= APK_PROGRESS; + +} + int main(int argc, char **argv) { struct apk_applet *applet; @@ -257,9 +273,7 @@ int main(int argc, char **argv) list_init(&dbopts.repository_list); apk_atom_init(); umask(0); - - if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) && isatty(STDIN_FILENO)) - apk_flags |= APK_PROGRESS; + setup_terminal(); applet = deduce_applet(argc, argv); num_options = ARRAY_SIZE(generic_options) + 1; diff --git a/src/apk_defines.h b/src/apk_defines.h index b11d181..b5ad12e 100644 --- a/src/apk_defines.h +++ b/src/apk_defines.h @@ -51,6 +51,7 @@ extern int apk_verbosity; extern unsigned int apk_flags; extern const char *apk_arch; extern char **apk_argv; +extern int apk_screen_width; #define APK_FORCE 0x0001 #define APK_SIMULATE 0x0002 diff --git a/src/state.c b/src/state.c index 3a8d3a6..cb6e5cc 100644 --- a/src/state.c +++ b/src/state.c @@ -668,19 +668,19 @@ static void apk_count_change(struct apk_change *change, struct apk_stats *stats) stats->packages ++; } -static inline void apk_draw_progress(int percent) +static void apk_draw_progress(int percent) { - char tmp[128]; - char reset[128]; + const int bar_width = (apk_screen_width - 15); int i; - snprintf(tmp, sizeof(tmp), "-[ ]- %3i%%", percent); - for (i = 0; (i < (percent/5)) && (i < (sizeof(tmp)-2)); i++) - tmp[2+i] = '#'; - memset(reset, '\b', strlen(tmp)); - fwrite(tmp, strlen(tmp), 1, stderr); - fwrite(reset, strlen(tmp), 1, stderr); + fputs("\e7-[", stderr); + for (i = 0; i < bar_width * percent / 100; i++) + fputc('#', stderr); + for (; i < bar_width; i++) + fputc(' ', stderr); + fprintf(stderr, "]- %3i%%", percent); fflush(stderr); + fputs("\e8\e[0K", stderr); } struct progress { @@ -950,6 +950,8 @@ int apk_state_commit(struct apk_state *state, list_for_each_entry(change, &state->change_list_head, change_list) { n++; apk_print_change(db, change->oldpkg, change->newpkg, n, state->num_changes); + if (apk_flags & APK_PROGRESS) + apk_draw_progress(prog.count); prog.pkg = change->newpkg; if (!(apk_flags & APK_SIMULATE)) { -- cgit v1.2.3