From 594157d1e0e2bdffb29d92d27570835f7c1dcb91 Mon Sep 17 00:00:00 2001 From: Cecylia Bocovich Date: Sat, 22 Jan 2022 11:35:42 -0500 Subject: [PATCH] join: fix default check order behaviour If neither --nocheck-order or --check-order are specified, only fail on unsorted inputs if either file contains unpaired lines. --- src/uu/join/src/join.rs | 44 +++++++++++++++++++++++++++----------- tests/by-util/test_join.rs | 2 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/uu/join/src/join.rs b/src/uu/join/src/join.rs index 691d374b4..70efc58c3 100644 --- a/src/uu/join/src/join.rs +++ b/src/uu/join/src/join.rs @@ -273,6 +273,7 @@ struct State<'a> { seq: Vec, line_num: usize, has_failed: bool, + has_unpaired: bool, } impl<'a> State<'a> { @@ -302,6 +303,7 @@ impl<'a> State<'a> { seq: Vec::new(), line_num: 0, has_failed: false, + has_unpaired: false, } } @@ -415,11 +417,18 @@ impl<'a> State<'a> { } fn finalize(&mut self, input: &Input, repr: &Repr) -> Result<(), std::io::Error> { - if self.has_line() && self.print_unpaired { - self.print_first_line(repr)?; + if self.has_line() { + if self.print_unpaired { + self.print_first_line(repr)?; + } - while let Some(line) = self.next_line(input) { - self.print_line(&line, repr)?; + let mut next_line = self.next_line(input); + while let Some(line) = &next_line { + if self.print_unpaired { + self.print_line(line, repr)?; + } + self.reset(next_line); + next_line = self.next_line(input); } } @@ -444,20 +453,21 @@ impl<'a> State<'a> { let diff = input.compare(self.get_current_key(), line.get_field(self.key)); if diff == Ordering::Greater { - eprintln!( - "{}: {}:{}: is not sorted: {}", - uucore::execution_phrase(), - self.file_name.maybe_quote(), - self.line_num, - String::from_utf8_lossy(&line.string) - ); + if input.check_order == CheckOrder::Enabled || (self.has_unpaired && !self.has_failed) { + eprintln!( + "{}: {}:{}: is not sorted: {}", + uucore::execution_phrase(), + self.file_name.maybe_quote(), + self.line_num, + String::from_utf8_lossy(&line.string) + ); + self.has_failed = true; + } // This is fatal if the check is enabled. if input.check_order == CheckOrder::Enabled { std::process::exit(1); } - - self.has_failed = true; } Some(line) @@ -760,9 +770,13 @@ fn exec(file1: &str, file2: &str, settings: Settings) -> Result<(), std::io::Err match diff { Ordering::Less => { state1.skip_line(&input, &repr)?; + state1.has_unpaired = true; + state2.has_unpaired = true; } Ordering::Greater => { state2.skip_line(&input, &repr)?; + state1.has_unpaired = true; + state2.has_unpaired = true; } Ordering::Equal => { let next_line1 = state1.extend(&input); @@ -782,6 +796,10 @@ fn exec(file1: &str, file2: &str, settings: Settings) -> Result<(), std::io::Err state2.finalize(&input, &repr)?; if state1.has_failed || state2.has_failed { + eprintln!( + "{}: input is not in sorted order", + uucore::execution_phrase() + ); set_exit_code(1); } Ok(()) diff --git a/tests/by-util/test_join.rs b/tests/by-util/test_join.rs index ea081da22..3bf296290 100644 --- a/tests/by-util/test_join.rs +++ b/tests/by-util/test_join.rs @@ -289,7 +289,7 @@ fn wrong_line_order() { .arg("fields_4.txt") .fails() .stderr_is(&format!( - "{} {}: fields_4.txt:5: is not sorted: 11 g 5 gh", + "{0} {1}: fields_4.txt:5: is not sorted: 11 g 5 gh\n{0} {1}: input is not in sorted order", ts.bin_path.to_string_lossy(), ts.util_name ));