*** empty log message ***
[coreutils.git] / lib / human.c
blob1178b9c4c237f9a40e0418dd0343e0098822ac01
1 /* human.c -- print human readable file size
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 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)
9 any later version.
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 /* Originally contributed by lm@sgi.com;
21 --si, output block size selection, large file support,
22 and grouping added by eggert@twinsun.com. */
24 #if HAVE_CONFIG_H
25 # include <config.h>
26 #endif
28 #if HAVE_STDBOOL_H
29 # include <stdbool.h>
30 #else
31 typedef enum {false = 0, true = 1} bool;
32 #endif
34 #if HAVE_INTTYPES_H
35 # include <inttypes.h>
36 #else
37 # if HAVE_STDINT_H
38 # include <stdint.h>
39 # endif
40 #endif
41 #ifndef SIZE_MAX
42 # define SIZE_MAX ((size_t) -1)
43 #endif
44 #ifndef UINTMAX_MAX
45 # define UINTMAX_MAX ((uintmax_t) -1)
46 #endif
48 #include <limits.h>
50 #if HAVE_LOCALE_H && HAVE_LOCALECONV
51 # include <locale.h>
52 #endif
54 #if HAVE_STDLIB_H
55 # include <stdlib.h>
56 #endif
57 #ifndef HAVE_DECL_GETENV
58 "this configure-time declaration test was not run"
59 #endif
60 #if !HAVE_DECL_GETENV
61 char *getenv ();
62 #endif
64 #if HAVE_STRING_H
65 # include <string.h>
66 #endif
68 #if HAVE_STRINGS_H
69 # include <strings.h>
70 #endif
72 #include <stdio.h>
73 #include <sys/types.h>
75 #include <gettext.h>
76 #define _(text) gettext (text)
78 #include <argmatch.h>
79 #include <error.h>
80 #include <xstrtol.h>
82 #include "human.h"
84 /* The maximum length of a suffix like "KiB". */
85 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
87 static const char power_letter[] =
89 0, /* not used */
90 'K', /* kibi ('k' for kilo is a special case) */
91 'M', /* mega or mebi */
92 'G', /* giga or gibi */
93 'T', /* tera or tebi */
94 'P', /* peta or pebi */
95 'E', /* exa or exbi */
96 'Z', /* zetta or 2**70 */
97 'Y' /* yotta or 2**80 */
101 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
102 possible, adjust VALUE according to the style. */
104 static long double
105 adjust_value (int inexact_style, long double value)
107 /* Do not use the floorl or ceill functions, as that would mean
108 checking for their presence and possibly linking with the
109 standard math library, which is a porting pain. So leave the
110 value alone if it is too large to easily round. */
111 if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
113 uintmax_t u = value;
114 value = u + (inexact_style == human_ceiling && u != value);
117 return value;
120 /* Group the digits of NUMBER according to the grouping rules of the
121 current locale. NUMBER contains NUMBERLEN digits. Modify the
122 bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
123 each byte inserted. Return the starting address of the modified
124 number.
126 To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
127 lconv' from <locale.h>. */
129 static char *
130 group_number (char *number, size_t numberlen,
131 char const *grouping, char const *thousands_sep)
133 register char *d;
134 size_t grouplen = SIZE_MAX;
135 size_t thousands_seplen = strlen (thousands_sep);
136 size_t i = numberlen;
138 /* The maximum possible value for NUMBERLEN is the number of digits
139 in the square of the largest uintmax_t, so double the size of
140 uintmax_t before converting to a bound. 302 / 1000 is ceil
141 (log10 (2.0)). Add 1 for integer division truncation. */
142 char buf[2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1];
144 memcpy (buf, number, numberlen);
145 d = number + numberlen;
147 for (;;)
149 unsigned char g = *grouping;
151 if (g)
153 grouplen = g < CHAR_MAX ? g : i;
154 grouping++;
157 if (i < grouplen)
158 grouplen = i;
160 d -= grouplen;
161 i -= grouplen;
162 memcpy (d, buf + i, grouplen);
163 if (i == 0)
164 return d;
166 d -= thousands_seplen;
167 memcpy (d, thousands_sep, thousands_seplen);
171 /* Convert N to a human readable format in BUF, using the options OPTS.
173 N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
174 be nonnegative.
176 Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
177 must be positive.
179 Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
180 to determine whether to take the ceiling or floor of any result
181 that cannot be expressed exactly.
183 If (OPTS & human_group_digits), group the thousands digits
184 according to the locale, e.g., `1,000,000' in an American English
185 locale.
187 If (OPTS & human_autoscale), deduce the output block size
188 automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
189 output. Use powers of 1024 if (OPTS & human_base_1024), and powers
190 of 1000 otherwise. For example, assuming powers of 1024, 8500
191 would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
192 so on. Numbers smaller than the power aren't modified.
193 human_autoscale is normally used together with human_SI.
195 If (OPTS & human_SI), append an SI prefix indicating which power is
196 being used. If in addition (OPTS & human_B), append "B" (if base
197 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
198 human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
199 power of 1024 or of 1000, depending on (OPTS &
200 human_base_1024). */
202 char *
203 human_readable (uintmax_t n, char *buf, int opts,
204 uintmax_t from_block_size, uintmax_t to_block_size)
206 int inexact_style =
207 opts & (human_round_to_nearest | human_floor | human_ceiling);
208 unsigned int base = opts & human_base_1024 ? 1024 : 1000;
209 uintmax_t amt;
210 int tenths;
211 int exponent = -1;
212 int exponent_max = sizeof power_letter - 1;
213 char *p;
214 char *psuffix;
215 char const *integerlim;
217 /* 0 means adjusted N == AMT.TENTHS;
218 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
219 2 means adjusted N == AMT.TENTHS + 0.05;
220 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
221 int rounding;
223 char const *decimal_point = ".";
224 size_t decimal_pointlen = 1;
225 char const *grouping = "";
226 char const *thousands_sep = "";
227 #if HAVE_LOCALE_H && HAVE_LOCALECONV
228 struct lconv const *l = localeconv ();
229 size_t pointlen = strlen (l->decimal_point);
230 if (0 < pointlen && pointlen <= MB_LEN_MAX)
232 decimal_point = l->decimal_point;
233 decimal_pointlen = pointlen;
235 grouping = l->grouping;
236 if (strlen (l->thousands_sep) <= MB_LEN_MAX)
237 thousands_sep = l->thousands_sep;
238 #endif
240 psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
241 p = psuffix;
243 /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
244 units. If this can be done exactly with integer arithmetic, do
245 not use floating point operations. */
246 if (to_block_size <= from_block_size)
248 if (from_block_size % to_block_size == 0)
250 uintmax_t multiplier = from_block_size / to_block_size;
251 amt = n * multiplier;
252 if (amt / multiplier == n)
254 tenths = 0;
255 rounding = 0;
256 goto use_integer_arithmetic;
260 else if (from_block_size != 0 && to_block_size % from_block_size == 0)
262 uintmax_t divisor = to_block_size / from_block_size;
263 uintmax_t r10 = (n % divisor) * 10;
264 uintmax_t r2 = (r10 % divisor) * 2;
265 amt = n / divisor;
266 tenths = r10 / divisor;
267 rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
268 goto use_integer_arithmetic;
272 /* Either the result cannot be computed easily using uintmax_t,
273 or from_block_size is zero. Fall back on floating point.
274 FIXME: This can yield answers that are slightly off. */
276 long double dto_block_size = to_block_size;
277 long double damt = n * (from_block_size / dto_block_size);
278 size_t buflen;
279 size_t nonintegerlen;
281 if (! (opts & human_autoscale))
283 sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
284 buflen = strlen (buf);
285 nonintegerlen = 0;
287 else
289 long double e = 1;
290 exponent = 0;
294 e *= base;
295 exponent++;
297 while (e * base <= damt && exponent < exponent_max);
299 damt /= e;
301 sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
302 buflen = strlen (buf);
303 nonintegerlen = decimal_pointlen + 1;
305 if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
306 || ((opts & human_suppress_point_zero)
307 && buf[buflen - 1] == '0'))
309 sprintf (buf, "%.0Lf",
310 adjust_value (inexact_style, damt * 10) / 10);
311 buflen = strlen (buf);
312 nonintegerlen = 0;
316 p = psuffix - buflen;
317 memmove (p, buf, buflen);
318 integerlim = p + buflen - nonintegerlen;
320 goto do_grouping;
322 use_integer_arithmetic:
324 /* The computation can be done exactly, with integer arithmetic.
326 Use power of BASE notation if requested and if adjusted AMT is
327 large enough. */
329 if (opts & human_autoscale)
331 exponent = 0;
333 if (base <= amt)
337 unsigned r10 = (amt % base) * 10 + tenths;
338 unsigned r2 = (r10 % base) * 2 + (rounding >> 1);
339 amt /= base;
340 tenths = r10 / base;
341 rounding = (r2 < base
342 ? (r2 + rounding) != 0
343 : 2 + (base < r2 + rounding));
344 exponent++;
346 while (base <= amt && exponent < exponent_max);
348 if (amt < 10)
350 if (inexact_style == human_round_to_nearest
351 ? 2 < rounding + (tenths & 1)
352 : inexact_style == human_ceiling && 0 < rounding)
354 tenths++;
355 rounding = 0;
357 if (tenths == 10)
359 amt++;
360 tenths = 0;
364 if (amt < 10
365 && (tenths || ! (opts & human_suppress_point_zero)))
367 *--p = '0' + tenths;
368 p -= decimal_pointlen;
369 memcpy (p, decimal_point, decimal_pointlen);
370 tenths = rounding = 0;
376 if (inexact_style == human_ceiling
377 ? 0 < tenths + rounding
378 : inexact_style == human_round_to_nearest
379 ? 5 < tenths + (2 < rounding + (amt & 1))
380 : /* inexact_style == human_floor */ 0)
382 amt++;
384 if ((opts & human_autoscale)
385 && amt == base && exponent < exponent_max)
387 exponent++;
388 if (! (opts & human_suppress_point_zero))
390 *--p = '0';
391 p -= decimal_pointlen;
392 memcpy (p, decimal_point, decimal_pointlen);
394 amt = 1;
398 integerlim = p;
402 int digit = amt % 10;
403 *--p = digit + '0';
405 while ((amt /= 10) != 0);
408 do_grouping:
409 if (opts & human_group_digits)
410 p = group_number (p, integerlim - p, grouping, thousands_sep);
412 if (opts & human_SI)
414 if (exponent < 0)
416 uintmax_t power;
417 exponent = 0;
418 for (power = 1; power < to_block_size; power *= base)
419 if (++exponent == exponent_max)
420 break;
423 if (exponent)
424 *psuffix++ = (! (opts & human_base_1024) && exponent == 1
425 ? 'k'
426 : power_letter[exponent]);
428 if (opts & human_B)
430 if ((opts & human_base_1024) && exponent)
431 *psuffix++ = 'i';
432 *psuffix++ = 'B';
436 *psuffix = '\0';
438 return p;
442 /* The default block size used for output. This number may change in
443 the future as disks get larger. */
444 #ifndef DEFAULT_BLOCK_SIZE
445 # define DEFAULT_BLOCK_SIZE 1024
446 #endif
448 static char const *const block_size_args[] = { "human-readable", "si", 0 };
449 static int const block_size_opts[] =
451 human_autoscale + human_SI + human_base_1024,
452 human_autoscale + human_SI
455 static uintmax_t
456 default_block_size (void)
458 return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
461 static strtol_error
462 humblock (char const *spec, uintmax_t *block_size, int *options)
464 int i;
465 int opts = 0;
467 if (! spec && ! (spec = getenv ("BLOCK_SIZE")))
468 *block_size = default_block_size ();
469 else
471 if (*spec == '\'')
473 opts |= human_group_digits;
474 spec++;
477 if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
479 opts |= block_size_opts[i];
480 *block_size = 1;
482 else
484 char *ptr;
485 strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
486 "eEgGkKmMpPtTyYzZ0");
487 if (e != LONGINT_OK)
488 return e;
489 if (*ptr)
490 return LONGINT_INVALID_SUFFIX_CHAR;
491 for (; ! ('0' <= *spec && *spec <= '9'); spec++)
492 if (spec == ptr)
494 opts |= human_SI;
495 if (ptr[-1] == 'B')
496 opts |= human_B;
497 if (ptr[-1] != 'B' || ptr[-2] == 'i')
498 opts |= human_base_1024;
499 break;
504 *options = opts;
505 return LONGINT_OK;
509 human_options (char const *spec, bool report_errors, uintmax_t *block_size)
511 int opts;
512 strtol_error e = humblock (spec, block_size, &opts);
513 if (*block_size == 0)
515 *block_size = default_block_size ();
516 e = LONGINT_INVALID;
518 if (e != LONGINT_OK && report_errors)
519 STRTOL_FATAL_ERROR (spec, _("block size"), e);
520 return opts;