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)
40 # define SIZE_MAX ((size_t) -1)
43 # define UINTMAX_MAX ((uintmax_t) -1)
46 /* The maximum length of a suffix like "KiB". */
47 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
49 static const char power_letter[] =
52 'K', /* kibi ('k' for kilo is a special case) */
53 'M', /* mega or mebi */
54 'G', /* giga or gibi */
55 'T', /* tera or tebi */
56 'P', /* peta or pebi */
57 'E', /* exa or exbi */
58 'Z', /* zetta or 2**70 */
59 'Y' /* yotta or 2**80 */
63 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
64 possible, adjust VALUE according to the style. */
67 adjust_value (int inexact_style, long double value)
69 /* Do not use the floorl or ceill functions, as that would mean
70 checking for their presence and possibly linking with the
71 standard math library, which is a porting pain. So leave the
72 value alone if it is too large to easily round. */
73 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
76 value = u + (inexact_style == human_ceiling && u != value);
82 /* Group the digits of NUMBER according to the grouping rules of the
83 current locale. NUMBER contains NUMBERLEN digits. Modify the
84 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
85 each byte inserted. Return the starting address of the modified
88 To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
89 lconv' from <locale.h>. */
92 group_number (char *number, size_t numberlen,
93 char const *grouping, char const *thousands_sep)
96 size_t grouplen = SIZE_MAX;
97 size_t thousands_seplen = strlen (thousands_sep);
100 /* The maximum possible value for NUMBERLEN is the number of digits
101 in the square of the largest uintmax_t, so double the size needed. */
102 char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1];
104 memcpy (buf, number, numberlen);
105 d = number + numberlen;
109 unsigned char g = *grouping;
113 grouplen = g < CHAR_MAX ? g : i;
122 memcpy (d, buf + i, grouplen);
126 d -= thousands_seplen;
127 memcpy (d, thousands_sep, thousands_seplen);
131 /* Convert N to a human readable format in BUF, using the options OPTS.
133 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
136 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
139 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
140 to determine whether to take the ceiling or floor of any result
141 that cannot be expressed exactly.
143 If (OPTS & human_group_digits), group the thousands digits
144 according to the locale, e.g., `1,000,000' in an American English
147 If (OPTS & human_autoscale), deduce the output block size
148 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
149 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
150 of 1000 otherwise. For example, assuming powers of 1024, 8500
151 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
152 so on. Numbers smaller than the power aren't modified.
153 human_autoscale is normally used together with human_SI.
155 If (OPTS & human_space_before_unit), use a space to separate the
156 number from any suffix that is appended as described below.
158 If (OPTS & human_SI), append an SI prefix indicating which power is
159 being used. If in addition (OPTS & human_B), append "B" (if base
160 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
161 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
162 power of 1024 or of 1000, depending on (OPTS &
166 human_readable (uintmax_t n, char *buf, int opts,
167 uintmax_t from_block_size, uintmax_t to_block_size)
170 opts & (human_round_to_nearest | human_floor | human_ceiling);
171 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
175 int exponent_max = sizeof power_letter - 1;
178 char const *integerlim;
180 /* 0 means adjusted N == AMT.TENTHS;
181 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
182 2 means adjusted N == AMT.TENTHS + 0.05;
183 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
186 char const *decimal_point = ".";
187 size_t decimal_pointlen = 1;
188 char const *grouping = "";
189 char const *thousands_sep = "";
190 struct lconv const *l = localeconv ();
191 size_t pointlen = strlen (l->decimal_point);
192 if (0 < pointlen && pointlen <= MB_LEN_MAX)
194 decimal_point = l->decimal_point;
195 decimal_pointlen = pointlen;
197 grouping = l->grouping;
198 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
199 thousands_sep = l->thousands_sep;
201 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
204 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
205 units. If this can be done exactly with integer arithmetic, do
206 not use floating point operations. */
207 if (to_block_size <= from_block_size)
209 if (from_block_size % to_block_size == 0)
211 uintmax_t multiplier = from_block_size / to_block_size;
212 amt = n * multiplier;
213 if (amt / multiplier == n)
217 goto use_integer_arithmetic;
221 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
223 uintmax_t divisor = to_block_size / from_block_size;
224 uintmax_t r10 = (n % divisor) * 10;
225 uintmax_t r2 = (r10 % divisor) * 2;
227 tenths = r10 / divisor;
228 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
229 goto use_integer_arithmetic;
233 /* Either the result cannot be computed easily using uintmax_t,
234 or from_block_size is zero. Fall back on floating point.
235 FIXME: This can yield answers that are slightly off. */
237 long double dto_block_size = to_block_size;
238 long double damt = n * (from_block_size / dto_block_size);
240 size_t nonintegerlen;
242 if (! (opts & human_autoscale))
244 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
245 buflen = strlen (buf);
258 while (e * base <= damt && exponent < exponent_max);
262 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
263 buflen = strlen (buf);
264 nonintegerlen = decimal_pointlen + 1;
266 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
267 || ((opts & human_suppress_point_zero)
268 && buf[buflen - 1] == '0'))
270 sprintf (buf, "%.0Lf",
271 adjust_value (inexact_style, damt * 10) / 10);
272 buflen = strlen (buf);
277 p = psuffix - buflen;
278 memmove (p, buf, buflen);
279 integerlim = p + buflen - nonintegerlen;
283 use_integer_arithmetic:
285 /* The computation can be done exactly, with integer arithmetic.
287 Use power of BASE notation if requested and if adjusted AMT is
290 if (opts & human_autoscale)
298 unsigned int r10 = (amt % base) * 10 + tenths;
299 unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
302 rounding = (r2 < base
303 ? (r2 + rounding) != 0
304 : 2 + (base < r2 + rounding));
307 while (base <= amt && exponent < exponent_max);
311 if (inexact_style == human_round_to_nearest
312 ? 2 < rounding + (tenths & 1)
313 : inexact_style == human_ceiling && 0 < rounding)
326 && (tenths || ! (opts & human_suppress_point_zero)))
329 p -= decimal_pointlen;
330 memcpy (p, decimal_point, decimal_pointlen);
331 tenths = rounding = 0;
337 if (inexact_style == human_round_to_nearest
338 ? 5 < tenths + (0 < rounding + (amt & 1))
339 : inexact_style == human_ceiling && 0 < tenths + rounding)
343 if ((opts & human_autoscale)
344 && amt == base && exponent < exponent_max)
347 if (! (opts & human_suppress_point_zero))
350 p -= decimal_pointlen;
351 memcpy (p, decimal_point, decimal_pointlen);
361 int digit = amt % 10;
364 while ((amt /= 10) != 0);
368 if (opts & human_group_digits)
369 p = group_number (p, integerlim - p, grouping, thousands_sep);
377 for (power = 1; power < to_block_size; power *= base)
378 if (++exponent == exponent_max)
382 if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
386 *psuffix++ = (! (opts & human_base_1024) && exponent == 1
388 : power_letter[exponent]);
392 if ((opts & human_base_1024) && exponent)
404 /* The default block size used for output. This number may change in
405 the future as disks get larger. */
406 #ifndef DEFAULT_BLOCK_SIZE
407 # define DEFAULT_BLOCK_SIZE 1024
410 static char const *const block_size_args[] = { "human-readable", "si", 0 };
411 static int const block_size_opts[] =
413 human_autoscale + human_SI + human_base_1024,
414 human_autoscale + human_SI
418 default_block_size (void)
420 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
424 humblock (char const *spec, uintmax_t *block_size, int *options)
430 && ! (spec = getenv ("BLOCK_SIZE"))
431 && ! (spec = getenv ("BLOCKSIZE")))
432 *block_size = default_block_size ();
437 opts |= human_group_digits;
441 if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
443 opts |= block_size_opts[i];
449 strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
450 "eEgGkKmMpPtTyYzZ0");
456 for (; ! ('0' <= *spec && *spec <= '9'); spec++)
462 if (ptr[-1] != 'B' || ptr[-2] == 'i')
463 opts |= human_base_1024;
474 human_options (char const *spec, bool report_errors, uintmax_t *block_size)
477 strtol_error e = humblock (spec, block_size, &opts);
478 if (*block_size == 0)
480 *block_size = default_block_size ();
483 if (e != LONGINT_OK && report_errors)
484 STRTOL_FATAL_ERROR (spec, _("block size"), e);