1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #2846 from jfinkels/wc-uresult

wc: return UResult from uumain() function
This commit is contained in:
Sylvestre Ledru 2022-01-05 14:39:39 +01:00 committed by GitHub
commit ae7190ec73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -25,6 +25,7 @@ use std::io::{self, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use uucore::display::{Quotable, Quoted}; use uucore::display::{Quotable, Quoted};
use uucore::error::{UResult, USimpleError};
/// The minimum character width for formatting counts when reading from stdin. /// The minimum character width for formatting counts when reading from stdin.
const MINIMUM_WIDTH: usize = 7; const MINIMUM_WIDTH: usize = 7;
@ -132,7 +133,8 @@ impl Input {
} }
} }
pub fn uumain(args: impl uucore::Args) -> i32 { #[uucore_procs::gen_uumain]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let usage = usage(); let usage = usage();
let matches = uu_app().usage(&usage[..]).get_matches_from(args); let matches = uu_app().usage(&usage[..]).get_matches_from(args);
@ -157,11 +159,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let settings = Settings::new(&matches); let settings = Settings::new(&matches);
if wc(inputs, &settings).is_ok() { wc(inputs, &settings)
0
} else {
1
}
} }
pub fn uu_app() -> App<'static, 'static> { pub fn uu_app() -> App<'static, 'static> {
@ -326,19 +324,6 @@ fn word_count_from_input(input: &Input, settings: &Settings) -> CountResult {
} }
} }
/// Print a message appropriate for the particular error to `stderr`.
///
/// # Examples
///
/// This will print `wc: /tmp: Is a directory` to `stderr`.
///
/// ```rust,ignore
/// show_error(Input::Path("/tmp"), WcError::IsDirectory("/tmp"))
/// ```
fn show_error(input: &Input, err: io::Error) {
show_error!("{}: {}", input.path_display(), err);
}
/// Compute the number of digits needed to represent any count for this input. /// Compute the number of digits needed to represent any count for this input.
/// ///
/// If `input` is [`Input::Stdin`], then this function returns /// If `input` is [`Input::Stdin`], then this function returns
@ -418,7 +403,7 @@ fn max_width(inputs: &[Input]) -> usize {
result result
} }
fn wc(inputs: Vec<Input>, settings: &Settings) -> Result<(), u32> { fn wc(inputs: Vec<Input>, settings: &Settings) -> UResult<()> {
// Compute the width, in digits, to use when formatting counts. // Compute the width, in digits, to use when formatting counts.
// //
// The width is the number of digits needed to print the number of // The width is the number of digits needed to print the number of
@ -427,7 +412,6 @@ fn wc(inputs: Vec<Input>, settings: &Settings) -> Result<(), u32> {
// //
// If we only need to display a single number, set this to 0 to // If we only need to display a single number, set this to 0 to
// prevent leading spaces. // prevent leading spaces.
let mut failure = false;
let max_width = if settings.number_enabled() <= 1 { let max_width = if settings.number_enabled() <= 1 {
0 0
} else { } else {
@ -442,44 +426,50 @@ fn wc(inputs: Vec<Input>, settings: &Settings) -> Result<(), u32> {
let word_count = match word_count_from_input(input, settings) { let word_count = match word_count_from_input(input, settings) {
CountResult::Success(word_count) => word_count, CountResult::Success(word_count) => word_count,
CountResult::Interrupted(word_count, error) => { CountResult::Interrupted(word_count, error) => {
show_error(input, error); show!(USimpleError::new(
failure = true; 1,
format!("{}: {}", input.path_display(), error)
));
word_count word_count
} }
CountResult::Failure(error) => { CountResult::Failure(error) => {
show_error(input, error); show!(USimpleError::new(
failure = true; 1,
format!("{}: {}", input.path_display(), error)
));
continue; continue;
} }
}; };
total_word_count += word_count; total_word_count += word_count;
let result = word_count.with_title(input.to_title()); let result = word_count.with_title(input.to_title());
if let Err(err) = print_stats(settings, &result, max_width) { if let Err(err) = print_stats(settings, &result, max_width) {
show_warning!( show!(USimpleError::new(
"failed to print result for {}: {}", 1,
result format!(
.title "failed to print result for {}: {}",
.unwrap_or_else(|| "<stdin>".as_ref()) result
.maybe_quote(), .title
err .unwrap_or_else(|| "<stdin>".as_ref())
); .maybe_quote(),
failure = true; err,
),
));
} }
} }
if num_inputs > 1 { if num_inputs > 1 {
let total_result = total_word_count.with_title(Some("total".as_ref())); let total_result = total_word_count.with_title(Some("total".as_ref()));
if let Err(err) = print_stats(settings, &total_result, max_width) { if let Err(err) = print_stats(settings, &total_result, max_width) {
show_warning!("failed to print total: {}", err); show!(USimpleError::new(
failure = true; 1,
format!("failed to print total: {}", err)
));
} }
} }
if failure { // Although this appears to be returning `Ok`, the exit code may
Err(1) // have been set to a non-zero value by a call to `show!()` above.
} else { Ok(())
Ok(())
}
} }
fn print_stats(settings: &Settings, result: &TitledWordCount, min_width: usize) -> io::Result<()> { fn print_stats(settings: &Settings, result: &TitledWordCount, min_width: usize) -> io::Result<()> {