]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
numfmt: handle suffixes consistently with --{from,to}-unit
authorPádraig Brady <P@draigBrady.com>
Mon, 15 Jun 2015 02:55:46 +0000 (03:55 +0100)
committerPádraig Brady <P@draigBrady.com>
Fri, 19 Jun 2015 13:50:34 +0000 (14:50 +0100)
* src/numfmt.c (unit_to_umax): Support SI (power of 10) suffixes
with the --from-unit and --to-unit options.  Treat suffixes like
is done with --from=auto, which for example will change the meaning
of --to-unit=G to that of --to-unit=Gi.  The suffix support was
previously undocumented and it's better to avoid the traditional
coreutils suffix handling in numfmt by default.
* doc/coreutils.texi: Document the new behavior.  Also fix a typo
mentioning {from,to}=units=.
* tests/misc/numfmt.pl: Adjust accordingly.
* NEWS: Mention the change in behavior.

NEWS
doc/coreutils.texi
src/numfmt.c
tests/misc/numfmt.pl

diff --git a/NEWS b/NEWS
index 4c0f6e478a5436ce817b938eee01d836c027f186..9d69da3301aaae5337917ba8e196b57599c26a41 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -95,6 +95,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   insensitive file systems like HFS, mv would just remove a hardlinked 'file'
   if called like `mv file File`.  The feature was added in coreutils-5.0.1.
 
+  numfmt --from-unit and --to-unit options now interpret suffixes as SI units,
+  and IEC (power of 2) units are now specified by appending 'i'.
+
   tee will exit early if there are no more writable outputs.
 
   tee does not treat the file operand '-' as meaning standard output any longer,
index a7362b30c22ec805429dc9deef0ee95f92bbab1d..08316c9289a3f8312436c20097dbf544109d3f1d 100644 (file)
@@ -16916,7 +16916,8 @@ trigger an error.
 @opindex --from-unit
 Specify the input unit size (instead of the default 1).  Use this option when
 the input numbers represent other units (e.g. if the input number @samp{10}
-represents 10 units of 512 bytes, use @samp{--from=unit=512}).
+represents 10 units of 512 bytes, use @samp{--from-unit=512}).
+Suffixes are handled as with @samp{--from=auto}.
 
 @item --grouping
 @opindex --grouping
@@ -16970,7 +16971,8 @@ The default is no scaling, meaning all the digits of the number are printed.
 @opindex --to-unit
 Specify the output unit size (instead of the default 1).  Use this option when
 the output numbers represent other units (e.g. to represent @samp{4,000,000}
-bytes in blocks of 1KB, use @samp{--to=si --to=units=1000}).
+bytes in blocks of 1KB, use @samp{--to=si --to-unit=1000}).
+Suffixes are handled as with @samp{--from=auto}.
 
 @end table
 
index 9cbcb27530a3b5b19925533c23a98a1ad012b381..58520c26e3106e7da1346f56ee4c4c3fe18191db 100644 (file)
@@ -776,19 +776,48 @@ double_to_human (long double val, int precision,
 }
 
 /* Convert a string of decimal digits, N_STRING, with an optional suffix
-   to an integral value.  Upon successful conversion, return that value.
+   to an integral value.  Suffixes are handled as with --from=auto.
+   Upon successful conversion, return that value.
    If it cannot be converted, give a diagnostic and exit.  */
 static uintmax_t
 unit_to_umax (const char *n_string)
 {
   strtol_error s_err;
+  const char *c_string = n_string;
+  char *t_string = NULL;
+  size_t n_len = strlen (n_string);
   char *end = NULL;
   uintmax_t n;
+  const char *suffixes = "KMGTPEZY";
 
-  s_err = xstrtoumax (n_string, &end, 10, &n, "KMGTPEZY");
+  /* Adjust suffixes so K=1000, Ki=1024, KiB=invalid.  */
+  if (n_len && ! c_isdigit (n_string[n_len - 1]))
+    {
+      t_string = xmalloc (n_len + 2);
+      end = t_string + n_len - 1;
+      memcpy (t_string, n_string, n_len);
+
+      if (*end == 'i' && 2 <= n_len && ! c_isdigit (*(end - 1)))
+        *end = '\0';
+      else
+        {
+          *++end = 'B';
+          *++end = '\0';
+          suffixes = "KMGTPEZY0";
+        }
+
+      c_string = t_string;
+    }
+
+  s_err = xstrtoumax (c_string, &end, 10, &n, suffixes);
 
   if (s_err != LONGINT_OK || *end || n == 0)
-    error (EXIT_FAILURE, 0, _("invalid unit size: %s"), quote (n_string));
+    {
+      free (t_string);
+      error (EXIT_FAILURE, 0, _("invalid unit size: %s"), quote (n_string));
+    }
+
+  free (t_string);
 
   return n;
 }
index 8af55a471a3664c3ec5edbcaa4a2f38e804c2084..e8640c0f7f2385fdf162a8c0c2d5fd20c5b4f1c6 100755 (executable)
@@ -92,8 +92,14 @@ my @Tests =
      ['unit-6', '--from-unit=54W --from=iec --to=iec 4M',
              {ERR => "$prog: invalid unit size: '54W'\n"},
              {EXIT => '1'}],
-     # Not fully documented.. "--{from,to}-unit" can accept IEC suffixes
-     ['unit-7', '--from-unit=2K --to=iec 30', {OUT=>"60K"}],
+     ['unit-7', '--from-unit=K 30', {OUT=>"30000"}],
+     ['unit-7.1', '--from-unit=Ki 30', {OUT=>"30720"}],
+     ['unit-7.2', '--from-unit=i 0',
+             {ERR => "$prog: invalid unit size: 'i'\n"},
+             {EXIT => '1'}],
+     ['unit-7.3', '--from-unit=1i 0',
+             {ERR => "$prog: invalid unit size: '1i'\n"},
+             {EXIT => '1'}],
      ['unit-8', '--from-unit=1234567890123456789012345 --to=iec 30',
              {ERR => "$prog: invalid unit size: '1234567890123456789012345'\n"},
              {EXIT => '1'}],