1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #8252 from sylvestre/l10n-od

l10n: port od for translation + add french
This commit is contained in:
Daniel Hofstetter 2025-06-25 10:08:50 +02:00 committed by GitHub
commit 2ea3786bbc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 222 additions and 53 deletions

View file

@ -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 If an error occurred, a diagnostic message will be printed to stderr, and the
exit code will be non-zero. 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.

View file

@ -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.

View file

@ -25,6 +25,7 @@ mod prn_float;
mod prn_int; mod prn_int;
use std::cmp; use std::cmp;
use std::collections::HashMap;
use std::fmt::Write; use std::fmt::Write;
use std::io::BufReader; use std::io::BufReader;
@ -44,7 +45,7 @@ use clap::ArgAction;
use clap::{Arg, ArgMatches, Command, parser::ValueSource}; use clap::{Arg, ArgMatches, Command, parser::ValueSource};
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError}; 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::parse_size::ParseSizeError;
use uucore::parser::shortcut_value_parser::ShortcutValueParser; use uucore::parser::shortcut_value_parser::ShortcutValueParser;
use uucore::{format_usage, show_error, show_warning}; use uucore::{format_usage, show_error, show_warning};
@ -86,7 +87,10 @@ impl OdOptions {
_ => { _ => {
return Err(USimpleError::new( return Err(USimpleError::new(
1, 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<u64> = None; let mut label: Option<u64> = None;
let parsed_input = parse_inputs(matches) let parsed_input = parse_inputs(matches).map_err(|e| {
.map_err(|e| USimpleError::new(1, format!("Invalid inputs: {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 { let input_strings = match parsed_input {
CommandLineInputs::FileNames(v) => v, CommandLineInputs::FileNames(v) => v,
CommandLineInputs::FileAndOffset((f, s, l)) => { CommandLineInputs::FileAndOffset((f, s, l)) => {
@ -146,7 +157,16 @@ impl OdOptions {
cmp::max(max, next.formatter_item_info.byte_size) cmp::max(max, next.formatter_item_info.byte_size)
}); });
if line_bytes == 0 || line_bytes % min_bytes != 0 { 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; line_bytes = min_bytes;
} }
@ -183,16 +203,16 @@ impl OdOptions {
_ => { _ => {
return Err(USimpleError::new( return Err(USimpleError::new(
1, 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 { } else {
// Return an error instead of panicking when `od -A ''` is executed. // Return an error instead of panicking when `od -A ''` is executed.
return Err(USimpleError::new( return Err(USimpleError::new(1, get_message("od-error-radix-empty")));
1,
"Radix cannot be empty, and must be one of [o, d, x, n]".to_string(),
));
} }
} }
}; };
@ -261,34 +281,34 @@ pub fn uu_app() -> Command {
.arg( .arg(
Arg::new(options::HELP) Arg::new(options::HELP)
.long(options::HELP) .long(options::HELP)
.help("Print help information.") .help(get_message("od-help-help"))
.action(ArgAction::Help) .action(ArgAction::Help)
) )
.arg( .arg(
Arg::new(options::ADDRESS_RADIX) Arg::new(options::ADDRESS_RADIX)
.short('A') .short('A')
.long(options::ADDRESS_RADIX) .long(options::ADDRESS_RADIX)
.help("Select the base in which file offsets are printed.") .help(get_message("od-help-address-radix"))
.value_name("RADIX"), .value_name("RADIX"),
) )
.arg( .arg(
Arg::new(options::SKIP_BYTES) Arg::new(options::SKIP_BYTES)
.short('j') .short('j')
.long(options::SKIP_BYTES) .long(options::SKIP_BYTES)
.help("Skip bytes input bytes before formatting and writing.") .help(get_message("od-help-skip-bytes"))
.value_name("BYTES"), .value_name("BYTES"),
) )
.arg( .arg(
Arg::new(options::READ_BYTES) Arg::new(options::READ_BYTES)
.short('N') .short('N')
.long(options::READ_BYTES) .long(options::READ_BYTES)
.help("limit dump to BYTES input bytes") .help(get_message("od-help-read-bytes"))
.value_name("BYTES"), .value_name("BYTES"),
) )
.arg( .arg(
Arg::new(options::ENDIAN) Arg::new(options::ENDIAN)
.long(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_parser(ShortcutValueParser::new(["big", "little"]))
.value_name("big|little"), .value_name("big|little"),
) )
@ -306,31 +326,31 @@ pub fn uu_app() -> Command {
.arg( .arg(
Arg::new("a") Arg::new("a")
.short('a') .short('a')
.help("named characters, ignoring high-order bit") .help(get_message("od-help-a"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
Arg::new("b") Arg::new("b")
.short('b') .short('b')
.help("octal bytes") .help(get_message("od-help-b"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
Arg::new("c") Arg::new("c")
.short('c') .short('c')
.help("ASCII characters or backslash escapes") .help(get_message("od-help-c"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
Arg::new("d") Arg::new("d")
.short('d') .short('d')
.help("unsigned decimal 2-byte units") .help(get_message("od-help-d"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
Arg::new("D") Arg::new("D")
.short('D') .short('D')
.help("unsigned decimal 4-byte units") .help(get_message("od-help-D"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
@ -421,7 +441,7 @@ pub fn uu_app() -> Command {
Arg::new(options::FORMAT) Arg::new(options::FORMAT)
.short('t') .short('t')
.long("format") .long("format")
.help("select output format or formats") .help(get_message("od-help-format"))
.action(ArgAction::Append) .action(ArgAction::Append)
.num_args(1) .num_args(1)
.value_name("TYPE"), .value_name("TYPE"),
@ -430,17 +450,14 @@ pub fn uu_app() -> Command {
Arg::new(options::OUTPUT_DUPLICATES) Arg::new(options::OUTPUT_DUPLICATES)
.short('v') .short('v')
.long(options::OUTPUT_DUPLICATES) .long(options::OUTPUT_DUPLICATES)
.help("do not use * to mark line suppression") .help(get_message("od-help-output-duplicates"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
Arg::new(options::WIDTH) Arg::new(options::WIDTH)
.short('w') .short('w')
.long(options::WIDTH) .long(options::WIDTH)
.help( .help(get_message("od-help-width"))
"output BYTES bytes per output line. 32 is implied when BYTES is not \
specified.",
)
.default_missing_value("32") .default_missing_value("32")
.value_name("BYTES") .value_name("BYTES")
.num_args(..=1), .num_args(..=1),
@ -448,7 +465,7 @@ pub fn uu_app() -> Command {
.arg( .arg(
Arg::new(options::TRADITIONAL) Arg::new(options::TRADITIONAL)
.long(options::TRADITIONAL) .long(options::TRADITIONAL)
.help("compatibility mode with one input, offset and label.") .help(get_message("od-help-traditional"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
@ -631,12 +648,26 @@ fn format_error_message(error: &ParseSizeError, s: &str, option: &str) -> String
// NOTE: // NOTE:
// GNU's od echos affected flag, -N or --read-bytes (-j or --skip-bytes, etc.), depending user's selection // GNU's od echos affected flag, -N or --read-bytes (-j or --skip-bytes, etc.), depending user's selection
match error { match error {
ParseSizeError::InvalidSuffix(_) => { ParseSizeError::InvalidSuffix(_) => get_message_with_args(
format!("invalid suffix in --{option} argument {}", s.quote()) "od-error-invalid-suffix",
} HashMap::from([
ParseSizeError::ParseFailure(_) | ParseSizeError::PhysicalMem(_) => { ("option".to_string(), option.to_string()),
format!("invalid --{option} argument {}", s.quote()) ("value".to_string(), s.quote().to_string()),
} ]),
ParseSizeError::SizeTooBig(_) => format!("--{option} argument {} too large", s.quote()), ),
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()),
]),
),
} }
} }

View file

@ -4,7 +4,9 @@
// file that was distributed with this source code. // file that was distributed with this source code.
// spell-checker:ignore formatteriteminfo docopt fvox fvoxw vals acdx // spell-checker:ignore formatteriteminfo docopt fvox fvoxw vals acdx
use std::collections::HashMap;
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::locale::{get_message, get_message_with_args};
use crate::formatteriteminfo::FormatterItemInfo; use crate::formatteriteminfo::FormatterItemInfo;
use crate::prn_char::*; use crate::prn_char::*;
@ -150,7 +152,7 @@ pub fn parse_format_flags(args: &[String]) -> Result<Vec<ParsedFormatterItemInfo
} }
} }
if expect_type_string { if expect_type_string {
return Err("missing format specification after '--format' / '-t'".to_string()); return Err(get_message("od-error-missing-format-spec"));
} }
if formats.is_empty() { if formats.is_empty() {
@ -273,9 +275,12 @@ fn parse_type_string(params: &str) -> Result<Vec<ParsedFormatterItemInfo>, Strin
while let Some(type_char) = ch { while let Some(type_char) = ch {
let type_char = format_type(type_char).ok_or_else(|| { let type_char = format_type(type_char).ok_or_else(|| {
format!( get_message_with_args(
"unexpected char '{type_char}' in format specification {}", "od-error-unexpected-char",
params.quote() 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<Vec<ParsedFormatterItemInfo>, Strin
} }
if !decimal_size.is_empty() { if !decimal_size.is_empty() {
byte_size = decimal_size.parse().map_err(|_| { byte_size = decimal_size.parse().map_err(|_| {
format!( get_message_with_args(
"invalid number {} in format specification {}", "od-error-invalid-number",
decimal_size.quote(), HashMap::from([
params.quote() ("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<Vec<ParsedFormatterItemInfo>, Strin
} }
let ft = od_format_type(type_char, byte_size).ok_or_else(|| { let ft = od_format_type(type_char, byte_size).ok_or_else(|| {
format!( get_message_with_args(
"invalid size '{byte_size}' in format specification {}", "od-error-invalid-size",
params.quote() HashMap::from([
("size".to_string(), byte_size.to_string()),
("spec".to_string(), params.quote().to_string()),
]),
) )
})?; })?;
formats.push(ParsedFormatterItemInfo::new(ft, show_ascii_dump)); formats.push(ParsedFormatterItemInfo::new(ft, show_ascii_dump));

View file

@ -4,6 +4,8 @@
// file that was distributed with this source code. // file that was distributed with this source code.
use super::options; use super::options;
use clap::ArgMatches; use clap::ArgMatches;
use std::collections::HashMap;
use uucore::locale::{get_message, get_message_with_args};
/// Abstraction for getopts /// Abstraction for getopts
pub trait CommandLineOpts { pub trait CommandLineOpts {
@ -122,7 +124,10 @@ pub fn parse_inputs_traditional(input_strings: &[&str]) -> Result<CommandLineInp
m, m,
None, None,
))), ))),
_ => 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 => { 3 => {
@ -134,13 +139,19 @@ pub fn parse_inputs_traditional(input_strings: &[&str]) -> Result<CommandLineInp
n, n,
Some(m), Some(m),
))), ))),
(Err(_), _) => Err(format!("invalid offset: {}", input_strings[1])), (Err(_), _) => Err(get_message_with_args(
(_, Err(_)) => Err(format!("invalid label: {}", input_strings[2])), "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!( _ => Err(get_message_with_args(
"too many inputs after --traditional: {}", "od-error-too-many-inputs",
input_strings[3] HashMap::from([("input".to_string(), input_strings[3].to_string())]),
)), )),
} }
} }
@ -171,7 +182,7 @@ pub fn parse_offset_operand(s: &str) -> Result<u64, &'static str> {
} }
match u64::from_str_radix(&s[start..len], radix) { match u64::from_str_radix(&s[start..len], radix) {
Ok(i) => Ok(i * multiply), Ok(i) => Ok(i * multiply),
Err(_) => Err("parse failed"), Err(_) => Err(get_message("od-error-parse-failed").leak()),
} }
} }

View file

@ -9,6 +9,7 @@ use std::io;
use std::io::Read; use std::io::Read;
use crate::multifilereader::HasError; use crate::multifilereader::HasError;
use uucore::locale::get_message;
/// When a large number of bytes must be skipped, it will be read into a /// 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. /// dynamically allocated buffer. The buffer will be limited to this size.
@ -45,7 +46,7 @@ impl<R: Read> Read for PartialReader<R> {
// this is an error as we still have more to skip // this is an error as we still have more to skip
return Err(io::Error::new( return Err(io::Error::new(
io::ErrorKind::UnexpectedEof, io::ErrorKind::UnexpectedEof,
"tried to skip past end of input", get_message("od-error-skip-past-end"),
)); ));
} }
n => self.skip -= n as u64, n => self.skip -= n as u64,