diff --git a/src/uu/wc/locales/en-US.ftl b/src/uu/wc/locales/en-US.ftl index 7eb458ec2..8acb86f8e 100644 --- a/src/uu/wc/locales/en-US.ftl +++ b/src/uu/wc/locales/en-US.ftl @@ -1,3 +1,33 @@ -wc-about = Display newline, word, and byte counts for each FILE, and a total line if - more than one FILE is specified. With no FILE, or when FILE is -, read standard input. +wc-about = Print newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified. wc-usage = wc [OPTION]... [FILE]... + +# Help messages +wc-help-bytes = print the byte counts +wc-help-chars = print the character counts +wc-help-files0-from = read input from the files specified by + NUL-terminated names in file F; + If F is - then read names from standard input +wc-help-lines = print the newline counts +wc-help-max-line-length = print the length of the longest line +wc-help-total = when to print a line with total counts; + WHEN can be: auto, always, only, never +wc-help-words = print the word counts + +# Error messages +wc-error-files-disabled = extra operand '{ $extra }' + file operands cannot be combined with --files0-from +wc-error-stdin-repr-not-allowed = when reading file names from stdin, no file name of '-' allowed +wc-error-zero-length-filename = invalid zero-length file name +wc-error-zero-length-filename-ctx = { $path }:{ $idx }: invalid zero-length file name +wc-error-cannot-open-for-reading = cannot open { $path } for reading +wc-error-read-error = { $path }: read error +wc-error-failed-to-print-result = failed to print result for { $title } +wc-error-failed-to-print-total = failed to print total + +# Decoder error messages +decoder-error-invalid-byte-sequence = invalid byte sequence: { $bytes } +decoder-error-io = underlying bytestream error: { $error } + +# Other messages +wc-standard-input = standard input +wc-total = total diff --git a/src/uu/wc/locales/fr-FR.ftl b/src/uu/wc/locales/fr-FR.ftl new file mode 100644 index 000000000..2743bf14f --- /dev/null +++ b/src/uu/wc/locales/fr-FR.ftl @@ -0,0 +1,33 @@ +wc-about = Afficher le nombre de nouvelles lignes, de mots et d'octets pour chaque FICHIER, et une ligne totale si plus d'un FICHIER est spécifié. +wc-usage = wc [OPTION]... [FICHIER]... + +# Messages d'aide +wc-help-bytes = afficher le nombre d'octets +wc-help-chars = afficher le nombre de caractères +wc-help-files0-from = lire l'entrée depuis les fichiers spécifiés par + des noms terminés par NUL dans le fichier F ; + Si F est - alors lire les noms depuis l'entrée standard +wc-help-lines = afficher le nombre de nouvelles lignes +wc-help-max-line-length = afficher la longueur de la ligne la plus longue +wc-help-total = quand afficher une ligne avec les totaux ; + WHEN peut être : auto, always, only, never +wc-help-words = afficher le nombre de mots + +# Messages d'erreur +wc-error-files-disabled = opérande supplémentaire '{ $extra }' + les opérandes de fichier ne peuvent pas être combinées avec --files0-from +wc-error-stdin-repr-not-allowed = lors de la lecture des noms de fichiers depuis stdin, aucun nom de fichier '-' autorisé +wc-error-zero-length-filename = nom de fichier de longueur nulle invalide +wc-error-zero-length-filename-ctx = { $path }:{ $idx } : nom de fichier de longueur nulle invalide +wc-error-cannot-open-for-reading = impossible d'ouvrir { $path } en lecture +wc-error-read-error = { $path } : erreur de lecture +wc-error-failed-to-print-result = échec de l'affichage du résultat pour { $title } +wc-error-failed-to-print-total = échec de l'affichage du total + +# Messages d'erreur du décodeur +decoder-error-invalid-byte-sequence = séquence d'octets invalide : { $bytes } +decoder-error-io = erreur du flux d'octets sous-jacent : { $error } + +# Autres messages +wc-standard-input = entrée standard +wc-total = total diff --git a/src/uu/wc/src/utf8/read.rs b/src/uu/wc/src/utf8/read.rs index af10cbb53..2fb310123 100644 --- a/src/uu/wc/src/utf8/read.rs +++ b/src/uu/wc/src/utf8/read.rs @@ -4,8 +4,10 @@ // file that was distributed with this source code. // spell-checker:ignore bytestream use super::*; +use std::collections::HashMap; use std::io::{self, BufRead}; use thiserror::Error; +use uucore::locale::get_message_with_args; /// Wraps a `std::io::BufRead` buffered byte stream and decode it as UTF-8. pub struct BufReadDecoder { @@ -20,11 +22,11 @@ pub enum BufReadDecoderError<'a> { /// /// In lossy decoding, each such error should be replaced with U+FFFD. /// (See `BufReadDecoder::next_lossy` and `BufReadDecoderError::lossy`.) - #[error("invalid byte sequence: {0:02x?}")] + #[error("{}", get_message_with_args("decoder-error-invalid-byte-sequence", HashMap::from([("bytes".to_string(), format!("{:02x?}", .0))])))] InvalidByteSequence(&'a [u8]), /// An I/O error from the underlying byte stream - #[error("underlying bytestream error: {0}")] + #[error("{}", get_message_with_args("decoder-error-io", HashMap::from([("error".to_string(), .0.to_string())])))] Io(#[source] io::Error), } diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index f3414bb43..65a9c6fe1 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -13,6 +13,7 @@ mod word_count; use std::{ borrow::{Borrow, Cow}, cmp::max, + collections::HashMap, ffi::{OsStr, OsString}, fs::{self, File}, io::{self, Write}, @@ -24,7 +25,7 @@ use clap::{Arg, ArgAction, ArgMatches, Command, builder::ValueParser}; use thiserror::Error; use unicode_width::UnicodeWidthChar; use utf8::{BufReadDecoder, BufReadDecoderError}; -use uucore::locale::get_message; +use uucore::locale::{get_message, get_message_with_args}; use uucore::{ error::{FromIo, UError, UResult}, @@ -272,7 +273,7 @@ impl<'a> Input<'a> { fn path_display(&self) -> String { match self { Self::Path(path) => escape_name_wrapper(path.as_os_str()), - Self::Stdin(_) => String::from("standard input"), + Self::Stdin(_) => get_message("wc-standard-input"), } } @@ -347,13 +348,13 @@ impl TotalWhen { #[derive(Debug, Error)] enum WcError { - #[error("extra operand '{extra}'\nfile operands cannot be combined with --files0-from")] + #[error("{}", get_message_with_args("wc-error-files-disabled", HashMap::from([("extra".to_string(), extra.to_string())])))] FilesDisabled { extra: Cow<'static, str> }, - #[error("when reading file names from stdin, no file name of '-' allowed")] + #[error("{}", get_message("wc-error-stdin-repr-not-allowed"))] StdinReprNotAllowed, - #[error("invalid zero-length file name")] + #[error("{}", get_message("wc-error-zero-length-filename"))] ZeroLengthFileName, - #[error("{path}:{idx}: invalid zero-length file name")] + #[error("{}", get_message_with_args("wc-error-zero-length-filename-ctx", HashMap::from([("path".to_string(), path.to_string()), ("idx".to_string(), idx.to_string())])))] ZeroLengthFileNameCtx { path: Cow<'static, str>, idx: usize }, } @@ -403,25 +404,21 @@ pub fn uu_app() -> Command { Arg::new(options::BYTES) .short('c') .long(options::BYTES) - .help("print the byte counts") + .help(get_message("wc-help-bytes")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::CHAR) .short('m') .long(options::CHAR) - .help("print the character counts") + .help(get_message("wc-help-chars")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::FILES0_FROM) .long(options::FILES0_FROM) .value_name("F") - .help(concat!( - "read input from the files specified by\n", - " NUL-terminated names in file F;\n", - " If F is - then read names from standard input" - )) + .help(get_message("wc-help-files0-from")) .value_parser(ValueParser::os_string()) .value_hint(clap::ValueHint::FilePath), ) @@ -429,14 +426,14 @@ pub fn uu_app() -> Command { Arg::new(options::LINES) .short('l') .long(options::LINES) - .help("print the newline counts") + .help(get_message("wc-help-lines")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::MAX_LINE_LENGTH) .short('L') .long(options::MAX_LINE_LENGTH) - .help("print the length of the longest line") + .help(get_message("wc-help-max-line-length")) .action(ArgAction::SetTrue), ) .arg( @@ -447,16 +444,13 @@ pub fn uu_app() -> Command { ])) .value_name("WHEN") .hide_possible_values(true) - .help(concat!( - "when to print a line with total counts;\n", - " WHEN can be: auto, always, only, never" - )), + .help(get_message("wc-help-total")), ) .arg( Arg::new(options::WORDS) .short('w') .long(options::WORDS) - .help("print the word counts") + .help(get_message("wc-help-words")) .action(ArgAction::SetTrue), ) .arg( @@ -761,11 +755,14 @@ fn files0_iter_file<'a>(path: &Path) -> UResult Ok(files0_iter(f, path.into())), Err(e) => Err(e.map_err_context(|| { - format!( - "cannot open {} for reading", - quoting_style::escape_name(path.as_os_str(), QS_QUOTE_ESCAPE) - .into_string() - .expect("All escaped names with the escaping option return valid strings.") + get_message_with_args( + "wc-error-cannot-open-for-reading", + HashMap::from([( + "path".to_string(), + quoting_style::escape_name(path.as_os_str(), QS_QUOTE_ESCAPE) + .into_string() + .expect("All escaped names with the escaping option return valid strings."), + )]), ) })), } @@ -796,9 +793,12 @@ fn files0_iter<'a>( Ok(Input::Path(PathBuf::from(s).into())) } } - Err(e) => Err(e - .map_err_context(|| format!("{}: read error", escape_name_wrapper(&err_path))) - as Box), + Err(e) => Err(e.map_err_context(|| { + get_message_with_args( + "wc-error-read-error", + HashMap::from([("path".to_string(), escape_name_wrapper(&err_path))]), + ) + }) as Box), }), ); // Loop until there is an error; yield that error and then nothing else. @@ -854,18 +854,19 @@ fn wc(inputs: &Inputs, settings: &Settings) -> UResult<()> { let maybe_title_str = maybe_title.as_deref(); if let Err(err) = print_stats(settings, &word_count, maybe_title_str, number_width) { let title = maybe_title_str.unwrap_or(OsStr::new("")); - show!(err.map_err_context(|| format!( - "failed to print result for {}", - title.to_string_lossy() + show!(err.map_err_context(|| get_message_with_args( + "wc-error-failed-to-print-result", + HashMap::from([("title".to_string(), title.to_string_lossy().to_string())]) ))); } } } if settings.total_when.is_total_row_visible(num_inputs) { - let title = are_stats_visible.then_some(OsStr::new("total")); + let wc_total_msg = get_message("wc-total"); + let title = are_stats_visible.then_some(OsStr::new(&wc_total_msg)); if let Err(err) = print_stats(settings, &total_word_count, title, number_width) { - show!(err.map_err_context(|| "failed to print total".into())); + show!(err.map_err_context(|| get_message("wc-error-failed-to-print-total"))); } }