Subject: Re: bug#60583: Support for new SI prefixes R, Q

From: Pádraig Brady <[email-masked]>
Date: Fri, 6 Jan 2023 14:31:19 +0000

On 05/01/2023 21:11, Paul Eggert wrote:
> Building on Pádraig's Gnulib patches of November, I installed the
> attached to add support to Coreutils for the new SI prefixes R and Q.
> 
> It'll be a while before 'df -h' outputs them, as I'm not expecting file
> systems in the ronnabyte range soon, given that the total amount of data
> storage in the world is still less than a yottabyte, and given that
> we'll need 128-bit integers support all this consistently. Still, the
> new R and Q prefixes are supported by 'sort' and 'numfmt' as-is.

Thanks for doing that.
I see you missed my proposal from Nov,
which I didn't commit since I had a similar more complete
local patch set I was working on.
https://lists.gnu.org/archive/html/coreutils/2022-11/msg00027.html

We ended up with almost exactly the same thing which is good.

Attached are some further tweaks,
which I've pushed just now.

Marking this as done.

cheers,
Pádraig

From f4567ed953d3eb14b8eefc4744603c2594bb73f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Fri, 6 Jan 2023 13:13:54 +0000
Subject: [PATCH] all: further adjustments for new Ronna, Quetta SI prefixes

* src/dd.c (parse_integer): Support Q,R suffixes.
* src/od.c (main): Likewise.
* src/split.c (main): Likewise.
* src/stdbuf.c (parse_size): Likewise.
* src/truncate.c (main): Likewise.
* src/sort.c (specify_size_size): Likewise.
Also line length syntax check fix.
* tests/misc/numfmt.pl: Adust top end large number checks
to the new largest values.
* doc/coreutils.texi (numfmt invocation): Add a numfmt example.
* NEWS: Tweak to aid searchability.
---
 NEWS                 | 5 +++--
 doc/coreutils.texi   | 7 +++++++
 src/dd.c             | 2 +-
 src/od.c             | 2 +-
 src/sort.c           | 6 +++---
 src/split.c          | 2 +-
 src/stdbuf.c         | 2 +-
 src/truncate.c       | 2 +-
 tests/misc/numfmt.pl | 6 +++---
 9 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/NEWS b/NEWS
index 52c92ddb4..7ec3ce1fb 100644
--- a/NEWS
+++ b/NEWS
@@ -48,8 +48,9 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** Changes in behavior
 
-  Programs now use the new SI prefixes R (10**27) and Q (10**30)
-  along with their binary counterparts Ri (2**90) and Qi (2**100).
+  Programs now support the new Ronna (R), and Quetta (Q) SI prefixes,
+  corresponding to 10^27 and 10^30 respectively,
+  along with their binary counterparts Ri (2^90) and Qi (2^100).
   In some cases (e.g., 'sort -h') these new prefixes simply work;
   in others, where they exceed integer width limits, they now elicit
   the same integer overflow diagnostics as other large prefixes.
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 4c278bf27..f5e531d65 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -19073,6 +19073,13 @@ $ numfmt --from=si --to=iec 1T
 932G
 @end example
 
+With both input and output scales specified,
+the largest defined prefixes are supported:
+
+@example
+$ numfmt --from=si --to=iec-i 2000R
+1.6Qi
+@end example
 
 Converting a single field from an input file / piped input (these contrived
 examples are for demonstration purposes only, as both @command{ls} and
diff --git a/src/dd.c b/src/dd.c
index 6d448a57b..2808a79ab 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -1424,7 +1424,7 @@ parse_integer (char const *str, strtol_error *invalid)
   int indeterminate = 0;
   uintmax_t n = indeterminate;
   char *suffix;
-  static char const suffixes[] = "bcEGkKMPTwYZ0";
+  static char const suffixes[] = "bcEGkKMPQRTwYZ0";
   strtol_error e = xstrtoumax (str, &suffix, 10, &n, suffixes);
   intmax_t result;
 
diff --git a/src/od.c b/src/od.c
index 9e9142760..10a28e21f 100644
--- a/src/od.c
+++ b/src/od.c
@@ -1578,7 +1578,7 @@ main (int argc, char **argv)
   bool width_specified = false;
   bool ok = true;
   size_t width_per_block = 0;
-  static char const multipliers[] = "bEGKkMmPTYZ0";
+  static char const multipliers[] = "bEGKkMmPQRTYZ0";
 
   /* The old-style 'pseudo starting address' to be printed in parentheses
      after any true address.  */
diff --git a/src/sort.c b/src/sort.c
index 5f159374b..8ca7a88c4 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -519,8 +519,8 @@ the entire line as the key.  Use --debug to diagnose incorrect key usage.\n\
 SIZE may be followed by the following multiplicative suffixes:\n\
 "), stdout);
       fputs (_("\
-% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y, R, Q.\n\
-\n\
+% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y, R, Q.\
+\n\n\
 *** WARNING ***\n\
 The locale specified by the environment affects sort order.\n\
 Set LC_ALL=C to get the traditional sort order that uses\n\
@@ -1387,7 +1387,7 @@ specify_sort_size (int oi, char c, char const *s)
 {
   uintmax_t n;
   char *suffix;
-  enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkKmMPtTYZ");
+  enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkKmMPQRtTYZ");
 
   /* The default unit is KiB.  */
   if (e == LONGINT_OK && ISDIGIT (suffix[-1]))
diff --git a/src/split.c b/src/split.c
index d0f4e66e2..74b389f85 100644
--- a/src/split.c
+++ b/src/split.c
@@ -1307,7 +1307,7 @@ main (int argc, char **argv)
   uintmax_t k_units = 0;
   uintmax_t n_units = 0;
 
-  static char const multipliers[] = "bEGKkMmPTYZ0";
+  static char const multipliers[] = "bEGKkMmPQRTYZ0";
   int c;
   int digits_optind = 0;
   off_t file_size = OFF_T_MAX;
diff --git a/src/stdbuf.c b/src/stdbuf.c
index 2d7aec28c..0372eda32 100644
--- a/src/stdbuf.c
+++ b/src/stdbuf.c
@@ -66,7 +66,7 @@ static int
 parse_size (char const *str, size_t *size)
 {
   uintmax_t tmp_size;
-  enum strtol_error e = xstrtoumax (str, NULL, 10, &tmp_size, "EGkKMPTYZ0");
+  enum strtol_error e = xstrtoumax (str, NULL, 10, &tmp_size, "EGkKMPQRTYZ0");
   if (e == LONGINT_OK && SIZE_MAX < tmp_size)
     e = LONGINT_OVERFLOW;
 
diff --git a/src/truncate.c b/src/truncate.c
index 24f2db418..4e50d4bf3 100644
--- a/src/truncate.c
+++ b/src/truncate.c
@@ -269,7 +269,7 @@ main (int argc, char **argv)
             }
           /* Support dd BLOCK size suffixes + lowercase g,t,m for bsd compat.
              Note we don't support dd's b=512, c=1, w=2 or 21x512MiB formats. */
-          size = xdectoimax (optarg, OFF_T_MIN, OFF_T_MAX, "EgGkKmMPtTYZ0",
+          size = xdectoimax (optarg, OFF_T_MIN, OFF_T_MAX, "EgGkKmMPQRtTYZ0",
                              _("Invalid number"), 0);
           /* Rounding to multiple of 0 is nonsensical */
           if ((rel_mode == rm_rup || rel_mode == rm_rdn) && size == 0)
diff --git a/tests/misc/numfmt.pl b/tests/misc/numfmt.pl
index 31a87dc14..86fb78f1e 100755
--- a/tests/misc/numfmt.pl
+++ b/tests/misc/numfmt.pl
@@ -947,9 +947,9 @@ my @Limit_Tests =
      ['large-7','--from=si --to=si 80Y', {OUT=>"80Y"}],
      ['large-8','--from=si --to=si 9000Z', {OUT=>"9.0Y"}],
 
-     ['large-10','--from=si --to=si 999Y', {OUT=>"999Y"}],
-     ['large-11','--from=si --to=iec 999Y', {OUT=>"827Y"}],
-     ['large-12','--from=si --round=down --to=iec 999Y', {OUT=>"826Y"}],
+     ['large-10','--from=si --to=si 999Q', {OUT=>"999Q"}],
+     ['large-11','--from=si --to=iec 999Q', {OUT=>"789Q"}],
+     ['large-12','--from=si --round=down --to=iec 999Q', {OUT=>"788Q"}],
 
      # units can also affect the output
      ['large-13','--from=si --from-unit=1000000 9P',
-- 
2.26.2