diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-10-14 14:34:21 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-23 12:42:20 -0400 |
commit | a8659597bf744b0f8d2560e2a734b5c941569e0e (patch) | |
tree | b0630c44727dc3621a1d51a3e2fe5f51eb646e16 | |
parent | 3fe68cc152fc7cc6a763c692544a0ab71926c800 (diff) |
[SCSI] lib: string_get_size(): don't hang on zero; no decimals on exact
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>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | 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 8347925030ff..ab431d4cc970 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c | |||
@@ -23,7 +23,7 @@ | |||
23 | int string_get_size(u64 size, const enum string_size_units units, | 23 | int string_get_size(u64 size, const enum string_size_units units, |
24 | char *buf, int len) | 24 | char *buf, int len) |
25 | { | 25 | { |
26 | const char *units_10[] = { "B", "KB", "MB", "GB", "TB", "PB", | 26 | const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB", |
27 | "EB", "ZB", "YB", NULL}; | 27 | "EB", "ZB", "YB", NULL}; |
28 | const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", | 28 | const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", |
29 | "EiB", "ZiB", "YiB", NULL }; | 29 | "EiB", "ZiB", "YiB", NULL }; |
@@ -31,7 +31,7 @@ int string_get_size(u64 size, const enum string_size_units units, | |||
31 | [STRING_UNITS_10] = units_10, | 31 | [STRING_UNITS_10] = units_10, |
32 | [STRING_UNITS_2] = units_2, | 32 | [STRING_UNITS_2] = units_2, |
33 | }; | 33 | }; |
34 | const int divisor[] = { | 34 | const unsigned int divisor[] = { |
35 | [STRING_UNITS_10] = 1000, | 35 | [STRING_UNITS_10] = 1000, |
36 | [STRING_UNITS_2] = 1024, | 36 | [STRING_UNITS_2] = 1024, |
37 | }; | 37 | }; |
@@ -40,23 +40,27 @@ int string_get_size(u64 size, const enum string_size_units units, | |||
40 | char tmp[8]; | 40 | char tmp[8]; |
41 | 41 | ||
42 | tmp[0] = '\0'; | 42 | tmp[0] = '\0'; |
43 | i = 0; | ||
44 | if (size >= divisor[units]) { | ||
45 | while (size >= divisor[units] && units_str[units][i]) { | ||
46 | remainder = do_div(size, divisor[units]); | ||
47 | i++; | ||
48 | } | ||
43 | 49 | ||
44 | for (i = 0; size > divisor[units] && units_str[units][i]; i++) | 50 | sf_cap = size; |
45 | remainder = do_div(size, divisor[units]); | 51 | for (j = 0; sf_cap*10 < 1000; j++) |
52 | sf_cap *= 10; | ||
46 | 53 | ||
47 | sf_cap = size; | 54 | if (j) { |
48 | for (j = 0; sf_cap*10 < 1000; j++) | 55 | remainder *= 1000; |
49 | sf_cap *= 10; | 56 | do_div(remainder, divisor[units]); |
50 | 57 | snprintf(tmp, sizeof(tmp), ".%03lld", | |
51 | if (j) { | 58 | (unsigned long long)remainder); |
52 | remainder *= 1000; | 59 | tmp[j+1] = '\0'; |
53 | do_div(remainder, divisor[units]); | 60 | } |
54 | snprintf(tmp, sizeof(tmp), ".%03lld", | ||
55 | (unsigned long long)remainder); | ||
56 | tmp[j+1] = '\0'; | ||
57 | } | 61 | } |
58 | 62 | ||
59 | snprintf(buf, len, "%lld%s%s", (unsigned long long)size, | 63 | snprintf(buf, len, "%lld%s %s", (unsigned long long)size, |
60 | tmp, units_str[units][i]); | 64 | tmp, units_str[units][i]); |
61 | 65 | ||
62 | return 0; | 66 | return 0; |