mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
dd: allow multiple occurences for iflag, oflag and conv
The iflag, oflag and conv cli arguments take a list of values and the correct behavior is to collect all values from multiple occurences of theme. For example if we call `dd --iflag=directory --iflag=skip_bytes` this should collect the two values, `directory` and `skip_bytes` for iflag. The unittest was added for this case.
This commit is contained in:
parent
9c73926616
commit
c3b4d898ee
3 changed files with 50 additions and 48 deletions
|
@ -1060,8 +1060,11 @@ Printing performance stats is also triggered by the INFO signal (where supported
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::CONV)
|
Arg::new(options::CONV)
|
||||||
.long(options::CONV)
|
.long(options::CONV)
|
||||||
.overrides_with(options::CONV)
|
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
|
.multiple_occurrences(true)
|
||||||
|
.use_delimiter(true)
|
||||||
|
.require_delimiter(true)
|
||||||
|
.multiple_values(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("CONV")
|
.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.
|
.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(
|
||||||
Arg::new(options::IFLAG)
|
Arg::new(options::IFLAG)
|
||||||
.long(options::IFLAG)
|
.long(options::IFLAG)
|
||||||
.overrides_with(options::IFLAG)
|
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
|
.multiple_occurrences(true)
|
||||||
|
.use_delimiter(true)
|
||||||
|
.require_delimiter(true)
|
||||||
|
.multiple_values(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("FLAG")
|
.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.
|
.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(
|
||||||
Arg::new(options::OFLAG)
|
Arg::new(options::OFLAG)
|
||||||
.long(options::OFLAG)
|
.long(options::OFLAG)
|
||||||
.overrides_with(options::OFLAG)
|
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
|
.multiple_occurrences(true)
|
||||||
|
.use_delimiter(true)
|
||||||
|
.require_delimiter(true)
|
||||||
|
.multiple_values(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("FLAG")
|
.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.
|
.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.
|
||||||
|
|
|
@ -414,16 +414,11 @@ fn parse_flag_list<T: std::str::FromStr<Err = ParseError>>(
|
||||||
tag: &str,
|
tag: &str,
|
||||||
matches: &Matches,
|
matches: &Matches,
|
||||||
) -> Result<Vec<T>, ParseError> {
|
) -> Result<Vec<T>, ParseError> {
|
||||||
let mut flags = Vec::new();
|
matches
|
||||||
|
.values_of(tag)
|
||||||
if let Some(comma_str) = matches.value_of(tag) {
|
.unwrap_or_default()
|
||||||
for s in comma_str.split(',') {
|
.map(|f| f.parse())
|
||||||
let flag = s.parse()?;
|
.collect()
|
||||||
flags.push(flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(flags)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse Conversion Options (Input Variety)
|
/// Parse Conversion Options (Input Variety)
|
||||||
|
|
|
@ -300,7 +300,39 @@ fn test_status_level_noxfer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[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::<Flag>(options::IFLAG, &matches).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
vec![Flag::FullBlock, Flag::Directory, Flag::SkipBytes],
|
||||||
|
iflags
|
||||||
|
);
|
||||||
|
|
||||||
|
// oflag
|
||||||
|
let oflags = parse_flag_list::<Flag>(options::OFLAG, &matches).unwrap();
|
||||||
|
assert_eq!(vec![Flag::Direct, Flag::Dsync], oflags);
|
||||||
|
|
||||||
|
// conv
|
||||||
|
let conv = parse_flag_list::<ConvFlag>(options::CONV, &matches).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
vec![ConvFlag::FmtEtoA, ConvFlag::UCase, ConvFlag::Unblock],
|
||||||
|
conv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_override_multiple_options() {
|
||||||
let args = vec![
|
let args = vec![
|
||||||
String::from("dd"),
|
String::from("dd"),
|
||||||
String::from("--if=foo.file"),
|
String::from("--if=foo.file"),
|
||||||
|
@ -321,12 +353,6 @@ fn test_override_multiple_levels() {
|
||||||
String::from("--status=noxfer"),
|
String::from("--status=noxfer"),
|
||||||
String::from("--count=512"),
|
String::from("--count=512"),
|
||||||
String::from("--count=1024"),
|
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();
|
let matches = uu_app().try_get_matches_from(args).unwrap();
|
||||||
|
@ -368,14 +394,6 @@ fn test_override_multiple_levels() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
// conv
|
|
||||||
let exp = vec![ConvFlag::FmtEtoA, ConvFlag::LCase, ConvFlag::Unblock];
|
|
||||||
let act = parse_flag_list::<ConvFlag>("conv", &matches).unwrap();
|
|
||||||
assert_eq!(exp.len(), act.len());
|
|
||||||
for cf in &exp {
|
|
||||||
assert!(exp.contains(cf));
|
|
||||||
}
|
|
||||||
|
|
||||||
// count
|
// count
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
CountType::Bytes(1024),
|
CountType::Bytes(1024),
|
||||||
|
@ -389,26 +407,6 @@ fn test_override_multiple_levels() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.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 -----
|
// ----- IConvFlags/Output -----
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue