On 26/11/2023 16:09, Sven Köhler wrote:
So Pádraig's patch does allow for parsing lowercase k, but it does not change numfmt to use lowercase k in its output in si mode.As Pádraig has shown, ls uses lowercase k in --si mode. So it uses lowercase k for 1000. I think that numfmt should behave the same for consistency reasons.
It does output lowercase 'k' in SI mode. Attached is the full patch. Marking this as done. Will push this tomorrow. thanks, Pádraig
From 48b1b54d458897ebec98fe53139cb6b972ecc274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com> Date: Sun, 26 Nov 2023 16:41:56 +0000 Subject: [PATCH] numfmt: support lowercase 'k' for Kilo and Kibi For consistency with the "SI" standard, and with other coreutils which output a lowercase 'k' in "SI" mode. * src/numfmt.c (suffix_power): Treat 'k' like 'K' on input. (double_to_human): Output lowercase 'k' in SI mode. (usage): Adjust accordingly. * doc/coreutils.texi: Mention 'k' accepted, and printed in SI mode. * tests/misc/numfmt.pl: Adjust accordingly. * NEWS: Mention the change in behavior. Fixes https://bugs.gnu.org/47103 --- NEWS | 3 + doc/coreutils.texi | 35 +++++---- src/numfmt.c | 11 ++- tests/misc/numfmt.pl | 170 +++++++++++++++++++++++-------------------- 4 files changed, 119 insertions(+), 100 deletions(-) diff --git a/NEWS b/NEWS index b1088f683..1a08076a4 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,9 @@ GNU coreutils NEWS -*- outline -*- ls --dired now implies long format output without hyperlinks enabled, and will take precedence over previously specified formats or hyperlink mode. + numfmt will accept lowercase 'k' to indicate Kilo or Kibi units on input, + and user lowercase 'k' when outputting such units in '--to=si' mode. + wc no longer ignores encoding errors when counting words. Instead, it treats them as non white space. diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 75a310fc8..7ad8c0db7 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -19109,7 +19109,7 @@ 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-unit=1000}). +bytes in blocks of 1kB, use @samp{--to=si --to-unit=1000}). Suffixes are handled as with @samp{--from=auto}. @optZeroTerminated @@ -19137,7 +19137,8 @@ For output numbers, values larger than 1000 will be rounded, and printed with one of the following suffixes: @example -@samp{K} => @math{1000^1 = 10^3} (Kilo) +@samp{K} => @math{1000^1 = 10^3} (Kilo) (uppercase accepted on input) +@samp{k} => @math{1000^1 = 10^3} (Kilo) (lowercase used on output) @samp{M} => @math{1000^2 = 10^6} (Mega) @samp{G} => @math{1000^3 = 10^9} (Giga) @samp{T} => @math{1000^4 = 10^{12}} (Tera) @@ -19157,7 +19158,8 @@ For output numbers, values larger than 1024 will be rounded, and printed with one of the following suffixes: @example -@samp{K} => @math{1024^1 = 2^{10}} (Kibi) +@samp{K} => @math{1024^1 = 2^{10}} (Kibi) (uppercase used on output) +@samp{k} => @math{1024^1 = 2^{10}} (Kibi) (lowercase accepted on input) @samp{M} => @math{1024^2 = 2^{20}} (Mebi) @samp{G} => @math{1024^3 = 2^{30}} (Gibi) @samp{T} => @math{1024^4 = 2^{40}} (Tebi) @@ -19182,7 +19184,8 @@ For output numbers, values larger than 1024 will be rounded, and printed with one of the following suffixes: @example -@samp{Ki} => @math{1024^1 = 2^{10}} (Kibi) +@samp{Ki} => @math{1024^1 = 2^{10}} (Kibi) (uppercase used on output) +@samp{ki} => @math{1024^1 = 2^{10}} (Kibi) (lowercase accepted on input) @samp{Mi} => @math{1024^2 = 2^{20}} (Mebi) @samp{Gi} => @math{1024^3 = 2^{30}} (Gibi) @samp{Ti} => @math{1024^4 = 2^{40}} (Tebi) @@ -19212,7 +19215,7 @@ are interpreted as @emph{IEC} values. Converting a single number from/to @emph{human} representation: @example $ numfmt --to=si 500000 -500K +500k $ numfmt --to=iec 500000 489K @@ -19258,9 +19261,9 @@ output sizes in human-readable format): @example # Third field (file size) will be shown in SI representation $ ls -log | numfmt --field 3 --header --to=si | head -n4 --rw-r--r-- 1 94K Aug 23 2011 ABOUT-NLS --rw-r--r-- 1 3.7K Jan 7 16:15 AUTHORS --rw-r--r-- 1 36K Jun 1 2011 COPYING +-rw-r--r-- 1 94k Aug 23 2011 ABOUT-NLS +-rw-r--r-- 1 3.7k Jan 7 16:15 AUTHORS +-rw-r--r-- 1 36k Jun 1 2011 COPYING -rw-r--r-- 1 0 Jan 7 15:15 ChangeLog # Second field (size) will be shown in IEC representation @@ -19277,30 +19280,30 @@ Output can be tweaked using @option{--padding} or @option{--format}: @example # Pad to 10 characters, right-aligned $ du -s * | numfmt --to=si --padding=10 - 2.5K config.log + 2.5k config.log 108 config.status - 1.7K configure + 1.7k configure 20 configure.ac # Pad to 10 characters, left-aligned $ du -s * | numfmt --to=si --padding=-10 -2.5K config.log +2.5k config.log 108 config.status -1.7K configure +1.7k configure 20 configure.ac # Pad to 10 characters, left-aligned, using 'format' $ du -s * | numfmt --to=si --format="%10f" - 2.5K config.log + 2.5k config.log 108 config.status - 1.7K configure + 1.7k configure 20 configure.ac # Pad to 10 characters, left-aligned, using 'format' $ du -s * | numfmt --to=si --padding="%-10f" -2.5K config.log +2.5k config.log 108 config.status -1.7K configure +1.7k configure 20 configure.ac @end example diff --git a/src/numfmt.c b/src/numfmt.c index a5bdd2f4f..69ca8bd22 100644 --- a/src/numfmt.c +++ b/src/numfmt.c @@ -228,7 +228,7 @@ default_scale_base (enum scale_type scale) } } -static char const zero_and_valid_suffixes[] = "0KMGTPEZYRQ"; +static char const zero_and_valid_suffixes[] = "0KkMGTPEZYRQ"; static char const *valid_suffixes = 1 + zero_and_valid_suffixes; static inline bool @@ -242,6 +242,7 @@ suffix_power (const char suf) { switch (suf) { + case 'k': /* kilo. */ case 'K': /* kilo or kibi. */ return 1; @@ -811,7 +812,8 @@ double_to_human (long double val, int precision, int prec = user_precision == -1 ? show_decimal_point : user_precision; return snprintf (buf, buf_size, fmt, prec, val, - suffix_power_char (power), + power == 1 && scale == scale_SI + ? "k" : suffix_power_char (power), &"i"[! (scale == scale_IEC_I && 0 < power)], suffix ? suffix : ""); } @@ -946,12 +948,13 @@ UNIT options:\n"), stdout); fputs (_("\ auto accept optional single/two letter suffix:\n\ 1K = 1000,\n\ + 1k = 1000,\n\ 1Ki = 1024,\n\ 1M = 1000000,\n\ 1Mi = 1048576,\n"), stdout); fputs (_("\ si accept optional single letter suffix:\n\ - 1K = 1000,\n\ + 1k = 1000,\n\ 1M = 1000000,\n\ ...\n"), stdout); fputs (_("\ @@ -995,7 +998,7 @@ errors are not diagnosed and the exit status is 0.\n\ printf (_("\n\ Examples:\n\ $ %s --to=si 1000\n\ - -> \"1.0K\"\n\ + -> \"1.0k\"\n\ $ %s --to=iec 2048\n\ -> \"2.0K\"\n\ $ %s --to=iec-i 4096\n\ diff --git a/tests/misc/numfmt.pl b/tests/misc/numfmt.pl index e111b3498..3047f806d 100755 --- a/tests/misc/numfmt.pl +++ b/tests/misc/numfmt.pl @@ -48,16 +48,16 @@ my @Tests = {ERR => "$prog: invalid number: 'no_NL'\n"}, {EXIT => '2'}], - ['8', '--to=si 2000', {OUT => "2.0K"}], - ['9', '--to=si 2001', {OUT => "2.1K"}], - ['10', '--to=si 1999', {OUT => "2.0K"}], - ['11', '--to=si --round=down 2001', {OUT => "2.0K"}], - ['12', '--to=si --round=down 1999', {OUT => "1.9K"}], - ['13', '--to=si --round=up 1901', {OUT => "2.0K"}], - ['14', '--to=si --round=down 1901', {OUT => "1.9K"}], - ['15', '--to=si --round=nearest 1901', {OUT => "1.9K"}], - ['16', '--to=si --round=nearest 1945', {OUT => "1.9K"}], - ['17', '--to=si --round=nearest 1955', {OUT => "2.0K"}], + ['8', '--to=si 2000', {OUT => "2.0k"}], + ['9', '--to=si 2001', {OUT => "2.1k"}], + ['10', '--to=si 1999', {OUT => "2.0k"}], + ['11', '--to=si --round=down 2001', {OUT => "2.0k"}], + ['12', '--to=si --round=down 1999', {OUT => "1.9k"}], + ['13', '--to=si --round=up 1901', {OUT => "2.0k"}], + ['14', '--to=si --round=down 1901', {OUT => "1.9k"}], + ['15', '--to=si --round=nearest 1901', {OUT => "1.9k"}], + ['16', '--to=si --round=nearest 1945', {OUT => "1.9k"}], + ['17', '--to=si --round=nearest 1955', {OUT => "2.0k"}], ['18', '--to=iec 2048', {OUT => "2.0K"}], ['19', '--to=iec 2049', {OUT => "2.1K"}], @@ -149,7 +149,7 @@ my @Tests = ['suf-13', '--suffix=Foo 70', {OUT=>'70Foo'}], ['suf-14', '--suffix=Foo --from=si 70K', {OUT=>'70000Foo'}], ['suf-15', '--suffix=Foo --from=si 70KFoo', {OUT=>'70000Foo'}], - ['suf-16', '--suffix=Foo --to=si 7000Foo', {OUT=>'7.0KFoo'}], + ['suf-16', '--suffix=Foo --to=si 7000Foo', {OUT=>'7.0kFoo'}], ['suf-17', '--suffix=Foo --to=si 7000Bar', {ERR => "$prog: invalid suffix in input: '7000Bar'\n"}, {EXIT => '2'}], @@ -181,18 +181,18 @@ my @Tests = ['pad-3.1', '--padding=0 5', {ERR => "$prog: invalid padding value '0'\n"}, {EXIT => '1'}], - ['pad-4', '--padding=10 --to=si 50000', {OUT=>' 50K'}], - ['pad-5', '--padding=-10 --to=si 50000', {OUT=>'50K '}], + ['pad-4', '--padding=10 --to=si 50000', {OUT=>' 50k'}], + ['pad-5', '--padding=-10 --to=si 50000', {OUT=>'50k '}], # padding too narrow - ['pad-6', '--padding=2 --to=si 1000', {OUT=>'1.0K'}], + ['pad-6', '--padding=2 --to=si 1000', {OUT=>'1.0k'}], # Padding + suffix ['pad-7', '--padding=10 --suffix=foo --to=si 50000', - {OUT=>' 50Kfoo'}], + {OUT=>' 50kfoo'}], ['pad-8', '--padding=-10 --suffix=foo --to=si 50000', - {OUT=>'50Kfoo '}], + {OUT=>'50kfoo '}], # Delimiters @@ -231,63 +231,63 @@ my @Tests = # Multiple fields ['field-range-1', '--field 2,4 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1000 2.0K 3000 4.0K 5000"}], + {OUT=>"1000 2.0k 3000 4.0k 5000"}], ['field-range-2', '--field 2-4 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1000 2.0K 3.0K 4.0K 5000"}], + {OUT=>"1000 2.0k 3.0k 4.0k 5000"}], ['field-range-3', '--field 1,2,3-5 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4.0K 5.0K"}], + {OUT=>"1.0k 2.0k 3.0k 4.0k 5.0k"}], ['field-range-4', '--field 1-5 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4.0K 5.0K"}], + {OUT=>"1.0k 2.0k 3.0k 4.0k 5.0k"}], ['field-range-5', '--field 1-3,5 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4000 5.0K"}], + {OUT=>"1.0k 2.0k 3.0k 4000 5.0k"}], ['field-range-6', '--field 3- --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1000 2000 3.0K 4.0K 5.0K"}], + {OUT=>"1000 2000 3.0k 4.0k 5.0k"}], ['field-range-7', '--field -3 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4000 5000"}], + {OUT=>"1.0k 2.0k 3.0k 4000 5000"}], ['field-range-8', '--field 1-2,4-5 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3000 4.0K 5.0K"}], + {OUT=>"1.0k 2.0k 3000 4.0k 5.0k"}], ['field-range-9', '--field 4-5,1-2 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3000 4.0K 5.0K"}], + {OUT=>"1.0k 2.0k 3000 4.0k 5.0k"}], ['field-range-10','--field 1-3,2-4 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4.0K 5000"}], + {OUT=>"1.0k 2.0k 3.0k 4.0k 5000"}], ['field-range-11','--field 2-4,1-3 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4.0K 5000"}], + {OUT=>"1.0k 2.0k 3.0k 4.0k 5000"}], ['field-range-12','--field 1-1,3-3 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2000 3.0K 4000 5000"}], + {OUT=>"1.0k 2000 3.0k 4000 5000"}], ['field-range-13', '--field 1,-2 --to=si "1000 2000 3000"', - {OUT=>"1.0K 2.0K 3000"}], + {OUT=>"1.0k 2.0k 3000"}], ['field-range-14', '--field -2,4- --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3000 4.0K 5.0K"}], + {OUT=>"1.0k 2.0k 3000 4.0k 5.0k"}], ['field-range-15', '--field -2,-4 --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4.0K 5000"}], + {OUT=>"1.0k 2.0k 3.0k 4.0k 5000"}], ['field-range-16', '--field 2-,4- --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1000 2.0K 3.0K 4.0K 5.0K"}], + {OUT=>"1000 2.0k 3.0k 4.0k 5.0k"}], ['field-range-17', '--field 4-,2- --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1000 2.0K 3.0K 4.0K 5.0K"}], + {OUT=>"1000 2.0k 3.0k 4.0k 5.0k"}], # white space are valid field separators # (undocumented? but works in cut as well). ['field-range-18', '--field "1,2 4" --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3000 4.0K 5000"}], + {OUT=>"1.0k 2.0k 3000 4.0k 5000"}], # Unlike 'cut', a lone '-' means 'all fields', even as part of a list # of fields. ['field-range-19','--field 3,- --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4.0K 5.0K"}], + {OUT=>"1.0k 2.0k 3.0k 4.0k 5.0k"}], ['all-fields-1', '--field=- --to=si "1000 2000 3000 4000 5000"', - {OUT=>"1.0K 2.0K 3.0K 4.0K 5.0K"}], + {OUT=>"1.0k 2.0k 3.0k 4.0k 5.0k"}], ['field-range-err-1', '--field -foo --to=si 10', {EXIT=>1}, {ERR=>"$prog: invalid field value 'foo'\n$try"}], @@ -317,9 +317,9 @@ my @Tests = # Auto-consume white-space, setup auto-padding ['whitespace-1', '--to=si --field 2 "A 500 B"', {OUT=>"A 500 B"}], - ['whitespace-2', '--to=si --field 2 "A 5000 B"', {OUT=>"A 5.0K B"}], + ['whitespace-2', '--to=si --field 2 "A 5000 B"', {OUT=>"A 5.0k B"}], ['whitespace-3', '--to=si " 500"', {OUT=>" 500"}], - ['whitespace-4', '--to=si " 6500"', {OUT=>" 6.5K"}], + ['whitespace-4', '--to=si " 6500"', {OUT=>" 6.5k"}], # NOTE: auto-padding is not enabled if the value is on the first # field and there's no white-space before it. ['whitespace-5', '--to=si "6000000"', {OUT=>"6.0M"}], @@ -331,14 +331,14 @@ my @Tests = ['whitespace-7', '--to=si --field 2', {IN_PIPE=>"rootfs 100000\n" . "udevxx 2000000\n"}, - {OUT =>"rootfs 100K\n" . + {OUT =>"rootfs 100k\n" . "udevxx 2.0M"}], # auto-padding - second line requires a # larger padding (padding-buffer needs to be realloc'd) ['whitespace-8', '--to=si --field 2', {IN_PIPE=>"rootfs 100000\n" . "udev 20000000\n"}, - {OUT =>"rootfs 100K\n" . + {OUT =>"rootfs 100k\n" . "udev 20M"}], @@ -378,10 +378,10 @@ my @Tests = # The 'M' is treated as a delimiter, and so the input value is '4000' ['mix-13', '--delimiter=M --to=si --from=auto 4000M5000M9000', - {OUT=>"4.0KM5000M9000"}], + {OUT=>"4.0kM5000M9000"}], # 'M' is the delimiter, so the second input field is '5000' ['mix-14', '--delimiter=M --field 2 --from=auto --to=si 4000M5000M9000', - {OUT=>"4000M5.0KM9000"}], + {OUT=>"4000M5.0kM9000"}], @@ -467,7 +467,7 @@ my @Tests = ['dbl-to-human-1','--to=si 800', {OUT=>"800"}], ['dbl-to-human-2','--to=si 0', {OUT=>"0"}], ['dbl-to-human-2.1','--to=si 999', {OUT=>"999"}], - ['dbl-to-human-2.2','--to=si 1000', {OUT=>"1.0K"}], + ['dbl-to-human-2.2','--to=si 1000', {OUT=>"1.0k"}], #NOTE: the following are consistent with "ls -lh" output ['dbl-to-human-2.3','--to=iec 999', {OUT=>"999"}], ['dbl-to-human-2.4','--to=iec 1023', {OUT=>"1023"}], @@ -478,28 +478,28 @@ my @Tests = ['dbl-to-human-2.8','--to=iec-i 0', {OUT=>"0"}], # values resulting in "N.Nx" output - ['dbl-to-human-3','--to=si 8000', {OUT=>"8.0K"}], - ['dbl-to-human-3.1','--to=si 8001', {OUT=>"8.1K"}], - ['dbl-to-human-4','--to=si --round=down 8001', {OUT=>"8.0K"}], + ['dbl-to-human-3','--to=si 8000', {OUT=>"8.0k"}], + ['dbl-to-human-3.1','--to=si 8001', {OUT=>"8.1k"}], + ['dbl-to-human-4','--to=si --round=down 8001', {OUT=>"8.0k"}], - ['dbl-to-human-5','--to=si --round=down 3500', {OUT=>"3.5K"}], - ['dbl-to-human-6','--to=si --round=nearest 3500', {OUT=>"3.5K"}], - ['dbl-to-human-7','--to=si --round=up 3500', {OUT=>"3.5K"}], + ['dbl-to-human-5','--to=si --round=down 3500', {OUT=>"3.5k"}], + ['dbl-to-human-6','--to=si --round=nearest 3500', {OUT=>"3.5k"}], + ['dbl-to-human-7','--to=si --round=up 3500', {OUT=>"3.5k"}], - ['dbl-to-human-8','--to=si --round=down 3501', {OUT=>"3.5K"}], - ['dbl-to-human-9','--to=si --round=nearest 3501', {OUT=>"3.5K"}], - ['dbl-to-human-10','--to=si --round=up 3501', {OUT=>"3.6K"}], + ['dbl-to-human-8','--to=si --round=down 3501', {OUT=>"3.5k"}], + ['dbl-to-human-9','--to=si --round=nearest 3501', {OUT=>"3.5k"}], + ['dbl-to-human-10','--to=si --round=up 3501', {OUT=>"3.6k"}], - ['dbl-to-human-11','--to=si --round=nearest 3550', {OUT=>"3.6K"}], + ['dbl-to-human-11','--to=si --round=nearest 3550', {OUT=>"3.6k"}], ['dbl-to-human-12','--to=si --from=si 999.89K', {OUT=>"1.0M"}], - ['dbl-to-human-13','--to=si --from=si 9.9K', {OUT=>"9.9K"}], - ['dbl-to-human-14','--to=si 9900', {OUT=>"9.9K"}], + ['dbl-to-human-13','--to=si --from=si 9.9K', {OUT=>"9.9k"}], + ['dbl-to-human-14','--to=si 9900', {OUT=>"9.9k"}], ['dbl-to-human-15','--to=iec --from=si 3.3K', {OUT=>"3.3K"}], ['dbl-to-human-16','--to=iec --round=down --from=si 3.3K', {OUT=>"3.2K"}], # values resulting in 'NNx' output - ['dbl-to-human-17','--to=si 9999', {OUT=>"10K"}], - ['dbl-to-human-18','--to=si --round=down 35000', {OUT=>"35K"}], + ['dbl-to-human-17','--to=si 9999', {OUT=>"10k"}], + ['dbl-to-human-18','--to=si --round=down 35000', {OUT=>"35k"}], ['dbl-to-human-19','--to=iec 35000', {OUT=>"35K"}], ['dbl-to-human-20','--to=iec --round=down 35000', {OUT=>"34K"}], ['dbl-to-human-21','--to=iec 35000000', {OUT=>"34M"}], @@ -513,9 +513,9 @@ my @Tests = ['dbl-to-human-26','--to=si 999000000000', {OUT=>"999G"}], ['dbl-to-human-27','--to=iec 999000000000', {OUT=>"931G"}], ['dbl-to-human-28','--to=si 123600000000000', {OUT=>"124T"}], - ['dbl-to-human-29','--to=si 998123', {OUT=>"999K"}], - ['dbl-to-human-30','--to=si --round=nearest 998123', {OUT=>"998K"}], - ['dbl-to-human-31','--to=si 99999', {OUT=>"100K"}], + ['dbl-to-human-29','--to=si 998123', {OUT=>"999k"}], + ['dbl-to-human-30','--to=si --round=nearest 998123', {OUT=>"998k"}], + ['dbl-to-human-31','--to=si 99999', {OUT=>"100k"}], ['dbl-to-human-32','--to=iec 102399', {OUT=>"100K"}], ['dbl-to-human-33','--to=iec-i 102399', {OUT=>"100Ki"}], @@ -710,7 +710,7 @@ my @Tests = # Very large format strings ['fmt-15', '--format "--%100000f--" --to=si 4200', - {OUT=>"--" . " " x 99996 . "4.2K--" }], + {OUT=>"--" . " " x 99996 . "4.2k--" }], # --format padding overrides --padding ['fmt-16', '--format="%6f" --padding=66 1234',{OUT=>" 1234"}], @@ -765,28 +765,28 @@ my @Tests = ## Ignore Errors with multiple conversions ['ign-err-m1', '--invalid=ignore --to=si 1000 2000 bad 3000', - {OUT => "1.0K\n2.0K\nbad\n3.0K"}, + {OUT => "1.0k\n2.0k\nbad\n3.0k"}, {EXIT => 0}], ['ign-err-m1.1', '--invalid=ignore --to=si', {IN_PIPE => "1000\n2000\nbad\n3000\n"}, - {OUT => "1.0K\n2.0K\nbad\n3.0K"}, + {OUT => "1.0k\n2.0k\nbad\n3.0k"}, {EXIT => 0}], ['ign-err-m1.3', '--invalid=fail --debug --to=si 1000 2000 3000', - {OUT => "1.0K\n2.0K\n3.0K"}, + {OUT => "1.0k\n2.0k\n3.0k"}, {EXIT => 0}], ['ign-err-m2', '--invalid=fail --to=si 1000 Foo 3000', - {OUT => "1.0K\nFoo\n3.0K\n"}, + {OUT => "1.0k\nFoo\n3.0k\n"}, {ERR => "$prog: invalid number: 'Foo'\n"}, {EXIT => 2}], ['ign-err-m2.1', '--invalid=warn --to=si', {IN_PIPE => "1000\nFoo\n3000\n"}, - {OUT => "1.0K\nFoo\n3.0K"}, + {OUT => "1.0k\nFoo\n3.0k"}, {ERR => "$prog: invalid number: 'Foo'\n"}, {EXIT => 0}], # --debug will trigger a final warning at EOF ['ign-err-m2.2', '--invalid=fail --debug --to=si 1000 Foo 3000', - {OUT => "1.0K\nFoo\n3.0K\n"}, + {OUT => "1.0k\nFoo\n3.0k\n"}, {ERR => "$prog: invalid number: 'Foo'\n" . "$prog: failed to convert some of the input numbers\n"}, {EXIT => 2}], @@ -818,15 +818,15 @@ my @NullDelim_Tests = ['z4', '-z --field=3 --to=si', {IN_PIPE => "A B 1001 C\x00" . "D E 2002 F\x00"}, - {OUT => "A B 1.1K C\x00" . - "D E 2.1K F\x00"}], + {OUT => "A B 1.1k C\x00" . + "D E 2.1k F\x00"}], # Input from STDIN, with fields and embedded NL ['z5', '-z --field=3 --to=si', {IN_PIPE => "A\nB 1001 C\x00" . "D E\n2002 F\x00"}, - {OUT => "A B 1.1K C\x00" . - "D E 2.1K F\x00"}], + {OUT => "A B 1.1k C\x00" . + "D E 2.1k F\x00"}], ); my @Limit_Tests = @@ -851,9 +851,9 @@ my @Limit_Tests = ['large-3.1', '--to=si 1', {OUT=> "1"}], ['large-3.2', '--to=si 10', {OUT=> "10"}], ['large-3.3', '--to=si 100', {OUT=> "100"}], - ['large-3.4', '--to=si 1000', {OUT=>"1.0K"}], - ['large-3.5', '--to=si 10000', {OUT=> "10K"}], - ['large-3.6', '--to=si 100000', {OUT=>"100K"}], + ['large-3.4', '--to=si 1000', {OUT=>"1.0k"}], + ['large-3.5', '--to=si 10000', {OUT=> "10k"}], + ['large-3.6', '--to=si 100000', {OUT=>"100k"}], ['large-3.7', '--to=si 1000000', {OUT=>"1.0M"}], ['large-3.8', '--to=si 10000000', {OUT=> "10M"}], ['large-3.9', '--to=si 100000000', {OUT=>"100M"}], @@ -1069,18 +1069,28 @@ push @Tests, @Locale_Tests if $locale ne 'C'; ## Check all valid/invalid suffixes foreach my $suf ( 'A' .. 'Z', 'a' .. 'z' ) { - if ( $suf =~ /^[KMGTPEZYRQ]$/ ) + if ( $suf =~ /^[KkMGTPEZYRQ]$/ ) { + my $si_suf = $suf; + my $iec_suf = $suf; + if ( $suf eq "k" ) + { + $iec_suf = "K"; + } + if ( $suf eq "K" ) + { + $si_suf = "k"; + } push @Tests, ["auto-suf-si-$suf","--from=si --to=si 1$suf", - {OUT=>"1.0$suf"}]; + {OUT=>"1.0$si_suf"}]; push @Tests, ["auto-suf-iec-$suf","--from=iec --to=iec 1$suf", - {OUT=>"1.0$suf"}]; + {OUT=>"1.0$iec_suf"}]; push @Tests, ["auto-suf-auto-$suf","--from=auto --to=iec 1${suf}i", - {OUT=>"1.0$suf"}]; + {OUT=>"1.0$iec_suf"}]; push @Tests, ["auto-suf-iec-to-ieci-$suf","--from=iec --to=iec-i 1${suf}", - {OUT=>"1.0${suf}i"}]; + {OUT=>"1.0${iec_suf}i"}]; push @Tests, ["auto-suf-ieci-to-iec-$suf", - "--from=iec-i --to=iec 1${suf}i",{OUT=>"1.0${suf}"}]; + "--from=iec-i --to=iec 1${suf}i",{OUT=>"1.0${iec_suf}"}]; } else { -- 2.41.0