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, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
6 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* Written by Paul Eggert and Larry McVoy. */
36 /* The maximum length of a suffix like "KiB". */
37 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
39 static const char power_letter[] =
42 'K', /* kibi ('k' for kilo is a special case) */
43 'M', /* mega or mebi */
44 'G', /* giga or gibi */
45 'T', /* tera or tebi */
46 'P', /* peta or pebi */
47 'E', /* exa or exbi */
48 'Z', /* zetta or 2**70 */
49 'Y' /* yotta or 2**80 */
53 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
54 possible, adjust VALUE according to the style. */
57 adjust_value (int inexact_style, long double value)
59 /* Do not use the floorl or ceill functions, as that would mean
60 checking for their presence and possibly linking with the
61 standard math library, which is a porting pain. So leave the
62 value alone if it is too large to easily round. */
63 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
66 value = u + (inexact_style == human_ceiling && u != value);
72 /* Group the digits of NUMBER according to the grouping rules of the
73 current locale. NUMBER contains NUMBERLEN digits. Modify the
74 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
75 each byte inserted. Return the starting address of the modified
78 To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
79 lconv' from <locale.h>. */
82 group_number (char *number, size_t numberlen,
83 char const *grouping, char const *thousands_sep)
86 size_t grouplen = SIZE_MAX;
87 size_t thousands_seplen = strlen (thousands_sep);
90 /* The maximum possible value for NUMBERLEN is the number of digits
91 in the square of the largest uintmax_t, so double the size needed. */
92 char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1];
94 memcpy (buf, number, numberlen);
95 d = number + numberlen;
99 unsigned char g = *grouping;
103 grouplen = g < CHAR_MAX ? g : i;
112 memcpy (d, buf + i, grouplen);
116 d -= thousands_seplen;
117 memcpy (d, thousands_sep, thousands_seplen);
121 /* Convert N to a human readable format in BUF, using the options OPTS.
123 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
126 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
129 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
130 to determine whether to take the ceiling or floor of any result
131 that cannot be expressed exactly.
133 If (OPTS & human_group_digits), group the thousands digits
134 according to the locale, e.g., `1,000,000' in an American English
137 If (OPTS & human_autoscale), deduce the output block size
138 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
139 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
140 of 1000 otherwise. For example, assuming powers of 1024, 8500
141 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
142 so on. Numbers smaller than the power aren't modified.
143 human_autoscale is normally used together with human_SI.
145 If (OPTS & human_space_before_unit), use a space to separate the
146 number from any suffix that is appended as described below.
148 If (OPTS & human_SI), append an SI prefix indicating which power is
149 being used. If in addition (OPTS & human_B), append "B" (if base
150 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
151 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
152 power of 1024 or of 1000, depending on (OPTS &
156 human_readable (uintmax_t n, char *buf, int opts,
157 uintmax_t from_block_size, uintmax_t to_block_size)
160 opts & (human_round_to_nearest | human_floor | human_ceiling);
161 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
165 int exponent_max = sizeof power_letter - 1;
168 char const *integerlim;
170 /* 0 means adjusted N == AMT.TENTHS;
171 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
172 2 means adjusted N == AMT.TENTHS + 0.05;
173 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
176 char const *decimal_point = ".";
177 size_t decimal_pointlen = 1;
178 char const *grouping = "";
179 char const *thousands_sep = "";
180 struct lconv const *l = localeconv ();
181 size_t pointlen = strlen (l->decimal_point);
182 if (0 < pointlen && pointlen <= MB_LEN_MAX)
184 decimal_point = l->decimal_point;
185 decimal_pointlen = pointlen;
187 grouping = l->grouping;
188 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
189 thousands_sep = l->thousands_sep;
191 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
194 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
195 units. If this can be done exactly with integer arithmetic, do
196 not use floating point operations. */
197 if (to_block_size <= from_block_size)
199 if (from_block_size % to_block_size == 0)
201 uintmax_t multiplier = from_block_size / to_block_size;
202 amt = n * multiplier;
203 if (amt / multiplier == n)
207 goto use_integer_arithmetic;
211 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
213 uintmax_t divisor = to_block_size / from_block_size;
214 uintmax_t r10 = (n % divisor) * 10;
215 uintmax_t r2 = (r10 % divisor) * 2;
217 tenths = r10 / divisor;
218 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
219 goto use_integer_arithmetic;
223 /* Either the result cannot be computed easily using uintmax_t,
224 or from_block_size is zero. Fall back on floating point.
225 FIXME: This can yield answers that are slightly off. */
227 long double dto_block_size = to_block_size;
228 long double damt = n * (from_block_size / dto_block_size);
230 size_t nonintegerlen;
232 if (! (opts & human_autoscale))
234 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
235 buflen = strlen (buf);
248 while (e * base <= damt && exponent < exponent_max);
252 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
253 buflen = strlen (buf);
254 nonintegerlen = decimal_pointlen + 1;
256 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
257 || ((opts & human_suppress_point_zero)
258 && buf[buflen - 1] == '0'))
260 sprintf (buf, "%.0Lf",
261 adjust_value (inexact_style, damt * 10) / 10);
262 buflen = strlen (buf);
267 p = psuffix - buflen;
268 memmove (p, buf, buflen);
269 integerlim = p + buflen - nonintegerlen;
273 use_integer_arithmetic:
275 /* The computation can be done exactly, with integer arithmetic.
277 Use power of BASE notation if requested and if adjusted AMT is
280 if (opts & human_autoscale)
288 unsigned int r10 = (amt % base) * 10 + tenths;
289 unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
292 rounding = (r2 < base
293 ? (r2 + rounding) != 0
294 : 2 + (base < r2 + rounding));
297 while (base <= amt && exponent < exponent_max);
301 if (inexact_style == human_round_to_nearest
302 ? 2 < rounding + (tenths & 1)
303 : inexact_style == human_ceiling && 0 < rounding)
316 && (tenths || ! (opts & human_suppress_point_zero)))
319 p -= decimal_pointlen;
320 memcpy (p, decimal_point, decimal_pointlen);
321 tenths = rounding = 0;
327 if (inexact_style == human_round_to_nearest
328 ? 5 < tenths + (0 < rounding + (amt & 1))
329 : inexact_style == human_ceiling && 0 < tenths + rounding)
333 if ((opts & human_autoscale)
334 && amt == base && exponent < exponent_max)
337 if (! (opts & human_suppress_point_zero))
340 p -= decimal_pointlen;
341 memcpy (p, decimal_point, decimal_pointlen);
351 int digit = amt % 10;
354 while ((amt /= 10) != 0);
358 if (opts & human_group_digits)
359 p = group_number (p, integerlim - p, grouping, thousands_sep);
367 for (power = 1; power < to_block_size; power *= base)
368 if (++exponent == exponent_max)
372 if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
376 *psuffix++ = (! (opts & human_base_1024) && exponent == 1
378 : power_letter[exponent]);
382 if ((opts & human_base_1024) && exponent)
394 /* The default block size used for output. This number may change in
395 the future as disks get larger. */
396 #ifndef DEFAULT_BLOCK_SIZE
397 # define DEFAULT_BLOCK_SIZE 1024
400 static char const *const block_size_args[] = { "human-readable", "si", 0 };
401 static int const block_size_opts[] =
403 human_autoscale + human_SI + human_base_1024,
404 human_autoscale + human_SI
408 default_block_size (void)
410 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
414 humblock (char const *spec, uintmax_t *block_size, int *options)
420 && ! (spec = getenv ("BLOCK_SIZE"))
421 && ! (spec = getenv ("BLOCKSIZE")))
422 *block_size = default_block_size ();
427 opts |= human_group_digits;
431 if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
433 opts |= block_size_opts[i];
439 strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
440 "eEgGkKmMpPtTyYzZ0");
446 for (; ! ('0' <= *spec && *spec <= '9'); spec++)
452 if (ptr[-1] != 'B' || ptr[-2] == 'i')
453 opts |= human_base_1024;
464 human_options (char const *spec, int *opts, uintmax_t *block_size)
466 strtol_error e = humblock (spec, block_size, opts);
467 if (*block_size == 0)
469 *block_size = default_block_size ();