diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-07 23:48:34 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-07 23:48:34 +0100 |
| commit | 47529d3f165c06bd0c3be751fdd4b743b4bddedb (patch) | |
| tree | 9ff056176bd404213e9e8d95fab09f5def0c23fd /libbb | |
| parent | ab843e3244e98f92e16b9c9c1f06dbab87e97175 (diff) | |
| download | busybox-w32-47529d3f165c06bd0c3be751fdd4b743b4bddedb.tar.gz busybox-w32-47529d3f165c06bd0c3be751fdd4b743b4bddedb.tar.bz2 busybox-w32-47529d3f165c06bd0c3be751fdd4b743b4bddedb.zip | |
libbb: shrink wget/tftp progress indicator code a bit more
This makes size display 5-char wide instead of 6-char, but now it's smarter
(can show sizes in "12.3M" format).
function old new delta
bb_progress_update 654 622 -32
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/progress.c | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/libbb/progress.c b/libbb/progress.c index 17272fd17..f1d980d68 100644 --- a/libbb/progress.c +++ b/libbb/progress.c | |||
| @@ -71,10 +71,9 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
| 71 | uoff_t transferred, | 71 | uoff_t transferred, |
| 72 | uoff_t totalsize) | 72 | uoff_t totalsize) |
| 73 | { | 73 | { |
| 74 | unsigned beg_and_transferred; /* does not need uoff_t, see scaling code below */ | 74 | char numbuf5[6]; /* 5 + 1 for NUL */ |
| 75 | unsigned since_last_update, elapsed; | 75 | unsigned since_last_update, elapsed; |
| 76 | int notty; | 76 | int notty; |
| 77 | int kiloscale; | ||
| 78 | 77 | ||
| 79 | //transferred = 1234; /* use for stall detection testing */ | 78 | //transferred = 1234; /* use for stall detection testing */ |
| 80 | //totalsize = 0; /* use for unknown size download testing */ | 79 | //totalsize = 0; /* use for unknown size download testing */ |
| @@ -95,24 +94,22 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
| 95 | return; | 94 | return; |
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | kiloscale = 0; | 97 | /* Before we lose real, unscaled sizes, produce human-readable size string */ |
| 98 | smart_ulltoa5(beg_size + transferred, numbuf5, " kMGTPEZY")[0] = '\0'; | ||
| 99 | |||
| 99 | /* | 100 | /* |
| 100 | * Scale sizes down if they are close to overflowing. | 101 | * Scale sizes down if they are close to overflowing. |
| 101 | * This allows calculations like (100 * transferred / totalsize) | 102 | * This allows calculations like (100 * transferred / totalsize) |
| 102 | * without risking overflow: we guarantee 10 highest bits to be 0. | 103 | * without risking overflow: we guarantee 10 highest bits to be 0. |
| 103 | * Introduced error is less than 1 / 2^12 ~= 0.025% | 104 | * Introduced error is less than 1 / 2^12 ~= 0.025% |
| 104 | */ | 105 | */ |
| 105 | while (totalsize >= (1 << 22)) { | 106 | while (totalsize >= (1 << 20)) { |
| 106 | totalsize >>= 10; | 107 | totalsize >>= 8; |
| 107 | beg_size >>= 10; | 108 | beg_size >>= 8; |
| 108 | transferred >>= 10; | 109 | transferred >>= 8; |
| 109 | kiloscale++; | ||
| 110 | } | 110 | } |
| 111 | /* If they were huge, now they are scaled down to [4194303,4096] range. | 111 | /* If they were huge, now they are scaled down to [1048575,4096] range. |
| 112 | * (N * totalsize) won't overflow 32 bits for N up to 1024. | 112 | * (N * totalsize) won't overflow 32 bits for N up to 4096. |
| 113 | * The downside is that files larger than 4194303 kbytes (>4GB) | ||
| 114 | * never show kbytes download size, they show "0M","1M"... right away | ||
| 115 | * since kiloscale is already >1. | ||
| 116 | */ | 113 | */ |
| 117 | #if ULONG_MAX == 0xffffffff | 114 | #if ULONG_MAX == 0xffffffff |
| 118 | /* 32-bit CPU, uoff_t arithmetic is complex on it, cast variables to narrower types */ | 115 | /* 32-bit CPU, uoff_t arithmetic is complex on it, cast variables to narrower types */ |
| @@ -124,19 +121,26 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
| 124 | notty = !isatty(STDERR_FILENO); | 121 | notty = !isatty(STDERR_FILENO); |
| 125 | 122 | ||
| 126 | if (ENABLE_UNICODE_SUPPORT) | 123 | if (ENABLE_UNICODE_SUPPORT) |
| 127 | fprintf(stderr, "\r%s" + notty, p->curfile); | 124 | fprintf(stderr, "\r%s " + notty, p->curfile); |
| 128 | else | 125 | else |
| 129 | fprintf(stderr, "\r%-20.20s" + notty, p->curfile); | 126 | fprintf(stderr, "\r%-20.20s " + notty, p->curfile); |
| 130 | |||
| 131 | beg_and_transferred = beg_size + transferred; | ||
| 132 | 127 | ||
| 133 | if (totalsize != 0) { | 128 | if (totalsize != 0) { |
| 134 | int barlength; | 129 | int barlength; |
| 135 | unsigned ratio = 100 * beg_and_transferred / totalsize; | 130 | unsigned beg_and_transferred; /* does not need uoff_t, see scaling code */ |
| 136 | fprintf(stderr, "%4u%%", ratio); | 131 | unsigned ratio; |
| 132 | |||
| 133 | beg_and_transferred = beg_size + transferred; | ||
| 134 | ratio = 100 * beg_and_transferred / totalsize; | ||
| 135 | /* can't overflow ^^^^^^^^^^^^^^^ */ | ||
| 136 | fprintf(stderr, "%3u%% ", ratio); | ||
| 137 | 137 | ||
| 138 | barlength = get_terminal_width(2) - 49; | 138 | barlength = get_terminal_width(2) - 48; |
| 139 | if (barlength > 0) { | 139 | /* |
| 140 | * Must reject barlength <= 0 (terminal too narrow). While at it, | ||
| 141 | * also reject: 1-char bar (useless), 2-char bar (ridiculous). | ||
| 142 | */ | ||
| 143 | if (barlength > 2) { | ||
| 140 | if (barlength > 999) | 144 | if (barlength > 999) |
| 141 | barlength = 999; | 145 | barlength = 999; |
| 142 | { | 146 | { |
| @@ -147,18 +151,12 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
| 147 | memset(buf, ' ', barlength); | 151 | memset(buf, ' ', barlength); |
| 148 | buf[barlength] = '\0'; | 152 | buf[barlength] = '\0'; |
| 149 | memset(buf, '*', stars); | 153 | memset(buf, '*', stars); |
| 150 | fprintf(stderr, " |%s|", buf); | 154 | fprintf(stderr, "|%s| ", buf); |
| 151 | } | 155 | } |
| 152 | } | 156 | } |
| 153 | } | 157 | } |
| 154 | 158 | ||
| 155 | while (beg_and_transferred >= 100000) { | 159 | fputs(numbuf5, stderr); /* "NNNNk" */ |
| 156 | beg_and_transferred >>= 10; | ||
| 157 | kiloscale++; | ||
| 158 | } | ||
| 159 | /* see http://en.wikipedia.org/wiki/Tera */ | ||
| 160 | fprintf(stderr, "%6u%c", (unsigned)beg_and_transferred, " kMGTPEZY"[kiloscale]); | ||
| 161 | #define beg_and_transferred dont_use_beg_and_transferred_below() | ||
| 162 | 160 | ||
| 163 | since_last_update = elapsed - p->last_change_sec; | 161 | since_last_update = elapsed - p->last_change_sec; |
| 164 | if ((unsigned)transferred != p->last_size) { | 162 | if ((unsigned)transferred != p->last_size) { |
