lkml.org 
[lkml]   [2008]   [Oct]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 2/2] string_get_size(): don't hang on zero; no decimals on exact
Date
We would hang forever when passing a zero to string_get_size().
Furthermore, string_get_size() would produce decimals on a value small
enough to be exact. Finally, a few formatting issues are inconsistent
with standard SI style guidelines.

- If the value is less than the divisor, skip the entire rounding
step. This prints out all small values including zero as integers,
without decimals.
- Add a space between the value and the symbol for the unit,
consistent with standard SI practice.
- Lower case k in kB since we are talking about powers of 10.
- Finally, change "int" to "unsigned int" in one place to shut up a
gcc warning when compiling the code out-of-kernel for testing.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
lib/string_helpers.c | 34 +++++++++++++++++++---------------
1 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index 8347925..ab431d4 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -23,7 +23,7 @@
int string_get_size(u64 size, const enum string_size_units units,
char *buf, int len)
{
- const char *units_10[] = { "B", "KB", "MB", "GB", "TB", "PB",
+ const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB",
"EB", "ZB", "YB", NULL};
const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB",
"EiB", "ZiB", "YiB", NULL };
@@ -31,7 +31,7 @@ int string_get_size(u64 size, const enum string_size_units units,
[STRING_UNITS_10] = units_10,
[STRING_UNITS_2] = units_2,
};
- const int divisor[] = {
+ const unsigned int divisor[] = {
[STRING_UNITS_10] = 1000,
[STRING_UNITS_2] = 1024,
};
@@ -40,23 +40,27 @@ int string_get_size(u64 size, const enum string_size_units units,
char tmp[8];

tmp[0] = '\0';
+ i = 0;
+ if (size >= divisor[units]) {
+ while (size >= divisor[units] && units_str[units][i]) {
+ remainder = do_div(size, divisor[units]);
+ i++;
+ }

- for (i = 0; size > divisor[units] && units_str[units][i]; i++)
- remainder = do_div(size, divisor[units]);
+ sf_cap = size;
+ for (j = 0; sf_cap*10 < 1000; j++)
+ sf_cap *= 10;

- sf_cap = size;
- for (j = 0; sf_cap*10 < 1000; j++)
- sf_cap *= 10;
-
- if (j) {
- remainder *= 1000;
- do_div(remainder, divisor[units]);
- snprintf(tmp, sizeof(tmp), ".%03lld",
- (unsigned long long)remainder);
- tmp[j+1] = '\0';
+ if (j) {
+ remainder *= 1000;
+ do_div(remainder, divisor[units]);
+ snprintf(tmp, sizeof(tmp), ".%03lld",
+ (unsigned long long)remainder);
+ tmp[j+1] = '\0';
+ }
}

- snprintf(buf, len, "%lld%s%s", (unsigned long long)size,
+ snprintf(buf, len, "%lld%s %s", (unsigned long long)size,
tmp, units_str[units][i]);

return 0;
--
1.6.0.2


\
 
 \ /
  Last update: 2008-10-14 20:37    [W:0.151 / U:0.172 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site