]> Dogcows Code - chaz/tar/blobdiff - lib/human.c
Update
[chaz/tar] / lib / human.c
index 839f9d6ea5da05e18b281879ec479ecf31c41701..a9ccf38c48312e5270889101283f65c35672afb5 100644 (file)
@@ -1,5 +1,7 @@
 /* human.c -- print human readable file size
 /* human.c -- print human readable file size
-   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software
+   Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -66,16 +68,51 @@ char *getenv ();
 static const char suffixes[] =
 {
   0,   /* not used */
 static const char suffixes[] =
 {
   0,   /* not used */
-  'k', /* kilo */
-  'M', /* Mega */
-  'G', /* Giga */
-  'T', /* Tera */
-  'P', /* Peta */
-  'E', /* Exa */
-  'Z', /* Zetta */
-  'Y'  /* Yotta */
+  'K', /* kibi ('k' for kilo is a special case) */
+  'M', /* mega or mebi */
+  'G', /* giga or gibi */
+  'T', /* tera or tebi */
+  'P', /* peta or pebi */
+  'E', /* exa or exbi */
+  'Z', /* zetta or 2**70 */
+  'Y'  /* yotta or 2**80 */
 };
 
 };
 
+/* Generate into P[-1] (and possibly P[-2]) the proper suffix for
+   POWER and BASE.  Return the address of the generated suffix.  */
+static char *
+generate_suffix_backwards (char *p, int power, int base)
+{
+  char letter = suffixes[power];
+
+  if (base == 1000)
+    {
+      *--p = 'B';
+      if (power == 1)
+       letter = 'k';
+    }
+
+  *--p = letter;
+  return p;
+}
+
+/* If INEXACT_STYLE is not human_round_to_even, and if easily
+   possible, adjust VALUE according to the style.  */
+static double
+adjust_value (enum human_inexact_style inexact_style, double value)
+{
+  /* Do not use the floor or ceil functions, as that would mean
+     linking with the standard math library, which is a porting pain.
+     So leave the value alone if it is too large to easily round.  */
+  if (inexact_style != human_round_to_even && value < (uintmax_t) -1)
+    {
+      uintmax_t u = value;
+      value = u + (inexact_style == human_ceiling && u != value);
+    }
+
+  return value;
+}
+
 /* Like human_readable_inexact, except always round to even.  */
 char *
 human_readable (uintmax_t n, char *buf,
 /* Like human_readable_inexact, except always round to even.  */
 char *
 human_readable (uintmax_t n, char *buf,
@@ -96,7 +133,7 @@ human_readable (uintmax_t n, char *buf,
    Use INEXACT_STYLE to determine whether to take the ceiling or floor
    of any result that cannot be expressed exactly.
 
    Use INEXACT_STYLE to determine whether to take the ceiling or floor
    of any result that cannot be expressed exactly.
 
-   If OUTPUT_BLOCK_SIZE is negative, use a format like "127k" if
+   If OUTPUT_BLOCK_SIZE is negative, use a format like "127K" if
    possible, using powers of -OUTPUT_BLOCK_SIZE; otherwise, use
    ordinary decimal format.  Normally -OUTPUT_BLOCK_SIZE is either
    1000 or 1024; it must be at least 2.  Most people visually process
    possible, using powers of -OUTPUT_BLOCK_SIZE; otherwise, use
    ordinary decimal format.  Normally -OUTPUT_BLOCK_SIZE is either
    1000 or 1024; it must be at least 2.  Most people visually process
@@ -104,9 +141,10 @@ human_readable (uintmax_t n, char *buf,
    more prone to misinterpretation.  Hence, converting to an
    abbreviated form usually improves readability.  Use a suffix
    indicating which power is being used.  For example, assuming
    more prone to misinterpretation.  Hence, converting to an
    abbreviated form usually improves readability.  Use a suffix
    indicating which power is being used.  For example, assuming
-   -OUTPUT_BLOCK_SIZE is 1024, 8500 would be converted to 8.3k,
+   -OUTPUT_BLOCK_SIZE is 1024, 8500 would be converted to 8.3K,
    133456345 to 127M, 56990456345 to 53G, and so on.  Numbers smaller
    133456345 to 127M, 56990456345 to 53G, and so on.  Numbers smaller
-   than -OUTPUT_BLOCK_SIZE aren't modified.  */
+   than -OUTPUT_BLOCK_SIZE aren't modified.  If -OUTPUT_BLOCK_SIZE is
+   1024, append a "B" after any size letter.  */
 
 char *
 human_readable_inexact (uintmax_t n, char *buf,
 
 char *
 human_readable_inexact (uintmax_t n, char *buf,
@@ -173,9 +211,11 @@ human_readable_inexact (uintmax_t n, char *buf,
        double damt = n * (from_block_size / (double) to_block_size);
 
        if (! base)
        double damt = n * (from_block_size / (double) to_block_size);
 
        if (! base)
-         sprintf (buf, "%.0f", damt);
+         sprintf (buf, "%.0f", adjust_value (inexact_style, damt));
        else
          {
        else
          {
+           char suffix[3];
+           char const *psuffix;
            double e = 1;
            power = 0;
 
            double e = 1;
            power = 0;
 
@@ -188,9 +228,13 @@ human_readable_inexact (uintmax_t n, char *buf,
 
            damt /= e;
 
 
            damt /= e;
 
-           sprintf (buf, "%.1f%c", damt, suffixes[power]);
-           if (4 < strlen (buf))
-             sprintf (buf, "%.0f%c", damt, suffixes[power]);
+           suffix[2] = '\0';
+           psuffix = generate_suffix_backwards (suffix + 2, power, base);
+           sprintf (buf, "%.1f%s",
+                    adjust_value (inexact_style, damt), psuffix);
+           if (4 + (base == 1000) < strlen (buf))
+             sprintf (buf, "%.0f%s",
+                      adjust_value (inexact_style, damt * 10) / 10, psuffix);
          }
 
        return buf;
          }
 
        return buf;
@@ -216,7 +260,7 @@ human_readable_inexact (uintmax_t n, char *buf,
        }
       while (base <= amt && power < sizeof suffixes - 1);
 
        }
       while (base <= amt && power < sizeof suffixes - 1);
 
-      *--p = suffixes[power];
+      p = generate_suffix_backwards (p, power, base);
 
       if (amt < 10)
        {
 
       if (amt < 10)
        {
This page took 0.02625 seconds and 4 git commands to generate.