mirror of
https://github.com/uutils/coreutils
synced 2024-12-17 08:33:24 +00:00
dd: allow multiple instances of arguments
Correct the behavior of `dd` when multiple arguments are provided. Before this commit, if the multiple arguments was provided then the validation error are returned. For example ``` $ printf '' | ./target/debug/dd status=none status=noxfer error: The argument '--status=<LEVEL>' was provided more than once, but cannot be used multiple times USAGE: dd [OPTIONS] For more information try --help ``` The unittest was added for this case.
This commit is contained in:
parent
a764fdfb8e
commit
19cc63df9a
2 changed files with 125 additions and 0 deletions
|
@ -954,6 +954,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::INFILE)
|
Arg::new(options::INFILE)
|
||||||
.long(options::INFILE)
|
.long(options::INFILE)
|
||||||
|
.overrides_with(options::INFILE)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("FILE")
|
.value_name("FILE")
|
||||||
|
@ -962,6 +963,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::OUTFILE)
|
Arg::new(options::OUTFILE)
|
||||||
.long(options::OUTFILE)
|
.long(options::OUTFILE)
|
||||||
|
.overrides_with(options::OUTFILE)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("FILE")
|
.value_name("FILE")
|
||||||
|
@ -970,6 +972,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::IBS)
|
Arg::new(options::IBS)
|
||||||
.long(options::IBS)
|
.long(options::IBS)
|
||||||
|
.overrides_with(options::IBS)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("N")
|
.value_name("N")
|
||||||
|
@ -978,6 +981,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::OBS)
|
Arg::new(options::OBS)
|
||||||
.long(options::OBS)
|
.long(options::OBS)
|
||||||
|
.overrides_with(options::OBS)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("N")
|
.value_name("N")
|
||||||
|
@ -986,6 +990,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::BS)
|
Arg::new(options::BS)
|
||||||
.long(options::BS)
|
.long(options::BS)
|
||||||
|
.overrides_with(options::BS)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("N")
|
.value_name("N")
|
||||||
|
@ -994,6 +999,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::CBS)
|
Arg::new(options::CBS)
|
||||||
.long(options::CBS)
|
.long(options::CBS)
|
||||||
|
.overrides_with(options::CBS)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("N")
|
.value_name("N")
|
||||||
|
@ -1002,6 +1008,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::SKIP)
|
Arg::new(options::SKIP)
|
||||||
.long(options::SKIP)
|
.long(options::SKIP)
|
||||||
|
.overrides_with(options::SKIP)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("N")
|
.value_name("N")
|
||||||
|
@ -1010,6 +1017,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::SEEK)
|
Arg::new(options::SEEK)
|
||||||
.long(options::SEEK)
|
.long(options::SEEK)
|
||||||
|
.overrides_with(options::SEEK)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("N")
|
.value_name("N")
|
||||||
|
@ -1018,6 +1026,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::COUNT)
|
Arg::new(options::COUNT)
|
||||||
.long(options::COUNT)
|
.long(options::COUNT)
|
||||||
|
.overrides_with(options::COUNT)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("N")
|
.value_name("N")
|
||||||
|
@ -1026,6 +1035,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::STATUS)
|
Arg::new(options::STATUS)
|
||||||
.long(options::STATUS)
|
.long(options::STATUS)
|
||||||
|
.overrides_with(options::STATUS)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("LEVEL")
|
.value_name("LEVEL")
|
||||||
|
@ -1050,6 +1060,7 @@ 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)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("CONV")
|
.value_name("CONV")
|
||||||
|
@ -1087,6 +1098,7 @@ 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)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("FLAG")
|
.value_name("FLAG")
|
||||||
|
@ -1113,6 +1125,7 @@ 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)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("FLAG")
|
.value_name("FLAG")
|
||||||
|
|
|
@ -299,6 +299,118 @@ fn test_status_level_noxfer() {
|
||||||
assert_eq!(st, StatusLevel::Noxfer);
|
assert_eq!(st, StatusLevel::Noxfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_override_multiple_levels() {
|
||||||
|
let args = vec![
|
||||||
|
String::from("dd"),
|
||||||
|
String::from("--if=foo.file"),
|
||||||
|
String::from("--if=correct.file"),
|
||||||
|
String::from("--of=bar.file"),
|
||||||
|
String::from("--of=correct.file"),
|
||||||
|
String::from("--ibs=256"),
|
||||||
|
String::from("--ibs=1024"),
|
||||||
|
String::from("--obs=256"),
|
||||||
|
String::from("--obs=1024"),
|
||||||
|
String::from("--cbs=1"),
|
||||||
|
String::from("--cbs=2"),
|
||||||
|
String::from("--skip=0"),
|
||||||
|
String::from("--skip=2"),
|
||||||
|
String::from("--seek=0"),
|
||||||
|
String::from("--seek=2"),
|
||||||
|
String::from("--status=none"),
|
||||||
|
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();
|
||||||
|
|
||||||
|
// if
|
||||||
|
assert_eq!("correct.file", matches.value_of(options::INFILE).unwrap());
|
||||||
|
|
||||||
|
// of
|
||||||
|
assert_eq!("correct.file", matches.value_of(options::OUTFILE).unwrap());
|
||||||
|
|
||||||
|
// ibs
|
||||||
|
assert_eq!(1024, parse_ibs(&matches).unwrap());
|
||||||
|
|
||||||
|
// obs
|
||||||
|
assert_eq!(1024, parse_obs(&matches).unwrap());
|
||||||
|
|
||||||
|
// cbs
|
||||||
|
assert_eq!(2, parse_cbs(&matches).unwrap().unwrap());
|
||||||
|
|
||||||
|
// status
|
||||||
|
assert_eq!(
|
||||||
|
StatusLevel::Noxfer,
|
||||||
|
parse_status_level(&matches).unwrap().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// skip
|
||||||
|
assert_eq!(
|
||||||
|
200,
|
||||||
|
parse_skip_amt(&100, &IFlags::default(), &matches)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// seek
|
||||||
|
assert_eq!(
|
||||||
|
200,
|
||||||
|
parse_seek_amt(&100, &OFlags::default(), &matches)
|
||||||
|
.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
|
||||||
|
assert_eq!(
|
||||||
|
CountType::Bytes(1024),
|
||||||
|
parse_count(
|
||||||
|
&IFlags {
|
||||||
|
count_bytes: true,
|
||||||
|
..IFlags::default()
|
||||||
|
},
|
||||||
|
&matches
|
||||||
|
)
|
||||||
|
.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 -----
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue