From 8b06f4b65111510d256d7841d6c3b4ba039e5e0f Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 1 Sep 2026 12:31:04 +0200 Subject: [PATCH] numfmt: accept hyphen-leading values for the remaining options Follow-up to #14322. --padding, --suffix and -d learned to take a hyphen-leading value as a separate argument, but --from, --to, --from-unit, --to-unit, --round, --invalid and --unit-separator did not, so clap rejected the value as an unknown flag before our own validation could report it. GNU getopt_long hands the value to the utility in all of these cases: $ numfmt --from-unit -1 5 numfmt: invalid unit size: '-1' --- src/uu/numfmt/src/numfmt.rs | 21 ++++++++++++++------- tests/by-util/test_numfmt.rs | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index 304727c2a7e..a2152a0c966 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -600,28 +600,32 @@ pub fn uu_app() -> Command { .long(FROM) .help(translate!("numfmt-help-from")) .value_name("UNIT") - .default_value(FROM_DEFAULT), + .default_value(FROM_DEFAULT) + .allow_hyphen_values(true), ) .arg( Arg::new(FROM_UNIT) .long(FROM_UNIT) .help(translate!("numfmt-help-from-unit")) .value_name("N") - .default_value(FROM_UNIT_DEFAULT), + .default_value(FROM_UNIT_DEFAULT) + .allow_hyphen_values(true), ) .arg( Arg::new(TO) .long(TO) .help(translate!("numfmt-help-to")) .value_name("UNIT") - .default_value(TO_DEFAULT), + .default_value(TO_DEFAULT) + .allow_hyphen_values(true), ) .arg( Arg::new(TO_UNIT) .long(TO_UNIT) .help(translate!("numfmt-help-to-unit")) .value_name("N") - .default_value(TO_UNIT_DEFAULT), + .default_value(TO_UNIT_DEFAULT) + .allow_hyphen_values(true), ) .arg( Arg::new(PADDING) @@ -652,7 +656,8 @@ pub fn uu_app() -> Command { "from-zero", "towards-zero", "nearest", - ])), + ])) + .allow_hyphen_values(true), ) .arg( Arg::new(SUFFIX) @@ -665,7 +670,8 @@ pub fn uu_app() -> Command { Arg::new(UNIT_SEPARATOR) .long(UNIT_SEPARATOR) .help(translate!("numfmt-help-unit-separator")) - .value_name("STRING"), + .value_name("STRING") + .allow_hyphen_values(true), ) .arg( Arg::new(INVALID) @@ -673,7 +679,8 @@ pub fn uu_app() -> Command { .help(translate!("numfmt-help-invalid")) .default_value("abort") .value_parser(["abort", "fail", "warn", "ignore"]) - .value_name("INVALID"), + .value_name("INVALID") + .allow_hyphen_values(true), ) .arg( Arg::new(ZERO_TERMINATED) diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index a17e634bd25..5d3382bd6e4 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -173,11 +173,44 @@ fn test_delimiter_hyphen_leading_as_separate_arg() { // unrecognized flag. new_ucmd!() .args(&["-d", "-x", "--field=1"]) - .pipe_in("5-x6") .fails() .stderr_contains("the delimiter must be a single character"); } +#[test] +fn test_unit_size_hyphen_leading_as_separate_arg() { + // A hyphen-leading unit size passed as its own argument must reach + // our own validation instead of being read as an unknown flag. + for opt in ["--from-unit", "--to-unit"] { + new_ucmd!() + .args(&[opt, "-1"]) + .pipe_in("5\n") + .fails() + .stderr_contains("invalid unit size: '-1'"); + } +} + +#[test] +fn test_unit_hyphen_leading_as_separate_arg() { + // Same for the --from/--to units. + for opt in ["--from", "--to"] { + new_ucmd!() + .args(&[opt, "-x"]) + .pipe_in("5\n") + .fails() + .stderr_contains("invalid argument '-x' for '--"); + } +} + +#[test] +fn test_unit_separator_hyphen_leading_as_separate_arg() { + new_ucmd!() + .args(&["--to=si", "--unit-separator", "-"]) + .pipe_in("1000\n") + .succeeds() + .stdout_is("1.0-k\n"); +} + #[test] fn test_header() { new_ucmd!()