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 | |
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>
-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) { |