Skip to content

Commit

Permalink
hashsum: Refactor uu_app to isolate non-"GNU Coreutils" options
Browse files Browse the repository at this point in the history
Several binaries have been added to `hashsum` that have never been part
of GNU Coreutils:

- `sha3*sum` (uutils#869)
- `shake*sum` (uutils#987)
- `b3sum` (uutils#3108 and uutils#3164)

In particular, the `--bits` option, and the `--no-names` option added in
uutils#3361, are not valid for any GNU Coreutils `*sum` binary
(as of Coreutils 9.0).

This commit refactors the argument parsing so that `--bits` and
`--no-names` become invalid options for the binaries intended to match
the GNU Coreutils API, instead of being ignored options. It also
refactors the custom binary name handling to distinguish between
binaries intended to match the GNU Coreutils API, and binaries that
don't have that constraint.

Part of uutils#2930.
  • Loading branch information
str4d authored and sylvestre committed Jun 10, 2022
1 parent d1f7f51 commit fccab8a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 45 deletions.
12 changes: 8 additions & 4 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,25 @@ pub fn main() {
);

let map_value = format!("({krate}::uumain, {krate}::uu_app_common)", krate = krate);
let map_value_bits =
format!("({krate}::uumain, {krate}::uu_app_bits)", krate = krate);
let map_value_b3sum =
format!("({krate}::uumain, {krate}::uu_app_b3sum)", krate = krate);
phf_map.entry("md5sum", &map_value);
phf_map.entry("sha1sum", &map_value);
phf_map.entry("sha224sum", &map_value);
phf_map.entry("sha256sum", &map_value);
phf_map.entry("sha384sum", &map_value);
phf_map.entry("sha512sum", &map_value);
phf_map.entry("sha3sum", &map_value);
phf_map.entry("sha3sum", &map_value_bits);
phf_map.entry("sha3-224sum", &map_value);
phf_map.entry("sha3-256sum", &map_value);
phf_map.entry("sha3-384sum", &map_value);
phf_map.entry("sha3-512sum", &map_value);
phf_map.entry("shake128sum", &map_value);
phf_map.entry("shake256sum", &map_value);
phf_map.entry("shake128sum", &map_value_bits);
phf_map.entry("shake256sum", &map_value_bits);
phf_map.entry("b2sum", &map_value);
phf_map.entry("b3sum", &map_value);
phf_map.entry("b3sum", &map_value_b3sum);
tf.write_all(
format!(
"#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
Expand Down
89 changes: 48 additions & 41 deletions src/uu/hashsum/src/hashsum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,6 @@ struct Options {
output_bits: usize,
}

fn is_custom_binary(program: &str) -> bool {
matches!(
program,
"md5sum"
| "sha1sum"
| "sha224sum"
| "sha256sum"
| "sha384sum"
| "sha512sum"
| "sha3sum"
| "sha3-224sum"
| "sha3-256sum"
| "sha3-384sum"
| "sha3-512sum"
| "shake128sum"
| "shake256sum"
| "b2sum"
| "b3sum"
)
}

#[allow(clippy::cognitive_complexity)]
fn detect_algo(
program: &str,
Expand Down Expand Up @@ -373,11 +352,6 @@ pub fn uu_app_common<'a>() -> Command<'a> {
.long("tag")
.help("create a BSD-style checksum"),
)
.arg(
Arg::new("no-names")
.long("no-names")
.help("Omits filenames in the output (option not present in GNU/Coreutils)"),
)
.arg(
Arg::new("text")
.short('t')
Expand Down Expand Up @@ -408,16 +382,6 @@ pub fn uu_app_common<'a>() -> Command<'a> {
.long("warn")
.help("warn about improperly formatted checksum lines"),
)
// Needed for variable-length output sums (e.g. SHAKE)
.arg(
Arg::new("bits")
.long("bits")
.help("set the size of the output (only for SHAKE)")
.takes_value(true)
.value_name("BITS")
// XXX: should we actually use validators? they're not particularly efficient
.validator(is_valid_bit_num),
)
.arg(
Arg::new("FILE")
.index(1)
Expand All @@ -428,8 +392,37 @@ pub fn uu_app_common<'a>() -> Command<'a> {
)
}

pub fn uu_app_b3sum<'a>() -> Command<'a> {
uu_app_b3sum_opts(uu_app_common())
}

fn uu_app_b3sum_opts(command: Command) -> Command {
command.arg(
Arg::new("no-names")
.long("no-names")
.help("Omits filenames in the output (option not present in GNU/Coreutils)"),
)
}

pub fn uu_app_bits<'a>() -> Command<'a> {
uu_app_opt_bits(uu_app_common())
}

fn uu_app_opt_bits(command: Command) -> Command {
// Needed for variable-length output sums (e.g. SHAKE)
command.arg(
Arg::new("bits")
.long("bits")
.help("set the size of the output (only for SHAKE)")
.takes_value(true)
.value_name("BITS")
// XXX: should we actually use validators? they're not particularly efficient
.validator(is_valid_bit_num),
)
}

pub fn uu_app_custom<'a>() -> Command<'a> {
let mut command = uu_app_common();
let mut command = uu_app_b3sum_opts(uu_app_opt_bits(uu_app_common()));
let algorithms = &[
("md5", "work with MD5"),
("sha1", "work with SHA1"),
Expand Down Expand Up @@ -463,10 +456,24 @@ pub fn uu_app_custom<'a>() -> Command<'a> {
// hashsum is handled differently in build.rs, therefore this is not the same
// as in other utilities.
fn uu_app<'a>(binary_name: &str) -> Command<'a> {
if !is_custom_binary(binary_name) {
uu_app_custom()
} else {
uu_app_common()
match binary_name {
// These all support the same options.
"md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" => {
uu_app_common()
}
// b2sum supports the md5sum options plus -l/--length.
"b2sum" => uu_app_common(), // TODO: Implement -l/--length
// These have never been part of GNU Coreutils, but can function with the same
// options as md5sum.
"sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" => uu_app_common(),
// These have never been part of GNU Coreutils, and require an additional --bits
// option to specify their output size.
"sha3sum" | "shake128sum" | "shake256sum" => uu_app_bits(),
// b3sum has never been part of GNU Coreutils, and has a --no-names option in
// addition to the b2sum options.
"b3sum" => uu_app_b3sum(),
// We're probably just being called as `hashsum`, so give them everything.
_ => uu_app_custom(),
}
}

Expand Down

0 comments on commit fccab8a

Please sign in to comment.