1 /* human.c -- print human readable file size
3 Copyright (C) 1996-2007, 2009-2020 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 /* Written by Paul Eggert and Larry McVoy. */
33 /* The maximum length of a suffix like "KiB". */
34 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
36 static const char power_letter
[] =
39 'K', /* kibi ('k' for kilo is a special case) */
40 'M', /* mega or mebi */
41 'G', /* giga or gibi */
42 'T', /* tera or tebi */
43 'P', /* peta or pebi */
44 'E', /* exa or exbi */
45 'Z', /* zetta or 2**70 */
46 'Y' /* yotta or 2**80 */
50 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
51 possible, adjust VALUE according to the style. */
54 adjust_value (int inexact_style
, long double value
)
56 /* Do not use the floorl or ceill functions, as that would mean
57 checking for their presence and possibly linking with the
58 standard math library, which is a porting pain. So leave the
59 value alone if it is too large to easily round. */
60 if (inexact_style
!= human_round_to_nearest
&& value
< UINTMAX_MAX
)
63 value
= u
+ (inexact_style
== human_ceiling
&& u
!= value
);
69 /* Group the digits of NUMBER according to the grouping rules of the
70 current locale. NUMBER contains NUMBERLEN digits. Modify the
71 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
72 each byte inserted. Return the starting address of the modified
75 To group the digits, use GROUPING and THOUSANDS_SEP as in 'struct
76 lconv' from <locale.h>. */
79 group_number (char *number
, size_t numberlen
,
80 char const *grouping
, char const *thousands_sep
)
83 size_t grouplen
= SIZE_MAX
;
84 size_t thousands_seplen
= strlen (thousands_sep
);
87 /* The maximum possible value for NUMBERLEN is the number of digits
88 in the square of the largest uintmax_t, so double the size needed. */
89 char buf
[2 * INT_STRLEN_BOUND (uintmax_t) + 1];
91 memcpy (buf
, number
, numberlen
);
92 d
= number
+ numberlen
;
96 unsigned char g
= *grouping
;
100 grouplen
= g
< CHAR_MAX
? g
: i
;
109 memcpy (d
, buf
+ i
, grouplen
);
113 d
-= thousands_seplen
;
114 memcpy (d
, thousands_sep
, thousands_seplen
);
118 /* Convert N to a human readable format in BUF, using the options OPTS.
120 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
123 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
126 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
127 to determine whether to take the ceiling or floor of any result
128 that cannot be expressed exactly.
130 If (OPTS & human_group_digits), group the thousands digits
131 according to the locale, e.g., "1,000,000" in an American English
134 If (OPTS & human_autoscale), deduce the output block size
135 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
136 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
137 of 1000 otherwise. For example, assuming powers of 1024, 8500
138 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
139 so on. Numbers smaller than the power aren't modified.
140 human_autoscale is normally used together with human_SI.
142 If (OPTS & human_space_before_unit), use a space to separate the
143 number from any suffix that is appended as described below.
145 If (OPTS & human_SI), append an SI prefix indicating which power is
146 being used. If in addition (OPTS & human_B), append "B" (if base
147 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
148 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
149 power of 1024 or of 1000, depending on (OPTS &
153 human_readable (uintmax_t n
, char *buf
, int opts
,
154 uintmax_t from_block_size
, uintmax_t to_block_size
)
157 opts
& (human_round_to_nearest
| human_floor
| human_ceiling
);
158 unsigned int base
= opts
& human_base_1024
? 1024 : 1000;
162 int exponent_max
= sizeof power_letter
- 1;
165 char const *integerlim
;
167 /* 0 means adjusted N == AMT.TENTHS;
168 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
169 2 means adjusted N == AMT.TENTHS + 0.05;
170 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
173 char const *decimal_point
= ".";
174 size_t decimal_pointlen
= 1;
175 char const *grouping
= "";
176 char const *thousands_sep
= "";
177 struct lconv
const *l
= localeconv ();
178 size_t pointlen
= strlen (l
->decimal_point
);
179 if (0 < pointlen
&& pointlen
<= MB_LEN_MAX
)
181 decimal_point
= l
->decimal_point
;
182 decimal_pointlen
= pointlen
;
184 grouping
= l
->grouping
;
185 if (strlen (l
->thousands_sep
) <= MB_LEN_MAX
)
186 thousands_sep
= l
->thousands_sep
;
188 /* Leave room for a trailing space and following suffix. */
189 psuffix
= buf
+ LONGEST_HUMAN_READABLE
- 1 - HUMAN_READABLE_SUFFIX_LENGTH_MAX
;
192 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
193 units. If this can be done exactly with integer arithmetic, do
194 not use floating point operations. */
195 if (to_block_size
<= from_block_size
)
197 if (from_block_size
% to_block_size
== 0)
199 uintmax_t multiplier
= from_block_size
/ to_block_size
;
200 amt
= n
* multiplier
;
201 if (amt
/ multiplier
== n
)
205 goto use_integer_arithmetic
;
209 else if (from_block_size
!= 0 && to_block_size
% from_block_size
== 0)
211 uintmax_t divisor
= to_block_size
/ from_block_size
;
212 uintmax_t r10
= (n
% divisor
) * 10;
213 uintmax_t r2
= (r10
% divisor
) * 2;
215 tenths
= r10
/ divisor
;
216 rounding
= r2
< divisor
? 0 < r2
: 2 + (divisor
< r2
);
217 goto use_integer_arithmetic
;
221 /* Either the result cannot be computed easily using uintmax_t,
222 or from_block_size is zero. Fall back on floating point.
223 FIXME: This can yield answers that are slightly off. */
225 long double dto_block_size
= to_block_size
;
226 long double damt
= n
* (from_block_size
/ dto_block_size
);
228 size_t nonintegerlen
;
230 if (! (opts
& human_autoscale
))
232 sprintf (buf
, "%.0Lf", adjust_value (inexact_style
, damt
));
233 buflen
= strlen (buf
);
246 while (e
* base
<= damt
&& exponent
< exponent_max
);
250 sprintf (buf
, "%.1Lf", adjust_value (inexact_style
, damt
));
251 buflen
= strlen (buf
);
252 nonintegerlen
= decimal_pointlen
+ 1;
254 if (1 + nonintegerlen
+ ! (opts
& human_base_1024
) < buflen
255 || ((opts
& human_suppress_point_zero
)
256 && buf
[buflen
- 1] == '0'))
258 sprintf (buf
, "%.0Lf",
259 adjust_value (inexact_style
, damt
* 10) / 10);
260 buflen
= strlen (buf
);
265 p
= psuffix
- buflen
;
266 memmove (p
, buf
, buflen
);
267 integerlim
= p
+ buflen
- nonintegerlen
;
271 use_integer_arithmetic
:
273 /* The computation can be done exactly, with integer arithmetic.
275 Use power of BASE notation if requested and if adjusted AMT is
278 if (opts
& human_autoscale
)
286 unsigned int r10
= (amt
% base
) * 10 + tenths
;
287 unsigned int r2
= (r10
% base
) * 2 + (rounding
>> 1);
290 rounding
= (r2
< base
291 ? (r2
+ rounding
) != 0
292 : 2 + (base
< r2
+ rounding
));
295 while (base
<= amt
&& exponent
< exponent_max
);
299 if (inexact_style
== human_round_to_nearest
300 ? 2 < rounding
+ (tenths
& 1)
301 : inexact_style
== human_ceiling
&& 0 < rounding
)
314 && (tenths
|| ! (opts
& human_suppress_point_zero
)))
317 p
-= decimal_pointlen
;
318 memcpy (p
, decimal_point
, decimal_pointlen
);
319 tenths
= rounding
= 0;
325 if (inexact_style
== human_round_to_nearest
326 ? 5 < tenths
+ (0 < rounding
+ (amt
& 1))
327 : inexact_style
== human_ceiling
&& 0 < tenths
+ rounding
)
331 if ((opts
& human_autoscale
)
332 && amt
== base
&& exponent
< exponent_max
)
335 if (! (opts
& human_suppress_point_zero
))
338 p
-= decimal_pointlen
;
339 memcpy (p
, decimal_point
, decimal_pointlen
);
349 int digit
= amt
% 10;
352 while ((amt
/= 10) != 0);
356 if (opts
& human_group_digits
)
357 p
= group_number (p
, integerlim
- p
, grouping
, thousands_sep
);
365 for (power
= 1; power
< to_block_size
; power
*= base
)
366 if (++exponent
== exponent_max
)
370 if ((exponent
| (opts
& human_B
)) && (opts
& human_space_before_unit
))
374 *psuffix
++ = (! (opts
& human_base_1024
) && exponent
== 1
376 : power_letter
[exponent
]);
380 if ((opts
& human_base_1024
) && exponent
)
392 /* The default block size used for output. This number may change in
393 the future as disks get larger. */
394 #ifndef DEFAULT_BLOCK_SIZE
395 # define DEFAULT_BLOCK_SIZE 1024
398 static char const *const block_size_args
[] = { "human-readable", "si", 0 };
399 static int const block_size_opts
[] =
401 human_autoscale
+ human_SI
+ human_base_1024
,
402 human_autoscale
+ human_SI
406 default_block_size (void)
408 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE
;
412 humblock (char const *spec
, uintmax_t *block_size
, int *options
)
418 && ! (spec
= getenv ("BLOCK_SIZE"))
419 && ! (spec
= getenv ("BLOCKSIZE")))
420 *block_size
= default_block_size ();
425 opts
|= human_group_digits
;
429 if (0 <= (i
= ARGMATCH (spec
, block_size_args
, block_size_opts
)))
431 opts
|= block_size_opts
[i
];
437 strtol_error e
= xstrtoumax (spec
, &ptr
, 0, block_size
,
438 "eEgGkKmMpPtTyYzZ0");
444 for (; ! ('0' <= *spec
&& *spec
<= '9'); spec
++)
450 if (ptr
[-1] != 'B' || ptr
[-2] == 'i')
451 opts
|= human_base_1024
;
462 human_options (char const *spec
, int *opts
, uintmax_t *block_size
)
464 strtol_error e
= humblock (spec
, block_size
, opts
);
465 if (*block_size
== 0)
467 *block_size
= default_block_size ();