From: Pádraig Brady
Date: Mon, 15 Jun 2015 02:55:46 +0000 (+0100) Subject: numfmt: handle suffixes consistently with --{from,to}-unit X-Git-Tag: v8.24~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6fadd46acd5b813b545b58014ddd591ffdb5a41c;p=thirdparty%2Fcoreutils.git 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. --- diff --git a/NEWS b/NEWS index 4c0f6e478a..9d69da3301 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 a7362b30c2..08316c9289 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 9cbcb27530..58520c26e3 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 8af55a471a..e8640c0f7f 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'}],