26 |
* and "#if 0"'d below. |
* and "#if 0"'d below. |
27 |
*/ |
*/ |
28 |
|
|
|
#include <stdio.h> |
|
29 |
#include "libbb.h" |
#include "libbb.h" |
30 |
|
|
31 |
const char *make_human_readable_str(unsigned long long size, |
const char* FAST_FUNC make_human_readable_str(unsigned long long size, |
32 |
unsigned long block_size, unsigned long display_unit) |
unsigned long block_size, unsigned long display_unit) |
33 |
{ |
{ |
34 |
/* The code will adjust for additional (appended) units. */ |
/* The code will adjust for additional (appended) units */ |
35 |
static const char zero_and_units[] = { '0', 0, 'k', 'M', 'G', 'T' }; |
static const char unit_chars[] ALIGN1 = { |
36 |
static const char fmt[] = "%llu"; |
'\0', 'K', 'M', 'G', 'T', 'P', 'E' |
37 |
static const char fmt_tenths[] = "%llu.%d%c"; |
}; |
38 |
|
static const char fmt[] ALIGN1 = "%llu"; |
39 |
|
static const char fmt_tenths[] ALIGN1 = "%llu.%d%c"; |
40 |
|
|
41 |
static char str[21]; /* Sufficient for 64 bit unsigned integers. */ |
static char str[21] ALIGN1; /* Sufficient for 64 bit unsigned integers */ |
42 |
|
|
43 |
unsigned long long val; |
unsigned long long val; |
44 |
int frac; |
int frac; |
45 |
const char *u; |
const char *u; |
46 |
const char *f; |
const char *f; |
47 |
|
smallint no_tenths; |
48 |
|
|
49 |
u = zero_and_units; |
if (size == 0) |
50 |
f = fmt; |
return "0"; |
|
frac = 0; |
|
51 |
|
|
52 |
val = size * block_size; |
/* If block_size is 0 then do not print tenths */ |
53 |
if (val == 0) { |
no_tenths = 0; |
54 |
return u; |
if (block_size == 0) { |
55 |
|
no_tenths = 1; |
56 |
|
block_size = 1; |
57 |
} |
} |
58 |
|
|
59 |
|
u = unit_chars; |
60 |
|
val = size * block_size; |
61 |
|
f = fmt; |
62 |
|
frac = 0; |
63 |
|
|
64 |
if (display_unit) { |
if (display_unit) { |
65 |
val += display_unit/2; /* Deal with rounding. */ |
val += display_unit/2; /* Deal with rounding */ |
66 |
val /= display_unit; /* Don't combine with the line above!!! */ |
val /= display_unit; /* Don't combine with the line above!!! */ |
67 |
|
/* will just print it as ulonglong (below) */ |
68 |
} else { |
} else { |
|
++u; |
|
69 |
while ((val >= 1024) |
while ((val >= 1024) |
70 |
&& (u < zero_and_units + sizeof(zero_and_units) - 1) |
&& (u < unit_chars + sizeof(unit_chars) - 1) |
71 |
) { |
) { |
72 |
f = fmt_tenths; |
f = fmt_tenths; |
73 |
++u; |
u++; |
74 |
frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024; |
frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024; |
75 |
val /= 1024; |
val /= 1024; |
76 |
} |
} |
78 |
++val; |
++val; |
79 |
frac = 0; |
frac = 0; |
80 |
} |
} |
81 |
#if 0 |
#if 1 |
82 |
/* Sample code to omit decimal point and tenths digit. */ |
/* Sample code to omit decimal point and tenths digit. */ |
83 |
if ( /* no_tenths */ 1 ) { |
if (no_tenths) { |
84 |
if ( frac >= 5 ) { |
if (frac >= 5) { |
85 |
++val; |
++val; |
86 |
} |
} |
87 |
f = "%llu%*c" /* fmt_no_tenths */ ; |
f = "%llu%*c" /* fmt_no_tenths */; |
88 |
frac = 1; |
frac = 1; |
89 |
} |
} |
90 |
#endif |
#endif |