diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 296c6c6b1..a9d89dfca 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -1060,8 +1060,11 @@ Printing performance stats is also triggered by the INFO signal (where supported .arg( Arg::new(options::CONV) .long(options::CONV) - .overrides_with(options::CONV) .takes_value(true) + .multiple_occurrences(true) + .use_delimiter(true) + .require_delimiter(true) + .multiple_values(true) .require_equals(true) .value_name("CONV") .help("(alternatively conv=CONV[,CONV]) specifies a comma-separated list of conversion options or (for legacy reasons) file flags. Conversion options and file flags may be intermixed. @@ -1098,8 +1101,11 @@ Conversion Flags: .arg( Arg::new(options::IFLAG) .long(options::IFLAG) - .overrides_with(options::IFLAG) .takes_value(true) + .multiple_occurrences(true) + .use_delimiter(true) + .require_delimiter(true) + .multiple_values(true) .require_equals(true) .value_name("FLAG") .help("(alternatively iflag=FLAG[,FLAG]) a comma separated list of input flags which specify how the input source is treated. FLAG may be any of the input-flags or general-flags specified below. @@ -1125,8 +1131,11 @@ General-Flags .arg( Arg::new(options::OFLAG) .long(options::OFLAG) - .overrides_with(options::OFLAG) .takes_value(true) + .multiple_occurrences(true) + .use_delimiter(true) + .require_delimiter(true) + .multiple_values(true) .require_equals(true) .value_name("FLAG") .help("(alternatively oflag=FLAG[,FLAG]) a comma separated list of output flags which specify how the output source is treated. FLAG may be any of the output-flags or general-flags specified below. diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index 492ab70cb..73f731b24 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -414,16 +414,11 @@ fn parse_flag_list>( tag: &str, matches: &Matches, ) -> Result, ParseError> { - let mut flags = Vec::new(); - - if let Some(comma_str) = matches.value_of(tag) { - for s in comma_str.split(',') { - let flag = s.parse()?; - flags.push(flag); - } - } - - Ok(flags) + matches + .values_of(tag) + .unwrap_or_default() + .map(|f| f.parse()) + .collect() } /// Parse Conversion Options (Input Variety) diff --git a/src/uu/dd/src/parseargs/unit_tests.rs b/src/uu/dd/src/parseargs/unit_tests.rs index 64da4640f..1e5b4b930 100644 --- a/src/uu/dd/src/parseargs/unit_tests.rs +++ b/src/uu/dd/src/parseargs/unit_tests.rs @@ -300,7 +300,39 @@ fn test_status_level_noxfer() { } #[test] -fn test_override_multiple_levels() { +fn test_multiple_flags_options() { + let args = vec![ + String::from("dd"), + String::from("--iflag=fullblock,directory"), + String::from("--iflag=skip_bytes"), + String::from("--oflag=direct"), + String::from("--oflag=dsync"), + String::from("--conv=ascii,ucase"), + String::from("--conv=unblock"), + ]; + let matches = uu_app().try_get_matches_from(args).unwrap(); + + // iflag + let iflags = parse_flag_list::(options::IFLAG, &matches).unwrap(); + assert_eq!( + vec![Flag::FullBlock, Flag::Directory, Flag::SkipBytes], + iflags + ); + + // oflag + let oflags = parse_flag_list::(options::OFLAG, &matches).unwrap(); + assert_eq!(vec![Flag::Direct, Flag::Dsync], oflags); + + // conv + let conv = parse_flag_list::(options::CONV, &matches).unwrap(); + assert_eq!( + vec![ConvFlag::FmtEtoA, ConvFlag::UCase, ConvFlag::Unblock], + conv + ); +} + +#[test] +fn test_override_multiple_options() { let args = vec![ String::from("dd"), String::from("--if=foo.file"), @@ -321,12 +353,6 @@ fn test_override_multiple_levels() { String::from("--status=noxfer"), String::from("--count=512"), String::from("--count=1024"), - String::from("--conv=ascii,ucase"), - String::from("--conv=ebcdic,lcase,unblock"), - String::from("--iflag=direct,nocache"), - String::from("--iflag=count_bytes,skip_bytes"), - String::from("--oflag=append,direct"), - String::from("--oflag=append,seek_bytes"), ]; let matches = uu_app().try_get_matches_from(args).unwrap(); @@ -368,14 +394,6 @@ fn test_override_multiple_levels() { .unwrap() ); - // conv - let exp = vec![ConvFlag::FmtEtoA, ConvFlag::LCase, ConvFlag::Unblock]; - let act = parse_flag_list::("conv", &matches).unwrap(); - assert_eq!(exp.len(), act.len()); - for cf in &exp { - assert!(exp.contains(cf)); - } - // count assert_eq!( CountType::Bytes(1024), @@ -389,26 +407,6 @@ fn test_override_multiple_levels() { .unwrap() .unwrap() ); - - // iflag - assert_eq!( - IFlags { - count_bytes: true, - skip_bytes: true, - ..IFlags::default() - }, - parse_iflags(&matches).unwrap() - ); - - // oflag - assert_eq!( - OFlags { - seek_bytes: true, - append: true, - ..OFlags::default() - }, - parse_oflags(&matches).unwrap() - ); } // ----- IConvFlags/Output -----