@@ -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 ;
1011use std:: ffi:: { OsStr , OsString } ;
1112use std:: fs:: File ;
1213use std:: io:: { BufRead , BufReader , BufWriter , Write , stdin, stdout} ;
@@ -17,7 +18,7 @@ use uucore::format_usage;
1718use uucore:: parser:: shortcut_value_parser:: ShortcutValueParser ;
1819use uucore:: posix:: { OBSOLETE , posix_version} ;
1920
20- use uucore:: locale:: get_message;
21+ use uucore:: locale:: { get_message, get_message_with_args } ;
2122
2223pub 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- // uniq’ s `-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.
511520fn 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' \n Valid 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' \n Valid 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 \n Try ' 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 {
721723fn 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>> {
733739fn 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