Skip to content

Commit e4a1455

Browse files
Merge pull request #6114 from BenWiederhake/dev-csplit-repeated-args
csplit: Handle repeated args, fix remainder after error
2 parents 6f07bf1 + 27fd3e5 commit e4a1455

File tree

2 files changed

+58
-26
lines changed

2 files changed

+58
-26
lines changed

src/uu/csplit/src/csplit.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,17 @@ where
9999
let patterns: Vec<patterns::Pattern> = patterns::get_patterns(&patterns[..])?;
100100
let ret = do_csplit(&mut split_writer, patterns, &mut input_iter);
101101

102-
// consume the rest
103-
input_iter.rewind_buffer();
104-
if let Some((_, line)) = input_iter.next() {
105-
split_writer.new_writer()?;
106-
split_writer.writeln(&line?)?;
107-
for (_, line) in input_iter {
102+
// consume the rest, unless there was an error
103+
if ret.is_ok() {
104+
input_iter.rewind_buffer();
105+
if let Some((_, line)) = input_iter.next() {
106+
split_writer.new_writer()?;
108107
split_writer.writeln(&line?)?;
108+
for (_, line) in input_iter {
109+
split_writer.writeln(&line?)?;
110+
}
111+
split_writer.finish_split();
109112
}
110-
split_writer.finish_split();
111113
}
112114
// delete files on error by default
113115
if ret.is_err() && !options.keep_files {
@@ -585,6 +587,7 @@ pub fn uu_app() -> Command {
585587
.version(crate_version!())
586588
.about(ABOUT)
587589
.override_usage(format_usage(USAGE))
590+
.args_override_self(true)
588591
.infer_long_args(true)
589592
.arg(
590593
Arg::new(options::SUFFIX_FORMAT)

tests/by-util/test_csplit.rs

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ fn test_skip_to_match_context_underflow() {
575575
let (at, mut ucmd) = at_and_ucmd!();
576576
ucmd.args(&["numbers50.txt", "%5%-10"])
577577
.fails()
578-
.stdout_is("141\n")
578+
.stdout_is("")
579579
.stderr_is("csplit: '%5%-10': line number out of range\n");
580580

581581
let count = glob(&at.plus_as_string("xx*"))
@@ -586,14 +586,13 @@ fn test_skip_to_match_context_underflow() {
586586
let (at, mut ucmd) = at_and_ucmd!();
587587
ucmd.args(&["numbers50.txt", "%5%-10", "-k"])
588588
.fails()
589-
.stdout_is("141\n")
589+
.stdout_is("")
590590
.stderr_is("csplit: '%5%-10': line number out of range\n");
591591

592592
let count = glob(&at.plus_as_string("xx*"))
593593
.expect("counting splits")
594594
.count();
595-
assert_eq!(count, 1);
596-
assert_eq!(at.read("xx00"), generate(1, 51));
595+
assert_eq!(count, 0);
597596
}
598597

599598
#[test]
@@ -1225,13 +1224,12 @@ fn test_corner_case4() {
12251224
assert_eq!(at.read("xx02"), generate(26, 51));
12261225
}
12271226

1228-
// NOTE: differs from gnu's output: the empty split is not written
12291227
#[test]
12301228
fn test_up_to_match_context_underflow() {
12311229
let (at, mut ucmd) = at_and_ucmd!();
12321230
ucmd.args(&["numbers50.txt", "/5/-10"])
12331231
.fails()
1234-
.stdout_is("0\n141\n")
1232+
.stdout_is("0\n")
12351233
.stderr_is("csplit: '/5/-10': line number out of range\n");
12361234

12371235
let count = glob(&at.plus_as_string("xx*"))
@@ -1242,26 +1240,24 @@ fn test_up_to_match_context_underflow() {
12421240
let (at, mut ucmd) = at_and_ucmd!();
12431241
ucmd.args(&["numbers50.txt", "/5/-10", "-k"])
12441242
.fails()
1245-
.stdout_is("0\n141\n")
1243+
.stdout_is("0\n")
12461244
.stderr_is("csplit: '/5/-10': line number out of range\n");
12471245

12481246
let count = glob(&at.plus_as_string("xx*"))
12491247
.expect("counting splits")
12501248
.count();
1251-
assert_eq!(count, 2);
1249+
assert_eq!(count, 1);
12521250
assert_eq!(at.read("xx00"), "");
1253-
assert_eq!(at.read("xx01"), generate(1, 51));
12541251
}
12551252

12561253
// the offset is out of range because of the first pattern
1257-
// NOTE: output different than gnu's: the empty split is written but the rest of the input file is not
12581254
#[test]
12591255
fn test_line_num_range_with_up_to_match1() {
12601256
let (at, mut ucmd) = at_and_ucmd!();
12611257
ucmd.args(&["numbers50.txt", "10", "/12/-5"])
12621258
.fails()
12631259
.stderr_is("csplit: '/12/-5': line number out of range\n")
1264-
.stdout_is("18\n0\n123\n");
1260+
.stdout_is("18\n0\n");
12651261

12661262
let count = glob(&at.plus_as_string("xx*"))
12671263
.expect("there should be splits created")
@@ -1272,26 +1268,24 @@ fn test_line_num_range_with_up_to_match1() {
12721268
ucmd.args(&["numbers50.txt", "10", "/12/-5", "-k"])
12731269
.fails()
12741270
.stderr_is("csplit: '/12/-5': line number out of range\n")
1275-
.stdout_is("18\n0\n123\n");
1271+
.stdout_is("18\n0\n");
12761272

12771273
let count = glob(&at.plus_as_string("xx*"))
12781274
.expect("there should be splits created")
12791275
.count();
1280-
assert_eq!(count, 3);
1276+
assert_eq!(count, 2);
12811277
assert_eq!(at.read("xx00"), generate(1, 10));
12821278
assert_eq!(at.read("xx01"), "");
1283-
assert_eq!(at.read("xx02"), generate(10, 51));
12841279
}
12851280

12861281
// the offset is out of range because more lines are needed than physically available
1287-
// NOTE: output different than gnu's: the empty split is not written but the rest of the input file is
12881282
#[test]
12891283
fn test_line_num_range_with_up_to_match2() {
12901284
let (at, mut ucmd) = at_and_ucmd!();
12911285
ucmd.args(&["numbers50.txt", "10", "/12/-15"])
12921286
.fails()
12931287
.stderr_is("csplit: '/12/-15': line number out of range\n")
1294-
.stdout_is("18\n0\n123\n");
1288+
.stdout_is("18\n0\n");
12951289

12961290
let count = glob(&at.plus_as_string("xx*"))
12971291
.expect("there should be splits created")
@@ -1302,15 +1296,14 @@ fn test_line_num_range_with_up_to_match2() {
13021296
ucmd.args(&["numbers50.txt", "10", "/12/-15", "-k"])
13031297
.fails()
13041298
.stderr_is("csplit: '/12/-15': line number out of range\n")
1305-
.stdout_is("18\n0\n123\n");
1299+
.stdout_is("18\n0\n");
13061300

13071301
let count = glob(&at.plus_as_string("xx*"))
13081302
.expect("there should be splits created")
13091303
.count();
1310-
assert_eq!(count, 3);
1304+
assert_eq!(count, 2);
13111305
assert_eq!(at.read("xx00"), generate(1, 10));
13121306
assert_eq!(at.read("xx01"), "");
1313-
assert_eq!(at.read("xx02"), generate(10, 51));
13141307
}
13151308

13161309
// NOTE: output different than gnu's: the pattern /10/ is matched but should not
@@ -1376,3 +1369,39 @@ fn no_such_file() {
13761369
.fails()
13771370
.stderr_contains("cannot access 'in': No such file or directory");
13781371
}
1372+
1373+
#[test]
1374+
fn repeat_everything() {
1375+
let (at, mut ucmd) = at_and_ucmd!();
1376+
ucmd.args(&[
1377+
"numbers50.txt",
1378+
"--suppress-matched",
1379+
"--suppress-matched",
1380+
"-kzsn", // spell-checker:disable-line
1381+
"2",
1382+
"-szkn3", // spell-checker:disable-line
1383+
"-b",
1384+
"%03d",
1385+
"-b%03x",
1386+
"-f",
1387+
"xxy_",
1388+
"-fxxz_", // spell-checker:disable-line
1389+
"/13/",
1390+
"9",
1391+
"{5}",
1392+
])
1393+
.fails()
1394+
.no_stdout()
1395+
.code_is(1)
1396+
.stderr_only("csplit: '9': line number out of range on repetition 5\n");
1397+
let count = glob(&at.plus_as_string("xx*"))
1398+
.expect("there should be some splits created")
1399+
.count();
1400+
assert_eq!(count, 6);
1401+
assert_eq!(at.read("xxz_000"), generate(1, 12 + 1));
1402+
assert_eq!(at.read("xxz_001"), generate(14, 17 + 1)); // FIXME: GNU starts at 15
1403+
assert_eq!(at.read("xxz_002"), generate(19, 26 + 1));
1404+
assert_eq!(at.read("xxz_003"), generate(28, 35 + 1));
1405+
assert_eq!(at.read("xxz_004"), generate(37, 44 + 1));
1406+
assert_eq!(at.read("xxz_005"), generate(46, 50 + 1));
1407+
}

0 commit comments

Comments
 (0)