1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* human.c -- print human readable file size
5 Copyright (C) 1996-2007, 2009-2013 Free Software Foundation, Inc.
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* Written by Paul Eggert and Larry McVoy. */
35 /* The maximum length of a suffix like "KiB". */
36 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
38 static const char power_letter[] =
41 'K', /* kibi ('k' for kilo is a special case) */
42 'M', /* mega or mebi */
43 'G', /* giga or gibi */
44 'T', /* tera or tebi */
45 'P', /* peta or pebi */
46 'E', /* exa or exbi */
47 'Z', /* zetta or 2**70 */
48 'Y' /* yotta or 2**80 */
52 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
53 possible, adjust VALUE according to the style. */
56 adjust_value (int inexact_style, long double value)
58 /* Do not use the floorl or ceill functions, as that would mean
59 checking for their presence and possibly linking with the
60 standard math library, which is a porting pain. So leave the
61 value alone if it is too large to easily round. */
62 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
65 value = u + (inexact_style == human_ceiling && u != value);
71 /* Group the digits of NUMBER according to the grouping rules of the
72 current locale. NUMBER contains NUMBERLEN digits. Modify the
73 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
74 each byte inserted. Return the starting address of the modified
77 To group the digits, use GROUPING and THOUSANDS_SEP as in 'struct
78 lconv' from <locale.h>. */
81 group_number (char *number, size_t numberlen,
82 char const *grouping, char const *thousands_sep)
85 size_t grouplen = SIZE_MAX;
86 size_t thousands_seplen = strlen (thousands_sep);
89 /* The maximum possible value for NUMBERLEN is the number of digits
90 in the square of the largest uintmax_t, so double the size needed. */
91 char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1];
93 memcpy (buf, number, numberlen);
94 d = number + numberlen;
98 unsigned char g = *grouping;
102 grouplen = g < CHAR_MAX ? g : i;
111 memcpy (d, buf + i, grouplen);
115 d -= thousands_seplen;
116 memcpy (d, thousands_sep, thousands_seplen);
120 /* Convert N to a human readable format in BUF, using the options OPTS.
122 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
125 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
128 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
129 to determine whether to take the ceiling or floor of any result
130 that cannot be expressed exactly.
132 If (OPTS & human_group_digits), group the thousands digits
133 according to the locale, e.g., "1,000,000" in an American English
136 If (OPTS & human_autoscale), deduce the output block size
137 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
138 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
139 of 1000 otherwise. For example, assuming powers of 1024, 8500
140 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
141 so on. Numbers smaller than the power aren't modified.
142 human_autoscale is normally used together with human_SI.
144 If (OPTS & human_space_before_unit), use a space to separate the
145 number from any suffix that is appended as described below.
147 If (OPTS & human_SI), append an SI prefix indicating which power is
148 being used. If in addition (OPTS & human_B), append "B" (if base
149 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
150 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
151 power of 1024 or of 1000, depending on (OPTS &
155 human_readable (uintmax_t n, char *buf, int opts,
156 uintmax_t from_block_size, uintmax_t to_block_size)
159 opts & (human_round_to_nearest | human_floor | human_ceiling);
160 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
164 int exponent_max = sizeof power_letter - 1;
167 char const *integerlim;
169 /* 0 means adjusted N == AMT.TENTHS;
170 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
171 2 means adjusted N == AMT.TENTHS + 0.05;
172 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
175 char const *decimal_point = ".";
176 size_t decimal_pointlen = 1;
177 char const *grouping = "";
178 char const *thousands_sep = "";
179 struct lconv const *l = localeconv ();
180 size_t pointlen = strlen (l->decimal_point);
181 if (0 < pointlen && pointlen <= MB_LEN_MAX)
183 decimal_point = l->decimal_point;
184 decimal_pointlen = pointlen;
186 grouping = l->grouping;
187 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
188 thousands_sep = l->thousands_sep;
190 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
193 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
194 units. If this can be done exactly with integer arithmetic, do
195 not use floating point operations. */
196 if (to_block_size <= from_block_size)
198 if (from_block_size % to_block_size == 0)
200 uintmax_t multiplier = from_block_size / to_block_size;
201 amt = n * multiplier;
202 if (amt / multiplier == n)
206 goto use_integer_arithmetic;
210 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
212 uintmax_t divisor = to_block_size / from_block_size;
213 uintmax_t r10 = (n % divisor) * 10;
214 uintmax_t r2 = (r10 % divisor) * 2;
216 tenths = r10 / divisor;
217 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
218 goto use_integer_arithmetic;
222 /* Either the result cannot be computed easily using uintmax_t,
223 or from_block_size is zero. Fall back on floating point.
224 FIXME: This can yield answers that are slightly off. */
226 long double dto_block_size = to_block_size;
227 long double damt = n * (from_block_size / dto_block_size);
229 size_t nonintegerlen;
231 if (! (opts & human_autoscale))
233 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
234 buflen = strlen (buf);
247 while (e * base <= damt && exponent < exponent_max);
251 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
252 buflen = strlen (buf);
253 nonintegerlen = decimal_pointlen + 1;
255 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
256 || ((opts & human_suppress_point_zero)
257 && buf[buflen - 1] == '0'))
259 sprintf (buf, "%.0Lf",
260 adjust_value (inexact_style, damt * 10) / 10);
261 buflen = strlen (buf);
266 p = psuffix - buflen;
267 memmove (p, buf, buflen);
268 integerlim = p + buflen - nonintegerlen;
272 use_integer_arithmetic:
274 /* The computation can be done exactly, with integer arithmetic.
276 Use power of BASE notation if requested and if adjusted AMT is
279 if (opts & human_autoscale)
287 unsigned int r10 = (amt % base) * 10 + tenths;
288 unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
291 rounding = (r2 < base
292 ? (r2 + rounding) != 0
293 : 2 + (base < r2 + rounding));
296 while (base <= amt && exponent < exponent_max);
300 if (inexact_style == human_round_to_nearest
301 ? 2 < rounding + (tenths & 1)
302 : inexact_style == human_ceiling && 0 < rounding)
315 && (tenths || ! (opts & human_suppress_point_zero)))
318 p -= decimal_pointlen;
319 memcpy (p, decimal_point, decimal_pointlen);
320 tenths = rounding = 0;
326 if (inexact_style == human_round_to_nearest
327 ? 5 < tenths + (0 < rounding + (amt & 1))
328 : inexact_style == human_ceiling && 0 < tenths + rounding)
332 if ((opts & human_autoscale)
333 && amt == base && exponent < exponent_max)
336 if (! (opts & human_suppress_point_zero))
339 p -= decimal_pointlen;
340 memcpy (p, decimal_point, decimal_pointlen);
350 int digit = amt % 10;
353 while ((amt /= 10) != 0);
357 if (opts & human_group_digits)
358 p = group_number (p, integerlim - p, grouping, thousands_sep);
366 for (power = 1; power < to_block_size; power *= base)
367 if (++exponent == exponent_max)
371 if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
375 *psuffix++ = (! (opts & human_base_1024) && exponent == 1
377 : power_letter[exponent]);
381 if ((opts & human_base_1024) && exponent)
393 /* The default block size used for output. This number may change in
394 the future as disks get larger. */
395 #ifndef DEFAULT_BLOCK_SIZE
396 # define DEFAULT_BLOCK_SIZE 1024
399 static char const *const block_size_args[] = { "human-readable", "si", 0 };
400 static int const block_size_opts[] =
402 human_autoscale + human_SI + human_base_1024,
403 human_autoscale + human_SI
407 default_block_size (void)
409 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
413 humblock (char const *spec, uintmax_t *block_size, int *options)
419 && ! (spec = getenv ("BLOCK_SIZE"))
420 && ! (spec = getenv ("BLOCKSIZE")))
421 *block_size = default_block_size ();
426 opts |= human_group_digits;
430 if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
432 opts |= block_size_opts[i];
438 strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
439 "eEgGkKmMpPtTyYzZ0");
445 for (; ! ('0' <= *spec && *spec <= '9'); spec++)
451 if (ptr[-1] != 'B' || ptr[-2] == 'i')
452 opts |= human_base_1024;
463 human_options (char const *spec, int *opts, uintmax_t *block_size)
465 strtol_error e = humblock (spec, block_size, opts);
466 if (*block_size == 0)
468 *block_size = default_block_size ();