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

l10n: port join for translation + add french

This commit is contained in:
Sylvestre Ledru 2025-06-15 19:36:20 +02:00
parent 0a1a36d900
commit 5595d0716d
3 changed files with 134 additions and 41 deletions

View file

@ -3,3 +3,33 @@ join-about = For each pair of input lines with identical join fields, write a li
When FILE1 or FILE2 (not both) is -, read standard input.
join-usage = join [OPTION]... FILE1 FILE2
# Join help messages
join-help-a = also print unpairable lines from file FILENUM, where
FILENUM is 1 or 2, corresponding to FILE1 or FILE2
join-help-v = like -a FILENUM, but suppress joined output lines
join-help-e = replace missing input fields with EMPTY
join-help-i = ignore differences in case when comparing fields
join-help-j = equivalent to '-1 FIELD -2 FIELD'
join-help-o = obey FORMAT while constructing output line
join-help-t = use CHAR as input and output field separator
join-help-1 = join on this FIELD of file 1
join-help-2 = join on this FIELD of file 2
join-help-check-order = check that the input is correctly sorted, even if all input lines are pairable
join-help-nocheck-order = do not check that the input is correctly sorted
join-help-header = treat the first line in each file as field headers, print them without trying to pair them
join-help-z = line delimiter is NUL, not newline
# Join error messages
join-error-io = io error: { $error }
join-error-non-utf8-tab = non-UTF-8 multi-byte tab
join-error-unprintable-separators = unprintable field separators are only supported on unix-like platforms
join-error-multi-character-tab = multi-character tab { $value }
join-error-both-files-stdin = both files cannot be standard input
join-error-invalid-field-specifier = invalid field specifier: { $spec }
join-error-invalid-file-number = invalid file number in field spec: { $spec }
join-error-invalid-file-number-simple = invalid file number: { $value }
join-error-invalid-field-number = invalid field number: { $value }
join-error-incompatible-fields = incompatible join fields { $field1 }, { $field2 }
join-error-not-sorted = { $file }:{ $line_num }: is not sorted: { $content }
join-error-input-not-sorted = input is not in sorted order

View file

@ -0,0 +1,35 @@
join-about = Pour chaque paire de lignes d'entrée avec des champs de jointure identiques, écrire une ligne
sur la sortie standard. Le champ de jointure par défaut est le premier, délimité par des espaces.
Quand FILE1 ou FILE2 (mais pas les deux) est -, lire l'entrée standard.
join-usage = join [OPTION]... FICHIER1 FICHIER2
# Messages d'aide de join
join-help-a = afficher aussi les lignes non appariables du fichier NUMÉRO_FICHIER, où
NUMÉRO_FICHIER est 1 ou 2, correspondant à FICHIER1 ou FICHIER2
join-help-v = comme -a NUMÉRO_FICHIER, mais supprimer les lignes de sortie jointes
join-help-e = remplacer les champs d'entrée manquants par VIDE
join-help-i = ignorer les différences de casse lors de la comparaison des champs
join-help-j = équivalent à '-1 CHAMP -2 CHAMP'
join-help-o = obéir au FORMAT lors de la construction de la ligne de sortie
join-help-t = utiliser CHAR comme séparateur de champ d'entrée et de sortie
join-help-1 = joindre sur ce CHAMP du fichier 1
join-help-2 = joindre sur ce CHAMP du fichier 2
join-help-check-order = vérifier que l'entrée est correctement triée, même si toutes les lignes d'entrée sont appariables
join-help-nocheck-order = ne pas vérifier que l'entrée est correctement triée
join-help-header = traiter la première ligne de chaque fichier comme des en-têtes de champs, les imprimer sans essayer de les apparier
join-help-z = le délimiteur de ligne est NUL, pas de nouvelle ligne
# Messages d'erreur de join
join-error-io = erreur d'E/S : { $error }
join-error-non-utf8-tab = tabulation multi-octets non-UTF-8
join-error-unprintable-separators = les séparateurs de champs non imprimables ne sont pris en charge que sur les plateformes de type unix
join-error-multi-character-tab = tabulation multi-caractères { $value }
join-error-both-files-stdin = les deux fichiers ne peuvent pas être l'entrée standard
join-error-invalid-field-specifier = spécificateur de champ invalide : { $spec }
join-error-invalid-file-number = numéro de fichier invalide dans la spécification de champ : { $spec }
join-error-invalid-file-number-simple = numéro de fichier invalide : { $value }
join-error-invalid-field-number = numéro de champ invalide : { $value }
join-error-incompatible-fields = champs de jointure incompatibles { $field1 }, { $field2 }
join-error-not-sorted = { $file }:{ $line_num } : n'est pas trié : { $content }
join-error-input-not-sorted = l'entrée n'est pas dans l'ordre trié

View file

@ -9,6 +9,7 @@ use clap::builder::ValueParser;
use clap::{Arg, ArgAction, Command};
use memchr::{Memchr3, memchr_iter, memmem::Finder};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::ffi::OsString;
use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Split, Stdin, Write, stdin, stdout};
@ -21,11 +22,11 @@ use uucore::error::{FromIo, UError, UResult, USimpleError, set_exit_code};
use uucore::format_usage;
use uucore::line_ending::LineEnding;
use uucore::locale::get_message;
use uucore::locale::{get_message, get_message_with_args};
#[derive(Debug, Error)]
enum JoinError {
#[error("io error: {0}")]
#[error("{}", get_message_with_args("join-error-io", HashMap::from([("error".to_string(), .0.to_string())])))]
IOError(#[from] std::io::Error),
#[error("{0}")]
@ -361,7 +362,10 @@ impl Spec {
}
return Err(USimpleError::new(
1,
format!("invalid field specifier: {}", format.quote()),
get_message_with_args(
"join-error-invalid-field-specifier",
HashMap::from([("spec".to_string(), format.quote().to_string())]),
),
));
}
Some('1') => FileNum::File1,
@ -369,7 +373,10 @@ impl Spec {
_ => {
return Err(USimpleError::new(
1,
format!("invalid file number in field spec: {}", format.quote()),
get_message_with_args(
"join-error-invalid-file-number",
HashMap::from([("spec".to_string(), format.quote().to_string())]),
),
));
}
};
@ -380,7 +387,10 @@ impl Spec {
Err(USimpleError::new(
1,
format!("invalid field specifier: {}", format.quote()),
get_message_with_args(
"join-error-invalid-field-specifier",
HashMap::from([("spec".to_string(), format.quote().to_string())]),
),
))
}
}
@ -639,11 +649,16 @@ impl<'a> State<'a> {
&& (input.check_order == CheckOrder::Enabled
|| (self.has_unpaired && !self.has_failed))
{
let err_msg = format!(
"{}:{}: is not sorted: {}",
self.file_name.maybe_quote(),
self.line_num,
String::from_utf8_lossy(&line.string)
let err_msg = get_message_with_args(
"join-error-not-sorted",
HashMap::from([
("file".to_string(), self.file_name.maybe_quote().to_string()),
("line_num".to_string(), self.line_num.to_string()),
(
"content".to_string(),
String::from_utf8_lossy(&line.string).to_string(),
),
]),
);
// This is fatal if the check is enabled.
if input.check_order == CheckOrder::Enabled {
@ -720,11 +735,11 @@ fn parse_separator(value_os: &OsString) -> UResult<SepSetting> {
let Some(value) = value_os.to_str() else {
#[cfg(unix)]
return Err(USimpleError::new(1, "non-UTF-8 multi-byte tab"));
return Err(USimpleError::new(1, get_message("join-error-non-utf8-tab")));
#[cfg(not(unix))]
return Err(USimpleError::new(
1,
"unprintable field separators are only supported on unix-like platforms",
get_message("join-error-unprintable-separators"),
));
};
@ -733,7 +748,13 @@ fn parse_separator(value_os: &OsString) -> UResult<SepSetting> {
match chars.next() {
None => Ok(SepSetting::Char(value.into())),
Some('0') if c == '\\' => Ok(SepSetting::Byte(0)),
_ => Err(USimpleError::new(1, format!("multi-character tab {value}"))),
_ => Err(USimpleError::new(
1,
get_message_with_args(
"join-error-multi-character-tab",
HashMap::from([("value".to_string(), value.to_string())]),
),
)),
}
}
@ -832,7 +853,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let file2 = matches.get_one::<String>("file2").unwrap();
if file1 == "-" && file2 == "-" {
return Err(USimpleError::new(1, "both files cannot be standard input"));
return Err(USimpleError::new(
1,
get_message("join-error-both-files-stdin"),
));
}
let sep = settings.separator.clone();
@ -864,10 +888,7 @@ pub fn uu_app() -> Command {
.num_args(1)
.value_parser(["1", "2"])
.value_name("FILENUM")
.help(
"also print unpairable lines from file FILENUM, where
FILENUM is 1 or 2, corresponding to FILE1 or FILE2",
),
.help(get_message("join-help-a")),
)
.arg(
Arg::new("v")
@ -876,81 +897,75 @@ FILENUM is 1 or 2, corresponding to FILE1 or FILE2",
.num_args(1)
.value_parser(["1", "2"])
.value_name("FILENUM")
.help("like -a FILENUM, but suppress joined output lines"),
.help(get_message("join-help-v")),
)
.arg(
Arg::new("e")
.short('e')
.value_name("EMPTY")
.help("replace missing input fields with EMPTY"),
.help(get_message("join-help-e")),
)
.arg(
Arg::new("i")
.short('i')
.long("ignore-case")
.help("ignore differences in case when comparing fields")
.help(get_message("join-help-i"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("j")
.short('j')
.value_name("FIELD")
.help("equivalent to '-1 FIELD -2 FIELD'"),
.help(get_message("join-help-j")),
)
.arg(
Arg::new("o")
.short('o')
.value_name("FORMAT")
.help("obey FORMAT while constructing output line"),
.help(get_message("join-help-o")),
)
.arg(
Arg::new("t")
.short('t')
.value_name("CHAR")
.value_parser(ValueParser::os_string())
.help("use CHAR as input and output field separator"),
.help(get_message("join-help-t")),
)
.arg(
Arg::new("1")
.short('1')
.value_name("FIELD")
.help("join on this FIELD of file 1"),
.help(get_message("join-help-1")),
)
.arg(
Arg::new("2")
.short('2')
.value_name("FIELD")
.help("join on this FIELD of file 2"),
.help(get_message("join-help-2")),
)
.arg(
Arg::new("check-order")
.long("check-order")
.help(
"check that the input is correctly sorted, \
even if all input lines are pairable",
)
.help(get_message("join-help-check-order"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("nocheck-order")
.long("nocheck-order")
.help("do not check that the input is correctly sorted")
.help(get_message("join-help-nocheck-order"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("header")
.long("header")
.help(
"treat the first line in each file as field headers, \
print them without trying to pair them",
)
.help(get_message("join-help-header"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("z")
.short('z')
.long("zero-terminated")
.help("line delimiter is NUL, not newline")
.help(get_message("join-help-z"))
.action(ArgAction::SetTrue),
)
.arg(
@ -1082,8 +1097,9 @@ fn exec<Sep: Separator>(file1: &str, file2: &str, settings: Settings, sep: Sep)
if state1.has_failed || state2.has_failed {
eprintln!(
"{}: input is not in sorted order",
uucore::execution_phrase()
"{}: {}",
uucore::execution_phrase(),
get_message("join-error-input-not-sorted")
);
set_exit_code(1);
}
@ -1099,7 +1115,13 @@ fn get_field_number(keys: Option<usize>, key: Option<usize>) -> UResult<usize> {
// Show zero-based field numbers as one-based.
return Err(USimpleError::new(
1,
format!("incompatible join fields {}, {}", keys + 1, key + 1),
get_message_with_args(
"join-error-incompatible-fields",
HashMap::from([
("field1".to_string(), (keys + 1).to_string()),
("field2".to_string(), (key + 1).to_string()),
]),
),
));
}
}
@ -1118,7 +1140,10 @@ fn parse_field_number(value: &str) -> UResult<usize> {
Err(e) if e.kind() == &IntErrorKind::PosOverflow => Ok(usize::MAX),
_ => Err(USimpleError::new(
1,
format!("invalid field number: {}", value.quote()),
get_message_with_args(
"join-error-invalid-field-number",
HashMap::from([("value".to_string(), value.quote().to_string())]),
),
)),
}
}
@ -1129,7 +1154,10 @@ fn parse_file_number(value: &str) -> UResult<FileNum> {
"2" => Ok(FileNum::File2),
value => Err(USimpleError::new(
1,
format!("invalid file number: {}", value.quote()),
get_message_with_args(
"join-error-invalid-file-number-simple",
HashMap::from([("value".to_string(), value.quote().to_string())]),
),
)),
}
}