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
This commit is contained in:
Pádraig Brady 2023-11-26 16:41:56 +00:00
parent 74b9d6a6e8
commit 615167cc4d
4 changed files with 121 additions and 103 deletions

3
NEWS
View File

@ -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.

View File

@ -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

View File

@ -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 : "");
}
@ -945,23 +947,23 @@ UNIT options:\n"), stdout);
"), stdout);
fputs (_("\
auto accept optional single/two letter suffix:\n\
1K = 1000,\n\
1K = 1000, 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, 1K = 1000,\n\
1M = 1000000,\n\
...\n"), stdout);
fputs (_("\
iec accept optional single letter suffix:\n\
1K = 1024,\n\
1K = 1024, 1k = 1024,\n\
1M = 1048576,\n\
...\n"), stdout);
fputs (_("\
iec-i accept optional two-letter suffix:\n\
1Ki = 1024,\n\
1Ki = 1024, 1ki = 1024,\n\
1Mi = 1048576,\n\
...\n"), stdout);
@ -995,7 +997,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\

View File

@ -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
{