Skip to content

Commit 8db1b6e

Browse files
authored
Merge pull request #8108 from sylvestre/l10n-uniq
l10n: port uniq to translation + add french
2 parents 37cf6f5 + f3900fa commit 8db1b6e

3 files changed

Lines changed: 124 additions & 37 deletions

File tree

src/uu/uniq/locales/en-US.ftl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,39 @@ uniq-after-help = Filter adjacent matching lines from INPUT (or standard input),
55
66
Note: uniq does not detect repeated lines unless they are adjacent.
77
You may want to sort the input first, or use sort -u without uniq.
8+
9+
# Help messages
10+
uniq-help-all-repeated = print all duplicate lines. Delimiting is done with blank lines. [default: none]
11+
uniq-help-group = show all items, separating groups with an empty line. [default: separate]
12+
uniq-help-check-chars = compare no more than N characters in lines
13+
uniq-help-count = prefix lines by the number of occurrences
14+
uniq-help-ignore-case = ignore differences in case when comparing
15+
uniq-help-repeated = only print duplicate lines
16+
uniq-help-skip-chars = avoid comparing the first N characters
17+
uniq-help-skip-fields = avoid comparing the first N fields
18+
uniq-help-unique = only print unique lines
19+
uniq-help-zero-terminated = end lines with 0 byte, not newline
20+
21+
# Error messages
22+
uniq-error-write-line-terminator = Could not write line terminator
23+
uniq-error-write-error = write error
24+
uniq-error-invalid-argument = Invalid argument for { $opt_name }: { $arg }
25+
uniq-error-try-help = Try 'uniq --help' for more information.
26+
uniq-error-group-mutually-exclusive = --group is mutually exclusive with -c/-d/-D/-u
27+
uniq-error-group-badoption = invalid argument 'badoption' for '--group'
28+
Valid arguments are:
29+
- 'prepend'
30+
- 'append'
31+
- 'separate'
32+
- 'both'
33+
34+
uniq-error-all-repeated-badoption = invalid argument 'badoption' for '--all-repeated'
35+
Valid arguments are:
36+
- 'none'
37+
- 'prepend'
38+
- 'separate'
39+
40+
uniq-error-counts-and-repeated-meaningless = printing all duplicated lines and repeat counts is meaningless
41+
Try 'uniq --help' for more information.
42+
43+
uniq-error-could-not-open = Could not open { $path }

src/uu/uniq/locales/fr-FR.ftl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
uniq-about = Signaler ou omettre les lignes répétées.
2+
uniq-usage = uniq [OPTION]... [ENTRÉE [SORTIE]]
3+
uniq-after-help = Filtrer les lignes adjacentes correspondantes de ENTRÉE (ou l'entrée standard),
4+
en écrivant vers SORTIE (ou la sortie standard).
5+
Note : uniq ne détecte les lignes répétées que si elles sont adjacentes.
6+
Vous pourriez vouloir trier l'entrée d'abord, ou utiliser sort -u sans uniq.
7+
8+
# Messages d'aide
9+
uniq-help-all-repeated = afficher toutes les lignes dupliquées. La délimitation se fait avec des lignes vides. [défaut : none]
10+
uniq-help-group = afficher tous les éléments, en séparant les groupes avec une ligne vide. [défaut : separate]
11+
uniq-help-check-chars = comparer au maximum N caractères dans les lignes
12+
uniq-help-count = préfixer les lignes par le nombre d'occurrences
13+
uniq-help-ignore-case = ignorer les différences de casse lors de la comparaison
14+
uniq-help-repeated = afficher seulement les lignes dupliquées
15+
uniq-help-skip-chars = éviter de comparer les N premiers caractères
16+
uniq-help-skip-fields = éviter de comparer les N premiers champs
17+
uniq-help-unique = afficher seulement les lignes uniques
18+
uniq-help-zero-terminated = terminer les lignes avec un octet 0, pas une nouvelle ligne
19+
20+
# Messages d'erreur
21+
uniq-error-write-line-terminator = Impossible d'écrire le terminateur de ligne
22+
uniq-error-write-error = erreur d'écriture
23+
uniq-error-invalid-argument = Argument invalide pour { $opt_name } : { $arg }
24+
uniq-error-try-help = Essayez 'uniq --help' pour plus d'informations.
25+
uniq-error-group-mutually-exclusive = --group est mutuellement exclusif avec -c/-d/-D/-u
26+
uniq-error-group-badoption = argument invalide 'badoption' pour '--group'
27+
Arguments valides :
28+
- 'prepend'
29+
- 'append'
30+
- 'separate'
31+
- 'both'
32+
33+
uniq-error-all-repeated-badoption = argument invalide 'badoption' pour '--all-repeated'
34+
Arguments valides :
35+
- 'none'
36+
- 'prepend'
37+
- 'separate'
38+
39+
uniq-error-counts-and-repeated-meaningless = afficher toutes les lignes dupliquées et les nombres de répétitions n'a pas de sens
40+
Essayez 'uniq --help' pour plus d'informations.
41+
uniq-error-could-not-open = Impossible d'ouvrir { $path }

src/uu/uniq/src/uniq.rs

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use clap::{
77
Arg, ArgAction, ArgMatches, Command, builder::ValueParser, error::ContextKind, error::Error,
88
error::ErrorKind,
99
};
10+
use std::collections::HashMap;
1011
use std::ffi::{OsStr, OsString};
1112
use std::fs::File;
1213
use std::io::{BufRead, BufReader, BufWriter, Write, stdin, stdout};
@@ -17,7 +18,7 @@ use uucore::format_usage;
1718
use uucore::parser::shortcut_value_parser::ShortcutValueParser;
1819
use uucore::posix::{OBSOLETE, posix_version};
1920

20-
use uucore::locale::get_message;
21+
use uucore::locale::{get_message, get_message_with_args};
2122

2223
pub mod options {
2324
pub static ALL_REPEATED: &str = "all-repeated";
@@ -60,7 +61,7 @@ macro_rules! write_line_terminator {
6061
($writer:expr, $line_terminator:expr) => {
6162
$writer
6263
.write_all(&[$line_terminator])
63-
.map_err_context(|| "Could not write line terminator".to_string())
64+
.map_err_context(|| get_message("uniq-error-write-line-terminator"))
6465
};
6566
}
6667

@@ -108,7 +109,9 @@ impl Uniq {
108109
{
109110
write_line_terminator!(writer, line_terminator)?;
110111
}
111-
writer.flush().map_err_context(|| "write error".into())?;
112+
writer
113+
.flush()
114+
.map_err_context(|| get_message("uniq-error-write-error"))?;
112115
Ok(())
113116
}
114117

@@ -155,7 +158,7 @@ impl Uniq {
155158

156159
// Skip self.slice_start bytes (if -s was used).
157160
// self.slice_start is how many characters to skip, but historically
158-
// uniqs `-s N` means skip N *bytes*, so do that literally:
161+
// uniq's `-s N` means "skip N *bytes*," so do that literally:
159162
let skip_bytes = self.slice_start.unwrap_or(0);
160163
let fields_to_check = if skip_bytes < fields_to_check.len() {
161164
&fields_to_check[skip_bytes..]
@@ -167,7 +170,7 @@ impl Uniq {
167170
// Convert the leftover bytes to UTF-8 for character-based -w
168171
// If invalid UTF-8, just compare them as individual bytes (fallback).
169172
let Ok(string_after_skip) = std::str::from_utf8(fields_to_check) else {
170-
// Fallback: if invalid UTF-8, treat them as single-byte chars
173+
// Fallback: if invalid UTF-8, treat them as single-byte "chars"
171174
return closure(&mut fields_to_check.iter().map(|&b| b as char));
172175
};
173176

@@ -225,7 +228,7 @@ impl Uniq {
225228
} else {
226229
writer.write_all(line)
227230
}
228-
.map_err_context(|| "write error".to_string())?;
231+
.map_err_context(|| get_message("uniq-error-write-error"))?;
229232

230233
write_line_terminator!(writer, line_terminator)
231234
}
@@ -239,7 +242,13 @@ fn opt_parsed(opt_name: &str, matches: &ArgMatches) -> UResult<Option<usize>> {
239242
IntErrorKind::PosOverflow => Ok(Some(usize::MAX)),
240243
_ => Err(USimpleError::new(
241244
1,
242-
format!("Invalid argument for {opt_name}: {}", arg_str.maybe_quote()),
245+
get_message_with_args(
246+
"uniq-error-invalid-argument",
247+
HashMap::from([
248+
("opt_name".to_string(), opt_name.to_string()),
249+
("arg".to_string(), arg_str.maybe_quote().to_string()),
250+
]),
251+
),
243252
)),
244253
},
245254
},
@@ -509,11 +518,11 @@ fn handle_extract_obs_skip_chars(
509518
/// for `uniq` hardcode and require the exact wording of the error message
510519
/// and it is not compatible with how Clap formats and displays those error messages.
511520
fn map_clap_errors(clap_error: Error) -> Box<dyn UError> {
512-
let footer = "Try 'uniq --help' for more information.";
513-
let override_arg_conflict =
514-
"--group is mutually exclusive with -c/-d/-D/-u\n".to_string() + footer;
515-
let override_group_badoption = "invalid argument 'badoption' for '--group'\nValid arguments are:\n - 'prepend'\n - 'append'\n - 'separate'\n - 'both'\n".to_string() + footer;
516-
let override_all_repeated_badoption = "invalid argument 'badoption' for '--all-repeated'\nValid arguments are:\n - 'none'\n - 'prepend'\n - 'separate'\n".to_string() + footer;
521+
let footer = get_message("uniq-error-try-help");
522+
let override_arg_conflict = get_message("uniq-error-group-mutually-exclusive") + "\n" + &footer;
523+
let override_group_badoption = get_message("uniq-error-group-badoption") + "\n" + &footer;
524+
let override_all_repeated_badoption =
525+
get_message("uniq-error-all-repeated-badoption") + "\n" + &footer;
517526

518527
let error_message = match clap_error.kind() {
519528
ErrorKind::ArgumentConflict => override_arg_conflict,
@@ -578,7 +587,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
578587
if uniq.show_counts && uniq.all_repeated {
579588
return Err(USimpleError::new(
580589
1,
581-
"printing all duplicated lines and repeat counts is meaningless\nTry 'uniq --help' for more information.",
590+
get_message("uniq-error-counts-and-repeated-meaningless"),
582591
));
583592
}
584593

@@ -599,12 +608,8 @@ pub fn uu_app() -> Command {
599608
Arg::new(options::ALL_REPEATED)
600609
.short('D')
601610
.long(options::ALL_REPEATED)
602-
.value_parser(ShortcutValueParser::new([
603-
"none",
604-
"prepend",
605-
"separate"
606-
]))
607-
.help("print all duplicate lines. Delimiting is done with blank lines. [default: none]")
611+
.value_parser(ShortcutValueParser::new(["none", "prepend", "separate"]))
612+
.help(get_message("uniq-help-all-repeated"))
608613
.value_name("delimit-method")
609614
.num_args(0..=1)
610615
.default_missing_value("none")
@@ -614,12 +619,9 @@ pub fn uu_app() -> Command {
614619
Arg::new(options::GROUP)
615620
.long(options::GROUP)
616621
.value_parser(ShortcutValueParser::new([
617-
"separate",
618-
"prepend",
619-
"append",
620-
"both",
622+
"separate", "prepend", "append", "both",
621623
]))
622-
.help("show all items, separating groups with an empty line. [default: separate]")
624+
.help(get_message("uniq-help-group"))
623625
.value_name("group-method")
624626
.num_args(0..=1)
625627
.default_missing_value("separate")
@@ -628,63 +630,63 @@ pub fn uu_app() -> Command {
628630
options::REPEATED,
629631
options::ALL_REPEATED,
630632
options::UNIQUE,
631-
options::COUNT
633+
options::COUNT,
632634
]),
633635
)
634636
.arg(
635637
Arg::new(options::CHECK_CHARS)
636638
.short('w')
637639
.long(options::CHECK_CHARS)
638-
.help("compare no more than N characters in lines")
640+
.help(get_message("uniq-help-check-chars"))
639641
.value_name("N"),
640642
)
641643
.arg(
642644
Arg::new(options::COUNT)
643645
.short('c')
644646
.long(options::COUNT)
645-
.help("prefix lines by the number of occurrences")
647+
.help(get_message("uniq-help-count"))
646648
.action(ArgAction::SetTrue),
647649
)
648650
.arg(
649651
Arg::new(options::IGNORE_CASE)
650652
.short('i')
651653
.long(options::IGNORE_CASE)
652-
.help("ignore differences in case when comparing")
654+
.help(get_message("uniq-help-ignore-case"))
653655
.action(ArgAction::SetTrue),
654656
)
655657
.arg(
656658
Arg::new(options::REPEATED)
657659
.short('d')
658660
.long(options::REPEATED)
659-
.help("only print duplicate lines")
661+
.help(get_message("uniq-help-repeated"))
660662
.action(ArgAction::SetTrue),
661663
)
662664
.arg(
663665
Arg::new(options::SKIP_CHARS)
664666
.short('s')
665667
.long(options::SKIP_CHARS)
666-
.help("avoid comparing the first N characters")
668+
.help(get_message("uniq-help-skip-chars"))
667669
.value_name("N"),
668670
)
669671
.arg(
670672
Arg::new(options::SKIP_FIELDS)
671673
.short('f')
672674
.long(options::SKIP_FIELDS)
673-
.help("avoid comparing the first N fields")
675+
.help(get_message("uniq-help-skip-fields"))
674676
.value_name("N"),
675677
)
676678
.arg(
677679
Arg::new(options::UNIQUE)
678680
.short('u')
679681
.long(options::UNIQUE)
680-
.help("only print unique lines")
682+
.help(get_message("uniq-help-unique"))
681683
.action(ArgAction::SetTrue),
682684
)
683685
.arg(
684686
Arg::new(options::ZERO_TERMINATED)
685687
.short('z')
686688
.long(options::ZERO_TERMINATED)
687-
.help("end lines with 0 byte, not newline")
689+
.help(get_message("uniq-help-zero-terminated"))
688690
.action(ArgAction::SetTrue),
689691
)
690692
.arg(
@@ -721,8 +723,12 @@ fn get_delimiter(matches: &ArgMatches) -> Delimiters {
721723
fn open_input_file(in_file_name: Option<&OsStr>) -> UResult<Box<dyn BufRead>> {
722724
Ok(match in_file_name {
723725
Some(path) if path != "-" => {
724-
let in_file = File::open(path)
725-
.map_err_context(|| format!("Could not open {}", path.maybe_quote()))?;
726+
let in_file = File::open(path).map_err_context(|| {
727+
get_message_with_args(
728+
"uniq-error-could-not-open",
729+
HashMap::from([("path".to_string(), path.maybe_quote().to_string())]),
730+
)
731+
})?;
726732
Box::new(BufReader::new(in_file))
727733
}
728734
_ => Box::new(stdin().lock()),
@@ -733,8 +739,12 @@ fn open_input_file(in_file_name: Option<&OsStr>) -> UResult<Box<dyn BufRead>> {
733739
fn open_output_file(out_file_name: Option<&OsStr>) -> UResult<Box<dyn Write>> {
734740
Ok(match out_file_name {
735741
Some(path) if path != "-" => {
736-
let out_file = File::create(path)
737-
.map_err_context(|| format!("Could not open {}", path.maybe_quote()))?;
742+
let out_file = File::create(path).map_err_context(|| {
743+
get_message_with_args(
744+
"uniq-error-could-not-open",
745+
HashMap::from([("path".to_string(), path.maybe_quote().to_string())]),
746+
)
747+
})?;
738748
Box::new(BufWriter::new(out_file))
739749
}
740750
_ => Box::new(stdout().lock()),

0 commit comments

Comments
 (0)