(human_readable): Fix bug that rounded 10501 to 10k.
[gnulib.git] / lib / human.c
1 /* human.c -- print human readable file size
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
4    Software Foundation, Inc.
5
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.
10
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.
15
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.  */
19
20 /* Written by Paul Eggert and Larry McVoy.  */
21
22 #if HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include "human.h"
27
28 #ifndef SIZE_MAX
29 # define SIZE_MAX ((size_t) -1)
30 #endif
31 #ifndef UINTMAX_MAX
32 # define UINTMAX_MAX ((uintmax_t) -1)
33 #endif
34
35 #if HAVE_LOCALE_H && HAVE_LOCALECONV
36 # include <locale.h>
37 #endif
38
39 #if HAVE_STDLIB_H
40 # include <stdlib.h>
41 #endif
42 #ifndef HAVE_DECL_GETENV
43 "this configure-time declaration test was not run"
44 #endif
45 #if !HAVE_DECL_GETENV
46 char *getenv ();
47 #endif
48
49 #if HAVE_STRING_H
50 # include <string.h>
51 #endif
52
53 #if HAVE_STRINGS_H
54 # include <strings.h>
55 #endif
56
57 #include <stdio.h>
58
59 #include "gettext.h"
60 #define _(msgid) gettext (msgid)
61
62 #include <argmatch.h>
63 #include <error.h>
64 #include <xstrtol.h>
65
66 /* The maximum length of a suffix like "KiB".  */
67 #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
68
69 static const char power_letter[] =
70 {
71   0,    /* not used */
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 */
80 };
81
82
83 /* If INEXACT_STYLE is not human_round_to_nearest, and if easily
84    possible, adjust VALUE according to the style.  */
85
86 static long double
87 adjust_value (int inexact_style, long double value)
88 {
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)
94     {
95       uintmax_t u = value;
96       value = u + (inexact_style == human_ceiling && u != value);
97     }
98
99   return value;
100 }
101
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
106    number.
107
108    To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
109    lconv' from <locale.h>.  */
110
111 static char *
112 group_number (char *number, size_t numberlen,
113               char const *grouping, char const *thousands_sep)
114 {
115   register char *d;
116   size_t grouplen = SIZE_MAX;
117   size_t thousands_seplen = strlen (thousands_sep);
118   size_t i = numberlen;
119
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];
125
126   memcpy (buf, number, numberlen);
127   d = number + numberlen;
128
129   for (;;)
130     {
131       unsigned char g = *grouping;
132
133       if (g)
134         {
135           grouplen = g < CHAR_MAX ? g : i;
136           grouping++;
137         }
138
139       if (i < grouplen)
140         grouplen = i;
141
142       d -= grouplen;
143       i -= grouplen;
144       memcpy (d, buf + i, grouplen);
145       if (i == 0)
146         return d;
147
148       d -= thousands_seplen;
149       memcpy (d, thousands_sep, thousands_seplen);
150     }
151 }
152
153 /* Convert N to a human readable format in BUF, using the options OPTS.
154
155    N is expressed in units of FROM_BLOCK_SIZE.  FROM_BLOCK_SIZE must
156    be nonnegative.
157
158    Use units of TO_BLOCK_SIZE in the output number.  TO_BLOCK_SIZE
159    must be positive.
160
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.
164
165    If (OPTS & human_group_digits), group the thousands digits
166    according to the locale, e.g., `1,000,000' in an American English
167    locale.
168
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.
176
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 &
182    human_base_1024).  */
183
184 char *
185 human_readable (uintmax_t n, char *buf, int opts,
186                 uintmax_t from_block_size, uintmax_t to_block_size)
187 {
188   int inexact_style =
189     opts & (human_round_to_nearest | human_floor | human_ceiling);
190   unsigned int base = opts & human_base_1024 ? 1024 : 1000;
191   uintmax_t amt;
192   int tenths;
193   int exponent = -1;
194   int exponent_max = sizeof power_letter - 1;
195   char *p;
196   char *psuffix;
197   char const *integerlim;
198
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.  */
203   int rounding;
204
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)
213     {
214       decimal_point = l->decimal_point;
215       decimal_pointlen = pointlen;
216     }
217   grouping = l->grouping;
218   if (strlen (l->thousands_sep) <= MB_LEN_MAX)
219     thousands_sep = l->thousands_sep;
220 #endif
221
222   psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
223   p = psuffix;
224
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)
229     {
230       if (from_block_size % to_block_size == 0)
231         {
232           uintmax_t multiplier = from_block_size / to_block_size;
233           amt = n * multiplier;
234           if (amt / multiplier == n)
235             {
236               tenths = 0;
237               rounding = 0;
238               goto use_integer_arithmetic;
239             }
240         }
241     }
242   else if (from_block_size != 0 && to_block_size % from_block_size == 0)
243     {
244       uintmax_t divisor = to_block_size / from_block_size;
245       uintmax_t r10 = (n % divisor) * 10;
246       uintmax_t r2 = (r10 % divisor) * 2;
247       amt = n / divisor;
248       tenths = r10 / divisor;
249       rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
250       goto use_integer_arithmetic;
251     }
252
253   {
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.  */
257
258     long double dto_block_size = to_block_size;
259     long double damt = n * (from_block_size / dto_block_size);
260     size_t buflen;
261     size_t nonintegerlen;
262
263     if (! (opts & human_autoscale))
264       {
265         sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
266         buflen = strlen (buf);
267         nonintegerlen = 0;
268       }
269     else
270       {
271         long double e = 1;
272         exponent = 0;
273
274         do
275           {
276             e *= base;
277             exponent++;
278           }
279         while (e * base <= damt && exponent < exponent_max);
280
281         damt /= e;
282
283         sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
284         buflen = strlen (buf);
285         nonintegerlen = decimal_pointlen + 1;
286
287         if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
288             || ((opts & human_suppress_point_zero)
289                 && buf[buflen - 1] == '0'))
290           {
291             sprintf (buf, "%.0Lf",
292                      adjust_value (inexact_style, damt * 10) / 10);
293             buflen = strlen (buf);
294             nonintegerlen = 0;
295           }
296       }
297
298     p = psuffix - buflen;
299     memmove (p, buf, buflen);
300     integerlim = p + buflen - nonintegerlen;
301   }
302   goto do_grouping;
303
304  use_integer_arithmetic:
305   {
306     /* The computation can be done exactly, with integer arithmetic.
307
308        Use power of BASE notation if requested and if adjusted AMT is
309        large enough.  */
310
311     if (opts & human_autoscale)
312       {
313         exponent = 0;
314
315         if (base <= amt)
316           {
317             do
318               {
319                 unsigned r10 = (amt % base) * 10 + tenths;
320                 unsigned r2 = (r10 % base) * 2 + (rounding >> 1);
321                 amt /= base;
322                 tenths = r10 / base;
323                 rounding = (r2 < base
324                             ? (r2 + rounding) != 0
325                             : 2 + (base < r2 + rounding));
326                 exponent++;
327               }
328             while (base <= amt && exponent < exponent_max);
329
330             if (amt < 10)
331               {
332                 if (inexact_style == human_round_to_nearest
333                     ? 2 < rounding + (tenths & 1)
334                     : inexact_style == human_ceiling && 0 < rounding)
335                   {
336                     tenths++;
337                     rounding = 0;
338
339                     if (tenths == 10)
340                       {
341                         amt++;
342                         tenths = 0;
343                       }
344                   }
345
346                 if (amt < 10
347                     && (tenths || ! (opts & human_suppress_point_zero)))
348                   {
349                     *--p = '0' + tenths;
350                     p -= decimal_pointlen;
351                     memcpy (p, decimal_point, decimal_pointlen);
352                     tenths = rounding = 0;
353                   }
354               }
355           }
356       }
357
358     if (inexact_style == human_round_to_nearest
359         ? 5 < tenths + (0 < rounding + (amt & 1))
360         : inexact_style == human_ceiling && 0 < tenths + rounding)
361       {
362         amt++;
363
364         if ((opts & human_autoscale)
365             && amt == base && exponent < exponent_max)
366           {
367             exponent++;
368             if (! (opts & human_suppress_point_zero))
369               {
370                 *--p = '0';
371                 p -= decimal_pointlen;
372                 memcpy (p, decimal_point, decimal_pointlen);
373               }
374             amt = 1;
375           }
376       }
377
378     integerlim = p;
379
380     do
381       {
382         int digit = amt % 10;
383         *--p = digit + '0';
384       }
385     while ((amt /= 10) != 0);
386   }
387
388  do_grouping:
389   if (opts & human_group_digits)
390     p = group_number (p, integerlim - p, grouping, thousands_sep);
391
392   if (opts & human_SI)
393     {
394       if (exponent < 0)
395         {
396           uintmax_t power;
397           exponent = 0;
398           for (power = 1; power < to_block_size; power *= base)
399             if (++exponent == exponent_max)
400               break;
401         }
402
403       if (exponent)
404         *psuffix++ = (! (opts & human_base_1024) && exponent == 1
405                       ? 'k'
406                       : power_letter[exponent]);
407
408       if (opts & human_B)
409         {
410           if ((opts & human_base_1024) && exponent)
411             *psuffix++ = 'i';
412           *psuffix++ = 'B';
413         }
414     }
415
416   *psuffix = '\0';
417
418   return p;
419 }
420
421
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
426 #endif
427
428 static char const *const block_size_args[] = { "human-readable", "si", 0 };
429 static int const block_size_opts[] =
430   {
431     human_autoscale + human_SI + human_base_1024,
432     human_autoscale + human_SI
433   };
434
435 static uintmax_t
436 default_block_size (void)
437 {
438   return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
439 }
440
441 static strtol_error
442 humblock (char const *spec, uintmax_t *block_size, int *options)
443 {
444   int i;
445   int opts = 0;
446
447   if (! spec && ! (spec = getenv ("BLOCK_SIZE")))
448     *block_size = default_block_size ();
449   else
450     {
451       if (*spec == '\'')
452         {
453           opts |= human_group_digits;
454           spec++;
455         }
456
457       if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
458         {
459           opts |= block_size_opts[i];
460           *block_size = 1;
461         }
462       else
463         {
464           char *ptr;
465           strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
466                                        "eEgGkKmMpPtTyYzZ0");
467           if (e != LONGINT_OK)
468             return e;
469           if (*ptr)
470             return LONGINT_INVALID_SUFFIX_CHAR;
471           for (; ! ('0' <= *spec && *spec <= '9'); spec++)
472             if (spec == ptr)
473               {
474                 opts |= human_SI;
475                 if (ptr[-1] == 'B')
476                   opts |= human_B;
477                 if (ptr[-1] != 'B' || ptr[-2] == 'i')
478                   opts |= human_base_1024;
479                 break;
480               }
481         }
482     }
483
484   *options = opts;
485   return LONGINT_OK;
486 }
487
488 int
489 human_options (char const *spec, bool report_errors, uintmax_t *block_size)
490 {
491   int opts;
492   strtol_error e = humblock (spec, block_size, &opts);
493   if (*block_size == 0)
494     {
495       *block_size = default_block_size ();
496       e = LONGINT_INVALID;
497     }
498   if (e != LONGINT_OK && report_errors)
499     STRTOL_FATAL_ERROR (spec, _("block size"), e);
500   return opts;
501 }