1 /* human.c -- print human readable file size
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006 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. */
32 #define _(msgid) gettext (msgid)
39 /* The maximum length of a suffix like "KiB". */
40 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
42 static const char power_letter[] =
45 'K', /* kibi ('k' for kilo is a special case) */
46 'M', /* mega or mebi */
47 'G', /* giga or gibi */
48 'T', /* tera or tebi */
49 'P', /* peta or pebi */
50 'E', /* exa or exbi */
51 'Z', /* zetta or 2**70 */
52 'Y' /* yotta or 2**80 */
56 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
57 possible, adjust VALUE according to the style. */
60 adjust_value (int inexact_style, long double value)
62 /* Do not use the floorl or ceill functions, as that would mean
63 checking for their presence and possibly linking with the
64 standard math library, which is a porting pain. So leave the
65 value alone if it is too large to easily round. */
66 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
69 value = u + (inexact_style == human_ceiling && u != value);
75 /* Group the digits of NUMBER according to the grouping rules of the
76 current locale. NUMBER contains NUMBERLEN digits. Modify the
77 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
78 each byte inserted. Return the starting address of the modified
81 To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
82 lconv' from <locale.h>. */
85 group_number (char *number, size_t numberlen,
86 char const *grouping, char const *thousands_sep)
89 size_t grouplen = SIZE_MAX;
90 size_t thousands_seplen = strlen (thousands_sep);
93 /* The maximum possible value for NUMBERLEN is the number of digits
94 in the square of the largest uintmax_t, so double the size needed. */
95 char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1];
97 memcpy (buf, number, numberlen);
98 d = number + numberlen;
102 unsigned char g = *grouping;
106 grouplen = g < CHAR_MAX ? g : i;
115 memcpy (d, buf + i, grouplen);
119 d -= thousands_seplen;
120 memcpy (d, thousands_sep, thousands_seplen);
124 /* Convert N to a human readable format in BUF, using the options OPTS.
126 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
129 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
132 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
133 to determine whether to take the ceiling or floor of any result
134 that cannot be expressed exactly.
136 If (OPTS & human_group_digits), group the thousands digits
137 according to the locale, e.g., `1,000,000' in an American English
140 If (OPTS & human_autoscale), deduce the output block size
141 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
142 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
143 of 1000 otherwise. For example, assuming powers of 1024, 8500
144 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
145 so on. Numbers smaller than the power aren't modified.
146 human_autoscale is normally used together with human_SI.
148 If (OPTS & human_space_before_unit), use a space to separate the
149 number from any suffix that is appended as described below.
151 If (OPTS & human_SI), append an SI prefix indicating which power is
152 being used. If in addition (OPTS & human_B), append "B" (if base
153 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
154 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
155 power of 1024 or of 1000, depending on (OPTS &
159 human_readable (uintmax_t n, char *buf, int opts,
160 uintmax_t from_block_size, uintmax_t to_block_size)
163 opts & (human_round_to_nearest | human_floor | human_ceiling);
164 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
168 int exponent_max = sizeof power_letter - 1;
171 char const *integerlim;
173 /* 0 means adjusted N == AMT.TENTHS;
174 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
175 2 means adjusted N == AMT.TENTHS + 0.05;
176 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
179 char const *decimal_point = ".";
180 size_t decimal_pointlen = 1;
181 char const *grouping = "";
182 char const *thousands_sep = "";
183 struct lconv const *l = localeconv ();
184 size_t pointlen = strlen (l->decimal_point);
185 if (0 < pointlen && pointlen <= MB_LEN_MAX)
187 decimal_point = l->decimal_point;
188 decimal_pointlen = pointlen;
190 grouping = l->grouping;
191 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
192 thousands_sep = l->thousands_sep;
194 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
197 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
198 units. If this can be done exactly with integer arithmetic, do
199 not use floating point operations. */
200 if (to_block_size <= from_block_size)
202 if (from_block_size % to_block_size == 0)
204 uintmax_t multiplier = from_block_size / to_block_size;
205 amt = n * multiplier;
206 if (amt / multiplier == n)
210 goto use_integer_arithmetic;
214 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
216 uintmax_t divisor = to_block_size / from_block_size;
217 uintmax_t r10 = (n % divisor) * 10;
218 uintmax_t r2 = (r10 % divisor) * 2;
220 tenths = r10 / divisor;
221 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
222 goto use_integer_arithmetic;
226 /* Either the result cannot be computed easily using uintmax_t,
227 or from_block_size is zero. Fall back on floating point.
228 FIXME: This can yield answers that are slightly off. */
230 long double dto_block_size = to_block_size;
231 long double damt = n * (from_block_size / dto_block_size);
233 size_t nonintegerlen;
235 if (! (opts & human_autoscale))
237 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
238 buflen = strlen (buf);
251 while (e * base <= damt && exponent < exponent_max);
255 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
256 buflen = strlen (buf);
257 nonintegerlen = decimal_pointlen + 1;
259 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
260 || ((opts & human_suppress_point_zero)
261 && buf[buflen - 1] == '0'))
263 sprintf (buf, "%.0Lf",
264 adjust_value (inexact_style, damt * 10) / 10);
265 buflen = strlen (buf);
270 p = psuffix - buflen;
271 memmove (p, buf, buflen);
272 integerlim = p + buflen - nonintegerlen;
276 use_integer_arithmetic:
278 /* The computation can be done exactly, with integer arithmetic.
280 Use power of BASE notation if requested and if adjusted AMT is
283 if (opts & human_autoscale)
291 unsigned int r10 = (amt % base) * 10 + tenths;
292 unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
295 rounding = (r2 < base
296 ? (r2 + rounding) != 0
297 : 2 + (base < r2 + rounding));
300 while (base <= amt && exponent < exponent_max);
304 if (inexact_style == human_round_to_nearest
305 ? 2 < rounding + (tenths & 1)
306 : inexact_style == human_ceiling && 0 < rounding)
319 && (tenths || ! (opts & human_suppress_point_zero)))
322 p -= decimal_pointlen;
323 memcpy (p, decimal_point, decimal_pointlen);
324 tenths = rounding = 0;
330 if (inexact_style == human_round_to_nearest
331 ? 5 < tenths + (0 < rounding + (amt & 1))
332 : inexact_style == human_ceiling && 0 < tenths + rounding)
336 if ((opts & human_autoscale)
337 && amt == base && exponent < exponent_max)
340 if (! (opts & human_suppress_point_zero))
343 p -= decimal_pointlen;
344 memcpy (p, decimal_point, decimal_pointlen);
354 int digit = amt % 10;
357 while ((amt /= 10) != 0);
361 if (opts & human_group_digits)
362 p = group_number (p, integerlim - p, grouping, thousands_sep);
370 for (power = 1; power < to_block_size; power *= base)
371 if (++exponent == exponent_max)
375 if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
379 *psuffix++ = (! (opts & human_base_1024) && exponent == 1
381 : power_letter[exponent]);
385 if ((opts & human_base_1024) && exponent)
397 /* The default block size used for output. This number may change in
398 the future as disks get larger. */
399 #ifndef DEFAULT_BLOCK_SIZE
400 # define DEFAULT_BLOCK_SIZE 1024
403 static char const *const block_size_args[] = { "human-readable", "si", 0 };
404 static int const block_size_opts[] =
406 human_autoscale + human_SI + human_base_1024,
407 human_autoscale + human_SI
411 default_block_size (void)
413 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
417 humblock (char const *spec, uintmax_t *block_size, int *options)
423 && ! (spec = getenv ("BLOCK_SIZE"))
424 && ! (spec = getenv ("BLOCKSIZE")))
425 *block_size = default_block_size ();
430 opts |= human_group_digits;
434 if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
436 opts |= block_size_opts[i];
442 strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
443 "eEgGkKmMpPtTyYzZ0");
449 for (; ! ('0' <= *spec && *spec <= '9'); spec++)
455 if (ptr[-1] != 'B' || ptr[-2] == 'i')
456 opts |= human_base_1024;
467 human_options (char const *spec, bool report_errors, uintmax_t *block_size)
470 strtol_error e = humblock (spec, block_size, &opts);
471 if (*block_size == 0)
473 *block_size = default_block_size ();
476 if (e != LONGINT_OK && report_errors)
477 STRTOL_FATAL_ERROR (spec, _("block size"), e);