Skip to content

Commit da5da3b

Browse files
committed
checksum: Rework the OutputFormat decision
1 parent b1edc49 commit da5da3b

4 files changed

Lines changed: 81 additions & 58 deletions

File tree

src/uu/cksum/src/cksum.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use clap::builder::ValueParser;
99
use clap::{Arg, ArgAction, Command};
1010
use std::ffi::{OsStr, OsString};
1111
use uucore::checksum::compute::{
12-
ChecksumComputeOptions, figure_out_output_format, perform_checksum_computation,
12+
ChecksumComputeOptions, OutputFormat, perform_checksum_computation,
1313
};
1414
use uucore::checksum::validate::{
1515
ChecksumValidateOptions, ChecksumVerbose, perform_checksum_validation,
@@ -208,18 +208,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
208208

209209
let (tag, binary) = handle_tag_text_binary_flags(std::env::args_os())?;
210210

211+
let output_format = OutputFormat::from_cksum(
212+
algo_kind,
213+
tag,
214+
binary,
215+
matches.get_flag(options::RAW),
216+
matches.get_flag(options::BASE64),
217+
);
218+
211219
let algo = SizedAlgoKind::from_unsized(algo_kind, length)?;
212220
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));
213221

214222
let opts = ChecksumComputeOptions {
215223
algo_kind: algo,
216-
output_format: figure_out_output_format(
217-
algo,
218-
tag,
219-
binary,
220-
matches.get_flag(options::RAW),
221-
matches.get_flag(options::BASE64),
222-
),
224+
output_format,
223225
line_ending,
224226
};
225227

src/uu/hashsum/src/hashsum.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use clap::builder::ValueParser;
1313
use clap::{Arg, ArgAction, ArgMatches, Command};
1414

1515
use uucore::checksum::compute::{
16-
ChecksumComputeOptions, figure_out_output_format, perform_checksum_computation,
16+
ChecksumComputeOptions, OutputFormat, perform_checksum_computation,
1717
};
1818
use uucore::checksum::validate::{
1919
ChecksumValidateOptions, ChecksumVerbose, perform_checksum_validation,
@@ -121,9 +121,6 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
121121

122122
let args = iter::once(program.clone()).chain(args);
123123

124-
// Default binary in Windows, text mode otherwise
125-
let binary_flag_default = cfg!(windows);
126-
127124
let (command, is_hashsum_bin) = uu_app(&binary_name);
128125

129126
// FIXME: this should use try_get_matches_from() and crash!(), but at the moment that just
@@ -148,13 +145,6 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
148145
(AlgoKind::from_bin_name(&binary_name)?, length)
149146
};
150147

151-
let binary = if matches.get_flag("binary") {
152-
true
153-
} else if matches.get_flag("text") {
154-
false
155-
} else {
156-
binary_flag_default
157-
};
158148
let check = matches.get_flag("check");
159149

160150
let check_flag = |flag| match (check, matches.get_flag(flag)) {
@@ -204,16 +194,11 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
204194

205195
let algo = SizedAlgoKind::from_unsized(algo_kind, length)?;
206196
let line_ending = LineEnding::from_zero_flag(matches.get_flag("zero"));
197+
let output_format = OutputFormat::from_standalone(std::env::args_os())?;
207198

208199
let opts = ChecksumComputeOptions {
209200
algo_kind: algo,
210-
output_format: figure_out_output_format(
211-
algo,
212-
matches.get_flag(options::TAG),
213-
binary,
214-
/* raw */ false,
215-
/* base64: */ false,
216-
),
201+
output_format,
217202
line_ending,
218203
};
219204

src/uucore/src/lib/features/checksum/compute.rs

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55

66
// spell-checker:ignore bitlen
77

8-
use std::ffi::OsStr;
8+
use std::ffi::{OsStr, OsString};
99
use std::fs::File;
1010
use std::io::{self, BufReader, Read, Write};
1111
use std::path::Path;
1212

13-
use crate::checksum::{ChecksumError, SizedAlgoKind, digest_reader, escape_filename};
13+
use crate::checksum::{AlgoKind, ChecksumError, SizedAlgoKind, digest_reader, escape_filename};
1414
use crate::error::{FromIo, UResult, USimpleError};
1515
use crate::line_ending::LineEnding;
1616
use crate::sum::DigestOutput;
@@ -103,42 +103,76 @@ impl OutputFormat {
103103
fn is_raw(&self) -> bool {
104104
*self == Self::Raw
105105
}
106-
}
107106

108-
/// Use already-processed arguments to decide the output format.
109-
pub fn figure_out_output_format(
110-
algo: SizedAlgoKind,
111-
tag: bool,
112-
binary: bool,
113-
raw: bool,
114-
base64: bool,
115-
) -> OutputFormat {
116-
// Raw output format takes precedence over anything else.
117-
if raw {
118-
return OutputFormat::Raw;
119-
}
107+
/// Find the correct output format for cksum.
108+
pub fn from_cksum(algo: AlgoKind, tag: bool, binary: bool, raw: bool, base64: bool) -> Self {
109+
// Raw output format takes precedence over anything else.
110+
if raw {
111+
return Self::Raw;
112+
}
113+
114+
// Then, if the algo is legacy, takes precedence over the rest
115+
if algo.is_legacy() {
116+
return Self::Legacy;
117+
}
120118

121-
// Then, if the algo is legacy, takes precedence over the rest
122-
if algo.is_legacy() {
123-
return OutputFormat::Legacy;
119+
let digest_format = if base64 {
120+
DigestFormat::Base64
121+
} else {
122+
DigestFormat::Hexadecimal
123+
};
124+
125+
// After that, decide between tagged and untagged output
126+
if tag {
127+
Self::Tagged(digest_format)
128+
} else {
129+
let reading_mode = if binary {
130+
ReadingMode::Binary
131+
} else {
132+
ReadingMode::Text
133+
};
134+
Self::Untagged(digest_format, reading_mode)
135+
}
124136
}
125137

126-
let digest_format = if base64 {
127-
DigestFormat::Base64
128-
} else {
129-
DigestFormat::Hexadecimal
130-
};
138+
/// Find the correct output format for a standalone checksum util (b2sum,
139+
/// md5sum, etc)
140+
///
141+
/// Since standalone utils can't use the Raw or Legacy output format, it is
142+
/// decided only using the --tag, --binary and --text arguments.
143+
pub fn from_standalone(args: impl Iterator<Item = OsString>) -> UResult<Self> {
144+
let mut text = true;
145+
let mut tag = false;
146+
147+
for arg in args {
148+
if arg == "--" {
149+
break;
150+
} else if arg == "--tag" {
151+
tag = true;
152+
text = false;
153+
} else if arg == "--binary" || arg == "-b" {
154+
text = false;
155+
} else if arg == "--text" || arg == "-t" {
156+
// Finding a `--text` after `--tag` is an error.
157+
if tag {
158+
return Err(ChecksumError::TextAfterTag.into());
159+
}
160+
text = true;
161+
}
162+
}
131163

132-
// After that, decide between tagged and untagged output
133-
if tag {
134-
OutputFormat::Tagged(digest_format)
135-
} else {
136-
let reading_mode = if binary {
137-
ReadingMode::Binary
164+
if tag {
165+
Ok(Self::Tagged(DigestFormat::Hexadecimal))
138166
} else {
139-
ReadingMode::Text
140-
};
141-
OutputFormat::Untagged(digest_format, reading_mode)
167+
Ok(Self::Untagged(
168+
DigestFormat::Hexadecimal,
169+
if text {
170+
ReadingMode::Text
171+
} else {
172+
ReadingMode::Binary
173+
},
174+
))
175+
}
142176
}
143177
}
144178

src/uucore/src/lib/features/checksum/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ pub enum ChecksumError {
397397
BinaryTextConflict,
398398
#[error("--text mode is only supported with --untagged")]
399399
TextWithoutUntagged,
400+
#[error("--tag does not support --text mode")]
401+
TextAfterTag,
400402
#[error("--check is not supported with --algorithm={{bsd,sysv,crc,crc32b}}")]
401403
AlgorithmNotSupportedWithCheck,
402404
#[error("You cannot combine multiple hash algorithms!")]

0 commit comments

Comments
 (0)