diff --git a/src/uu/od/locales/en-US.ftl b/src/uu/od/locales/en-US.ftl index d451b30915e..03a9cfd6d8e 100644 --- a/src/uu/od/locales/en-US.ftl +++ b/src/uu/od/locales/en-US.ftl @@ -39,3 +39,40 @@ od-after-help = Displays data in various human-readable formats. If multiple for If an error occurred, a diagnostic message will be printed to stderr, and the exit code will be non-zero. + +# Error messages +od-error-invalid-endian = Invalid argument --endian={$endian} +od-error-invalid-inputs = Invalid inputs: {$msg} +od-error-too-large = value is too large +od-error-radix-invalid = Radix must be one of [o, d, x, n], got: {$radix} +od-error-radix-empty = Radix cannot be empty, and must be one of [o, d, x, n] +od-error-invalid-width = invalid width {$width}; using {$min} instead +od-error-missing-format-spec = missing format specification after '--format' / '-t' +od-error-unexpected-char = unexpected char '{$char}' in format specification {$spec} +od-error-invalid-number = invalid number {$number} in format specification {$spec} +od-error-invalid-size = invalid size '{$size}' in format specification {$spec} +od-error-invalid-offset = invalid offset: {$offset} +od-error-invalid-label = invalid label: {$label} +od-error-too-many-inputs = too many inputs after --traditional: {$input} +od-error-parse-failed = parse failed +od-error-invalid-suffix = invalid suffix in --{$option} argument {$value} +od-error-invalid-argument = invalid --{$option} argument {$value} +od-error-argument-too-large = --{$option} argument {$value} too large +od-error-skip-past-end = tried to skip past end of input + +# Help messages +od-help-help = Print help information. +od-help-address-radix = Select the base in which file offsets are printed. +od-help-skip-bytes = Skip bytes input bytes before formatting and writing. +od-help-read-bytes = limit dump to BYTES input bytes +od-help-endian = byte order to use for multi-byte formats +od-help-a = named characters, ignoring high-order bit +od-help-b = octal bytes +od-help-c = ASCII characters or backslash escapes +od-help-d = unsigned decimal 2-byte units +od-help-D = unsigned decimal 4-byte units +od-help-format = select output format or formats +od-help-output-duplicates = do not use * to mark line suppression +od-help-width = output BYTES bytes per output line. 32 is implied when BYTES is not + specified. +od-help-traditional = compatibility mode with one input, offset and label. diff --git a/src/uu/od/locales/fr-FR.ftl b/src/uu/od/locales/fr-FR.ftl new file mode 100644 index 00000000000..4e110254866 --- /dev/null +++ b/src/uu/od/locales/fr-FR.ftl @@ -0,0 +1,79 @@ +od-about = Afficher les fichiers en format octal et autres formats +od-usage = od [OPTION]... [--] [NOMFICHIER]... + od [-abcdDefFhHiIlLoOsxX] [NOMFICHIER] [[+][0x]DÉCALAGE[.][b]] + od --traditional [OPTION]... [NOMFICHIER] [[+][0x]DÉCALAGE[.][b] [[+][0x]ÉTIQUETTE[.][b]]] +od-after-help = Affiche les données dans divers formats lisibles par l'homme. Si plusieurs + formats sont spécifiés, la sortie contiendra tous les formats dans l'ordre où ils + apparaissent sur la ligne de commande. Chaque format sera imprimé sur une nouvelle + ligne. Seule la ligne contenant le premier format sera préfixée avec le décalage. + + Si aucun nom de fichier n'est spécifié, ou si c'est "-", stdin sera utilisé. Après + un "--", aucune autre option ne sera reconnue. Cela permet d'avoir des noms de + fichiers commençant par "-". + + Si un nom de fichier est un nombre valide qui peut être utilisé comme décalage dans + la deuxième forme, vous pouvez le forcer à être reconnu comme un nom de fichier si + vous incluez une option comme "-j0", qui n'est valide que dans la première forme. + + RADIX est l'un de o,d,x,n pour octal, décimal, hexadécimal ou aucun. + + OCTETS est décimal par défaut, octal si préfixé par "0", ou hexadécimal si préfixé + par "0x". Les suffixes b, KB, K, MB, M, GB, G multiplieront le nombre par 512, + 1000, 1024, 1000^2, 1024^2, 1000^3, 1024^3, 1000^2, 1024^2. + + DÉCALAGE et ÉTIQUETTE sont octaux par défaut, hexadécimaux si préfixés par "0x" ou + décimaux si un suffixe "." est ajouté. Le suffixe "b" multipliera par 512. + + TYPE contient une ou plusieurs spécifications de format constituées de : + a pour ASCII imprimable 7-bits + c pour caractères utf-8 ou octal pour caractères non définis + d[TAILLE] pour décimal signé + f[TAILLE] pour virgule flottante + o[TAILLE] pour octal + u[TAILLE] pour décimal non signé + x[TAILLE] pour hexadécimal + TAILLE est le nombre d'octets qui peut être le nombre 1, 2, 4, 8 ou 16, + ou C, I, S, L pour 1, 2, 4, 8 octets pour les types entiers, + ou F, D, L pour 4, 8, 16 octets pour les virgules flottantes. + Toute spécification de type peut avoir un suffixe "z", qui ajoutera un dump ASCII + à la fin de la ligne. + + Si une erreur s'est produite, un message de diagnostic sera imprimé sur stderr, et + le code de sortie sera non-zéro. + +# Messages d'erreur +od-error-invalid-endian = Argument invalide --endian={$endian} +od-error-invalid-inputs = Entrées invalides : {$msg} +od-error-too-large = la valeur est trop grande +od-error-radix-invalid = Radix doit être l'un de [o, d, x, n], reçu : {$radix} +od-error-radix-empty = Radix ne peut pas être vide, et doit être l'un de [o, d, x, n] +od-error-invalid-width = largeur invalide {$width} ; utilisation de {$min} à la place +od-error-missing-format-spec = spécification de format manquante après '--format' / '-t' +od-error-unexpected-char = caractère inattendu '{$char}' dans la spécification de format {$spec} +od-error-invalid-number = nombre invalide {$number} dans la spécification de format {$spec} +od-error-invalid-size = taille invalide '{$size}' dans la spécification de format {$spec} +od-error-invalid-offset = décalage invalide : {$offset} +od-error-invalid-label = étiquette invalide : {$label} +od-error-too-many-inputs = trop d'entrées après --traditional : {$input} +od-error-parse-failed = échec de l'analyse +od-error-invalid-suffix = suffixe invalide dans l'argument --{$option} {$value} +od-error-invalid-argument = argument --{$option} invalide {$value} +od-error-argument-too-large = argument --{$option} {$value} trop grand +od-error-skip-past-end = tentative d'ignorer au-delà de la fin de l'entrée + +# Messages d'aide +od-help-help = Afficher les informations d'aide. +od-help-address-radix = Sélectionner la base dans laquelle les décalages de fichier sont imprimés. +od-help-skip-bytes = Ignorer les octets d'entrée avant le formatage et l'écriture. +od-help-read-bytes = limiter le dump à OCTETS octets d'entrée +od-help-endian = ordre des octets à utiliser pour les formats multi-octets +od-help-a = caractères nommés, ignorant le bit d'ordre supérieur +od-help-b = octets octaux +od-help-c = caractères ASCII ou échappements antislash +od-help-d = unités décimales non signées 2-octets +od-help-D = unités décimales non signées 4-octets +od-help-format = sélectionner le(s) format(s) de sortie +od-help-output-duplicates = ne pas utiliser * pour marquer la suppression de ligne +od-help-width = sortir OCTETS octets par ligne de sortie. 32 est impliqué quand OCTETS n'est pas + spécifié. +od-help-traditional = mode de compatibilité avec une entrée, décalage et étiquette. diff --git a/src/uu/od/src/od.rs b/src/uu/od/src/od.rs index a84adece255..4dc4fb2e5b5 100644 --- a/src/uu/od/src/od.rs +++ b/src/uu/od/src/od.rs @@ -25,6 +25,7 @@ mod prn_float; mod prn_int; use std::cmp; +use std::collections::HashMap; use std::fmt::Write; use std::io::BufReader; @@ -44,7 +45,7 @@ use clap::ArgAction; use clap::{Arg, ArgMatches, Command, parser::ValueSource}; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError}; -use uucore::locale::get_message; +use uucore::locale::{get_message, get_message_with_args}; use uucore::parser::parse_size::ParseSizeError; use uucore::parser::shortcut_value_parser::ShortcutValueParser; use uucore::{format_usage, show_error, show_warning}; @@ -86,7 +87,10 @@ impl OdOptions { _ => { return Err(USimpleError::new( 1, - format!("Invalid argument --endian={s}"), + get_message_with_args( + "od-error-invalid-endian", + HashMap::from([("endian".to_string(), s.to_string())]), + ), )); } } @@ -109,8 +113,15 @@ impl OdOptions { let mut label: Option = None; - let parsed_input = parse_inputs(matches) - .map_err(|e| USimpleError::new(1, format!("Invalid inputs: {e}")))?; + let parsed_input = parse_inputs(matches).map_err(|e| { + USimpleError::new( + 1, + get_message_with_args( + "od-error-invalid-inputs", + HashMap::from([("msg".to_string(), e.to_string())]), + ), + ) + })?; let input_strings = match parsed_input { CommandLineInputs::FileNames(v) => v, CommandLineInputs::FileAndOffset((f, s, l)) => { @@ -146,7 +157,16 @@ impl OdOptions { cmp::max(max, next.formatter_item_info.byte_size) }); if line_bytes == 0 || line_bytes % min_bytes != 0 { - show_warning!("invalid width {line_bytes}; using {min_bytes} instead"); + show_warning!( + "{}", + get_message_with_args( + "od-error-invalid-width", + HashMap::from([ + ("width".to_string(), line_bytes.to_string()), + ("min".to_string(), min_bytes.to_string()) + ]) + ) + ); line_bytes = min_bytes; } @@ -183,16 +203,16 @@ impl OdOptions { _ => { return Err(USimpleError::new( 1, - "Radix must be one of [o, d, x, n]".to_string(), + get_message_with_args( + "od-error-radix-invalid", + HashMap::from([("radix".to_string(), s.to_string())]), + ), )); } } } else { // Return an error instead of panicking when `od -A ''` is executed. - return Err(USimpleError::new( - 1, - "Radix cannot be empty, and must be one of [o, d, x, n]".to_string(), - )); + return Err(USimpleError::new(1, get_message("od-error-radix-empty"))); } } }; @@ -261,34 +281,34 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::HELP) .long(options::HELP) - .help("Print help information.") + .help(get_message("od-help-help")) .action(ArgAction::Help) ) .arg( Arg::new(options::ADDRESS_RADIX) .short('A') .long(options::ADDRESS_RADIX) - .help("Select the base in which file offsets are printed.") + .help(get_message("od-help-address-radix")) .value_name("RADIX"), ) .arg( Arg::new(options::SKIP_BYTES) .short('j') .long(options::SKIP_BYTES) - .help("Skip bytes input bytes before formatting and writing.") + .help(get_message("od-help-skip-bytes")) .value_name("BYTES"), ) .arg( Arg::new(options::READ_BYTES) .short('N') .long(options::READ_BYTES) - .help("limit dump to BYTES input bytes") + .help(get_message("od-help-read-bytes")) .value_name("BYTES"), ) .arg( Arg::new(options::ENDIAN) .long(options::ENDIAN) - .help("byte order to use for multi-byte formats") + .help(get_message("od-help-endian")) .value_parser(ShortcutValueParser::new(["big", "little"])) .value_name("big|little"), ) @@ -306,31 +326,31 @@ pub fn uu_app() -> Command { .arg( Arg::new("a") .short('a') - .help("named characters, ignoring high-order bit") + .help(get_message("od-help-a")) .action(ArgAction::SetTrue), ) .arg( Arg::new("b") .short('b') - .help("octal bytes") + .help(get_message("od-help-b")) .action(ArgAction::SetTrue), ) .arg( Arg::new("c") .short('c') - .help("ASCII characters or backslash escapes") + .help(get_message("od-help-c")) .action(ArgAction::SetTrue), ) .arg( Arg::new("d") .short('d') - .help("unsigned decimal 2-byte units") + .help(get_message("od-help-d")) .action(ArgAction::SetTrue), ) .arg( Arg::new("D") .short('D') - .help("unsigned decimal 4-byte units") + .help(get_message("od-help-D")) .action(ArgAction::SetTrue), ) .arg( @@ -421,7 +441,7 @@ pub fn uu_app() -> Command { Arg::new(options::FORMAT) .short('t') .long("format") - .help("select output format or formats") + .help(get_message("od-help-format")) .action(ArgAction::Append) .num_args(1) .value_name("TYPE"), @@ -430,17 +450,14 @@ pub fn uu_app() -> Command { Arg::new(options::OUTPUT_DUPLICATES) .short('v') .long(options::OUTPUT_DUPLICATES) - .help("do not use * to mark line suppression") + .help(get_message("od-help-output-duplicates")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::WIDTH) .short('w') .long(options::WIDTH) - .help( - "output BYTES bytes per output line. 32 is implied when BYTES is not \ - specified.", - ) + .help(get_message("od-help-width")) .default_missing_value("32") .value_name("BYTES") .num_args(..=1), @@ -448,7 +465,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::TRADITIONAL) .long(options::TRADITIONAL) - .help("compatibility mode with one input, offset and label.") + .help(get_message("od-help-traditional")) .action(ArgAction::SetTrue), ) .arg( @@ -631,12 +648,26 @@ fn format_error_message(error: &ParseSizeError, s: &str, option: &str) -> String // NOTE: // GNU's od echos affected flag, -N or --read-bytes (-j or --skip-bytes, etc.), depending user's selection match error { - ParseSizeError::InvalidSuffix(_) => { - format!("invalid suffix in --{option} argument {}", s.quote()) - } - ParseSizeError::ParseFailure(_) | ParseSizeError::PhysicalMem(_) => { - format!("invalid --{option} argument {}", s.quote()) - } - ParseSizeError::SizeTooBig(_) => format!("--{option} argument {} too large", s.quote()), + ParseSizeError::InvalidSuffix(_) => get_message_with_args( + "od-error-invalid-suffix", + HashMap::from([ + ("option".to_string(), option.to_string()), + ("value".to_string(), s.quote().to_string()), + ]), + ), + ParseSizeError::ParseFailure(_) | ParseSizeError::PhysicalMem(_) => get_message_with_args( + "od-error-invalid-argument", + HashMap::from([ + ("option".to_string(), option.to_string()), + ("value".to_string(), s.quote().to_string()), + ]), + ), + ParseSizeError::SizeTooBig(_) => get_message_with_args( + "od-error-argument-too-large", + HashMap::from([ + ("option".to_string(), option.to_string()), + ("value".to_string(), s.quote().to_string()), + ]), + ), } } diff --git a/src/uu/od/src/parse_formats.rs b/src/uu/od/src/parse_formats.rs index 86f32a25a4a..26b5b7173db 100644 --- a/src/uu/od/src/parse_formats.rs +++ b/src/uu/od/src/parse_formats.rs @@ -4,7 +4,9 @@ // file that was distributed with this source code. // spell-checker:ignore formatteriteminfo docopt fvox fvoxw vals acdx +use std::collections::HashMap; use uucore::display::Quotable; +use uucore::locale::{get_message, get_message_with_args}; use crate::formatteriteminfo::FormatterItemInfo; use crate::prn_char::*; @@ -150,7 +152,7 @@ pub fn parse_format_flags(args: &[String]) -> Result Result, Strin while let Some(type_char) = ch { let type_char = format_type(type_char).ok_or_else(|| { - format!( - "unexpected char '{type_char}' in format specification {}", - params.quote() + get_message_with_args( + "od-error-unexpected-char", + HashMap::from([ + ("char".to_string(), type_char.to_string()), + ("spec".to_string(), params.quote().to_string()), + ]), ) })?; @@ -294,10 +299,12 @@ fn parse_type_string(params: &str) -> Result, Strin } if !decimal_size.is_empty() { byte_size = decimal_size.parse().map_err(|_| { - format!( - "invalid number {} in format specification {}", - decimal_size.quote(), - params.quote() + get_message_with_args( + "od-error-invalid-number", + HashMap::from([ + ("number".to_string(), decimal_size.quote().to_string()), + ("spec".to_string(), params.quote().to_string()), + ]), ) })?; } @@ -307,9 +314,12 @@ fn parse_type_string(params: &str) -> Result, Strin } let ft = od_format_type(type_char, byte_size).ok_or_else(|| { - format!( - "invalid size '{byte_size}' in format specification {}", - params.quote() + get_message_with_args( + "od-error-invalid-size", + HashMap::from([ + ("size".to_string(), byte_size.to_string()), + ("spec".to_string(), params.quote().to_string()), + ]), ) })?; formats.push(ParsedFormatterItemInfo::new(ft, show_ascii_dump)); diff --git a/src/uu/od/src/parse_inputs.rs b/src/uu/od/src/parse_inputs.rs index 241d842af9f..69ce279b758 100644 --- a/src/uu/od/src/parse_inputs.rs +++ b/src/uu/od/src/parse_inputs.rs @@ -4,6 +4,8 @@ // file that was distributed with this source code. use super::options; use clap::ArgMatches; +use std::collections::HashMap; +use uucore::locale::{get_message, get_message_with_args}; /// Abstraction for getopts pub trait CommandLineOpts { @@ -122,7 +124,10 @@ pub fn parse_inputs_traditional(input_strings: &[&str]) -> Result Err(format!("invalid offset: {}", input_strings[1])), + _ => Err(get_message_with_args( + "od-error-invalid-offset", + HashMap::from([("offset".to_string(), input_strings[1].to_string())]), + )), } } 3 => { @@ -134,13 +139,19 @@ pub fn parse_inputs_traditional(input_strings: &[&str]) -> Result Err(format!("invalid offset: {}", input_strings[1])), - (_, Err(_)) => Err(format!("invalid label: {}", input_strings[2])), + (Err(_), _) => Err(get_message_with_args( + "od-error-invalid-offset", + HashMap::from([("offset".to_string(), input_strings[1].to_string())]), + )), + (_, Err(_)) => Err(get_message_with_args( + "od-error-invalid-label", + HashMap::from([("label".to_string(), input_strings[2].to_string())]), + )), } } - _ => Err(format!( - "too many inputs after --traditional: {}", - input_strings[3] + _ => Err(get_message_with_args( + "od-error-too-many-inputs", + HashMap::from([("input".to_string(), input_strings[3].to_string())]), )), } } @@ -171,7 +182,7 @@ pub fn parse_offset_operand(s: &str) -> Result { } match u64::from_str_radix(&s[start..len], radix) { Ok(i) => Ok(i * multiply), - Err(_) => Err("parse failed"), + Err(_) => Err(get_message("od-error-parse-failed").leak()), } } diff --git a/src/uu/od/src/partialreader.rs b/src/uu/od/src/partialreader.rs index 6825f1ae4b9..95e177c0fff 100644 --- a/src/uu/od/src/partialreader.rs +++ b/src/uu/od/src/partialreader.rs @@ -9,6 +9,7 @@ use std::io; use std::io::Read; use crate::multifilereader::HasError; +use uucore::locale::get_message; /// When a large number of bytes must be skipped, it will be read into a /// dynamically allocated buffer. The buffer will be limited to this size. @@ -45,7 +46,7 @@ impl Read for PartialReader { // this is an error as we still have more to skip return Err(io::Error::new( io::ErrorKind::UnexpectedEof, - "tried to skip past end of input", + get_message("od-error-skip-past-end"), )); } n => self.skip -= n as u64,