1 /* human.c -- print human readable file size
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20 /* Written by Paul Eggert and Larry McVoy. */
34 #define _(msgid) gettext (msgid)
42 # define SIZE_MAX ((size_t) -1)
45 # define UINTMAX_MAX ((uintmax_t) -1)
48 /* The maximum length of a suffix like "KiB". */
49 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
51 static const char power_letter[] =
54 'K', /* kibi ('k' for kilo is a special case) */
55 'M', /* mega or mebi */
56 'G', /* giga or gibi */
57 'T', /* tera or tebi */
58 'P', /* peta or pebi */
59 'E', /* exa or exbi */
60 'Z', /* zetta or 2**70 */
61 'Y' /* yotta or 2**80 */
65 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
66 possible, adjust VALUE according to the style. */
69 adjust_value (int inexact_style, long double value)
71 /* Do not use the floorl or ceill functions, as that would mean
72 checking for their presence and possibly linking with the
73 standard math library, which is a porting pain. So leave the
74 value alone if it is too large to easily round. */
75 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
78 value = u + (inexact_style == human_ceiling && u != value);
84 /* Group the digits of NUMBER according to the grouping rules of the
85 current locale. NUMBER contains NUMBERLEN digits. Modify the
86 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
87 each byte inserted. Return the starting address of the modified
90 To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
91 lconv' from <locale.h>. */
94 group_number (char *number, size_t numberlen,
95 char const *grouping, char const *thousands_sep)
98 size_t grouplen = SIZE_MAX;
99 size_t thousands_seplen = strlen (thousands_sep);
100 size_t i = numberlen;
102 /* The maximum possible value for NUMBERLEN is the number of digits
103 in the square of the largest uintmax_t, so double the size needed. */
104 char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1];
106 memcpy (buf, number, numberlen);
107 d = number + numberlen;
111 unsigned char g = *grouping;
115 grouplen = g < CHAR_MAX ? g : i;
124 memcpy (d, buf + i, grouplen);
128 d -= thousands_seplen;
129 memcpy (d, thousands_sep, thousands_seplen);
133 /* Convert N to a human readable format in BUF, using the options OPTS.
135 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
138 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
141 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
142 to determine whether to take the ceiling or floor of any result
143 that cannot be expressed exactly.
145 If (OPTS & human_group_digits), group the thousands digits
146 according to the locale, e.g., `1,000,000' in an American English
149 If (OPTS & human_autoscale), deduce the output block size
150 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
151 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
152 of 1000 otherwise. For example, assuming powers of 1024, 8500
153 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
154 so on. Numbers smaller than the power aren't modified.
155 human_autoscale is normally used together with human_SI.
157 If (OPTS & human_space_before_unit), use a space to separate the
158 number from any suffix that is appended as described below.
160 If (OPTS & human_SI), append an SI prefix indicating which power is
161 being used. If in addition (OPTS & human_B), append "B" (if base
162 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
163 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
164 power of 1024 or of 1000, depending on (OPTS &
168 human_readable (uintmax_t n, char *buf, int opts,
169 uintmax_t from_block_size, uintmax_t to_block_size)
172 opts & (human_round_to_nearest | human_floor | human_ceiling);
173 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
177 int exponent_max = sizeof power_letter - 1;
180 char const *integerlim;
182 /* 0 means adjusted N == AMT.TENTHS;
183 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
184 2 means adjusted N == AMT.TENTHS + 0.05;
185 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
188 char const *decimal_point = ".";
189 size_t decimal_pointlen = 1;
190 char const *grouping = "";
191 char const *thousands_sep = "";
192 struct lconv const *l = localeconv ();
193 size_t pointlen = strlen (l->decimal_point);
194 if (0 < pointlen && pointlen <= MB_LEN_MAX)
196 decimal_point = l->decimal_point;
197 decimal_pointlen = pointlen;
199 grouping = l->grouping;
200 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
201 thousands_sep = l->thousands_sep;
203 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
206 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
207 units. If this can be done exactly with integer arithmetic, do
208 not use floating point operations. */
209 if (to_block_size <= from_block_size)
211 if (from_block_size % to_block_size == 0)
213 uintmax_t multiplier = from_block_size / to_block_size;
214 amt = n * multiplier;
215 if (amt / multiplier == n)
219 goto use_integer_arithmetic;
223 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
225 uintmax_t divisor = to_block_size / from_block_size;
226 uintmax_t r10 = (n % divisor) * 10;
227 uintmax_t r2 = (r10 % divisor) * 2;
229 tenths = r10 / divisor;
230 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
231 goto use_integer_arithmetic;
235 /* Either the result cannot be computed easily using uintmax_t,
236 or from_block_size is zero. Fall back on floating point.
237 FIXME: This can yield answers that are slightly off. */
239 long double dto_block_size = to_block_size;
240 long double damt = n * (from_block_size / dto_block_size);
242 size_t nonintegerlen;
244 if (! (opts & human_autoscale))
246 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
247 buflen = strlen (buf);
260 while (e * base <= damt && exponent < exponent_max);
264 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
265 buflen = strlen (buf);
266 nonintegerlen = decimal_pointlen + 1;
268 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
269 || ((opts & human_suppress_point_zero)
270 && buf[buflen - 1] == '0'))
272 sprintf (buf, "%.0Lf",
273 adjust_value (inexact_style, damt * 10) / 10);
274 buflen = strlen (buf);
279 p = psuffix - buflen;
280 memmove (p, buf, buflen);
281 integerlim = p + buflen - nonintegerlen;
285 use_integer_arithmetic:
287 /* The computation can be done exactly, with integer arithmetic.
289 Use power of BASE notation if requested and if adjusted AMT is
292 if (opts & human_autoscale)
300 unsigned int r10 = (amt % base) * 10 + tenths;
301 unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
304 rounding = (r2 < base
305 ? (r2 + rounding) != 0
306 : 2 + (base < r2 + rounding));
309 while (base <= amt && exponent < exponent_max);
313 if (inexact_style == human_round_to_nearest
314 ? 2 < rounding + (tenths & 1)
315 : inexact_style == human_ceiling && 0 < rounding)
328 && (tenths || ! (opts & human_suppress_point_zero)))
331 p -= decimal_pointlen;
332 memcpy (p, decimal_point, decimal_pointlen);
333 tenths = rounding = 0;
339 if (inexact_style == human_round_to_nearest
340 ? 5 < tenths + (0 < rounding + (amt & 1))
341 : inexact_style == human_ceiling && 0 < tenths + rounding)
345 if ((opts & human_autoscale)
346 && amt == base && exponent < exponent_max)
349 if (! (opts & human_suppress_point_zero))
352 p -= decimal_pointlen;
353 memcpy (p, decimal_point, decimal_pointlen);
363 int digit = amt % 10;
366 while ((amt /= 10) != 0);
370 if (opts & human_group_digits)
371 p = group_number (p, integerlim - p, grouping, thousands_sep);
379 for (power = 1; power < to_block_size; power *= base)
380 if (++exponent == exponent_max)
384 if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
388 *psuffix++ = (! (opts & human_base_1024) && exponent == 1
390 : power_letter[exponent]);
394 if ((opts & human_base_1024) && exponent)
406 /* The default block size used for output. This number may change in
407 the future as disks get larger. */
408 #ifndef DEFAULT_BLOCK_SIZE
409 # define DEFAULT_BLOCK_SIZE 1024
412 static char const *const block_size_args[] = { "human-readable", "si", 0 };
413 static int const block_size_opts[] =
415 human_autoscale + human_SI + human_base_1024,
416 human_autoscale + human_SI
420 default_block_size (void)
422 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
426 humblock (char const *spec, uintmax_t *block_size, int *options)
432 && ! (spec = getenv ("BLOCK_SIZE"))
433 && ! (spec = getenv ("BLOCKSIZE")))
434 *block_size = default_block_size ();
439 opts |= human_group_digits;
443 if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
445 opts |= block_size_opts[i];
451 strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
452 "eEgGkKmMpPtTyYzZ0");
458 for (; ! ('0' <= *spec && *spec <= '9'); spec++)
464 if (ptr[-1] != 'B' || ptr[-2] == 'i')
465 opts |= human_base_1024;
476 human_options (char const *spec, bool report_errors, uintmax_t *block_size)
479 strtol_error e = humblock (spec, block_size, &opts);
480 if (*block_size == 0)
482 *block_size = default_block_size ();
485 if (e != LONGINT_OK && report_errors)
486 STRTOL_FATAL_ERROR (spec, _("block size"), e);