From e00167bd6b4b6e99dcb79782aa1618736a12e242 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 29 Jun 2025 18:36:14 +0200 Subject: [PATCH 1/3] l10n: port base32 for translation + add french --- src/uu/base32/locales/en-US.ftl | 11 +++++++++++ src/uu/base32/locales/fr-FR.ftl | 20 +++++++++++++++++++ src/uu/base32/src/base_common.rs | 34 +++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/uu/base32/locales/fr-FR.ftl diff --git a/src/uu/base32/locales/en-US.ftl b/src/uu/base32/locales/en-US.ftl index e3d2beb98..f1c00d31a 100644 --- a/src/uu/base32/locales/en-US.ftl +++ b/src/uu/base32/locales/en-US.ftl @@ -7,3 +7,14 @@ base32-about = encode/decode data and print to standard output to attempt to recover from any other non-alphabet bytes in the encoded stream. base32-usage = base32 [OPTION]... [FILE] + +# Error messages +base32-extra-operand = extra operand {$operand} +base32-no-such-file = {$file}: No such file or directory +base32-invalid-wrap-size = invalid wrap size: {$size} +base32-read-error = read error: {$error} + +# Help messages +base32-help-decode = decode data +base32-help-ignore-garbage = when decoding, ignore non-alphabetic characters +base32-help-wrap = wrap encoded lines after COLS character (default {$default}, 0 to disable wrapping) diff --git a/src/uu/base32/locales/fr-FR.ftl b/src/uu/base32/locales/fr-FR.ftl new file mode 100644 index 000000000..c38a9f153 --- /dev/null +++ b/src/uu/base32/locales/fr-FR.ftl @@ -0,0 +1,20 @@ +base32-about = encoder/décoder les données et les imprimer sur la sortie standard + Sans FICHIER, ou quand FICHIER est -, lire l'entrée standard. + + Les données sont encodées comme décrit pour l'alphabet base32 dans RFC 4648. + Lors du décodage, l'entrée peut contenir des retours à la ligne en plus + des octets de l'alphabet base32 formel. Utilisez --ignore-garbage + pour tenter de récupérer des autres octets non-alphabétiques dans + le flux encodé. +base32-usage = base32 [OPTION]... [FICHIER] + +# Messages d'erreur +base32-extra-operand = opérande supplémentaire {$operand} +base32-no-such-file = {$file} : Aucun fichier ou répertoire de ce type +base32-invalid-wrap-size = taille de retour à la ligne invalide : {$size} +base32-read-error = erreur de lecture : {$error} + +# Messages d'aide +base32-help-decode = décoder les données +base32-help-ignore-garbage = lors du décodage, ignorer les caractères non-alphabétiques +base32-help-wrap = retour à la ligne des lignes encodées après COLS caractères (par défaut {$default}, 0 pour désactiver le retour à la ligne) diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index 05bfc89b2..5229b5155 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -6,6 +6,7 @@ // spell-checker:ignore hexupper lsbf msbf unpadded nopad aGVsbG8sIHdvcmxkIQ use clap::{Arg, ArgAction, Command}; +use std::collections::HashMap; use std::fs::File; use std::io::{self, ErrorKind, Read, Seek, SeekFrom}; use std::path::{Path, PathBuf}; @@ -17,6 +18,7 @@ use uucore::encoding::{ use uucore::encoding::{EncodingWrapper, SupportsFastDecodeAndEncode}; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::format_usage; +use uucore::locale::{get_message, get_message_with_args}; pub const BASE_CMD_PARSE_ERROR: i32 = 1; @@ -50,7 +52,10 @@ impl Config { if let Some(extra_op) = values.next() { return Err(UUsageError::new( BASE_CMD_PARSE_ERROR, - format!("extra operand {}", extra_op.quote()), + get_message_with_args( + "base32-extra-operand", + HashMap::from([("operand".to_string(), extra_op.quote().to_string())]), + ), )); } @@ -62,7 +67,13 @@ impl Config { if !path.exists() { return Err(USimpleError::new( BASE_CMD_PARSE_ERROR, - format!("{}: No such file or directory", path.maybe_quote()), + get_message_with_args( + "base32-no-such-file", + HashMap::from([( + "file".to_string(), + path.maybe_quote().to_string(), + )]), + ), )); } @@ -78,7 +89,10 @@ impl Config { num.parse::().map_err(|_| { USimpleError::new( BASE_CMD_PARSE_ERROR, - format!("invalid wrap size: {}", num.quote()), + get_message_with_args( + "base32-invalid-wrap-size", + HashMap::from([("size".to_string(), num.quote().to_string())]), + ), ) }) }) @@ -114,7 +128,7 @@ pub fn base_app(about: &'static str, usage: &str) -> Command { .short('d') .visible_short_alias('D') .long(options::DECODE) - .help("decode data") + .help(get_message("base32-help-decode")) .action(ArgAction::SetTrue) .overrides_with(options::DECODE), ) @@ -122,7 +136,7 @@ pub fn base_app(about: &'static str, usage: &str) -> Command { Arg::new(options::IGNORE_GARBAGE) .short('i') .long(options::IGNORE_GARBAGE) - .help("when decoding, ignore non-alphabetic characters") + .help(get_message("base32-help-ignore-garbage")) .action(ArgAction::SetTrue) .overrides_with(options::IGNORE_GARBAGE), ) @@ -131,7 +145,10 @@ pub fn base_app(about: &'static str, usage: &str) -> Command { .short('w') .long(options::WRAP) .value_name("COLS") - .help(format!("wrap encoded lines after COLS character (default {WRAP_DEFAULT}, 0 to disable wrapping)")) + .help(get_message_with_args( + "base32-help-wrap", + HashMap::from([("default".to_string(), WRAP_DEFAULT.to_string())]), + )) .overrides_with(options::WRAP), ) // "multiple" arguments are used to check whether there is more than one @@ -813,7 +830,10 @@ fn format_read_error(kind: ErrorKind) -> String { } } - format!("read error: {kind_string_capitalized}") + get_message_with_args( + "base32-read-error", + HashMap::from([("error".to_string(), kind_string_capitalized)]), + ) } #[cfg(test)] From f12111b7a2c0dee42af4f195001150fac93d4425 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 29 Jun 2025 19:52:34 +0200 Subject: [PATCH 2/3] base*: create a common locale directory with symlinks --- src/uu/base32/locales/en-US.ftl | 56 +++++++++++++++++++++++++++----- src/uu/base32/locales/fr-FR.ftl | 51 ++++++++++++++++++++++++----- src/uu/base32/src/base_common.rs | 14 ++++---- src/uu/base64/locales/en-US.ftl | 9 ----- src/uu/basenc/locales/en-US.ftl | 22 ------------- src/uu/basenc/locales/fr-FR.ftl | 22 ------------- tests/by-util/test_base64.rs | 4 +++ 7 files changed, 100 insertions(+), 78 deletions(-) delete mode 100644 src/uu/base64/locales/en-US.ftl delete mode 100644 src/uu/basenc/locales/en-US.ftl delete mode 100644 src/uu/basenc/locales/fr-FR.ftl diff --git a/src/uu/base32/locales/en-US.ftl b/src/uu/base32/locales/en-US.ftl index f1c00d31a..c083d8928 100644 --- a/src/uu/base32/locales/en-US.ftl +++ b/src/uu/base32/locales/en-US.ftl @@ -1,3 +1,8 @@ +# This file contains base32, base64 and basenc strings +# This is because we have some common strings for all these tools +# and it is easier to have a single file than one file for program +# and loading several bundles at the same time. + base32-about = encode/decode data and print to standard output With no FILE, or when FILE is -, read standard input. @@ -8,13 +13,46 @@ base32-about = encode/decode data and print to standard output encoded stream. base32-usage = base32 [OPTION]... [FILE] -# Error messages -base32-extra-operand = extra operand {$operand} -base32-no-such-file = {$file}: No such file or directory -base32-invalid-wrap-size = invalid wrap size: {$size} -base32-read-error = read error: {$error} +base64-about = encode/decode data and print to standard output + With no FILE, or when FILE is -, read standard input. -# Help messages -base32-help-decode = decode data -base32-help-ignore-garbage = when decoding, ignore non-alphabetic characters -base32-help-wrap = wrap encoded lines after COLS character (default {$default}, 0 to disable wrapping) + The data are encoded as described for the base64 alphabet in RFC 3548. + When decoding, the input may contain newlines in addition + to the bytes of the formal base64 alphabet. Use --ignore-garbage + to attempt to recover from any other non-alphabet bytes in the + encoded stream. +base64-usage = base64 [OPTION]... [FILE] + +basenc-about = Encode/decode data and print to standard output + With no FILE, or when FILE is -, read standard input. + + When decoding, the input may contain newlines in addition to the bytes of + the formal alphabet. Use --ignore-garbage to attempt to recover + from any other non-alphabet bytes in the encoded stream. +basenc-usage = basenc [OPTION]... [FILE] + +# Help messages for encoding formats +basenc-help-base64 = same as 'base64' program +basenc-help-base64url = file- and url-safe base64 +basenc-help-base32 = same as 'base32' program +basenc-help-base32hex = extended hex alphabet base32 +basenc-help-base16 = hex encoding +basenc-help-base2lsbf = bit string with least significant bit (lsb) first +basenc-help-base2msbf = bit string with most significant bit (msb) first +basenc-help-z85 = ascii85-like encoding; + when encoding, input length must be a multiple of 4; + when decoding, input length must be a multiple of 5 + +# Error messages +basenc-error-missing-encoding-type = missing encoding type + +# Shared base_common error messages (used by base32, base64, basenc) +base-common-extra-operand = extra operand {$operand} +base-common-no-such-file = {$file}: No such file or directory +base-common-invalid-wrap-size = invalid wrap size: {$size} +base-common-read-error = read error: {$error} + +# Shared base_common help messages +base-common-help-decode = decode data +base-common-help-ignore-garbage = when decoding, ignore non-alphabetic characters +base-common-help-wrap = wrap encoded lines after COLS character (default {$default}, 0 to disable wrapping) diff --git a/src/uu/base32/locales/fr-FR.ftl b/src/uu/base32/locales/fr-FR.ftl index c38a9f153..98c554bfb 100644 --- a/src/uu/base32/locales/fr-FR.ftl +++ b/src/uu/base32/locales/fr-FR.ftl @@ -8,13 +8,46 @@ base32-about = encoder/décoder les données et les imprimer sur la sortie stand le flux encodé. base32-usage = base32 [OPTION]... [FICHIER] -# Messages d'erreur -base32-extra-operand = opérande supplémentaire {$operand} -base32-no-such-file = {$file} : Aucun fichier ou répertoire de ce type -base32-invalid-wrap-size = taille de retour à la ligne invalide : {$size} -base32-read-error = erreur de lecture : {$error} +base64-about = encoder/décoder les données et les imprimer sur la sortie standard + Sans FICHIER, ou quand FICHIER est -, lire l'entrée standard. -# Messages d'aide -base32-help-decode = décoder les données -base32-help-ignore-garbage = lors du décodage, ignorer les caractères non-alphabétiques -base32-help-wrap = retour à la ligne des lignes encodées après COLS caractères (par défaut {$default}, 0 pour désactiver le retour à la ligne) + Les données sont encodées comme décrit pour l'alphabet base64 dans RFC 3548. + Lors du décodage, l'entrée peut contenir des retours à la ligne en plus + des octets de l'alphabet base64 formel. Utilisez --ignore-garbage + pour tenter de récupérer des autres octets non-alphabétiques dans + le flux encodé. +base64-usage = base64 [OPTION]... [FICHIER] + +basenc-about = Encoder/décoder des données et afficher vers la sortie standard + Sans FICHIER, ou lorsque FICHIER est -, lire l'entrée standard. + + Lors du décodage, l'entrée peut contenir des nouvelles lignes en plus des octets de + l'alphabet formel. Utilisez --ignore-garbage pour tenter de récupérer + depuis tout autre octet non-alphabétique dans le flux encodé. +basenc-usage = basenc [OPTION]... [FICHIER] + +# Messages d'aide pour les formats d'encodage +basenc-help-base64 = identique au programme 'base64' +basenc-help-base64url = base64 sécurisé pour fichiers et URLs +basenc-help-base32 = identique au programme 'base32' +basenc-help-base32hex = base32 avec alphabet hexadécimal étendu +basenc-help-base16 = encodage hexadécimal +basenc-help-base2lsbf = chaîne de bits avec le bit de poids faible (lsb) en premier +basenc-help-base2msbf = chaîne de bits avec le bit de poids fort (msb) en premier +basenc-help-z85 = encodage de type ascii85 ; + lors de l'encodage, la longueur d'entrée doit être un multiple de 4 ; + lors du décodage, la longueur d'entrée doit être un multiple de 5 + +# Messages d'erreur +basenc-error-missing-encoding-type = type d'encodage manquant + +# Messages d'erreur partagés de base_common (utilisés par base32, base64, basenc) +base-common-extra-operand = opérande supplémentaire {$operand} +base-common-no-such-file = {$file} : Aucun fichier ou répertoire de ce type +base-common-invalid-wrap-size = taille de retour à la ligne invalide : {$size} +base-common-read-error = erreur de lecture : {$error} + +# Messages d'aide partagés de base_common +base-common-help-decode = décoder les données +base-common-help-ignore-garbage = lors du décodage, ignorer les caractères non-alphabétiques +base-common-help-wrap = retour à la ligne des lignes encodées après COLS caractères (par défaut {$default}, 0 pour désactiver le retour à la ligne) diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index 5229b5155..9d0c69688 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -53,7 +53,7 @@ impl Config { return Err(UUsageError::new( BASE_CMD_PARSE_ERROR, get_message_with_args( - "base32-extra-operand", + "base-common-extra-operand", HashMap::from([("operand".to_string(), extra_op.quote().to_string())]), ), )); @@ -68,7 +68,7 @@ impl Config { return Err(USimpleError::new( BASE_CMD_PARSE_ERROR, get_message_with_args( - "base32-no-such-file", + "base-common-no-such-file", HashMap::from([( "file".to_string(), path.maybe_quote().to_string(), @@ -90,7 +90,7 @@ impl Config { USimpleError::new( BASE_CMD_PARSE_ERROR, get_message_with_args( - "base32-invalid-wrap-size", + "base-common-invalid-wrap-size", HashMap::from([("size".to_string(), num.quote().to_string())]), ), ) @@ -128,7 +128,7 @@ pub fn base_app(about: &'static str, usage: &str) -> Command { .short('d') .visible_short_alias('D') .long(options::DECODE) - .help(get_message("base32-help-decode")) + .help(get_message("base-common-help-decode")) .action(ArgAction::SetTrue) .overrides_with(options::DECODE), ) @@ -136,7 +136,7 @@ pub fn base_app(about: &'static str, usage: &str) -> Command { Arg::new(options::IGNORE_GARBAGE) .short('i') .long(options::IGNORE_GARBAGE) - .help(get_message("base32-help-ignore-garbage")) + .help(get_message("base-common-help-ignore-garbage")) .action(ArgAction::SetTrue) .overrides_with(options::IGNORE_GARBAGE), ) @@ -146,7 +146,7 @@ pub fn base_app(about: &'static str, usage: &str) -> Command { .long(options::WRAP) .value_name("COLS") .help(get_message_with_args( - "base32-help-wrap", + "base-common-help-wrap", HashMap::from([("default".to_string(), WRAP_DEFAULT.to_string())]), )) .overrides_with(options::WRAP), @@ -831,7 +831,7 @@ fn format_read_error(kind: ErrorKind) -> String { } get_message_with_args( - "base32-read-error", + "base-common-read-error", HashMap::from([("error".to_string(), kind_string_capitalized)]), ) } diff --git a/src/uu/base64/locales/en-US.ftl b/src/uu/base64/locales/en-US.ftl deleted file mode 100644 index 891920565..000000000 --- a/src/uu/base64/locales/en-US.ftl +++ /dev/null @@ -1,9 +0,0 @@ -base64-about = encode/decode data and print to standard output - With no FILE, or when FILE is -, read standard input. - - The data are encoded as described for the base64 alphabet in RFC 3548. - When decoding, the input may contain newlines in addition - to the bytes of the formal base64 alphabet. Use --ignore-garbage - to attempt to recover from any other non-alphabet bytes in the - encoded stream. -base64-usage = base64 [OPTION]... [FILE] diff --git a/src/uu/basenc/locales/en-US.ftl b/src/uu/basenc/locales/en-US.ftl deleted file mode 100644 index a851acae9..000000000 --- a/src/uu/basenc/locales/en-US.ftl +++ /dev/null @@ -1,22 +0,0 @@ -basenc-about = Encode/decode data and print to standard output - With no FILE, or when FILE is -, read standard input. - - When decoding, the input may contain newlines in addition to the bytes of - the formal alphabet. Use --ignore-garbage to attempt to recover - from any other non-alphabet bytes in the encoded stream. -basenc-usage = basenc [OPTION]... [FILE] - -# Help messages for encoding formats -basenc-help-base64 = same as 'base64' program -basenc-help-base64url = file- and url-safe base64 -basenc-help-base32 = same as 'base32' program -basenc-help-base32hex = extended hex alphabet base32 -basenc-help-base16 = hex encoding -basenc-help-base2lsbf = bit string with least significant bit (lsb) first -basenc-help-base2msbf = bit string with most significant bit (msb) first -basenc-help-z85 = ascii85-like encoding; - when encoding, input length must be a multiple of 4; - when decoding, input length must be a multiple of 5 - -# Error messages -basenc-error-missing-encoding-type = missing encoding type diff --git a/src/uu/basenc/locales/fr-FR.ftl b/src/uu/basenc/locales/fr-FR.ftl deleted file mode 100644 index 7bf87265f..000000000 --- a/src/uu/basenc/locales/fr-FR.ftl +++ /dev/null @@ -1,22 +0,0 @@ -basenc-about = Encoder/décoder des données et afficher vers la sortie standard - Sans FICHIER, ou lorsque FICHIER est -, lire l'entrée standard. - - Lors du décodage, l'entrée peut contenir des nouvelles lignes en plus des octets de - l'alphabet formel. Utilisez --ignore-garbage pour tenter de récupérer - depuis tout autre octet non-alphabétique dans le flux encodé. -basenc-usage = basenc [OPTION]... [FICHIER] - -# Messages d'aide pour les formats d'encodage -basenc-help-base64 = identique au programme 'base64' -basenc-help-base64url = base64 sécurisé pour fichiers et URLs -basenc-help-base32 = identique au programme 'base32' -basenc-help-base32hex = base32 avec alphabet hexadécimal étendu -basenc-help-base16 = encodage hexadécimal -basenc-help-base2lsbf = chaîne de bits avec le bit de poids faible (lsb) en premier -basenc-help-base2msbf = chaîne de bits avec le bit de poids fort (msb) en premier -basenc-help-z85 = encodage de type ascii85 ; - lors de l'encodage, la longueur d'entrée doit être un multiple de 4 ; - lors du décodage, la longueur d'entrée doit être un multiple de 5 - -# Messages d'erreur -basenc-error-missing-encoding-type = type d'encodage manquant diff --git a/tests/by-util/test_base64.rs b/tests/by-util/test_base64.rs index ba0e3adaf..7813ad1e6 100644 --- a/tests/by-util/test_base64.rs +++ b/tests/by-util/test_base64.rs @@ -231,6 +231,10 @@ cyBvdmVyIHRoZSBsYXp5IGRvZy4= #[test] fn test_manpage() { use std::process::{Command, Stdio}; + unsafe { + // force locale to english to avoid issues with manpage output + std::env::set_var("LANG", "C"); + } let test_scenario = TestScenario::new(""); From 7bc0883c24d8807e1adfa8514bc0788e1fd1ba87 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 29 Jun 2025 19:56:01 +0200 Subject: [PATCH 3/3] base*: create the symlink --- src/uu/base64/locales | 1 + src/uu/basenc/locales | 1 + 2 files changed, 2 insertions(+) create mode 120000 src/uu/base64/locales create mode 120000 src/uu/basenc/locales diff --git a/src/uu/base64/locales b/src/uu/base64/locales new file mode 120000 index 000000000..4d6838e66 --- /dev/null +++ b/src/uu/base64/locales @@ -0,0 +1 @@ +../base32/locales \ No newline at end of file diff --git a/src/uu/basenc/locales b/src/uu/basenc/locales new file mode 120000 index 000000000..4d6838e66 --- /dev/null +++ b/src/uu/basenc/locales @@ -0,0 +1 @@ +../base32/locales \ No newline at end of file