summaryrefslogtreecommitdiff
path: root/release/src/router/busybox/libbb/human_readable.c
diff options
context:
space:
mode:
Diffstat (limited to 'release/src/router/busybox/libbb/human_readable.c')
-rw-r--r--release/src/router/busybox/libbb/human_readable.c71
1 files changed, 46 insertions, 25 deletions
diff --git a/release/src/router/busybox/libbb/human_readable.c b/release/src/router/busybox/libbb/human_readable.c
index 21e13dc4..05e7d86e 100644
--- a/release/src/router/busybox/libbb/human_readable.c
+++ b/release/src/router/busybox/libbb/human_readable.c
@@ -1,3 +1,4 @@
+/* vi: set sw=4 ts=4: */
/*
* June 30, 2001 Manuel Novoa III
*
@@ -13,8 +14,8 @@
* representations (say, powers of 1024) and manipulating coefficients.
* The base ten "bytes" output could be handled similarly.
*
- * 2) This routine always outputs a decimal point and a tenths digit when
- * display_unit != 0. Hence, it isn't uncommon for the returned string
+ * 2) This routine always outputs a decimal point and a tenths digit when
+ * display_unit != 0. Hence, it isn't uncommon for the returned string
* to have a length of 5 or 6.
*
* It might be nice to add a flag to indicate no decimal digits in
@@ -23,52 +24,72 @@
*
* Some code to omit the decimal point and tenths digit is sketched out
* and "#if 0"'d below.
+ *
+ * Licensed under GPLv2, see file LICENSE in this tarball for details.
*/
-#include <stdio.h>
#include "libbb.h"
-const char *make_human_readable_str(unsigned long size,
- unsigned long block_size,
- unsigned long display_unit)
+const char* FAST_FUNC make_human_readable_str(unsigned long long size,
+ unsigned long block_size, unsigned long display_unit)
{
- /* The code will adjust for additional (appended) units. */
- static const char zero_and_units[] = { '0', 0, 'k', 'M', 'G', 'T' };
- static const char fmt[] = "%Lu";
- static const char fmt_tenths[] = "%Lu.%d%c";
+ /* The code will adjust for additional (appended) units */
+ static const char unit_chars[] ALIGN1 = {
+ '\0', 'K', 'M', 'G', 'T', 'P', 'E'
+ };
+ static const char fmt[] ALIGN1 = "%llu";
+ static const char fmt_tenths[] ALIGN1 = "%llu.%d%c";
+
+ static char str[21] ALIGN1; /* Sufficient for 64 bit unsigned integers */
- static char str[21]; /* Sufficient for 64 bit unsigned integers. */
-
unsigned long long val;
int frac;
const char *u;
const char *f;
+ smallint no_tenths;
- u = zero_and_units;
- f = fmt;
- frac = 0;
+ if (size == 0)
+ return "0";
- val = ((unsigned long long) size) * block_size;
- if (val == 0) {
- return u;
+ /* If block_size is 0 then do not print tenths */
+ no_tenths = 0;
+ if (block_size == 0) {
+ no_tenths = 1;
+ block_size = 1;
}
+ u = unit_chars;
+ val = size * block_size;
+ f = fmt;
+ frac = 0;
+
if (display_unit) {
- val += display_unit/2; /* Deal with rounding. */
+ val += display_unit/2; /* Deal with rounding */
val /= display_unit; /* Don't combine with the line above!!! */
+ /* will just print it as ulonglong (below) */
} else {
- ++u;
- while ((val >= KILOBYTE)
- && (u < zero_and_units + sizeof(zero_and_units) - 1)) {
+ while ((val >= 1024)
+ && (u < unit_chars + sizeof(unit_chars) - 1)
+ ) {
f = fmt_tenths;
- ++u;
- frac = ((((int)(val % KILOBYTE)) * 10) + (KILOBYTE/2)) / KILOBYTE;
- val /= KILOBYTE;
+ u++;
+ frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024;
+ val /= 1024;
}
if (frac >= 10) { /* We need to round up here. */
++val;
frac = 0;
}
+#if 1
+ /* Sample code to omit decimal point and tenths digit. */
+ if (no_tenths) {
+ if (frac >= 5) {
+ ++val;
+ }
+ f = "%llu%*c" /* fmt_no_tenths */;
+ frac = 1;
+ }
+#endif
}
/* If f==fmt then 'frac' and 'u' are ignored. */