diff --git a/src/uu/join/src/join.rs b/src/uu/join/src/join.rs index d108a08ef..ae991489f 100644 --- a/src/uu/join/src/join.rs +++ b/src/uu/join/src/join.rs @@ -11,7 +11,7 @@ extern crate uucore; use clap::{crate_version, App, Arg}; -use std::cmp::{min, Ordering}; +use std::cmp::Ordering; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Lines, Stdin}; @@ -102,17 +102,12 @@ impl<'a> Repr<'a> { } /// Print each field except the one at the index. - fn print_fields(&self, line: &Line, index: usize, max_fields: Option) { - for i in 0..min(max_fields.unwrap_or(usize::max_value()), line.fields.len()) { + fn print_fields(&self, line: &Line, index: usize) { + for i in 0..line.fields.len() { if i != index { print!("{}{}", self.separator, line.fields[i]); } } - if let Some(n) = max_fields { - for _ in line.fields.len()..n { - print!("{}", self.separator) - } - } } /// Print each field or the empty filler if the field is not set. @@ -233,7 +228,6 @@ struct State<'a> { print_unpaired: bool, lines: Lines>, seq: Vec, - max_fields: Option, line_num: usize, has_failed: bool, } @@ -262,7 +256,6 @@ impl<'a> State<'a> { print_unpaired, lines: f.lines(), seq: Vec::new(), - max_fields: None, line_num: 0, has_failed: false, } @@ -329,8 +322,8 @@ impl<'a> State<'a> { }); } else { repr.print_field(key); - repr.print_fields(line1, self.key, self.max_fields); - repr.print_fields(line2, other.key, other.max_fields); + repr.print_fields(line1, self.key); + repr.print_fields(line2, other.key); } println!(); @@ -361,14 +354,15 @@ impl<'a> State<'a> { !self.seq.is_empty() } - fn initialize(&mut self, read_sep: Sep, autoformat: bool) { + fn initialize(&mut self, read_sep: Sep, autoformat: bool) -> usize { if let Some(line) = self.read_line(read_sep) { - if autoformat { - self.max_fields = Some(line.fields.len()); - } - self.seq.push(line); + + if autoformat { + return self.seq[0].fields.len(); + } } + 0 } fn finalize(&mut self, input: &Input, repr: &Repr) { @@ -431,7 +425,7 @@ impl<'a> State<'a> { }); } else { repr.print_field(line.get_field(self.key)); - repr.print_fields(line, self.key, self.max_fields); + repr.print_fields(line, self.key); } println!(); @@ -512,7 +506,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { crash!(1, "both files cannot be standard input"); } - exec(file1, file2, &settings) + exec(file1, file2, settings) } pub fn uu_app() -> App<'static, 'static> { @@ -622,7 +616,7 @@ FILENUM is 1 or 2, corresponding to FILE1 or FILE2", ) } -fn exec(file1: &str, file2: &str, settings: &Settings) -> i32 { +fn exec(file1: &str, file2: &str, settings: Settings) -> i32 { let stdin = stdin(); let mut state1 = State::new( @@ -647,18 +641,34 @@ fn exec(file1: &str, file2: &str, settings: &Settings) -> i32 { settings.check_order, ); + let format = if settings.autoformat { + let mut format = vec![Spec::Key]; + let mut initialize = |state: &mut State| { + let max_fields = state.initialize(settings.separator, settings.autoformat); + for i in 0..max_fields { + if i != state.key { + format.push(Spec::Field(state.file_num, i)); + } + } + }; + initialize(&mut state1); + initialize(&mut state2); + format + } else { + state1.initialize(settings.separator, settings.autoformat); + state2.initialize(settings.separator, settings.autoformat); + settings.format + }; + let repr = Repr::new( match settings.separator { Sep::Char(sep) => sep, _ => ' ', }, - &settings.format, + &format, &settings.empty, ); - state1.initialize(settings.separator, settings.autoformat); - state2.initialize(settings.separator, settings.autoformat); - if settings.headers { state1.print_headers(&state2, &repr); state1.reset_read_line(&input); diff --git a/tests/by-util/test_join.rs b/tests/by-util/test_join.rs index 1cab8361a..1d92bf8e7 100644 --- a/tests/by-util/test_join.rs +++ b/tests/by-util/test_join.rs @@ -227,6 +227,19 @@ fn autoformat() { .pipe_in("1 x y z\n2 p") .succeeds() .stdout_only("1 x y z a\n2 p b\n"); + + new_ucmd!() + .arg("-") + .arg("fields_2.txt") + .arg("-a") + .arg("1") + .arg("-o") + .arg("auto") + .arg("-e") + .arg(".") + .pipe_in("1 x y z\n2 p\n99 a b\n") + .succeeds() + .stdout_only("1 x y z a\n2 p . . b\n99 a b . .\n"); } #[test]