1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

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.
This commit is contained in:
Cecylia Bocovich 2022-01-22 11:35:42 -05:00
parent 8a787fe028
commit 594157d1e0
No known key found for this signature in database
GPG key ID: 009DE379FD9B7B90
2 changed files with 32 additions and 14 deletions

View file

@ -273,6 +273,7 @@ struct State<'a> {
seq: Vec<Line>, seq: Vec<Line>,
line_num: usize, line_num: usize,
has_failed: bool, has_failed: bool,
has_unpaired: bool,
} }
impl<'a> State<'a> { impl<'a> State<'a> {
@ -302,6 +303,7 @@ impl<'a> State<'a> {
seq: Vec::new(), seq: Vec::new(),
line_num: 0, line_num: 0,
has_failed: false, 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> { fn finalize(&mut self, input: &Input, repr: &Repr) -> Result<(), std::io::Error> {
if self.has_line() && self.print_unpaired { if self.has_line() {
self.print_first_line(repr)?; if self.print_unpaired {
self.print_first_line(repr)?;
}
while let Some(line) = self.next_line(input) { let mut next_line = self.next_line(input);
self.print_line(&line, repr)?; 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)); let diff = input.compare(self.get_current_key(), line.get_field(self.key));
if diff == Ordering::Greater { if diff == Ordering::Greater {
eprintln!( if input.check_order == CheckOrder::Enabled || (self.has_unpaired && !self.has_failed) {
"{}: {}:{}: is not sorted: {}", eprintln!(
uucore::execution_phrase(), "{}: {}:{}: is not sorted: {}",
self.file_name.maybe_quote(), uucore::execution_phrase(),
self.line_num, self.file_name.maybe_quote(),
String::from_utf8_lossy(&line.string) self.line_num,
); String::from_utf8_lossy(&line.string)
);
self.has_failed = true;
}
// This is fatal if the check is enabled. // This is fatal if the check is enabled.
if input.check_order == CheckOrder::Enabled { if input.check_order == CheckOrder::Enabled {
std::process::exit(1); std::process::exit(1);
} }
self.has_failed = true;
} }
Some(line) Some(line)
@ -760,9 +770,13 @@ fn exec(file1: &str, file2: &str, settings: Settings) -> Result<(), std::io::Err
match diff { match diff {
Ordering::Less => { Ordering::Less => {
state1.skip_line(&input, &repr)?; state1.skip_line(&input, &repr)?;
state1.has_unpaired = true;
state2.has_unpaired = true;
} }
Ordering::Greater => { Ordering::Greater => {
state2.skip_line(&input, &repr)?; state2.skip_line(&input, &repr)?;
state1.has_unpaired = true;
state2.has_unpaired = true;
} }
Ordering::Equal => { Ordering::Equal => {
let next_line1 = state1.extend(&input); 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)?; state2.finalize(&input, &repr)?;
if state1.has_failed || state2.has_failed { if state1.has_failed || state2.has_failed {
eprintln!(
"{}: input is not in sorted order",
uucore::execution_phrase()
);
set_exit_code(1); set_exit_code(1);
} }
Ok(()) Ok(())

View file

@ -289,7 +289,7 @@ fn wrong_line_order() {
.arg("fields_4.txt") .arg("fields_4.txt")
.fails() .fails()
.stderr_is(&format!( .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.bin_path.to_string_lossy(),
ts.util_name ts.util_name
)); ));