diff options
author | Wolfram Sang <w.sang@pengutronix.de> | 2012-12-17 16:48:25 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-19 10:30:56 +0100 |
commit | 4f03bc5d9fd06f0c3f58e674356b75e2830414b7 (patch) | |
tree | 4e2a6d0cad229c58e28f703abc21b21544467085 /lib/display_options.c | |
parent | 904adb80d40eed1d6b527290714b233e8c37cb35 (diff) | |
download | barebox-4f03bc5d9fd06f0c3f58e674356b75e2830414b7.tar.gz barebox-4f03bc5d9fd06f0c3f58e674356b75e2830414b7.tar.xz |
lib: update size_human_readable to latest version
Copy over the latest version from u-boot which handles bigger sizes now
and does arithmetic with shifts instead of divisions.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib/display_options.c')
-rw-r--r-- | lib/display_options.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/lib/display_options.c b/lib/display_options.c index a6050cbf4f..0871552aaa 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -21,35 +21,50 @@ /* * return a pointer to a string containing the size - * as "xxx kB", "xxx.y kB", "xxx MB" or "xxx.y MB" as needed; + *"as xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB", + * xxx GiB, xxx.y GiB, etc as needed; */ -char *size_human_readable(ulong size) +char *size_human_readable(unsigned long long size) { static char buf[20]; - ulong m, n; - ulong d = 1 << 20; /* 1 MB */ - char c = 'M'; + unsigned long m = 0, n; + unsigned long long f; + static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'}; + unsigned long d = 10 * ARRAY_SIZE(names); + char c = 0; + unsigned int i; char *ptr = buf; - if (size < d) { /* print in kB */ - c = 'k'; - d = 1 << 10; + for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) { + if (size >> d) { + c = names[i]; + break; + } } - n = size / d; + if (!c) { + sprintf(buf, "%llu Bytes", size); + return buf; + } + + n = size >> d; + f = size & ((1ULL << d) - 1); - m = (10 * (size - (n * d)) + (d / 2) ) / d; + /* If there's a remainder, deal with it */ + if (f) { + m = (10ULL * f + (1ULL << (d - 1))) >> d; - if (m >= 10) { - m -= 10; - n += 1; + if (m >= 10) { + m -= 10; + n += 1; + } } - ptr += sprintf(buf, "%2ld", n); + ptr += sprintf(buf, "%lu", n); if (m) { - ptr += sprintf (ptr,".%ld", m); + ptr += sprintf(ptr, ".%ld", m); } - sprintf(ptr, " %cB", c); + sprintf(ptr, " %ciB", c); return buf; } |