diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index f3f87beef..f37716258 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -359,12 +359,22 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let complement = matches.get_flag(options::COMPLEMENT); + let mode_args_count = [ + matches.indices_of(options::BYTES), + matches.indices_of(options::CHARACTERS), + matches.indices_of(options::FIELDS), + ] + .into_iter() + .filter_map(|mode| mode.map(|indices| indices.len())) + .sum(); + let mode_parse = match ( + mode_args_count, matches.get_one::(options::BYTES), matches.get_one::(options::CHARACTERS), matches.get_one::(options::FIELDS), ) { - (Some(byte_ranges), None, None) => list_to_ranges(byte_ranges, complement).map(|ranges| { + (1, Some(byte_ranges), None, None) => list_to_ranges(byte_ranges, complement).map(|ranges| { Mode::Bytes( ranges, Options { @@ -379,7 +389,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }, ) }), - (None, Some(char_ranges), None) => list_to_ranges(char_ranges, complement).map(|ranges| { + (1, None, Some(char_ranges), None) => list_to_ranges(char_ranges, complement).map(|ranges| { Mode::Characters( ranges, Options { @@ -394,7 +404,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }, ) }), - (None, None, Some(field_ranges)) => { + (1, None, None, Some(field_ranges)) => { list_to_ranges(field_ranges, complement).and_then(|ranges| { let out_delim = match matches.get_one::(options::OUTPUT_DELIMITER) { Some(s) => { @@ -461,7 +471,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } }) } - (ref b, ref c, ref f) if b.is_some() || c.is_some() || f.is_some() => Err( + (2.., _, _, _) => Err( "invalid usage: expects no more than one of --fields (-f), --chars (-c) or --bytes (-b)".into() ), _ => Err("invalid usage: expects one of --fields (-f), --chars (-c) or --bytes (-b)".into()), @@ -518,7 +528,8 @@ pub fn uu_app() -> Command { .long(options::BYTES) .help("filter byte columns from the input source") .allow_hyphen_values(true) - .value_name("LIST"), + .value_name("LIST") + .action(ArgAction::Append), ) .arg( Arg::new(options::CHARACTERS) @@ -526,7 +537,8 @@ pub fn uu_app() -> Command { .long(options::CHARACTERS) .help("alias for character mode") .allow_hyphen_values(true) - .value_name("LIST"), + .value_name("LIST") + .action(ArgAction::Append), ) .arg( Arg::new(options::DELIMITER) @@ -548,7 +560,8 @@ pub fn uu_app() -> Command { .long(options::FIELDS) .help("filter field columns from the input source") .allow_hyphen_values(true) - .value_name("LIST"), + .value_name("LIST") + .action(ArgAction::Append), ) .arg( Arg::new(options::COMPLEMENT) diff --git a/tests/by-util/test_cut.rs b/tests/by-util/test_cut.rs index bfa0885ce..2473ead19 100644 --- a/tests/by-util/test_cut.rs +++ b/tests/by-util/test_cut.rs @@ -270,3 +270,21 @@ fn test_multiple() { assert_eq!(result.stdout_str(), "b\n"); assert_eq!(result.stderr_str(), ""); } + +#[test] +fn test_multiple_mode_args() { + for args in [ + vec!["-b1", "-b2"], + vec!["-c1", "-c2"], + vec!["-f1", "-f2"], + vec!["-b1", "-c2"], + vec!["-b1", "-f2"], + vec!["-c1", "-f2"], + vec!["-b1", "-c2", "-f3"], + ] { + new_ucmd!() + .args(&args) + .fails() + .stderr_is("cut: invalid usage: expects no more than one of --fields (-f), --chars (-c) or --bytes (-b)\n"); + } +}