@@ -9,6 +9,7 @@ use clap::builder::ValueParser;
99use clap:: { Arg , ArgAction , Command } ;
1010use memchr:: { Memchr3 , memchr_iter, memmem:: Finder } ;
1111use std:: cmp:: Ordering ;
12+ use std:: collections:: HashMap ;
1213use std:: ffi:: OsString ;
1314use std:: fs:: File ;
1415use std:: io:: { BufRead , BufReader , BufWriter , Split , Stdin , Write , stdin, stdout} ;
@@ -21,11 +22,11 @@ use uucore::error::{FromIo, UError, UResult, USimpleError, set_exit_code};
2122use uucore:: format_usage;
2223use uucore:: line_ending:: LineEnding ;
2324
24- use uucore:: locale:: get_message;
25+ use uucore:: locale:: { get_message, get_message_with_args } ;
2526
2627#[ derive( Debug , Error ) ]
2728enum JoinError {
28- #[ error( "io error: {0}" ) ]
29+ #[ error( "{}" , get_message_with_args ( "join- error-io" , HashMap :: from ( [ ( "error" . to_string ( ) , . 0 . to_string ( ) ) ] ) ) ) ]
2930 IOError ( #[ from] std:: io:: Error ) ,
3031
3132 #[ error( "{0}" ) ]
@@ -361,15 +362,21 @@ impl Spec {
361362 }
362363 return Err ( USimpleError :: new (
363364 1 ,
364- format ! ( "invalid field specifier: {}" , format. quote( ) ) ,
365+ get_message_with_args (
366+ "join-error-invalid-field-specifier" ,
367+ HashMap :: from ( [ ( "spec" . to_string ( ) , format. quote ( ) . to_string ( ) ) ] ) ,
368+ ) ,
365369 ) ) ;
366370 }
367371 Some ( '1' ) => FileNum :: File1 ,
368372 Some ( '2' ) => FileNum :: File2 ,
369373 _ => {
370374 return Err ( USimpleError :: new (
371375 1 ,
372- format ! ( "invalid file number in field spec: {}" , format. quote( ) ) ,
376+ get_message_with_args (
377+ "join-error-invalid-file-number" ,
378+ HashMap :: from ( [ ( "spec" . to_string ( ) , format. quote ( ) . to_string ( ) ) ] ) ,
379+ ) ,
373380 ) ) ;
374381 }
375382 } ;
@@ -380,7 +387,10 @@ impl Spec {
380387
381388 Err ( USimpleError :: new (
382389 1 ,
383- format ! ( "invalid field specifier: {}" , format. quote( ) ) ,
390+ get_message_with_args (
391+ "join-error-invalid-field-specifier" ,
392+ HashMap :: from ( [ ( "spec" . to_string ( ) , format. quote ( ) . to_string ( ) ) ] ) ,
393+ ) ,
384394 ) )
385395 }
386396}
@@ -639,11 +649,16 @@ impl<'a> State<'a> {
639649 && ( input. check_order == CheckOrder :: Enabled
640650 || ( self . has_unpaired && !self . has_failed ) )
641651 {
642- let err_msg = format ! (
643- "{}:{}: is not sorted: {}" ,
644- self . file_name. maybe_quote( ) ,
645- self . line_num,
646- String :: from_utf8_lossy( & line. string)
652+ let err_msg = get_message_with_args (
653+ "join-error-not-sorted" ,
654+ HashMap :: from ( [
655+ ( "file" . to_string ( ) , self . file_name . maybe_quote ( ) . to_string ( ) ) ,
656+ ( "line_num" . to_string ( ) , self . line_num . to_string ( ) ) ,
657+ (
658+ "content" . to_string ( ) ,
659+ String :: from_utf8_lossy ( & line. string ) . to_string ( ) ,
660+ ) ,
661+ ] ) ,
647662 ) ;
648663 // This is fatal if the check is enabled.
649664 if input. check_order == CheckOrder :: Enabled {
@@ -720,11 +735,11 @@ fn parse_separator(value_os: &OsString) -> UResult<SepSetting> {
720735
721736 let Some ( value) = value_os. to_str ( ) else {
722737 #[ cfg( unix) ]
723- return Err ( USimpleError :: new ( 1 , "non-UTF-8 multi-byte tab") ) ;
738+ return Err ( USimpleError :: new ( 1 , get_message ( "join-error-non-utf8- tab") ) ) ;
724739 #[ cfg( not( unix) ) ]
725740 return Err ( USimpleError :: new (
726741 1 ,
727- " unprintable field separators are only supported on unix-like platforms" ,
742+ get_message ( "join-error- unprintable-separators" ) ,
728743 ) ) ;
729744 } ;
730745
@@ -733,7 +748,13 @@ fn parse_separator(value_os: &OsString) -> UResult<SepSetting> {
733748 match chars. next ( ) {
734749 None => Ok ( SepSetting :: Char ( value. into ( ) ) ) ,
735750 Some ( '0' ) if c == '\\' => Ok ( SepSetting :: Byte ( 0 ) ) ,
736- _ => Err ( USimpleError :: new ( 1 , format ! ( "multi-character tab {value}" ) ) ) ,
751+ _ => Err ( USimpleError :: new (
752+ 1 ,
753+ get_message_with_args (
754+ "join-error-multi-character-tab" ,
755+ HashMap :: from ( [ ( "value" . to_string ( ) , value. to_string ( ) ) ] ) ,
756+ ) ,
757+ ) ) ,
737758 }
738759}
739760
@@ -832,7 +853,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
832853 let file2 = matches. get_one :: < String > ( "file2" ) . unwrap ( ) ;
833854
834855 if file1 == "-" && file2 == "-" {
835- return Err ( USimpleError :: new ( 1 , "both files cannot be standard input" ) ) ;
856+ return Err ( USimpleError :: new (
857+ 1 ,
858+ get_message ( "join-error-both-files-stdin" ) ,
859+ ) ) ;
836860 }
837861
838862 let sep = settings. separator . clone ( ) ;
@@ -864,10 +888,7 @@ pub fn uu_app() -> Command {
864888 . num_args ( 1 )
865889 . value_parser ( [ "1" , "2" ] )
866890 . value_name ( "FILENUM" )
867- . help (
868- "also print unpairable lines from file FILENUM, where
869- FILENUM is 1 or 2, corresponding to FILE1 or FILE2" ,
870- ) ,
891+ . help ( get_message ( "join-help-a" ) ) ,
871892 )
872893 . arg (
873894 Arg :: new ( "v" )
@@ -876,81 +897,75 @@ FILENUM is 1 or 2, corresponding to FILE1 or FILE2",
876897 . num_args ( 1 )
877898 . value_parser ( [ "1" , "2" ] )
878899 . value_name ( "FILENUM" )
879- . help ( "like -a FILENUM, but suppress joined output lines" ) ,
900+ . help ( get_message ( "join-help-v" ) ) ,
880901 )
881902 . arg (
882903 Arg :: new ( "e" )
883904 . short ( 'e' )
884905 . value_name ( "EMPTY" )
885- . help ( "replace missing input fields with EMPTY" ) ,
906+ . help ( get_message ( "join-help-e" ) ) ,
886907 )
887908 . arg (
888909 Arg :: new ( "i" )
889910 . short ( 'i' )
890911 . long ( "ignore-case" )
891- . help ( "ignore differences in case when comparing fields" )
912+ . help ( get_message ( "join-help-i" ) )
892913 . action ( ArgAction :: SetTrue ) ,
893914 )
894915 . arg (
895916 Arg :: new ( "j" )
896917 . short ( 'j' )
897918 . value_name ( "FIELD" )
898- . help ( "equivalent to '-1 FIELD -2 FIELD'" ) ,
919+ . help ( get_message ( "join-help-j" ) ) ,
899920 )
900921 . arg (
901922 Arg :: new ( "o" )
902923 . short ( 'o' )
903924 . value_name ( "FORMAT" )
904- . help ( "obey FORMAT while constructing output line" ) ,
925+ . help ( get_message ( "join-help-o" ) ) ,
905926 )
906927 . arg (
907928 Arg :: new ( "t" )
908929 . short ( 't' )
909930 . value_name ( "CHAR" )
910931 . value_parser ( ValueParser :: os_string ( ) )
911- . help ( "use CHAR as input and output field separator" ) ,
932+ . help ( get_message ( "join-help-t" ) ) ,
912933 )
913934 . arg (
914935 Arg :: new ( "1" )
915936 . short ( '1' )
916937 . value_name ( "FIELD" )
917- . help ( "join on this FIELD of file 1" ) ,
938+ . help ( get_message ( "join-help-1" ) ) ,
918939 )
919940 . arg (
920941 Arg :: new ( "2" )
921942 . short ( '2' )
922943 . value_name ( "FIELD" )
923- . help ( "join on this FIELD of file 2" ) ,
944+ . help ( get_message ( "join-help-2" ) ) ,
924945 )
925946 . arg (
926947 Arg :: new ( "check-order" )
927948 . long ( "check-order" )
928- . help (
929- "check that the input is correctly sorted, \
930- even if all input lines are pairable",
931- )
949+ . help ( get_message ( "join-help-check-order" ) )
932950 . action ( ArgAction :: SetTrue ) ,
933951 )
934952 . arg (
935953 Arg :: new ( "nocheck-order" )
936954 . long ( "nocheck-order" )
937- . help ( "do not check that the input is correctly sorted" )
955+ . help ( get_message ( "join-help-nocheck-order" ) )
938956 . action ( ArgAction :: SetTrue ) ,
939957 )
940958 . arg (
941959 Arg :: new ( "header" )
942960 . long ( "header" )
943- . help (
944- "treat the first line in each file as field headers, \
945- print them without trying to pair them",
946- )
961+ . help ( get_message ( "join-help-header" ) )
947962 . action ( ArgAction :: SetTrue ) ,
948963 )
949964 . arg (
950965 Arg :: new ( "z" )
951966 . short ( 'z' )
952967 . long ( "zero-terminated" )
953- . help ( "line delimiter is NUL, not newline" )
968+ . help ( get_message ( "join-help-z" ) )
954969 . action ( ArgAction :: SetTrue ) ,
955970 )
956971 . arg (
@@ -1082,8 +1097,9 @@ fn exec<Sep: Separator>(file1: &str, file2: &str, settings: Settings, sep: Sep)
10821097
10831098 if state1. has_failed || state2. has_failed {
10841099 eprintln ! (
1085- "{}: input is not in sorted order" ,
1086- uucore:: execution_phrase( )
1100+ "{}: {}" ,
1101+ uucore:: execution_phrase( ) ,
1102+ get_message( "join-error-input-not-sorted" )
10871103 ) ;
10881104 set_exit_code ( 1 ) ;
10891105 }
@@ -1099,7 +1115,13 @@ fn get_field_number(keys: Option<usize>, key: Option<usize>) -> UResult<usize> {
10991115 // Show zero-based field numbers as one-based.
11001116 return Err ( USimpleError :: new (
11011117 1 ,
1102- format ! ( "incompatible join fields {}, {}" , keys + 1 , key + 1 ) ,
1118+ get_message_with_args (
1119+ "join-error-incompatible-fields" ,
1120+ HashMap :: from ( [
1121+ ( "field1" . to_string ( ) , ( keys + 1 ) . to_string ( ) ) ,
1122+ ( "field2" . to_string ( ) , ( key + 1 ) . to_string ( ) ) ,
1123+ ] ) ,
1124+ ) ,
11031125 ) ) ;
11041126 }
11051127 }
@@ -1118,7 +1140,10 @@ fn parse_field_number(value: &str) -> UResult<usize> {
11181140 Err ( e) if e. kind ( ) == & IntErrorKind :: PosOverflow => Ok ( usize:: MAX ) ,
11191141 _ => Err ( USimpleError :: new (
11201142 1 ,
1121- format ! ( "invalid field number: {}" , value. quote( ) ) ,
1143+ get_message_with_args (
1144+ "join-error-invalid-field-number" ,
1145+ HashMap :: from ( [ ( "value" . to_string ( ) , value. quote ( ) . to_string ( ) ) ] ) ,
1146+ ) ,
11221147 ) ) ,
11231148 }
11241149}
@@ -1129,7 +1154,10 @@ fn parse_file_number(value: &str) -> UResult<FileNum> {
11291154 "2" => Ok ( FileNum :: File2 ) ,
11301155 value => Err ( USimpleError :: new (
11311156 1 ,
1132- format ! ( "invalid file number: {}" , value. quote( ) ) ,
1157+ get_message_with_args (
1158+ "join-error-invalid-file-number-simple" ,
1159+ HashMap :: from ( [ ( "value" . to_string ( ) , value. quote ( ) . to_string ( ) ) ] ) ,
1160+ ) ,
11331161 ) ) ,
11341162 }
11351163}
0 commit comments