summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2015-06-15 03:55:46 +0100
committerPádraig Brady <P@draigBrady.com>2015-06-19 14:50:34 +0100
commit6fadd46acd5b813b545b58014ddd591ffdb5a41c (patch)
tree2b9982ef2fed456428e9a64e9a4270ee88985b00
parenta262318f833c0d929da4bbd1c3002f891fa9bfa1 (diff)
downloadcoreutils-6fadd46acd5b813b545b58014ddd591ffdb5a41c.tar.xz
numfmt: handle suffixes consistently with --{from,to}-unit
* 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.
-rw-r--r--NEWS3
-rw-r--r--doc/coreutils.texi6
-rw-r--r--src/numfmt.c35
-rwxr-xr-xtests/misc/numfmt.pl10
4 files changed, 47 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 4c0f6e478..9d69da330 100644
--- 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,
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index a7362b30c..08316c928 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -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
diff --git a/src/numfmt.c b/src/numfmt.c
index 9cbcb2753..58520c26e 100644
--- a/src/numfmt.c
+++ b/src/numfmt.c
@@ -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;
}
diff --git a/tests/misc/numfmt.pl b/tests/misc/numfmt.pl
index 8af55a471..e8640c0f7 100755
--- a/tests/misc/numfmt.pl
+++ b/tests/misc/numfmt.pl
@@ -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'}],