fix(tools): h5rs diff names its options as h5diff does
-c meant "list at most N differences" in h5rs, but in h5diff -c is --compare (a flag) and the count is -n/--count=N, so a script moved over from h5diff behaved differently: `h5diff -r -c 2 A B` exits 2 (the 2 is taken as a file name) while h5rs exited 1. The count is now -n/--count, -c/--compare is accepted (h5rs always lists objects that are not comparable), and the --count=N, --delta=D, --relative=R forms are accepted; exit codes equal h5diff's on 7 cases. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -11,30 +11,37 @@ pub struct Out<'a> {
|
||||
/// The arguments after the subcommand name.
|
||||
pub struct Args {
|
||||
cmd: &'static str,
|
||||
rest: std::vec::IntoIter<String>,
|
||||
rest: std::collections::VecDeque<String>,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
pub fn new(cmd: &'static str, rest: Vec<String>) -> Self {
|
||||
Self {
|
||||
cmd,
|
||||
rest: rest.into_iter(),
|
||||
rest: rest.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn next(&mut self) -> Option<String> {
|
||||
self.rest.next()
|
||||
self.rest.pop_front()
|
||||
}
|
||||
|
||||
/// Put an option and its value back, to be read next (for the
|
||||
/// `--name=value` form).
|
||||
pub fn push_front(&mut self, name: String, value: String) {
|
||||
self.rest.push_front(value);
|
||||
self.rest.push_front(name);
|
||||
}
|
||||
|
||||
/// The value after an option such as `--max-bytes`.
|
||||
pub fn value(&mut self) -> Option<String> {
|
||||
self.rest.next()
|
||||
self.rest.pop_front()
|
||||
}
|
||||
|
||||
/// A numeric option value.
|
||||
pub fn number<T: std::str::FromStr>(&mut self) -> Option<T> {
|
||||
self.rest.next().and_then(|s| s.parse().ok())
|
||||
self.rest.pop_front().and_then(|s| s.parse().ok())
|
||||
}
|
||||
|
||||
/// Report a usage problem; exit status 2.
|
||||
|
||||
@@ -29,7 +29,9 @@ soft link is compared as a link, as h5diff does, unless --follow-symlinks).
|
||||
-d, --delta D numbers differ only when |a - b| > D
|
||||
-p, --relative R numbers differ only when |a - b| / |a| > R (an R below
|
||||
the f64 epsilon, 2.2e-16, compares exactly, as h5diff)
|
||||
-c, --count N list at most N differing elements per object with -r
|
||||
-n, --count N list at most N differing elements per object with -r
|
||||
-c, --compare list objects that are not comparable (always done;
|
||||
accepted for h5diff compatibility)
|
||||
--max-bytes N largest dataset read (default 1 GiB); a larger one is an error
|
||||
|
||||
Two NaNs compare equal. Unlike h5diff, objects that cannot be compared
|
||||
@@ -139,7 +141,9 @@ pub fn run(args: &mut Args, out: &mut Out) -> std::io::Result<i32> {
|
||||
}
|
||||
_ => return args.usage_error(out, "--relative needs a number >= 0", USAGE),
|
||||
},
|
||||
"-c" | "--count" => match args.number() {
|
||||
// h5diff's -c: h5rs always lists them.
|
||||
"-c" | "--compare" => {}
|
||||
"-n" | "--count" => match args.number() {
|
||||
Some(n) => opts.count = n,
|
||||
None => return args.usage_error(out, "--count needs a number", USAGE),
|
||||
},
|
||||
@@ -151,6 +155,14 @@ pub fn run(args: &mut Args, out: &mut Out) -> std::io::Result<i32> {
|
||||
writeln!(out.o, "{USAGE}")?;
|
||||
return Ok(0);
|
||||
}
|
||||
// h5diff's --count=N, --delta=D, --relative=R forms.
|
||||
s if s.starts_with("--") && s.contains('=') => {
|
||||
let (k, v) = s.split_once('=').unwrap_or((s, ""));
|
||||
if !matches!(k, "--count" | "--delta" | "--relative" | "--max-bytes") {
|
||||
return args.usage_error(out, &format!("unknown option {a}"), USAGE);
|
||||
}
|
||||
args.push_front(k.to_string(), v.to_string());
|
||||
}
|
||||
s if s.starts_with('-') && s.len() > 1 => {
|
||||
return args.usage_error(out, &format!("unknown option {a}"), USAGE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user