1 /* human.c -- print human readable file size
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
4 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 /* Written by Paul Eggert and Larry McVoy. */
29 # define SIZE_MAX ((size_t) -1)
32 # define UINTMAX_MAX ((uintmax_t) -1)
35 #if HAVE_LOCALE_H && HAVE_LOCALECONV
42 #ifndef HAVE_DECL_GETENV
43 "this configure-time declaration test was not run"
58 #define _(msgid) gettext (msgid)
64 /* The maximum length of a suffix like "KiB". */
65 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
67 static const char power_letter[] =
70 'K', /* kibi ('k' for kilo is a special case) */
71 'M', /* mega or mebi */
72 'G', /* giga or gibi */
73 'T', /* tera or tebi */
74 'P', /* peta or pebi */
75 'E', /* exa or exbi */
76 'Z', /* zetta or 2**70 */
77 'Y' /* yotta or 2**80 */
81 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
82 possible, adjust VALUE according to the style. */
85 adjust_value (int inexact_style, long double value)
87 /* Do not use the floorl or ceill functions, as that would mean
88 checking for their presence and possibly linking with the
89 standard math library, which is a porting pain. So leave the
90 value alone if it is too large to easily round. */
91 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
94 value = u + (inexact_style == human_ceiling && u != value);
100 /* Group the digits of NUMBER according to the grouping rules of the
101 current locale. NUMBER contains NUMBERLEN digits. Modify the
102 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
103 each byte inserted. Return the starting address of the modified
106 To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
107 lconv' from <locale.h>. */
110 group_number (char *number, size_t numberlen,
111 char const *grouping, char const *thousands_sep)
114 size_t grouplen = SIZE_MAX;
115 size_t thousands_seplen = strlen (thousands_sep);
116 size_t i = numberlen;
118 /* The maximum possible value for NUMBERLEN is the number of digits
119 in the square of the largest uintmax_t, so double the size of
120 uintmax_t before converting to a bound. 302 / 1000 is ceil
121 (log10 (2.0)). Add 1 for integer division truncation. */
122 char buf[2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1];
124 memcpy (buf, number, numberlen);
125 d = number + numberlen;
129 unsigned char g = *grouping;
133 grouplen = g < CHAR_MAX ? g : i;
142 memcpy (d, buf + i, grouplen);
146 d -= thousands_seplen;
147 memcpy (d, thousands_sep, thousands_seplen);
151 /* Convert N to a human readable format in BUF, using the options OPTS.
153 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
156 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
159 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
160 to determine whether to take the ceiling or floor of any result
161 that cannot be expressed exactly.
163 If (OPTS & human_group_digits), group the thousands digits
164 according to the locale, e.g., `1,000,000' in an American English
167 If (OPTS & human_autoscale), deduce the output block size
168 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
169 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
170 of 1000 otherwise. For example, assuming powers of 1024, 8500
171 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
172 so on. Numbers smaller than the power aren't modified.
173 human_autoscale is normally used together with human_SI.
175 If (OPTS & human_SI), append an SI prefix indicating which power is
176 being used. If in addition (OPTS & human_B), append "B" (if base
177 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
178 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
179 power of 1024 or of 1000, depending on (OPTS &
183 human_readable (uintmax_t n, char *buf, int opts,
184 uintmax_t from_block_size, uintmax_t to_block_size)
187 opts & (human_round_to_nearest | human_floor | human_ceiling);
188 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
192 int exponent_max = sizeof power_letter - 1;
195 char const *integerlim;
197 /* 0 means adjusted N == AMT.TENTHS;
198 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
199 2 means adjusted N == AMT.TENTHS + 0.05;
200 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
203 char const *decimal_point = ".";
204 size_t decimal_pointlen = 1;
205 char const *grouping = "";
206 char const *thousands_sep = "";
207 #if HAVE_LOCALE_H && HAVE_LOCALECONV
208 struct lconv const *l = localeconv ();
209 size_t pointlen = strlen (l->decimal_point);
210 if (0 < pointlen && pointlen <= MB_LEN_MAX)
212 decimal_point = l->decimal_point;
213 decimal_pointlen = pointlen;
215 grouping = l->grouping;
216 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
217 thousands_sep = l->thousands_sep;
220 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
223 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
224 units. If this can be done exactly with integer arithmetic, do
225 not use floating point operations. */
226 if (to_block_size <= from_block_size)
228 if (from_block_size % to_block_size == 0)
230 uintmax_t multiplier = from_block_size / to_block_size;
231 amt = n * multiplier;
232 if (amt / multiplier == n)
236 goto use_integer_arithmetic;
240 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
242 uintmax_t divisor = to_block_size / from_block_size;
243 uintmax_t r10 = (n % divisor) * 10;
244 uintmax_t r2 = (r10 % divisor) * 2;
246 tenths = r10 / divisor;
247 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
248 goto use_integer_arithmetic;
252 /* Either the result cannot be computed easily using uintmax_t,
253 or from_block_size is zero. Fall back on floating point.
254 FIXME: This can yield answers that are slightly off. */
256 long double dto_block_size = to_block_size;
257 long double damt = n * (from_block_size / dto_block_size);
259 size_t nonintegerlen;
261 if (! (opts & human_autoscale))
263 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
264 buflen = strlen (buf);
277 while (e * base <= damt && exponent < exponent_max);
281 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
282 buflen = strlen (buf);
283 nonintegerlen = decimal_pointlen + 1;
285 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
286 || ((opts & human_suppress_point_zero)
287 && buf[buflen - 1] == '0'))
289 sprintf (buf, "%.0Lf",
290 adjust_value (inexact_style, damt * 10) / 10);
291 buflen = strlen (buf);
296 p = psuffix - buflen;
297 memmove (p, buf, buflen);
298 integerlim = p + buflen - nonintegerlen;
302 use_integer_arithmetic:
304 /* The computation can be done exactly, with integer arithmetic.
306 Use power of BASE notation if requested and if adjusted AMT is
309 if (opts & human_autoscale)
317 unsigned r10 = (amt % base) * 10 + tenths;
318 unsigned r2 = (r10 % base) * 2 + (rounding >> 1);
321 rounding = (r2 < base
322 ? (r2 + rounding) != 0
323 : 2 + (base < r2 + rounding));
326 while (base <= amt && exponent < exponent_max);
330 if (inexact_style == human_round_to_nearest
331 ? 2 < rounding + (tenths & 1)
332 : inexact_style == human_ceiling && 0 < rounding)
345 && (tenths || ! (opts & human_suppress_point_zero)))
348 p -= decimal_pointlen;
349 memcpy (p, decimal_point, decimal_pointlen);
350 tenths = rounding = 0;
356 if (inexact_style == human_ceiling
357 ? 0 < tenths + rounding
358 : inexact_style == human_round_to_nearest
359 ? 5 < tenths + (2 < rounding + (amt & 1))
360 : /* inexact_style == human_floor */ 0)
364 if ((opts & human_autoscale)
365 && amt == base && exponent < exponent_max)
368 if (! (opts & human_suppress_point_zero))
371 p -= decimal_pointlen;
372 memcpy (p, decimal_point, decimal_pointlen);
382 int digit = amt % 10;
385 while ((amt /= 10) != 0);
389 if (opts & human_group_digits)
390 p = group_number (p, integerlim - p, grouping, thousands_sep);
398 for (power = 1; power < to_block_size; power *= base)
399 if (++exponent == exponent_max)
404 *psuffix++ = (! (opts & human_base_1024) && exponent == 1
406 : power_letter[exponent]);
410 if ((opts & human_base_1024) && exponent)
422 /* The default block size used for output. This number may change in
423 the future as disks get larger. */
424 #ifndef DEFAULT_BLOCK_SIZE
425 # define DEFAULT_BLOCK_SIZE 1024
428 static char const *const block_size_args[] = { "human-readable", "si", 0 };
429 static int const block_size_opts[] =
431 human_autoscale + human_SI + human_base_1024,
432 human_autoscale + human_SI
436 default_block_size (void)
438 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
442 humblock (char const *spec, uintmax_t *block_size, int *options)
447 if (! spec && ! (spec = getenv ("BLOCK_SIZE")))
448 *block_size = default_block_size ();
453 opts |= human_group_digits;
457 if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
459 opts |= block_size_opts[i];
465 strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
466 "eEgGkKmMpPtTyYzZ0");
470 return LONGINT_INVALID_SUFFIX_CHAR;
471 for (; ! ('0' <= *spec && *spec <= '9'); spec++)
477 if (ptr[-1] != 'B' || ptr[-2] == 'i')
478 opts |= human_base_1024;
489 human_options (char const *spec, bool report_errors, uintmax_t *block_size)
492 strtol_error e = humblock (spec, block_size, &opts);
493 if (*block_size == 0)
495 *block_size = default_block_size ();
498 if (e != LONGINT_OK && report_errors)
499 STRTOL_FATAL_ERROR (spec, _("block size"), e);