@@ -16,6 +16,7 @@ use clap::builder::{PossibleValue, ValueParser};
1616use clap:: { Arg , ArgAction , ArgGroup , ArgMatches , Command } ;
1717use filetime:: { FileTime , set_file_times, set_symlink_file_times} ;
1818use std:: borrow:: Cow ;
19+ use std:: collections:: HashMap ;
1920use std:: ffi:: OsString ;
2021use std:: fs:: { self , File } ;
2122use std:: io:: { Error , ErrorKind } ;
@@ -26,7 +27,7 @@ use uucore::parser::shortcut_value_parser::ShortcutValueParser;
2627use uucore:: { format_usage, show} ;
2728
2829use crate :: error:: TouchError ;
29- use uucore:: locale:: get_message;
30+ use uucore:: locale:: { get_message, get_message_with_args } ;
3031
3132/// Options contains all the possible behaviors and flags for touch.
3233///
@@ -192,9 +193,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
192193 . ok_or_else ( || {
193194 USimpleError :: new (
194195 1 ,
195- format ! (
196- "missing file operand\n Try '{} --help' for more information." ,
197- uucore:: execution_phrase( )
196+ get_message_with_args (
197+ "touch-error-missing-file-operand" ,
198+ HashMap :: from ( [ (
199+ "help_command" . to_string ( ) ,
200+ uucore:: execution_phrase ( ) . to_string ( ) ,
201+ ) ] ) ,
198202 ) ,
199203 )
200204 } ) ?
@@ -263,58 +267,55 @@ pub fn uu_app() -> Command {
263267 . arg (
264268 Arg :: new ( options:: HELP )
265269 . long ( options:: HELP )
266- . help ( "Print help information." )
270+ . help ( get_message ( "touch- help-help" ) )
267271 . action ( ArgAction :: Help ) ,
268272 )
269273 . arg (
270274 Arg :: new ( options:: ACCESS )
271275 . short ( 'a' )
272- . help ( "change only the access time" )
276+ . help ( get_message ( "touch-help- access" ) )
273277 . action ( ArgAction :: SetTrue ) ,
274278 )
275279 . arg (
276280 Arg :: new ( options:: sources:: TIMESTAMP )
277281 . short ( 't' )
278- . help ( "use [[CC]YY]MMDDhhmm[.ss] instead of the current time" )
282+ . help ( get_message ( "touch-help-timestamp" ) )
279283 . value_name ( "STAMP" ) ,
280284 )
281285 . arg (
282286 Arg :: new ( options:: sources:: DATE )
283287 . short ( 'd' )
284288 . long ( options:: sources:: DATE )
285289 . allow_hyphen_values ( true )
286- . help ( "parse argument and use it instead of current time" )
290+ . help ( get_message ( "touch-help-date" ) )
287291 . value_name ( "STRING" )
288292 . conflicts_with ( options:: sources:: TIMESTAMP ) ,
289293 )
290294 . arg (
291295 Arg :: new ( options:: MODIFICATION )
292296 . short ( 'm' )
293- . help ( "change only the modification time" )
297+ . help ( get_message ( "touch-help- modification" ) )
294298 . action ( ArgAction :: SetTrue ) ,
295299 )
296300 . arg (
297301 Arg :: new ( options:: NO_CREATE )
298302 . short ( 'c' )
299303 . long ( options:: NO_CREATE )
300- . help ( "do not create any files" )
304+ . help ( get_message ( "touch-help-no- create" ) )
301305 . action ( ArgAction :: SetTrue ) ,
302306 )
303307 . arg (
304308 Arg :: new ( options:: NO_DEREF )
305309 . short ( 'h' )
306310 . long ( options:: NO_DEREF )
307- . help (
308- "affect each symbolic link instead of any referenced file \
309- (only for systems that can change the timestamps of a symlink)",
310- )
311+ . help ( get_message ( "touch-help-no-deref" ) )
311312 . action ( ArgAction :: SetTrue ) ,
312313 )
313314 . arg (
314315 Arg :: new ( options:: sources:: REFERENCE )
315316 . short ( 'r' )
316317 . long ( options:: sources:: REFERENCE )
317- . help ( "use this file's times instead of the current time" )
318+ . help ( get_message ( "touch-help-reference" ) )
318319 . value_name ( "FILE" )
319320 . value_parser ( ValueParser :: os_string ( ) )
320321 . value_hint ( clap:: ValueHint :: AnyPath )
@@ -323,11 +324,7 @@ pub fn uu_app() -> Command {
323324 . arg (
324325 Arg :: new ( options:: TIME )
325326 . long ( options:: TIME )
326- . help (
327- "change only the specified time: \" access\" , \" atime\" , or \
328- \" use\" are equivalent to -a; \" modify\" or \" mtime\" are \
329- equivalent to -m",
330- )
327+ . help ( get_message ( "touch-help-time" ) )
331328 . value_name ( "WORD" )
332329 . value_parser ( ShortcutValueParser :: new ( [
333330 PossibleValue :: new ( "atime" ) . alias ( "access" ) . alias ( "use" ) ,
@@ -442,7 +439,12 @@ fn touch_file(
442439
443440 if let Err ( e) = metadata_result {
444441 if e. kind ( ) != ErrorKind :: NotFound {
445- return Err ( e. map_err_context ( || format ! ( "setting times of {}" , filename. quote( ) ) ) ) ;
442+ return Err ( e. map_err_context ( || {
443+ get_message_with_args (
444+ "touch-error-setting-times-of" ,
445+ HashMap :: from ( [ ( "filename" . to_string ( ) , filename. quote ( ) . to_string ( ) ) ] ) ,
446+ )
447+ } ) ) ;
446448 }
447449
448450 if opts. no_create {
@@ -452,9 +454,9 @@ fn touch_file(
452454 if opts. no_deref {
453455 let e = USimpleError :: new (
454456 1 ,
455- format ! (
456- "setting times of {}: No such file or directory " ,
457- filename. quote( )
457+ get_message_with_args (
458+ "touch-error- setting- times-no- such- file" ,
459+ HashMap :: from ( [ ( " filename" . to_string ( ) , filename . quote ( ) . to_string ( ) ) ] ) ,
458460 ) ,
459461 ) ;
460462 if opts. strict {
@@ -475,12 +477,20 @@ fn touch_file(
475477 false
476478 } ;
477479 if is_directory {
478- let custom_err = Error :: other ( "No such file or directory" ) ;
479- return Err (
480- custom_err. map_err_context ( || format ! ( "cannot touch {}" , filename. quote( ) ) )
481- ) ;
480+ let custom_err = Error :: other ( get_message ( "touch-error-no-such-file-or-directory" ) ) ;
481+ return Err ( custom_err. map_err_context ( || {
482+ get_message_with_args (
483+ "touch-error-cannot-touch" ,
484+ HashMap :: from ( [ ( "filename" . to_string ( ) , filename. quote ( ) . to_string ( ) ) ] ) ,
485+ )
486+ } ) ) ;
482487 }
483- let e = e. map_err_context ( || format ! ( "cannot touch {}" , path. quote( ) ) ) ;
488+ let e = e. map_err_context ( || {
489+ get_message_with_args (
490+ "touch-error-cannot-touch" ,
491+ HashMap :: from ( [ ( "filename" . to_string ( ) , path. quote ( ) . to_string ( ) ) ] ) ,
492+ )
493+ } ) ;
484494 if opts. strict {
485495 return Err ( e) ;
486496 }
@@ -543,12 +553,22 @@ fn update_times(
543553 ChangeTimes :: AtimeOnly => (
544554 atime,
545555 stat ( path, !opts. no_deref )
546- . map_err_context ( || format ! ( "failed to get attributes of {}" , path. quote( ) ) ) ?
556+ . map_err_context ( || {
557+ get_message_with_args (
558+ "touch-error-failed-to-get-attributes" ,
559+ HashMap :: from ( [ ( "path" . to_string ( ) , path. quote ( ) . to_string ( ) ) ] ) ,
560+ )
561+ } ) ?
547562 . 1 ,
548563 ) ,
549564 ChangeTimes :: MtimeOnly => (
550565 stat ( path, !opts. no_deref )
551- . map_err_context ( || format ! ( "failed to get attributes of {}" , path. quote( ) ) ) ?
566+ . map_err_context ( || {
567+ get_message_with_args (
568+ "touch-error-failed-to-get-attributes" ,
569+ HashMap :: from ( [ ( "path" . to_string ( ) , path. quote ( ) . to_string ( ) ) ] ) ,
570+ )
571+ } ) ?
552572 . 0 ,
553573 mtime,
554574 ) ,
@@ -563,7 +583,12 @@ fn update_times(
563583 } else {
564584 set_file_times ( path, atime, mtime)
565585 }
566- . map_err_context ( || format ! ( "setting times of {}" , path. quote( ) ) )
586+ . map_err_context ( || {
587+ get_message_with_args (
588+ "touch-error-setting-times-of-path" ,
589+ HashMap :: from ( [ ( "path" . to_string ( ) , path. quote ( ) . to_string ( ) ) ] ) ,
590+ )
591+ } )
567592}
568593
569594/// Get metadata of the provided path
@@ -645,9 +670,15 @@ fn parse_date(ref_time: DateTime<Local>, s: &str) -> Result<FileTime, TouchError
645670/// - 68 and before is interpreted as 20xx
646671/// - 69 and after is interpreted as 19xx
647672fn prepend_century ( s : & str ) -> UResult < String > {
648- let first_two_digits = s[ ..2 ]
649- . parse :: < u32 > ( )
650- . map_err ( |_| USimpleError :: new ( 1 , format ! ( "invalid date ts format {}" , s. quote( ) ) ) ) ?;
673+ let first_two_digits = s[ ..2 ] . parse :: < u32 > ( ) . map_err ( |_| {
674+ USimpleError :: new (
675+ 1 ,
676+ get_message_with_args (
677+ "touch-error-invalid-date-ts-format" ,
678+ HashMap :: from ( [ ( "date" . to_string ( ) , s. quote ( ) . to_string ( ) ) ] ) ,
679+ ) ,
680+ )
681+ } ) ?;
651682 Ok ( format ! (
652683 "{}{s}" ,
653684 if first_two_digits > 68 { 19 } else { 20 }
@@ -678,17 +709,30 @@ fn parse_timestamp(s: &str) -> UResult<FileTime> {
678709 _ => {
679710 return Err ( USimpleError :: new (
680711 1 ,
681- format ! ( "invalid date format {}" , s. quote( ) ) ,
712+ get_message_with_args (
713+ "touch-error-invalid-date-format" ,
714+ HashMap :: from ( [ ( "date" . to_string ( ) , s. quote ( ) . to_string ( ) ) ] ) ,
715+ ) ,
682716 ) ) ;
683717 }
684718 } ;
685719
686- let local = NaiveDateTime :: parse_from_str ( & ts, format)
687- . map_err ( |_| USimpleError :: new ( 1 , format ! ( "invalid date ts format {}" , ts. quote( ) ) ) ) ?;
720+ let local = NaiveDateTime :: parse_from_str ( & ts, format) . map_err ( |_| {
721+ USimpleError :: new (
722+ 1 ,
723+ get_message_with_args (
724+ "touch-error-invalid-date-ts-format" ,
725+ HashMap :: from ( [ ( "date" . to_string ( ) , ts. quote ( ) . to_string ( ) ) ] ) ,
726+ ) ,
727+ )
728+ } ) ?;
688729 let LocalResult :: Single ( mut local) = Local . from_local_datetime ( & local) else {
689730 return Err ( USimpleError :: new (
690731 1 ,
691- format ! ( "invalid date ts format {}" , ts. quote( ) ) ,
732+ get_message_with_args (
733+ "touch-error-invalid-date-ts-format" ,
734+ HashMap :: from ( [ ( "date" . to_string ( ) , ts. quote ( ) . to_string ( ) ) ] ) ,
735+ ) ,
692736 ) ) ;
693737 } ;
694738
@@ -709,7 +753,10 @@ fn parse_timestamp(s: &str) -> UResult<FileTime> {
709753 if local. hour ( ) != local2. hour ( ) {
710754 return Err ( USimpleError :: new (
711755 1 ,
712- format ! ( "invalid date format {}" , s. quote( ) ) ,
756+ get_message_with_args (
757+ "touch-error-invalid-date-format" ,
758+ HashMap :: from ( [ ( "date" . to_string ( ) , s. quote ( ) . to_string ( ) ) ] ) ,
759+ ) ,
713760 ) ) ;
714761 }
715762
@@ -763,15 +810,22 @@ fn pathbuf_from_stdout() -> Result<PathBuf, TouchError> {
763810
764811 let buffer_size = match ret {
765812 ERROR_PATH_NOT_FOUND | ERROR_NOT_ENOUGH_MEMORY | ERROR_INVALID_PARAMETER => {
766- return Err ( TouchError :: WindowsStdoutPathError ( format ! (
767- "GetFinalPathNameByHandleW failed with code {ret}"
813+ return Err ( TouchError :: WindowsStdoutPathError ( get_message_with_args (
814+ "touch-error-windows-stdout-path-failed" ,
815+ HashMap :: from ( [ ( "code" . to_string ( ) , ret. to_string ( ) ) ] ) ,
768816 ) ) ) ;
769817 }
770818 0 => {
771- return Err ( TouchError :: WindowsStdoutPathError ( format ! (
772- "GetFinalPathNameByHandleW failed with code {}" ,
773- // SAFETY: GetLastError is thread-safe and has no documented memory unsafety.
774- unsafe { GetLastError ( ) } ,
819+ return Err ( TouchError :: WindowsStdoutPathError ( get_message_with_args (
820+ "touch-error-windows-stdout-path-failed" ,
821+ HashMap :: from ( [ (
822+ "code" . to_string ( ) ,
823+ format ! (
824+ "{}" ,
825+ // SAFETY: GetLastError is thread-safe and has no documented memory unsafety.
826+ unsafe { GetLastError ( ) }
827+ ) ,
828+ ) ] ) ,
775829 ) ) ) ;
776830 }
777831 e => e as usize ,
0 commit comments