doc: stat: clarify that %t and %T expand to the file system type
[coreutils/ericb.git] / tests / misc / cut
blob7ed41344875fa343a6f6c795e37e305456175ac1
1 #!/usr/bin/perl
2 # Test "cut".
4 # Copyright (C) 2006-2011 Free Software Foundation, Inc.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 use strict;
21 (my $ME = $0) =~ s|.*/||;
23 # Turn off localization of executable's output.
24 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
26 my $mb_locale = $ENV{LOCALE_FR_UTF8};
27 ! defined $mb_locale || $mb_locale eq 'none'
28 and $mb_locale = 'C';
30 my $prog = 'cut';
31 my $try = "Try \`$prog --help' for more information.\n";
32 my $from_1 = "$prog: fields and positions are numbered from 1\n$try";
33 my $inval = "$prog: invalid byte or field list\n$try";
34 my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try";
36 my @Tests =
38 # Provoke a double-free in cut from coreutils-6.7.
39 ['dbl-free', '-f2-', {IN=>{f=>'x'}}, {IN=>{g=>'y'}}, {OUT=>"x\ny\n"}],
41 # This failed (as it should) even before coreutils-6.9.90,
42 # but cut from 6.9.90 produces a more useful diagnostic.
43 ['zero-1', '-b0', {ERR=>$from_1}, {EXIT => 1} ],
45 # Up to coreutils-6.9, specifying a range of 0-2 was not an error.
46 # It was treated just like "-2".
47 ['zero-2', '-f0-2', {ERR=>$from_1}, {EXIT => 1} ],
49 ['1', '-d:', '-f1,3-', {IN=>"a:b:c\n"}, {OUT=>"a:c\n"}],
50 ['2', '-d:', '-f1,3-', {IN=>"a:b:c\n"}, {OUT=>"a:c\n"}],
51 ['3', qw(-d: -f2-), {IN=>"a:b:c\n"}, {OUT=>"b:c\n"}],
52 ['4', qw(-d: -f4), {IN=>"a:b:c\n"}, {OUT=>"\n"}],
53 ['5', qw(-d: -f4), {IN=>""}, {OUT=>""}],
54 ['6', '-c4', {IN=>"123\n"}, {OUT=>"\n"}],
55 ['7', '-c4', {IN=>"123"}, {OUT=>"\n"}],
56 ['8', '-c4', {IN=>"123\n1"}, {OUT=>"\n\n"}],
57 ['9', '-c4', {IN=>""}, {OUT=>""}],
58 ['a', qw(-s -d:), '-f3-', {IN=>"a:b:c\n"}, {OUT=>"c\n"}],
59 ['b', qw(-s -d:), '-f2,3', {IN=>"a:b:c\n"}, {OUT=>"b:c\n"}],
60 ['c', qw(-s -d:), '-f1,3', {IN=>"a:b:c\n"}, {OUT=>"a:c\n"}],
61 # Trailing colon should not be output
62 ['d', qw(-s -d:), '-f1,3', {IN=>"a:b:c:\n"}, {OUT=>"a:c\n"}],
63 ['e', qw(-s -d:), '-f3-', {IN=>"a:b:c:\n"}, {OUT=>"c:\n"}],
64 ['f', qw(-s -d:), '-f3-4', {IN=>"a:b:c:\n"}, {OUT=>"c:\n"}],
65 ['g', qw(-s -d:), '-f3,4', {IN=>"a:b:c:\n"}, {OUT=>"c:\n"}],
66 # Make sure -s suppresses non-delimited lines
67 ['h', qw(-s -d:), '-f2,3', {IN=>"abc\n"}, {OUT=>""}],
69 ['i', qw(-d: -f1-3), {IN=>":::\n"}, {OUT=>"::\n"}],
70 ['j', qw(-d: -f1-4), {IN=>":::\n"}, {OUT=>":::\n"}],
71 ['k', qw(-d: -f2-3), {IN=>":::\n"}, {OUT=>":\n"}],
72 ['l', qw(-d: -f2-4), {IN=>":::\n"}, {OUT=>"::\n"}],
73 ['m', qw(-s -d: -f1-3), {IN=>":::\n"}, {OUT=>"::\n"}],
74 ['n', qw(-s -d: -f1-4), {IN=>":::\n"}, {OUT=>":::\n"}],
75 ['o', qw(-s -d: -f2-3), {IN=>":::\n"}, {OUT=>":\n"}],
76 ['p', qw(-s -d: -f2-4), {IN=>":::\n"}, {OUT=>"::\n"}],
77 ['q', qw(-s -d: -f2-4), {IN=>":::\n:\n"}, {OUT=>"::\n\n"}],
78 ['r', qw(-s -d: -f2-4), {IN=>":::\n:1\n"}, {OUT=>"::\n1\n"}],
79 ['s', qw(-s -d: -f1-4), {IN=>":::\n:a\n"}, {OUT=>":::\n:a\n"}],
80 ['t', qw(-s -d: -f3-), {IN=>":::\n:1\n"}, {OUT=>":\n\n"}],
81 # Make sure it handles empty input properly, with and without -s.
82 ['u', qw(-s -f3-), {IN=>""}, {OUT=>""}],
83 ['v', '-f3-', {IN=>""}, {OUT=>""}],
84 # Make sure it handles empty input properly.
85 ['w', qw(-b 1), {IN=>""}, {OUT=>""}],
86 ['x', qw(-s -d: -f2-4), {IN=>":\n"}, {OUT=>"\n"}],
87 # Errors
88 # -s may be used only with -f
89 ['y', qw(-s -b4), {IN=>":\n"}, {OUT=>""}, {EXIT=>1},
90 {ERR=>"$prog: suppressing non-delimited lines makes sense\n"
91 . "\tonly when operating on fields\n$try"}],
92 # You must specify bytes or fields (or chars)
93 ['z', '', {IN=>":\n"}, {OUT=>""}, {EXIT=>1},
94 {ERR=>"$prog: you must specify a list of bytes, characters, or fields\n$try"}
96 # Empty field list
97 ['empty-fl', qw(-f ''), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$from_1}],
98 # Missing field list
99 ['missing-fl', qw(-f --), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$inval}],
100 # Empty byte list
101 ['empty-bl', qw(-b ''), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$from_1}],
102 # Missing byte list
103 ['missing-bl', qw(-b --), {IN=>":\n"}, {OUT=>""}, {EXIT=>1}, {ERR=>$inval}],
105 # This test fails with cut from textutils-1.22.
106 ['empty-f1', '-f1', {IN=>""}, {OUT=>""}],
108 ['empty-f2', '-f2', {IN=>""}, {OUT=>""}],
110 ['o-delim', qw(-d: --out=_), '-f2,3', {IN=>"a:b:c\n"}, {OUT=>"b_c\n"}],
111 ['nul-idelim', qw(-d '' --out=_), '-f2,3', {IN=>"a\0b\0c\n"}, {OUT=>"b_c\n"}],
112 ['nul-odelim', qw(-d: --out=), '-f2,3', {IN=>"a:b:c\n"}, {OUT=>"b\0c\n"}],
113 ['multichar-od', qw(-d: --out=_._), '-f2,3', {IN=>"a:b:c\n"},
114 {OUT=>"b_._c\n"}],
116 # Prior to 1.22i, you couldn't use a delimiter that would sign-extend.
117 ['8bit-delim', '-d', "\255", '--out=_', '-f2,3', {IN=>"a\255b\255c\n"},
118 {OUT=>"b_c\n"}],
120 # New functionality:
121 ['out-delim1', '-c1-3,5-', '--output-d=:', {IN=>"abcdefg\n"},
122 {OUT=>"abc:efg\n"}],
123 # A totally overlapped field shouldn't change anything:
124 ['out-delim2', '-c1-3,2,5-', '--output-d=:', {IN=>"abcdefg\n"},
125 {OUT=>"abc:efg\n"}],
126 # Partial overlap: index `2' is not at the start of a range.
127 ['out-delim3', '-c1-3,2-4,6', '--output-d=:', {IN=>"abcdefg\n"},
128 {OUT=>"abcd:f\n"}],
129 ['out-delim3a', '-c1-3,2-4,6-', '--output-d=:', {IN=>"abcdefg\n"},
130 {OUT=>"abcd:fg\n"}],
131 # Ensure that the following two commands produce the same output.
132 # Before an off-by-1 fix, the output from the former would not contain a `:'.
133 ['out-delim4', '-c4-,2-3', '--output-d=:',
134 {IN=>"abcdefg\n"}, {OUT=>"bc:defg\n"}],
135 ['out-delim5', '-c2-3,4-', '--output-d=:',
136 {IN=>"abcdefg\n"}, {OUT=>"bc:defg\n"}],
137 # This test would fail for cut from coreutils-5.0.1 and earlier.
138 ['out-delim6', '-c2,1-3', '--output-d=:', {IN=>"abc\n"}, {OUT=>"abc\n"}],
140 ['od-abut', '-b1-2,3-4', '--output-d=:', {IN=>"abcd\n"}, {OUT=>"ab:cd\n"}],
141 ['od-overlap', '-b1-2,2', '--output-d=:', {IN=>"abc\n"}, {OUT=>"ab\n"}],
142 ['od-overlap2', '-b1-2,2-', '--output-d=:', {IN=>"abc\n"}, {OUT=>"abc\n"}],
143 ['od-overlap3', '-b1-3,2-', '--output-d=:', {IN=>"abcd\n"}, {OUT=>"abcd\n"}],
144 ['od-overlap4', '-b1-3,2-3', '--output-d=:', {IN=>"abcd\n"}, {OUT=>"abc\n"}],
145 ['od-overlap5', '-b1-3,1-4', '--output-d=:',
146 {IN=>"abcde\n"}, {OUT=>"abcd\n"}],
148 # None of the following invalid ranges provoked an error up to coreutils-6.9.
149 ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1},
150 {ERR=>"$prog: invalid decreasing range\n$try"}],
151 ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
152 ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
153 ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1},
154 {ERR=>$no_endpoint}],
155 ['inval5', '-f', '1-,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
156 ['inval6', '-f', '-1,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
157 # This would evoke a segfault from 5.3.0..6.10
158 ['big-unbounded-b', '--output-d=:', '-b1234567890-', {IN=>''}, {OUT=>''}],
159 ['big-unbounded-c', '--output-d=:', '-c1234567890-', {IN=>''}, {OUT=>''}],
160 ['big-unbounded-f', '--output-d=:', '-f1234567890-', {IN=>''}, {OUT=>''}],
163 if ($mb_locale ne 'C')
165 # Duplicate each test vector, appending "-mb" to the test name and
166 # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
167 # provide coverage for the distro-added multi-byte code paths.
168 my @new;
169 foreach my $t (@Tests)
171 my @new_t = @$t;
172 my $test_name = shift @new_t;
174 # Depending on whether cut is multi-byte-patched,
175 # it emits different diagnostics:
176 # non-MB: invalid byte or field list
177 # MB: invalid byte, character or field list
178 # Adjust the expected error output accordingly.
179 if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
180 (@new_t))
182 my $sub = {ERR_SUBST => 's/, character//'};
183 push @new_t, $sub;
184 push @$t, $sub;
186 push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
188 push @Tests, @new;
192 @Tests = triple_test \@Tests;
194 my $save_temps = $ENV{DEBUG};
195 my $verbose = $ENV{VERBOSE};
197 my $fail = run_tests ($ME, $prog, \@Tests, $save_temps, $verbose);
198 exit $fail;