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"
60 #define _(msgid) gettext (msgid)
66 /* The maximum length of a suffix like "KiB". */
67 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
69 static const char power_letter[] =
72 'K', /* kibi ('k' for kilo is a special case) */
73 'M', /* mega or mebi */
74 'G', /* giga or gibi */
75 'T', /* tera or tebi */
76 'P', /* peta or pebi */
77 'E', /* exa or exbi */
78 'Z', /* zetta or 2**70 */
79 'Y' /* yotta or 2**80 */
83 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
84 possible, adjust VALUE according to the style. */
87 adjust_value (int inexact_style, long double value)
89 /* Do not use the floorl or ceill functions, as that would mean
90 checking for their presence and possibly linking with the
91 standard math library, which is a porting pain. So leave the
92 value alone if it is too large to easily round. */
93 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
96 value = u + (inexact_style == human_ceiling && u != value);
102 /* Group the digits of NUMBER according to the grouping rules of the
103 current locale. NUMBER contains NUMBERLEN digits. Modify the
104 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
105 each byte inserted. Return the starting address of the modified
108 To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
109 lconv' from <locale.h>. */
112 group_number (char *number, size_t numberlen,
113 char const *grouping, char const *thousands_sep)
116 size_t grouplen = SIZE_MAX;
117 size_t thousands_seplen = strlen (thousands_sep);
118 size_t i = numberlen;
120 /* The maximum possible value for NUMBERLEN is the number of digits
121 in the square of the largest uintmax_t, so double the size of
122 uintmax_t before converting to a bound. 302 / 1000 is ceil
123 (log10 (2.0)). Add 1 for integer division truncation. */
124 char buf[2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1];
126 memcpy (buf, number, numberlen);
127 d = number + numberlen;
131 unsigned char g = *grouping;
135 grouplen = g < CHAR_MAX ? g : i;
144 memcpy (d, buf + i, grouplen);
148 d -= thousands_seplen;
149 memcpy (d, thousands_sep, thousands_seplen);
153 /* Convert N to a human readable format in BUF, using the options OPTS.
155 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
158 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
161 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
162 to determine whether to take the ceiling or floor of any result
163 that cannot be expressed exactly.
165 If (OPTS & human_group_digits), group the thousands digits
166 according to the locale, e.g., `1,000,000' in an American English
169 If (OPTS & human_autoscale), deduce the output block size
170 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
171 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
172 of 1000 otherwise. For example, assuming powers of 1024, 8500
173 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
174 so on. Numbers smaller than the power aren't modified.
175 human_autoscale is normally used together with human_SI.
177 If (OPTS & human_SI), append an SI prefix indicating which power is
178 being used. If in addition (OPTS & human_B), append "B" (if base
179 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
180 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
181 power of 1024 or of 1000, depending on (OPTS &
185 human_readable (uintmax_t n, char *buf, int opts,
186 uintmax_t from_block_size, uintmax_t to_block_size)
189 opts & (human_round_to_nearest | human_floor | human_ceiling);
190 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
194 int exponent_max = sizeof power_letter - 1;
197 char const *integerlim;
199 /* 0 means adjusted N == AMT.TENTHS;
200 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
201 2 means adjusted N == AMT.TENTHS + 0.05;
202 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
205 char const *decimal_point = ".";
206 size_t decimal_pointlen = 1;
207 char const *grouping = "";
208 char const *thousands_sep = "";
209 #if HAVE_LOCALE_H && HAVE_LOCALECONV
210 struct lconv const *l = localeconv ();
211 size_t pointlen = strlen (l->decimal_point);
212 if (0 < pointlen && pointlen <= MB_LEN_MAX)
214 decimal_point = l->decimal_point;
215 decimal_pointlen = pointlen;
217 grouping = l->grouping;
218 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
219 thousands_sep = l->thousands_sep;
222 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
225 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
226 units. If this can be done exactly with integer arithmetic, do
227 not use floating point operations. */
228 if (to_block_size <= from_block_size)
230 if (from_block_size % to_block_size == 0)
232 uintmax_t multiplier = from_block_size / to_block_size;
233 amt = n * multiplier;
234 if (amt / multiplier == n)
238 goto use_integer_arithmetic;
242 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
244 uintmax_t divisor = to_block_size / from_block_size;
245 uintmax_t r10 = (n % divisor) * 10;
246 uintmax_t r2 = (r10 % divisor) * 2;
248 tenths = r10 / divisor;
249 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
250 goto use_integer_arithmetic;
254 /* Either the result cannot be computed easily using uintmax_t,
255 or from_block_size is zero. Fall back on floating point.
256 FIXME: This can yield answers that are slightly off. */
258 long double dto_block_size = to_block_size;
259 long double damt = n * (from_block_size / dto_block_size);
261 size_t nonintegerlen;
263 if (! (opts & human_autoscale))
265 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
266 buflen = strlen (buf);
279 while (e * base <= damt && exponent < exponent_max);
283 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
284 buflen = strlen (buf);
285 nonintegerlen = decimal_pointlen + 1;
287 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
288 || ((opts & human_suppress_point_zero)
289 && buf[buflen - 1] == '0'))
291 sprintf (buf, "%.0Lf",
292 adjust_value (inexact_style, damt * 10) / 10);
293 buflen = strlen (buf);
298 p = psuffix - buflen;
299 memmove (p, buf, buflen);
300 integerlim = p + buflen - nonintegerlen;
304 use_integer_arithmetic:
306 /* The computation can be done exactly, with integer arithmetic.
308 Use power of BASE notation if requested and if adjusted AMT is
311 if (opts & human_autoscale)
319 unsigned r10 = (amt % base) * 10 + tenths;
320 unsigned r2 = (r10 % base) * 2 + (rounding >> 1);
323 rounding = (r2 < base
324 ? (r2 + rounding) != 0
325 : 2 + (base < r2 + rounding));
328 while (base <= amt && exponent < exponent_max);
332 if (inexact_style == human_round_to_nearest
333 ? 2 < rounding + (tenths & 1)
334 : inexact_style == human_ceiling && 0 < rounding)
347 && (tenths || ! (opts & human_suppress_point_zero)))
350 p -= decimal_pointlen;
351 memcpy (p, decimal_point, decimal_pointlen);
352 tenths = rounding = 0;
358 if (inexact_style == human_round_to_nearest
359 ? 5 < tenths + (0 < rounding + (amt & 1))
360 : inexact_style == human_ceiling && 0 < tenths + rounding)
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);