diff --git a/Cargo.lock b/Cargo.lock index 7b5d5ead0..810cc2a66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3601,6 +3601,7 @@ dependencies = [ "dunce", "fluent", "fluent-bundle", + "fluent-syntax", "glob", "hex", "itertools 0.14.0", diff --git a/Cargo.toml b/Cargo.toml index 88adba126..752c0cfef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -364,6 +364,7 @@ digest = "0.10.7" fluent-bundle = "0.16.0" fluent = "0.17.0" unic-langid = "0.9.6" +fluent-syntax = "0.12.0" uucore = { version = "0.1.0", package = "uucore", path = "src/uucore" } uucore_procs = { version = "0.1.0", package = "uucore_procs", path = "src/uucore_procs" } diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index cd9aae5a4..765d3c0a9 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -1418,6 +1418,7 @@ dependencies = [ "dunce", "fluent", "fluent-bundle", + "fluent-syntax", "glob", "hex", "itertools", diff --git a/src/bin/coreutils.rs b/src/bin/coreutils.rs index b29e7ea23..2821988c2 100644 --- a/src/bin/coreutils.rs +++ b/src/bin/coreutils.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore manpages mangen +// spell-checker:ignore manpages mangen prefixcat testcat use clap::{Arg, Command}; use clap_complete::Shell; @@ -14,6 +14,7 @@ use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::process; use uucore::display::Quotable; +use uucore::locale; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -50,6 +51,48 @@ fn name(binary_path: &Path) -> Option<&str> { binary_path.file_stem()?.to_str() } +fn get_canonical_util_name(util_name: &str) -> &str { + match util_name { + // uu_test aliases - '[' is an alias for test + "[" => "test", + + // hashsum aliases - all these hash commands are aliases for hashsum + "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" + | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" + | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => "hashsum", + + "dir" => "ls", // dir is an alias for ls + + // Default case - return the util name as is + _ => util_name, + } +} + +fn find_prefixed_util<'a>( + binary_name: &str, + mut util_keys: impl Iterator, +) -> Option<&'a str> { + util_keys.find(|util| { + binary_name.ends_with(*util) + && binary_name.len() > util.len() // Ensure there's actually a prefix + && !binary_name[..binary_name.len() - (*util).len()] + .ends_with(char::is_alphanumeric) + }) +} + +fn setup_localization_or_exit(util_name: &str) { + locale::setup_localization(get_canonical_util_name(util_name)).unwrap_or_else(|err| { + match err { + uucore::locale::LocalizationError::ParseResource { + error: err_msg, + snippet, + } => eprintln!("Localization parse error at {snippet}: {err_msg}"), + other => eprintln!("Could not init the localization system: {other}"), + } + process::exit(99) + }); +} + #[allow(clippy::cognitive_complexity)] fn main() { uucore::panic::mute_sigpipe_panic(); @@ -70,13 +113,10 @@ fn main() { // binary name equals prefixed util name? // * prefix/stem may be any string ending in a non-alphanumeric character - let util_name = if let Some(util) = utils.keys().find(|util| { - binary_as_util.ends_with(*util) - && !binary_as_util[..binary_as_util.len() - (*util).len()] - .ends_with(char::is_alphanumeric) - }) { + // For example, if the binary is named `uu_test`, it will match `test` as a utility. + let util_name = if let Some(util) = find_prefixed_util(binary_as_util, utils.keys().copied()) { // prefixed util => replace 0th (aka, executable name) argument - Some(OsString::from(*util)) + Some(OsString::from(util)) } else { // unmatched binary name => regard as multi-binary container and advance argument list uucore::set_utility_is_second_arg(); @@ -111,6 +151,12 @@ fn main() { match utils.get(util) { Some(&(uumain, _)) => { + // TODO: plug the deactivation of the translation + // and load the English strings directly at compilation time in the + // binary to avoid the load of the flt + // Could be something like: + // #[cfg(not(feature = "only_english"))] + setup_localization_or_exit(util); process::exit(uumain(vec![util_os].into_iter().chain(args))); } None => { @@ -213,6 +259,7 @@ fn gen_manpage( let command = if utility == "coreutils" { gen_coreutils_app(util_map) } else { + setup_localization_or_exit(utility); util_map.get(utility).unwrap().1() }; @@ -239,3 +286,70 @@ fn gen_coreutils_app(util_map: &UtilityMap) -> Command { } command } + +#[cfg(test)] +mod tests { + use super::*; + use std::path::Path; + + #[test] + fn test_get_canonical_util_name() { + // Test a few key aliases + assert_eq!(get_canonical_util_name("["), "test"); + assert_eq!(get_canonical_util_name("md5sum"), "hashsum"); + assert_eq!(get_canonical_util_name("dir"), "ls"); + + // Test passthrough case + assert_eq!(get_canonical_util_name("cat"), "cat"); + } + + #[test] + fn test_name() { + // Test normal executable name + assert_eq!(name(Path::new("/usr/bin/ls")), Some("ls")); + assert_eq!(name(Path::new("cat")), Some("cat")); + assert_eq!( + name(Path::new("./target/debug/coreutils")), + Some("coreutils") + ); + + // Test with extensions + assert_eq!(name(Path::new("program.exe")), Some("program")); + assert_eq!(name(Path::new("/path/to/utility.bin")), Some("utility")); + + // Test edge cases + assert_eq!(name(Path::new("")), None); + assert_eq!(name(Path::new("/")), None); + } + + #[test] + fn test_find_prefixed_util() { + let utils = ["test", "cat", "ls", "cp"]; + + // Test exact prefixed matches + assert_eq!( + find_prefixed_util("uu_test", utils.iter().copied()), + Some("test") + ); + assert_eq!( + find_prefixed_util("my-cat", utils.iter().copied()), + Some("cat") + ); + assert_eq!( + find_prefixed_util("prefix_ls", utils.iter().copied()), + Some("ls") + ); + + // Test non-alphanumeric separator requirement + assert_eq!(find_prefixed_util("prefixcat", utils.iter().copied()), None); // no separator + assert_eq!(find_prefixed_util("testcat", utils.iter().copied()), None); // no separator + + // Test no match + assert_eq!(find_prefixed_util("unknown", utils.iter().copied()), None); + assert_eq!(find_prefixed_util("", utils.iter().copied()), None); + + // Test exact util name (should not match as prefixed) + assert_eq!(find_prefixed_util("test", utils.iter().copied()), None); + assert_eq!(find_prefixed_util("cat", utils.iter().copied()), None); + } +} diff --git a/src/uu/arch/src/arch.rs b/src/uu/arch/src/arch.rs index 82e9bb79e..aad79b430 100644 --- a/src/uu/arch/src/arch.rs +++ b/src/uu/arch/src/arch.rs @@ -7,11 +7,10 @@ use platform_info::*; use clap::Command; use uucore::error::{UResult, USimpleError}; -use uucore::locale::{self, get_message}; +use uucore::locale::get_message; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - locale::setup_localization(uucore::util_name())?; uu_app().try_get_matches_from(args)?; let uts = diff --git a/src/uu/base32/base32.md b/src/uu/base32/base32.md deleted file mode 100644 index 1805d433b..000000000 --- a/src/uu/base32/base32.md +++ /dev/null @@ -1,14 +0,0 @@ -# base32 - -``` -base32 [OPTION]... [FILE] -``` - -encode/decode data and print to standard output -With no FILE, or when FILE is -, read standard input. - -The data are encoded as described for the base32 alphabet in RFC 4648. -When decoding, the input may contain newlines in addition -to the bytes of the formal base32 alphabet. Use --ignore-garbage -to attempt to recover from any other non-alphabet bytes in the -encoded stream. diff --git a/src/uu/base32/locales/en-US.ftl b/src/uu/base32/locales/en-US.ftl new file mode 100644 index 000000000..e3d2beb98 --- /dev/null +++ b/src/uu/base32/locales/en-US.ftl @@ -0,0 +1,9 @@ +base32-about = encode/decode data and print to standard output + With no FILE, or when FILE is -, read standard input. + + The data are encoded as described for the base32 alphabet in RFC 4648. + When decoding, the input may contain newlines in addition + to the bytes of the formal base32 alphabet. Use --ignore-garbage + to attempt to recover from any other non-alphabet bytes in the + encoded stream. +base32-usage = base32 [OPTION]... [FILE] diff --git a/src/uu/base32/src/base32.rs b/src/uu/base32/src/base32.rs index e14e83921..37bf01e32 100644 --- a/src/uu/base32/src/base32.rs +++ b/src/uu/base32/src/base32.rs @@ -5,24 +5,25 @@ pub mod base_common; -use base_common::ReadSeek; use clap::Command; -use uucore::{encoding::Format, error::UResult, help_about, help_usage}; - -const ABOUT: &str = help_about!("base32.md"); -const USAGE: &str = help_usage!("base32.md"); +use uucore::{encoding::Format, error::UResult, locale::get_message}; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let format = Format::Base32; - - let config = base_common::parse_base_cmd_args(args, ABOUT, USAGE)?; - - let mut input: Box = base_common::get_input(&config)?; - + let (about, usage) = get_info(); + let config = base_common::parse_base_cmd_args(args, about, usage)?; + let mut input = base_common::get_input(&config)?; base_common::handle_input(&mut input, format, config) } pub fn uu_app() -> Command { - base_common::base_app(ABOUT, USAGE) + let (about, usage) = get_info(); + base_common::base_app(about, usage) +} + +fn get_info() -> (&'static str, &'static str) { + let about: &'static str = Box::leak(get_message("base32-about").into_boxed_str()); + let usage: &'static str = Box::leak(get_message("base32-usage").into_boxed_str()); + (about, usage) } diff --git a/src/uu/base64/base64.md b/src/uu/base64/base64.md deleted file mode 100644 index ed3aa4f76..000000000 --- a/src/uu/base64/base64.md +++ /dev/null @@ -1,14 +0,0 @@ -# base64 - -``` -base64 [OPTION]... [FILE] -``` - -encode/decode data and print to standard output -With no FILE, or when FILE is -, read standard input. - -The data are encoded as described for the base64 alphabet in RFC 3548. -When decoding, the input may contain newlines in addition -to the bytes of the formal base64 alphabet. Use --ignore-garbage -to attempt to recover from any other non-alphabet bytes in the -encoded stream. diff --git a/src/uu/base64/locales/en-US.ftl b/src/uu/base64/locales/en-US.ftl new file mode 100644 index 000000000..891920565 --- /dev/null +++ b/src/uu/base64/locales/en-US.ftl @@ -0,0 +1,9 @@ +base64-about = encode/decode data and print to standard output + With no FILE, or when FILE is -, read standard input. + + The data are encoded as described for the base64 alphabet in RFC 3548. + When decoding, the input may contain newlines in addition + to the bytes of the formal base64 alphabet. Use --ignore-garbage + to attempt to recover from any other non-alphabet bytes in the + encoded stream. +base64-usage = base64 [OPTION]... [FILE] diff --git a/src/uu/base64/src/base64.rs b/src/uu/base64/src/base64.rs index 86eb75bf1..cd3ab66bd 100644 --- a/src/uu/base64/src/base64.rs +++ b/src/uu/base64/src/base64.rs @@ -5,22 +5,24 @@ use clap::Command; use uu_base32::base_common; -use uucore::{encoding::Format, error::UResult, help_about, help_usage}; - -const ABOUT: &str = help_about!("base64.md"); -const USAGE: &str = help_usage!("base64.md"); +use uucore::{encoding::Format, error::UResult, locale::get_message}; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let format = Format::Base64; - - let config = base_common::parse_base_cmd_args(args, ABOUT, USAGE)?; - + let (about, usage) = get_info(); + let config = base_common::parse_base_cmd_args(args, about, usage)?; let mut input = base_common::get_input(&config)?; - base_common::handle_input(&mut input, format, config) } pub fn uu_app() -> Command { - base_common::base_app(ABOUT, USAGE) + let (about, usage) = get_info(); + base_common::base_app(about, usage) +} + +fn get_info() -> (&'static str, &'static str) { + let about: &'static str = Box::leak(get_message("base64-about").into_boxed_str()); + let usage: &'static str = Box::leak(get_message("base64-usage").into_boxed_str()); + (about, usage) } diff --git a/src/uu/basename/basename.md b/src/uu/basename/basename.md deleted file mode 100644 index ee87fa76d..000000000 --- a/src/uu/basename/basename.md +++ /dev/null @@ -1,9 +0,0 @@ -# basename - -``` -basename [-z] NAME [SUFFIX] -basename OPTION... NAME... -``` - -Print NAME with any leading directory components removed -If specified, also remove a trailing SUFFIX diff --git a/src/uu/basename/locales/en-US.ftl b/src/uu/basename/locales/en-US.ftl new file mode 100644 index 000000000..fd0a8335b --- /dev/null +++ b/src/uu/basename/locales/en-US.ftl @@ -0,0 +1,4 @@ +basename-about = Print NAME with any leading directory components removed + If specified, also remove a trailing SUFFIX +basename-usage = basename [-z] NAME [SUFFIX] + basename OPTION... NAME... diff --git a/src/uu/basename/src/basename.rs b/src/uu/basename/src/basename.rs index a40fcc185..c39c329df 100644 --- a/src/uu/basename/src/basename.rs +++ b/src/uu/basename/src/basename.rs @@ -9,12 +9,10 @@ use clap::{Arg, ArgAction, Command}; use std::path::{PathBuf, is_separator}; use uucore::display::Quotable; use uucore::error::{UResult, UUsageError}; +use uucore::format_usage; use uucore::line_ending::LineEnding; -use uucore::{format_usage, help_about, help_usage}; -static ABOUT: &str = help_about!("basename.md"); - -const USAGE: &str = help_usage!("basename.md"); +use uucore::locale::get_message; pub mod options { pub static MULTIPLE: &str = "multiple"; @@ -77,8 +75,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("basename-about")) + .override_usage(format_usage(&get_message("basename-usage"))) .infer_long_args(true) .arg( Arg::new(options::MULTIPLE) diff --git a/src/uu/basenc/basenc.md b/src/uu/basenc/basenc.md deleted file mode 100644 index 001babe9e..000000000 --- a/src/uu/basenc/basenc.md +++ /dev/null @@ -1,12 +0,0 @@ -# basenc - -``` -basenc [OPTION]... [FILE] -``` - -Encode/decode data and print to standard output -With no FILE, or when FILE is -, read standard input. - -When decoding, the input may contain newlines in addition to the bytes of -the formal alphabet. Use --ignore-garbage to attempt to recover -from any other non-alphabet bytes in the encoded stream. diff --git a/src/uu/basenc/locales/en-US.ftl b/src/uu/basenc/locales/en-US.ftl new file mode 100644 index 000000000..520292c85 --- /dev/null +++ b/src/uu/basenc/locales/en-US.ftl @@ -0,0 +1,7 @@ +basenc-about = Encode/decode data and print to standard output + With no FILE, or when FILE is -, read standard input. + + When decoding, the input may contain newlines in addition to the bytes of + the formal alphabet. Use --ignore-garbage to attempt to recover + from any other non-alphabet bytes in the encoded stream. +basenc-usage = basenc [OPTION]... [FILE] diff --git a/src/uu/basenc/src/basenc.rs b/src/uu/basenc/src/basenc.rs index 100907652..9da71e9de 100644 --- a/src/uu/basenc/src/basenc.rs +++ b/src/uu/basenc/src/basenc.rs @@ -8,15 +8,11 @@ use clap::{Arg, ArgAction, Command}; use uu_base32::base_common::{self, BASE_CMD_PARSE_ERROR, Config}; use uucore::error::UClapError; +use uucore::locale::get_message; use uucore::{ encoding::Format, error::{UResult, UUsageError}, }; -use uucore::{help_about, help_usage}; - -const ABOUT: &str = help_about!("basenc.md"); -const USAGE: &str = help_usage!("basenc.md"); - const ENCODINGS: &[(&str, Format, &str)] = &[ ("base64", Format::Base64, "same as 'base64' program"), ("base64url", Format::Base64Url, "file- and url-safe base64"), @@ -47,7 +43,10 @@ const ENCODINGS: &[(&str, Format, &str)] = &[ ]; pub fn uu_app() -> Command { - let mut command = base_common::base_app(ABOUT, USAGE); + let about: &'static str = Box::leak(get_message("basenc-about").into_boxed_str()); + let usage: &'static str = Box::leak(get_message("basenc-usage").into_boxed_str()); + + let mut command = base_common::base_app(about, usage); for encoding in ENCODINGS { let raw_arg = Arg::new(encoding.0) .long(encoding.0) diff --git a/src/uu/cat/cat.md b/src/uu/cat/cat.md deleted file mode 100644 index efcd317eb..000000000 --- a/src/uu/cat/cat.md +++ /dev/null @@ -1,8 +0,0 @@ -# cat - -``` -cat [OPTION]... [FILE]... -``` - -Concatenate FILE(s), or standard input, to standard output -With no FILE, or when FILE is -, read standard input. diff --git a/src/uu/cat/locales/en-US.ftl b/src/uu/cat/locales/en-US.ftl new file mode 100644 index 000000000..108000d5a --- /dev/null +++ b/src/uu/cat/locales/en-US.ftl @@ -0,0 +1,3 @@ +cat-about = Concatenate FILE(s), or standard input, to standard output + With no FILE, or when FILE is -, read standard input. +cat-usage = cat [OPTION]... [FILE]... diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index 45fbe6ceb..cd89c3bc3 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -24,15 +24,13 @@ use thiserror::Error; use uucore::display::Quotable; use uucore::error::UResult; use uucore::fs::FileInformation; -use uucore::{fast_inc::fast_inc_one, format_usage, help_about, help_usage}; +use uucore::locale::get_message; +use uucore::{fast_inc::fast_inc_one, format_usage}; /// Linux splice support #[cfg(any(target_os = "linux", target_os = "android"))] mod splice; -const USAGE: &str = help_usage!("cat.md"); -const ABOUT: &str = help_about!("cat.md"); - // Allocate 32 digits for the line number. // An estimate is that we can print about 1e8 lines/seconds, so 32 digits // would be enough for billions of universe lifetimes. @@ -275,8 +273,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("cat-usage"))) + .about(get_message("cat-about")) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/chcon/chcon.md b/src/uu/chcon/chcon.md deleted file mode 100644 index 64c64f47b..000000000 --- a/src/uu/chcon/chcon.md +++ /dev/null @@ -1,11 +0,0 @@ - -# chcon - -``` -chcon [OPTION]... CONTEXT FILE... -chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE... -chcon [OPTION]... --reference=RFILE FILE... -``` - -Change the SELinux security context of each FILE to CONTEXT. -With --reference, change the security context of each FILE to that of RFILE. diff --git a/src/uu/chcon/locales/en-US.ftl b/src/uu/chcon/locales/en-US.ftl new file mode 100644 index 000000000..66c51f5af --- /dev/null +++ b/src/uu/chcon/locales/en-US.ftl @@ -0,0 +1,5 @@ +chcon-about = Change the SELinux security context of each FILE to CONTEXT. + With --reference, change the security context of each FILE to that of RFILE. +chcon-usage = chcon [OPTION]... CONTEXT FILE... + chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE... + chcon [OPTION]... --reference=RFILE FILE... diff --git a/src/uu/chcon/src/chcon.rs b/src/uu/chcon/src/chcon.rs index 2b1ff2e8f..be1bc2d5b 100644 --- a/src/uu/chcon/src/chcon.rs +++ b/src/uu/chcon/src/chcon.rs @@ -8,7 +8,7 @@ use clap::builder::ValueParser; use uucore::error::{UResult, USimpleError, UUsageError}; -use uucore::{display::Quotable, format_usage, help_about, help_usage, show_error, show_warning}; +use uucore::{display::Quotable, format_usage, show_error, show_warning}; use clap::{Arg, ArgAction, Command}; use selinux::{OpaqueSecurityContext, SecurityContext}; @@ -24,8 +24,7 @@ mod fts; use errors::*; -const ABOUT: &str = help_about!("chcon.md"); -const USAGE: &str = help_usage!("chcon.md"); +use uucore::locale::get_message; pub mod options { pub static HELP: &str = "help"; @@ -151,8 +150,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("chcon-about")) + .override_usage(format_usage(&get_message("chcon-usage"))) .infer_long_args(true) .disable_help_flag(true) .args_override_self(true) diff --git a/src/uu/chgrp/chgrp.md b/src/uu/chgrp/chgrp.md deleted file mode 100644 index 79bc068d2..000000000 --- a/src/uu/chgrp/chgrp.md +++ /dev/null @@ -1,10 +0,0 @@ - - -# chgrp - -``` -chgrp [OPTION]... GROUP FILE... -chgrp [OPTION]... --reference=RFILE FILE... -``` - -Change the group of each FILE to GROUP. diff --git a/src/uu/chgrp/locales/en-US.ftl b/src/uu/chgrp/locales/en-US.ftl new file mode 100644 index 000000000..5d399aa4d --- /dev/null +++ b/src/uu/chgrp/locales/en-US.ftl @@ -0,0 +1,3 @@ +chgrp-about = Change the group of each FILE to GROUP. +chgrp-usage = chgrp [OPTION]... GROUP FILE... + chgrp [OPTION]... --reference=RFILE FILE... diff --git a/src/uu/chgrp/src/chgrp.rs b/src/uu/chgrp/src/chgrp.rs index 1763bbfeb..0fb048903 100644 --- a/src/uu/chgrp/src/chgrp.rs +++ b/src/uu/chgrp/src/chgrp.rs @@ -8,16 +8,15 @@ use uucore::display::Quotable; pub use uucore::entries; use uucore::error::{FromIo, UResult, USimpleError}; +use uucore::format_usage; use uucore::perms::{GidUidOwnerFilter, IfFrom, chown_base, options}; -use uucore::{format_usage, help_about, help_usage}; use clap::{Arg, ArgAction, ArgMatches, Command}; use std::fs; use std::os::unix::fs::MetadataExt; -const ABOUT: &str = help_about!("chgrp.md"); -const USAGE: &str = help_usage!("chgrp.md"); +use uucore::locale::get_message; fn parse_gid_from_str(group: &str) -> Result { if let Some(gid_str) = group.strip_prefix(':') { @@ -99,8 +98,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("chgrp-about")) + .override_usage(format_usage(&get_message("chgrp-usage"))) .infer_long_args(true) .disable_help_flag(true) .arg( diff --git a/src/uu/chmod/chmod.md b/src/uu/chmod/chmod.md deleted file mode 100644 index 10ddb48a2..000000000 --- a/src/uu/chmod/chmod.md +++ /dev/null @@ -1,16 +0,0 @@ - - -# chmod - -``` -chmod [OPTION]... MODE[,MODE]... FILE... -chmod [OPTION]... OCTAL-MODE FILE... -chmod [OPTION]... --reference=RFILE FILE... -``` - -Change the mode of each FILE to MODE. -With --reference, change the mode of each FILE to that of RFILE. - -## After Help - -Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+`. diff --git a/src/uu/chmod/locales/en-US.ftl b/src/uu/chmod/locales/en-US.ftl new file mode 100644 index 000000000..c0d4d39ab --- /dev/null +++ b/src/uu/chmod/locales/en-US.ftl @@ -0,0 +1,6 @@ +chmod-about = Change the mode of each FILE to MODE. + With --reference, change the mode of each FILE to that of RFILE. +chmod-usage = chmod [OPTION]... MODE[,MODE]... FILE... + chmod [OPTION]... OCTAL-MODE FILE... + chmod [OPTION]... --reference=RFILE FILE... +chmod-after-help = Each MODE is of the form [ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+. diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index dfe304859..7367d4b76 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -17,11 +17,9 @@ use uucore::libc::mode_t; #[cfg(not(windows))] use uucore::mode; use uucore::perms::{TraverseSymlinks, configure_symlink_and_recursion}; -use uucore::{format_usage, help_about, help_section, help_usage, show, show_error}; +use uucore::{format_usage, show, show_error}; -const ABOUT: &str = help_about!("chmod.md"); -const USAGE: &str = help_usage!("chmod.md"); -const LONG_USAGE: &str = help_section!("after help", "chmod.md"); +use uucore::locale::get_message; mod options { pub const HELP: &str = "help"; @@ -94,7 +92,9 @@ fn extract_negative_modes(mut args: impl uucore::Args) -> (Option, Vec UResult<()> { let (parsed_cmode, args) = extract_negative_modes(args.skip(1)); // skip binary name - let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; + let matches = uu_app() + .after_help(get_message("chmod-after-help")) + .try_get_matches_from(args)?; let changes = matches.get_flag(options::CHANGES); let quiet = matches.get_flag(options::QUIET); @@ -159,8 +159,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("chmod-about")) + .override_usage(format_usage(&get_message("chmod-usage"))) .args_override_self(true) .infer_long_args(true) .no_binary_name(true) diff --git a/src/uu/chown/chown.md b/src/uu/chown/chown.md deleted file mode 100644 index 83101c74c..000000000 --- a/src/uu/chown/chown.md +++ /dev/null @@ -1,9 +0,0 @@ - -# chown - -``` -chown [OPTION]... [OWNER][:[GROUP]] FILE... -chown [OPTION]... --reference=RFILE FILE... -``` - -Change file owner and group diff --git a/src/uu/chown/locales/en-US.ftl b/src/uu/chown/locales/en-US.ftl new file mode 100644 index 000000000..4c8f2a46a --- /dev/null +++ b/src/uu/chown/locales/en-US.ftl @@ -0,0 +1,3 @@ +chown-about = Change file owner and group +chown-usage = chown [OPTION]... [OWNER][:[GROUP]] FILE... + chown [OPTION]... --reference=RFILE FILE... diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 4389d92f6..bf820c11e 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -7,8 +7,8 @@ use uucore::display::Quotable; pub use uucore::entries::{self, Group, Locate, Passwd}; +use uucore::format_usage; use uucore::perms::{GidUidOwnerFilter, IfFrom, chown_base, options}; -use uucore::{format_usage, help_about, help_usage}; use uucore::error::{FromIo, UResult, USimpleError}; @@ -17,9 +17,7 @@ use clap::{Arg, ArgAction, ArgMatches, Command}; use std::fs; use std::os::unix::fs::MetadataExt; -static ABOUT: &str = help_about!("chown.md"); - -const USAGE: &str = help_usage!("chown.md"); +use uucore::locale::get_message; fn parse_gid_uid_and_filter(matches: &ArgMatches) -> UResult { let filter = if let Some(spec) = matches.get_one::(options::FROM) { @@ -79,8 +77,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("chown-about")) + .override_usage(format_usage(&get_message("chown-usage"))) .infer_long_args(true) .disable_help_flag(true) .arg( diff --git a/src/uu/chroot/chroot.md b/src/uu/chroot/chroot.md deleted file mode 100644 index 3967d08f9..000000000 --- a/src/uu/chroot/chroot.md +++ /dev/null @@ -1,8 +0,0 @@ - -# chroot - -``` -chroot [OPTION]... NEWROOT [COMMAND [ARG]...] -``` - -Run COMMAND with root directory set to NEWROOT. diff --git a/src/uu/chroot/locales/en-US.ftl b/src/uu/chroot/locales/en-US.ftl new file mode 100644 index 000000000..86687fea8 --- /dev/null +++ b/src/uu/chroot/locales/en-US.ftl @@ -0,0 +1,2 @@ +chroot-about = Run COMMAND with root directory set to NEWROOT. +chroot-usage = chroot [OPTION]... NEWROOT [COMMAND [ARG]...] diff --git a/src/uu/chroot/src/chroot.rs b/src/uu/chroot/src/chroot.rs index 15c7bac4d..0b04e79ae 100644 --- a/src/uu/chroot/src/chroot.rs +++ b/src/uu/chroot/src/chroot.rs @@ -17,10 +17,9 @@ use uucore::entries::{Locate, Passwd, grp2gid, usr2uid}; use uucore::error::{UClapError, UResult, UUsageError, set_exit_code}; use uucore::fs::{MissingHandling, ResolveMode, canonicalize}; use uucore::libc::{self, chroot, setgid, setgroups, setuid}; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; -static ABOUT: &str = help_about!("chroot.md"); -static USAGE: &str = help_usage!("chroot.md"); +use uucore::locale::get_message; mod options { pub const NEWROOT: &str = "newroot"; @@ -237,8 +236,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("chroot-about")) + .override_usage(format_usage(&get_message("chroot-usage"))) .infer_long_args(true) .trailing_var_arg(true) .arg( diff --git a/src/uu/cksum/cksum.md b/src/uu/cksum/cksum.md deleted file mode 100644 index 5ca83b401..000000000 --- a/src/uu/cksum/cksum.md +++ /dev/null @@ -1,24 +0,0 @@ -# cksum - -``` -cksum [OPTIONS] [FILE]... -``` - -Print CRC and size for each file - -## After Help - -DIGEST determines the digest algorithm and default output format: - -- `sysv`: (equivalent to sum -s) -- `bsd`: (equivalent to sum -r) -- `crc`: (equivalent to cksum) -- `crc32b`: (only available through cksum) -- `md5`: (equivalent to md5sum) -- `sha1`: (equivalent to sha1sum) -- `sha224`: (equivalent to sha224sum) -- `sha256`: (equivalent to sha256sum) -- `sha384`: (equivalent to sha384sum) -- `sha512`: (equivalent to sha512sum) -- `blake2b`: (equivalent to b2sum) -- `sm3`: (only available through cksum) diff --git a/src/uu/cksum/locales/en-US.ftl b/src/uu/cksum/locales/en-US.ftl new file mode 100644 index 000000000..75a4bc8d0 --- /dev/null +++ b/src/uu/cksum/locales/en-US.ftl @@ -0,0 +1,16 @@ +cksum-about = Print CRC and size for each file +cksum-usage = cksum [OPTIONS] [FILE]... +cksum-after-help = DIGEST determines the digest algorithm and default output format: + + - sysv: (equivalent to sum -s) + - bsd: (equivalent to sum -r) + - crc: (equivalent to cksum) + - crc32b: (only available through cksum) + - md5: (equivalent to md5sum) + - sha1: (equivalent to sha1sum) + - sha224: (equivalent to sha224sum) + - sha256: (equivalent to sha256sum) + - sha384: (equivalent to sha384sum) + - sha512: (equivalent to sha512sum) + - blake2b: (equivalent to b2sum) + - sm3: (only available through cksum) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index a1a9115d9..0ded6c634 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -17,19 +17,16 @@ use uucore::checksum::{ ChecksumVerbose, SUPPORTED_ALGORITHMS, calculate_blake2b_length, detect_algo, digest_reader, perform_checksum_validation, }; +use uucore::locale::get_message; use uucore::{ encoding, error::{FromIo, UResult, USimpleError}, - format_usage, help_about, help_section, help_usage, + format_usage, line_ending::LineEnding, os_str_as_bytes, show, sum::Digest, }; -const USAGE: &str = help_usage!("cksum.md"); -const ABOUT: &str = help_about!("cksum.md"); -const AFTER_HELP: &str = help_section!("after help", "cksum.md"); - #[derive(Debug, PartialEq)] enum OutputFormat { Hexadecimal, @@ -343,8 +340,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("cksum-about")) + .override_usage(format_usage(&get_message("cksum-usage"))) .infer_long_args(true) .args_override_self(true) .arg( @@ -468,7 +465,7 @@ pub fn uu_app() -> Command { ) .action(ArgAction::SetTrue), ) - .after_help(AFTER_HELP) + .after_help(get_message("cksum-after-help")) } #[cfg(test)] diff --git a/src/uu/comm/comm.md b/src/uu/comm/comm.md deleted file mode 100644 index 91f4467d4..000000000 --- a/src/uu/comm/comm.md +++ /dev/null @@ -1,13 +0,0 @@ -# comm - -``` -comm [OPTION]... FILE1 FILE2 -``` - -Compare two sorted files line by line. - -When FILE1 or FILE2 (not both) is -, read standard input. - -With no options, produce three-column output. Column one contains -lines unique to FILE1, column two contains lines unique to FILE2, -and column three contains lines common to both files. diff --git a/src/uu/comm/locales/en-US.ftl b/src/uu/comm/locales/en-US.ftl new file mode 100644 index 000000000..56b67be37 --- /dev/null +++ b/src/uu/comm/locales/en-US.ftl @@ -0,0 +1,8 @@ +comm-about = Compare two sorted files line by line. + + When FILE1 or FILE2 (not both) is -, read standard input. + + With no options, produce three-column output. Column one contains + lines unique to FILE1, column two contains lines unique to FILE2, + and column three contains lines common to both files. +comm-usage = comm [OPTION]... FILE1 FILE2 diff --git a/src/uu/comm/src/comm.rs b/src/uu/comm/src/comm.rs index 11752c331..d595b463d 100644 --- a/src/uu/comm/src/comm.rs +++ b/src/uu/comm/src/comm.rs @@ -9,14 +9,13 @@ use std::cmp::Ordering; use std::fs::{File, metadata}; use std::io::{self, BufRead, BufReader, Read, Stdin, stdin}; use uucore::error::{FromIo, UResult, USimpleError}; +use uucore::format_usage; use uucore::fs::paths_refer_to_same_file; use uucore::line_ending::LineEnding; -use uucore::{format_usage, help_about, help_usage}; use clap::{Arg, ArgAction, ArgMatches, Command}; -const ABOUT: &str = help_about!("comm.md"); -const USAGE: &str = help_usage!("comm.md"); +use uucore::locale::get_message; mod options { pub const COLUMN_1: &str = "1"; @@ -314,8 +313,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("comm-about")) + .override_usage(format_usage(&get_message("comm-usage"))) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/cp/cp.md b/src/uu/cp/cp.md deleted file mode 100644 index 7485340f2..000000000 --- a/src/uu/cp/cp.md +++ /dev/null @@ -1,25 +0,0 @@ -# cp - -``` -cp [OPTION]... [-T] SOURCE DEST -cp [OPTION]... SOURCE... DIRECTORY -cp [OPTION]... -t DIRECTORY SOURCE... -``` - -Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. - -## After Help - -Do not copy a non-directory that has an existing destination with the same or newer modification timestamp; -instead, silently skip the file without failing. If timestamps are being preserved, the comparison is to the -source timestamp truncated to the resolutions of the destination file system and of the system calls used to -update timestamps; this avoids duplicate work if several `cp -pu` commands are executed with the same source -and destination. This option is ignored if the `-n` or `--no-clobber` option is also specified. Also, if -`--preserve=links` is also specified (like with `cp -au` for example), that will take precedence; consequently, -depending on the order that files are processed from the source, newer files in the destination may be replaced, -to mirror hard links in the source. which gives more control over which existing files in the destination are -replaced, and its value can be one of the following: - -* `all` This is the default operation when an `--update` option is not specified, and results in all existing files in the destination being replaced. -* `none` This is similar to the `--no-clobber` option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. -* `older` This is the default operation when `--update` is specified, and results in files being replaced if they’re older than the corresponding source file. diff --git a/src/uu/cp/locales/en-US.ftl b/src/uu/cp/locales/en-US.ftl new file mode 100644 index 000000000..7150d1b88 --- /dev/null +++ b/src/uu/cp/locales/en-US.ftl @@ -0,0 +1,17 @@ +cp-about = Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. +cp-usage = cp [OPTION]... [-T] SOURCE DEST + cp [OPTION]... SOURCE... DIRECTORY + cp [OPTION]... -t DIRECTORY SOURCE... +cp-after-help = Do not copy a non-directory that has an existing destination with the same or newer modification timestamp; + instead, silently skip the file without failing. If timestamps are being preserved, the comparison is to the + source timestamp truncated to the resolutions of the destination file system and of the system calls used to + update timestamps; this avoids duplicate work if several cp -pu commands are executed with the same source + and destination. This option is ignored if the -n or --no-clobber option is also specified. Also, if + --preserve=links is also specified (like with cp -au for example), that will take precedence; consequently, + depending on the order that files are processed from the source, newer files in the destination may be replaced, + to mirror hard links in the source. which gives more control over which existing files in the destination are + replaced, and its value can be one of the following: + + - all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. + - none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. + - older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file. diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 7ca39f6e3..d2966c5c4 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -36,11 +36,12 @@ use uucore::{backup_control, update_control}; // requires these enum. pub use uucore::{backup_control::BackupMode, update_control::UpdateMode}; use uucore::{ - format_usage, help_about, help_section, help_usage, - parser::shortcut_value_parser::ShortcutValueParser, prompt_yes, show_error, show_warning, + format_usage, parser::shortcut_value_parser::ShortcutValueParser, prompt_yes, show_error, + show_warning, }; use crate::copydir::copy_directory; +use uucore::locale::get_message; mod copydir; mod platform; @@ -451,10 +452,6 @@ fn show_debug(copy_debug: &CopyDebug) { ); } -const ABOUT: &str = help_about!("cp.md"); -const USAGE: &str = help_usage!("cp.md"); -const AFTER_HELP: &str = help_section!("after help", "cp.md"); - static EXIT_ERR: i32 = 1; // Argument constants @@ -523,10 +520,11 @@ pub fn uu_app() -> Command { ]; Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("cp-about")) + .override_usage(format_usage(&get_message("cp-usage"))) .after_help(format!( - "{AFTER_HELP}\n\n{}", + "{}\n\n{}", + get_message("cp-after-help"), backup_control::BACKUP_CONTROL_LONG_HELP )) .infer_long_args(true) diff --git a/src/uu/csplit/csplit.md b/src/uu/csplit/csplit.md deleted file mode 100644 index 1d428fc8e..000000000 --- a/src/uu/csplit/csplit.md +++ /dev/null @@ -1,11 +0,0 @@ -# csplit - -``` -csplit [OPTION]... FILE PATTERN... -``` - -Split a file into sections determined by context lines - -## After Help - -Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output. diff --git a/src/uu/csplit/locales/en-US.ftl b/src/uu/csplit/locales/en-US.ftl new file mode 100644 index 000000000..0198b521b --- /dev/null +++ b/src/uu/csplit/locales/en-US.ftl @@ -0,0 +1,3 @@ +csplit-about = Split a file into sections determined by context lines +csplit-usage = csplit [OPTION]... FILE PATTERN... +csplit-after-help = Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output. diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index 621823aeb..5b2478ccd 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -16,7 +16,7 @@ use clap::{Arg, ArgAction, ArgMatches, Command}; use regex::Regex; use uucore::display::Quotable; use uucore::error::{FromIo, UResult}; -use uucore::{format_usage, help_about, help_section, help_usage}; +use uucore::format_usage; mod csplit_error; mod patterns; @@ -25,9 +25,7 @@ mod split_name; use crate::csplit_error::CsplitError; use crate::split_name::SplitName; -const ABOUT: &str = help_about!("csplit.md"); -const AFTER_HELP: &str = help_section!("after help", "csplit.md"); -const USAGE: &str = help_usage!("csplit.md"); +use uucore::locale::get_message; mod options { pub const SUFFIX_FORMAT: &str = "suffix-format"; @@ -631,8 +629,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("csplit-about")) + .override_usage(format_usage(&get_message("csplit-usage"))) .args_override_self(true) .infer_long_args(true) .arg( @@ -697,7 +695,7 @@ pub fn uu_app() -> Command { .action(ArgAction::Append) .required(true), ) - .after_help(AFTER_HELP) + .after_help(get_message("csplit-after-help")) } #[cfg(test)] diff --git a/src/uu/cut/cut.md b/src/uu/cut/cut.md deleted file mode 100644 index 5c21d23dc..000000000 --- a/src/uu/cut/cut.md +++ /dev/null @@ -1,112 +0,0 @@ -# cut - - - -``` -cut OPTION... [FILE]... -``` - -Prints specified byte or field columns from each line of stdin or the input files - -## After Help - -Each call must specify a mode (what to use for columns), -a sequence (which columns to print), and provide a data source - -### Specifying a mode - -Use `--bytes` (`-b`) or `--characters` (`-c`) to specify byte mode - -Use `--fields` (`-f`) to specify field mode, where each line is broken into -fields identified by a delimiter character. For example for a typical CSV -you could use this in combination with setting comma as the delimiter - -### Specifying a sequence - -A sequence is a group of 1 or more numbers or inclusive ranges separated -by a commas. - -``` -cut -f 2,5-7 some_file.txt -``` - -will display the 2nd, 5th, 6th, and 7th field for each source line - -Ranges can extend to the end of the row by excluding the second number - -``` -cut -f 3- some_file.txt -``` - -will display the 3rd field and all fields after for each source line - -The first number of a range can be excluded, and this is effectively the -same as using 1 as the first number: it causes the range to begin at the -first column. Ranges can also display a single column - -``` -cut -f 1,3-5 some_file.txt -``` - -will display the 1st, 3rd, 4th, and 5th field for each source line - -The `--complement` option, when used, inverts the effect of the sequence - -``` -cut --complement -f 4-6 some_file.txt -``` - -will display the every field but the 4th, 5th, and 6th - -### Specifying a data source - -If no `sourcefile` arguments are specified, stdin is used as the source of -lines to print - -If `sourcefile` arguments are specified, stdin is ignored and all files are -read in consecutively if a `sourcefile` is not successfully read, a warning -will print to stderr, and the eventual status code will be 1, but cut -will continue to read through proceeding `sourcefiles` - -To print columns from both STDIN and a file argument, use `-` (dash) as a -`sourcefile` argument to represent stdin. - -### Field Mode options - -The fields in each line are identified by a delimiter (separator) - -#### Set the delimiter - -Set the delimiter which separates fields in the file using the -`--delimiter` (`-d`) option. Setting the delimiter is optional. -If not set, a default delimiter of Tab will be used. - -If the `-w` option is provided, fields will be separated by any number -of whitespace characters (Space and Tab). The output delimiter will -be a Tab unless explicitly specified. Only one of `-d` or `-w` option can be specified. -This is an extension adopted from FreeBSD. - -#### Optionally Filter based on delimiter - -If the `--only-delimited` (`-s`) flag is provided, only lines which -contain the delimiter will be printed - -#### Replace the delimiter - -If the `--output-delimiter` option is provided, the argument used for -it will replace the delimiter character in each line printed. This is -useful for transforming tabular data - e.g. to convert a CSV to a -TSV (tab-separated file) - -### Line endings - -When the `--zero-terminated` (`-z`) option is used, cut sees \\0 (null) as the -'line ending' character (both for the purposes of reading lines and -separating printed lines) instead of \\n (newline). This is useful for -tabular data where some of the cells may contain newlines - -``` -echo 'ab\\0cd' | cut -z -c 1 -``` - -will result in 'a\\0c\\0' diff --git a/src/uu/cut/locales/en-US.ftl b/src/uu/cut/locales/en-US.ftl new file mode 100644 index 000000000..b7feb048c --- /dev/null +++ b/src/uu/cut/locales/en-US.ftl @@ -0,0 +1,92 @@ +cut-about = Prints specified byte or field columns from each line of stdin or the input files +cut-usage = cut OPTION... [FILE]... +cut-after-help = Each call must specify a mode (what to use for columns), + a sequence (which columns to print), and provide a data source + + ### Specifying a mode + + Use --bytes (-b) or --characters (-c) to specify byte mode + + Use --fields (-f) to specify field mode, where each line is broken into + fields identified by a delimiter character. For example for a typical CSV + you could use this in combination with setting comma as the delimiter + + ### Specifying a sequence + + A sequence is a group of 1 or more numbers or inclusive ranges separated + by a commas. + + cut -f 2,5-7 some_file.txt + + will display the 2nd, 5th, 6th, and 7th field for each source line + + Ranges can extend to the end of the row by excluding the second number + + cut -f 3- some_file.txt + + will display the 3rd field and all fields after for each source line + + The first number of a range can be excluded, and this is effectively the + same as using 1 as the first number: it causes the range to begin at the + first column. Ranges can also display a single column + + cut -f 1,3-5 some_file.txt + + will display the 1st, 3rd, 4th, and 5th field for each source line + + The --complement option, when used, inverts the effect of the sequence + + cut --complement -f 4-6 some_file.txt + + will display the every field but the 4th, 5th, and 6th + + ### Specifying a data source + + If no sourcefile arguments are specified, stdin is used as the source of + lines to print + + If sourcefile arguments are specified, stdin is ignored and all files are + read in consecutively if a sourcefile is not successfully read, a warning + will print to stderr, and the eventual status code will be 1, but cut + will continue to read through proceeding sourcefiles + + To print columns from both STDIN and a file argument, use - (dash) as a + sourcefile argument to represent stdin. + + ### Field Mode options + + The fields in each line are identified by a delimiter (separator) + + #### Set the delimiter + + Set the delimiter which separates fields in the file using the + --delimiter (-d) option. Setting the delimiter is optional. + If not set, a default delimiter of Tab will be used. + + If the -w option is provided, fields will be separated by any number + of whitespace characters (Space and Tab). The output delimiter will + be a Tab unless explicitly specified. Only one of -d or -w option can be specified. + This is an extension adopted from FreeBSD. + + #### Optionally Filter based on delimiter + + If the --only-delimited (-s) flag is provided, only lines which + contain the delimiter will be printed + + #### Replace the delimiter + + If the --output-delimiter option is provided, the argument used for + it will replace the delimiter character in each line printed. This is + useful for transforming tabular data - e.g. to convert a CSV to a + TSV (tab-separated file) + + ### Line endings + + When the --zero-terminated (-z) option is used, cut sees \\0 (null) as the + 'line ending' character (both for the purposes of reading lines and + separating printed lines) instead of \\n (newline). This is useful for + tabular data where some of the cells may contain newlines + + echo 'ab\\0cd' | cut -z -c 1 + + will result in 'a\\0c\\0' diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index 49f5445f3..19d5d7c0a 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -18,16 +18,13 @@ use uucore::os_str_as_bytes; use self::searcher::Searcher; use matcher::{ExactMatcher, Matcher, WhitespaceMatcher}; +use uucore::locale::get_message; use uucore::ranges::Range; -use uucore::{format_usage, help_about, help_section, help_usage, show_error, show_if_err}; +use uucore::{format_usage, show_error, show_if_err}; mod matcher; mod searcher; -const USAGE: &str = help_usage!("cut.md"); -const ABOUT: &str = help_about!("cut.md"); -const AFTER_HELP: &str = help_section!("after help", "cut.md"); - struct Options<'a> { out_delimiter: Option<&'a [u8]>, line_ending: LineEnding, @@ -580,9 +577,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) - .after_help(AFTER_HELP) + .override_usage(format_usage(&get_message("cut-usage"))) + .about(get_message("cut-about")) + .after_help(get_message("cut-after-help")) .infer_long_args(true) // While `args_override_self(true)` for some arguments, such as `-d` // and `--output-delimiter`, is consistent to the behavior of GNU cut, diff --git a/src/uu/date/date-usage.md b/src/uu/date/date-usage.md deleted file mode 100644 index 109bfd398..000000000 --- a/src/uu/date/date-usage.md +++ /dev/null @@ -1,81 +0,0 @@ -# `date` usage - - - -FORMAT controls the output. Interpreted sequences are: - -| Sequence | Description | Example | -| -------- | -------------------------------------------------------------------- | ---------------------- | -| %% | a literal % | % | -| %a | locale's abbreviated weekday name | Sun | -| %A | locale's full weekday name | Sunday | -| %b | locale's abbreviated month name | Jan | -| %B | locale's full month name | January | -| %c | locale's date and time | Thu Mar 3 23:05:25 2005| -| %C | century; like %Y, except omit last two digits | 20 | -| %d | day of month | 01 | -| %D | date; same as %m/%d/%y | 12/31/99 | -| %e | day of month, space padded; same as %_d | 3 | -| %F | full date; same as %Y-%m-%d | 2005-03-03 | -| %g | last two digits of year of ISO week number (see %G) | 05 | -| %G | year of ISO week number (see %V); normally useful only with %V | 2005 | -| %h | same as %b | Jan | -| %H | hour (00..23) | 23 | -| %I | hour (01..12) | 11 | -| %j | day of year (001..366) | 062 | -| %k | hour, space padded ( 0..23); same as %_H | 3 | -| %l | hour, space padded ( 1..12); same as %_I | 9 | -| %m | month (01..12) | 03 | -| %M | minute (00..59) | 30 | -| %n | a newline | \n | -| %N | nanoseconds (000000000..999999999) | 123456789 | -| %p | locale's equivalent of either AM or PM; blank if not known | PM | -| %P | like %p, but lower case | pm | -| %q | quarter of year (1..4) | 1 | -| %r | locale's 12-hour clock time | 11:11:04 PM | -| %R | 24-hour hour and minute; same as %H:%M | 23:30 | -| %s | seconds since 1970-01-01 00:00:00 UTC | 1615432800 | -| %S | second (00..60) | 30 | -| %t | a tab | \t | -| %T | time; same as %H:%M:%S | 23:30:30 | -| %u | day of week (1..7); 1 is Monday | 4 | -| %U | week number of year, with Sunday as first day of week (00..53) | 10 | -| %V | ISO week number, with Monday as first day of week (01..53) | 12 | -| %w | day of week (0..6); 0 is Sunday | 4 | -| %W | week number of year, with Monday as first day of week (00..53) | 11 | -| %x | locale's date representation | 03/03/2005 | -| %X | locale's time representation | 23:30:30 | -| %y | last two digits of year (00..99) | 05 | -| %Y | year | 2005 | -| %z | +hhmm numeric time zone | -0400 | -| %:z | +hh:mm numeric time zone | -04:00 | -| %::z | +hh:mm:ss numeric time zone | -04:00:00 | -| %:::z | numeric time zone with : to necessary precision | -04, +05:30 | -| %Z | alphabetic time zone abbreviation | EDT | - -By default, date pads numeric fields with zeroes. -The following optional flags may follow '%': - -* `-` (hyphen) do not pad the field -* `_` (underscore) pad with spaces -* `0` (zero) pad with zeros -* `^` use upper case if possible -* `#` use opposite case if possible - -After any flags comes an optional field width, as a decimal number; -then an optional modifier, which is either -E to use the locale's alternate representations if available, or -O to use the locale's alternate numeric symbols if available. - -Examples: -Convert seconds since the epoch (1970-01-01 UTC) to a date - -``` -date --date='@2147483647' -``` - -Show the time on the west coast of the US (use tzselect(1) to find TZ) - -``` -TZ='America/Los_Angeles' date -``` diff --git a/src/uu/date/date.md b/src/uu/date/date.md deleted file mode 100644 index 97f134016..000000000 --- a/src/uu/date/date.md +++ /dev/null @@ -1,10 +0,0 @@ - - -# date - -``` -date [OPTION]... [+FORMAT]... -date [OPTION]... [MMDDhhmm[[CC]YY][.ss]] -``` - -Print or set the system date and time diff --git a/src/uu/date/locales/en-US.ftl b/src/uu/date/locales/en-US.ftl new file mode 100644 index 000000000..8889943be --- /dev/null +++ b/src/uu/date/locales/en-US.ftl @@ -0,0 +1,76 @@ +date-about = + Print or set the system date and time + +date-usage = + date [OPTION]... [+FORMAT]... + date [OPTION]... [MMDDhhmm[[CC]YY][.ss]] + + FORMAT controls the output. Interpreted sequences are: + { "| Sequence | Description | Example |" } + { "| -------- | -------------------------------------------------------------------- | ---------------------- |" } + { "| %% | a literal % | % |" } + { "| %a | locale's abbreviated weekday name | Sun |" } + { "| %A | locale's full weekday name | Sunday |" } + { "| %b | locale's abbreviated month name | Jan |" } + { "| %B | locale's full month name | January |" } + { "| %c | locale's date and time | Thu Mar 3 23:05:25 2005|" } + { "| %C | century; like %Y, except omit last two digits | 20 |" } + { "| %d | day of month | 01 |" } + { "| %D | date; same as %m/%d/%y | 12/31/99 |" } + { "| %e | day of month, space padded; same as %_d | 3 |" } + { "| %F | full date; same as %Y-%m-%d | 2005-03-03 |" } + { "| %g | last two digits of year of ISO week number (see %G) | 05 |" } + { "| %G | year of ISO week number (see %V); normally useful only with %V | 2005 |" } + { "| %h | same as %b | Jan |" } + { "| %H | hour (00..23) | 23 |" } + { "| %I | hour (01..12) | 11 |" } + { "| %j | day of year (001..366) | 062 |" } + { "| %k | hour, space padded ( 0..23); same as %_H | 3 |" } + { "| %l | hour, space padded ( 1..12); same as %_I | 9 |" } + { "| %m | month (01..12) | 03 |" } + { "| %M | minute (00..59) | 30 |" } + { "| %n | a newline | \\n |" } + { "| %N | nanoseconds (000000000..999999999) | 123456789 |" } + { "| %p | locale's equivalent of either AM or PM; blank if not known | PM |" } + { "| %P | like %p, but lower case | pm |" } + { "| %q | quarter of year (1..4) | 1 |" } + { "| %r | locale's 12-hour clock time | 11:11:04 PM |" } + { "| %R | 24-hour hour and minute; same as %H:%M | 23:30 |" } + { "| %s | seconds since 1970-01-01 00:00:00 UTC | 1615432800 |" } + { "| %S | second (00..60) | 30 |" } + { "| %t | a tab | \\t |" } + { "| %T | time; same as %H:%M:%S | 23:30:30 |" } + { "| %u | day of week (1..7); 1 is Monday | 4 |" } + { "| %U | week number of year, with Sunday as first day of week (00..53) | 10 |" } + { "| %V | ISO week number, with Monday as first day of week (01..53) | 12 |" } + { "| %w | day of week (0..6); 0 is Sunday | 4 |" } + { "| %W | week number of year, with Monday as first day of week (00..53) | 11 |" } + { "| %x | locale's date representation | 03/03/2005 |" } + { "| %X | locale's time representation | 23:30:30 |" } + { "| %y | last two digits of year (00..99) | 05 |" } + { "| %Y | year | 2005 |" } + { "| %z | +hhmm numeric time zone | -0400 |" } + { "| %:z | +hh:mm numeric time zone | -04:00 |" } + { "| %::z | +hh:mm:ss numeric time zone | -04:00:00 |" } + { "| %:::z | numeric time zone with : to necessary precision | -04, +05:30 |" } + { "| %Z | alphabetic time zone abbreviation | EDT |" } + + By default, date pads numeric fields with zeroes. + The following optional flags may follow '%': + { "* `-` (hyphen) do not pad the field" } + { "* `_` (underscore) pad with spaces" } + { "* `0` (zero) pad with zeros" } + { "* `^` use upper case if possible" } + { "* `#` use opposite case if possible" } + After any flags comes an optional field width, as a decimal number; + then an optional modifier, which is either + { "* `E` to use the locale's alternate representations if available, or" } + { "* `O` to use the locale's alternate numeric symbols if available." } + Examples: + Convert seconds since the epoch (1970-01-01 UTC) to a date + + date --date='@2147483647' + + Show the time on the west coast of the US (use tzselect(1) to find TZ) + + TZ='America/Los_Angeles' date diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index aff353fee..9f8b4c095 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -17,10 +17,11 @@ use std::path::PathBuf; use uucore::display::Quotable; use uucore::error::FromIo; use uucore::error::{UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; #[cfg(windows)] use windows_sys::Win32::{Foundation::SYSTEMTIME, System::SystemInformation::SetSystemTime}; +use uucore::locale::get_message; use uucore::parser::shortcut_value_parser::ShortcutValueParser; // Options @@ -30,9 +31,6 @@ const MINUTES: &str = "minutes"; const SECONDS: &str = "seconds"; const NS: &str = "ns"; -const ABOUT: &str = help_about!("date.md"); -const USAGE: &str = help_usage!("date.md"); - const OPT_DATE: &str = "date"; const OPT_FORMAT: &str = "format"; const OPT_FILE: &str = "file"; @@ -290,8 +288,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("date-about")) + .override_usage(format_usage(&get_message("date-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_DATE) diff --git a/src/uu/dd/dd.md b/src/uu/dd/dd.md deleted file mode 100644 index 504910884..000000000 --- a/src/uu/dd/dd.md +++ /dev/null @@ -1,126 +0,0 @@ -# dd - - - -``` -dd [OPERAND]... -dd OPTION -``` - -Copy, and optionally convert, a file system resource - -## After Help - -### Operands - -- `bs=BYTES` : read and write up to BYTES bytes at a time (default: 512); - overwrites `ibs` and `obs`. -- `cbs=BYTES` : the 'conversion block size' in bytes. Applies to the - `conv=block`, and `conv=unblock` operations. -- `conv=CONVS` : a comma-separated list of conversion options or (for legacy - reasons) file flags. -- `count=N` : stop reading input after N ibs-sized read operations rather - than proceeding until EOF. See `iflag=count_bytes` if stopping after N bytes - is preferred -- `ibs=N` : the size of buffer used for reads (default: 512) -- `if=FILE` : the file used for input. When not specified, stdin is used instead -- `iflag=FLAGS` : a comma-separated list of input flags which specify how the - input source is treated. FLAGS may be any of the input-flags or general-flags - specified below. -- `skip=N` (or `iseek=N`) : skip N ibs-sized records into input before beginning - copy/convert operations. See iflag=seek_bytes if seeking N bytes is preferred. -- `obs=N` : the size of buffer used for writes (default: 512) -- `of=FILE` : the file used for output. When not specified, stdout is used - instead -- `oflag=FLAGS` : comma separated list of output flags which specify how the - output source is treated. FLAGS may be any of the output flags or general - flags specified below -- `seek=N` (or `oseek=N`) : seeks N obs-sized records into output before - beginning copy/convert operations. See oflag=seek_bytes if seeking N bytes is - preferred -- `status=LEVEL` : controls whether volume and performance stats are written to - stderr. - - When unspecified, dd will print stats upon completion. An example is below. - - ```plain - 6+0 records in - 16+0 records out - 8192 bytes (8.2 kB, 8.0 KiB) copied, 0.00057009 s, - 14.4 MB/s - ``` - - The first two lines are the 'volume' stats and the final line is the - 'performance' stats. - The volume stats indicate the number of complete and partial ibs-sized reads, - or obs-sized writes that took place during the copy. The format of the volume - stats is `+`. If records have been truncated (see - `conv=block`), the volume stats will contain the number of truncated records. - - Possible LEVEL values are: - - `progress` : Print periodic performance stats as the copy proceeds. - - `noxfer` : Print final volume stats, but not performance stats. - - `none` : Do not print any stats. - - Printing performance stats is also triggered by the INFO signal (where supported), - or the USR1 signal. Setting the POSIXLY_CORRECT environment variable to any value - (including an empty value) will cause the USR1 signal to be ignored. - -### Conversion Options - -- `ascii` : convert from EBCDIC to ASCII. This is the inverse of the `ebcdic` - option. Implies `conv=unblock`. -- `ebcdic` : convert from ASCII to EBCDIC. This is the inverse of the `ascii` - option. Implies `conv=block`. -- `ibm` : convert from ASCII to EBCDIC, applying the conventions for `[`, `]` - and `~` specified in POSIX. Implies `conv=block`. - -- `ucase` : convert from lower-case to upper-case. -- `lcase` : converts from upper-case to lower-case. - -- `block` : for each newline less than the size indicated by cbs=BYTES, remove - the newline and pad with spaces up to cbs. Lines longer than cbs are truncated. -- `unblock` : for each block of input of the size indicated by cbs=BYTES, remove - right-trailing spaces and replace with a newline character. - -- `sparse` : attempts to seek the output when an obs-sized block consists of - only zeros. -- `swab` : swaps each adjacent pair of bytes. If an odd number of bytes is - present, the final byte is omitted. -- `sync` : pad each ibs-sided block with zeros. If `block` or `unblock` is - specified, pad with spaces instead. -- `excl` : the output file must be created. Fail if the output file is already - present. -- `nocreat` : the output file will not be created. Fail if the output file in - not already present. -- `notrunc` : the output file will not be truncated. If this option is not - present, output will be truncated when opened. -- `noerror` : all read errors will be ignored. If this option is not present, - dd will only ignore Error::Interrupted. -- `fdatasync` : data will be written before finishing. -- `fsync` : data and metadata will be written before finishing. - -### Input flags - -- `count_bytes` : a value to `count=N` will be interpreted as bytes. -- `skip_bytes` : a value to `skip=N` will be interpreted as bytes. -- `fullblock` : wait for ibs bytes from each read. zero-length reads are still - considered EOF. - -### Output flags - -- `append` : open file in append mode. Consider setting conv=notrunc as well. -- `seek_bytes` : a value to seek=N will be interpreted as bytes. - -### General Flags - -- `direct` : use direct I/O for data. -- `directory` : fail unless the given input (if used as an iflag) or - output (if used as an oflag) is a directory. -- `dsync` : use synchronized I/O for data. -- `sync` : use synchronized I/O for data and metadata. -- `nonblock` : use non-blocking I/O. -- `noatime` : do not update access time. -- `nocache` : request that OS drop cache. -- `noctty` : do not assign a controlling tty. -- `nofollow` : do not follow system links. diff --git a/src/uu/dd/locales/en-US.ftl b/src/uu/dd/locales/en-US.ftl new file mode 100644 index 000000000..56f391c79 --- /dev/null +++ b/src/uu/dd/locales/en-US.ftl @@ -0,0 +1,115 @@ +dd-about = Copy, and optionally convert, a file system resource +dd-usage = dd [OPERAND]... + dd OPTION +dd-after-help = ### Operands + + - bs=BYTES : read and write up to BYTES bytes at a time (default: 512); + overwrites ibs and obs. + - cbs=BYTES : the 'conversion block size' in bytes. Applies to the + conv=block, and conv=unblock operations. + - conv=CONVS : a comma-separated list of conversion options or (for legacy + reasons) file flags. + - count=N : stop reading input after N ibs-sized read operations rather + than proceeding until EOF. See iflag=count_bytes if stopping after N bytes + is preferred + - ibs=N : the size of buffer used for reads (default: 512) + - if=FILE : the file used for input. When not specified, stdin is used instead + - iflag=FLAGS : a comma-separated list of input flags which specify how the + input source is treated. FLAGS may be any of the input-flags or general-flags + specified below. + - skip=N (or iseek=N) : skip N ibs-sized records into input before beginning + copy/convert operations. See iflag=seek_bytes if seeking N bytes is preferred. + - obs=N : the size of buffer used for writes (default: 512) + - of=FILE : the file used for output. When not specified, stdout is used + instead + - oflag=FLAGS : comma separated list of output flags which specify how the + output source is treated. FLAGS may be any of the output flags or general + flags specified below + - seek=N (or oseek=N) : seeks N obs-sized records into output before + beginning copy/convert operations. See oflag=seek_bytes if seeking N bytes is + preferred + - status=LEVEL : controls whether volume and performance stats are written to + stderr. + + When unspecified, dd will print stats upon completion. An example is below. + + ```plain + 6+0 records in + 16+0 records out + 8192 bytes (8.2 kB, 8.0 KiB) copied, 0.00057009 s, + 14.4 MB/s + + The first two lines are the 'volume' stats and the final line is the + 'performance' stats. + The volume stats indicate the number of complete and partial ibs-sized reads, + or obs-sized writes that took place during the copy. The format of the volume + stats is +. If records have been truncated (see + conv=block), the volume stats will contain the number of truncated records. + + Possible LEVEL values are: + - progress : Print periodic performance stats as the copy proceeds. + - noxfer : Print final volume stats, but not performance stats. + - none : Do not print any stats. + + Printing performance stats is also triggered by the INFO signal (where supported), + or the USR1 signal. Setting the POSIXLY_CORRECT environment variable to any value + (including an empty value) will cause the USR1 signal to be ignored. + + ### Conversion Options + + - ascii : convert from EBCDIC to ASCII. This is the inverse of the ebcdic + option. Implies conv=unblock. + - ebcdic : convert from ASCII to EBCDIC. This is the inverse of the ascii + option. Implies conv=block. + - ibm : convert from ASCII to EBCDIC, applying the conventions for [, ] + and ~ specified in POSIX. Implies conv=block. + + - ucase : convert from lower-case to upper-case. + - lcase : converts from upper-case to lower-case. + + - block : for each newline less than the size indicated by cbs=BYTES, remove + the newline and pad with spaces up to cbs. Lines longer than cbs are truncated. + - unblock : for each block of input of the size indicated by cbs=BYTES, remove + right-trailing spaces and replace with a newline character. + + - sparse : attempts to seek the output when an obs-sized block consists of + only zeros. + - swab : swaps each adjacent pair of bytes. If an odd number of bytes is + present, the final byte is omitted. + - sync : pad each ibs-sided block with zeros. If block or unblock is + specified, pad with spaces instead. + - excl : the output file must be created. Fail if the output file is already + present. + - nocreat : the output file will not be created. Fail if the output file in + not already present. + - notrunc : the output file will not be truncated. If this option is not + present, output will be truncated when opened. + - noerror : all read errors will be ignored. If this option is not present, + dd will only ignore Error::Interrupted. + - fdatasync : data will be written before finishing. + - fsync : data and metadata will be written before finishing. + + ### Input flags + + - count_bytes : a value to count=N will be interpreted as bytes. + - skip_bytes : a value to skip=N will be interpreted as bytes. + - fullblock : wait for ibs bytes from each read. zero-length reads are still + considered EOF. + + ### Output flags + + - append : open file in append mode. Consider setting conv=notrunc as well. + - seek_bytes : a value to seek=N will be interpreted as bytes. + + ### General Flags + + - direct : use direct I/O for data. + - directory : fail unless the given input (if used as an iflag) or + output (if used as an oflag) is a directory. + - dsync : use synchronized I/O for data. + - sync : use synchronized I/O for data and metadata. + - nonblock : use non-blocking I/O. + - noatime : do not update access time. + - nocache : request that OS drop cache. + - noctty : do not assign a controlling tty. + - nofollow : do not follow system links. diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 4de05246f..c0e37263f 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -60,11 +60,9 @@ use uucore::error::{FromIo, UResult}; use uucore::error::{USimpleError, set_exit_code}; #[cfg(target_os = "linux")] use uucore::show_if_err; -use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +use uucore::{format_usage, show_error}; -const ABOUT: &str = help_about!("dd.md"); -const AFTER_HELP: &str = help_section!("after help", "dd.md"); -const USAGE: &str = help_usage!("dd.md"); +use uucore::locale::get_message; const BUF_INIT_BYTE: u8 = 0xDD; /// Final settings after parsing @@ -1427,9 +1425,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .about(get_message("dd-about")) + .override_usage(format_usage(&get_message("dd-usage"))) + .after_help(get_message("dd-after-help")) .infer_long_args(true) .arg(Arg::new(options::OPERANDS).num_args(1..)) } diff --git a/src/uu/df/df.md b/src/uu/df/df.md deleted file mode 100644 index 1a192f8fd..000000000 --- a/src/uu/df/df.md +++ /dev/null @@ -1,18 +0,0 @@ -# df - -``` -df [OPTION]... [FILE]... -``` - -Show information about the file system on which each FILE resides, -or all file systems by default. - -## After Help - -Display values are in units of the first available SIZE from --block-size, -and the DF_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables. -Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set). - -SIZE is an integer and optional unit (example: 10M is 10*1024*1024). -Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB,... (powers -of 1000). diff --git a/src/uu/df/locales/en-US.ftl b/src/uu/df/locales/en-US.ftl new file mode 100644 index 000000000..cbc69df76 --- /dev/null +++ b/src/uu/df/locales/en-US.ftl @@ -0,0 +1,10 @@ +df-about = Show information about the file system on which each FILE resides, + or all file systems by default. +df-usage = df [OPTION]... [FILE]... +df-after-help = Display values are in units of the first available SIZE from --block-size, + and the DF_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables. + Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set). + + SIZE is an integer and optional unit (example: 10M is 10*1024*1024). + Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB,... (powers + of 1000). diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index 9e2bb6920..c346cf163 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -15,7 +15,7 @@ use uucore::display::Quotable; use uucore::error::{UError, UResult, USimpleError, get_exit_code}; use uucore::fsext::{MountInfo, read_fs_list}; use uucore::parser::parse_size::ParseSizeError; -use uucore::{format_usage, help_about, help_section, help_usage, show}; +use uucore::{format_usage, show}; use clap::{Arg, ArgAction, ArgMatches, Command, parser::ValueSource}; @@ -29,9 +29,7 @@ use crate::filesystem::Filesystem; use crate::filesystem::FsError; use crate::table::Table; -const ABOUT: &str = help_about!("df.md"); -const USAGE: &str = help_usage!("df.md"); -const AFTER_HELP: &str = help_section!("after help", "df.md"); +use uucore::locale::get_message; static OPT_HELP: &str = "help"; static OPT_ALL: &str = "all"; @@ -452,9 +450,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .about(get_message("df-about")) + .override_usage(format_usage(&get_message("df-usage"))) + .after_help(get_message("df-after-help")) .infer_long_args(true) .disable_help_flag(true) .arg( diff --git a/src/uu/dircolors/dircolors.md b/src/uu/dircolors/dircolors.md deleted file mode 100644 index 959b8fd19..000000000 --- a/src/uu/dircolors/dircolors.md +++ /dev/null @@ -1,13 +0,0 @@ -# dircolors - -``` -dircolors [OPTION]... [FILE] -``` - -Output commands to set the LS_COLORS environment variable. - -## After Help - -If FILE is specified, read it to determine which colors to use for which -file types and extensions. Otherwise, a precompiled database is used. -For details on the format of these files, run 'dircolors --print-database' diff --git a/src/uu/dircolors/locales/en-US.ftl b/src/uu/dircolors/locales/en-US.ftl new file mode 100644 index 000000000..65b0b874c --- /dev/null +++ b/src/uu/dircolors/locales/en-US.ftl @@ -0,0 +1,5 @@ +dircolors-about = Output commands to set the LS_COLORS environment variable. +dircolors-usage = dircolors [OPTION]... [FILE] +dircolors-after-help = If FILE is specified, read it to determine which colors to use for which + file types and extensions. Otherwise, a precompiled database is used. + For details on the format of these files, run 'dircolors --print-database' diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 4fb9228eb..ae9b76177 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -16,7 +16,8 @@ use clap::{Arg, ArgAction, Command}; use uucore::colors::{FILE_ATTRIBUTE_CODES, FILE_COLORS, FILE_TYPES, TERMS}; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError, UUsageError}; -use uucore::{format_usage, help_about, help_section, help_usage, parser::parse_glob}; +use uucore::locale::get_message; +use uucore::{format_usage, parser::parse_glob}; mod options { pub const BOURNE_SHELL: &str = "bourne-shell"; @@ -26,10 +27,6 @@ mod options { pub const FILE: &str = "FILE"; } -const USAGE: &str = help_usage!("dircolors.md"); -const ABOUT: &str = help_about!("dircolors.md"); -const AFTER_HELP: &str = help_section!("after help", "dircolors.md"); - #[derive(PartialEq, Eq, Debug)] pub enum OutputFmt { Shell, @@ -245,9 +242,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("dircolors-about")) + .after_help(get_message("dircolors-after-help")) + .override_usage(format_usage(&get_message("dircolors-usage"))) .args_override_self(true) .infer_long_args(true) .arg( diff --git a/src/uu/dirname/dirname.md b/src/uu/dirname/dirname.md deleted file mode 100644 index f08c1c4c9..000000000 --- a/src/uu/dirname/dirname.md +++ /dev/null @@ -1,12 +0,0 @@ -# dirname - -``` -dirname [OPTION] NAME... -``` - -Strip last component from file name - -## After Help - -Output each NAME with its last non-slash component and trailing slashes -removed; if NAME contains no /'s, output '.' (meaning the current directory). diff --git a/src/uu/dirname/locales/en-US.ftl b/src/uu/dirname/locales/en-US.ftl new file mode 100644 index 000000000..37f33df47 --- /dev/null +++ b/src/uu/dirname/locales/en-US.ftl @@ -0,0 +1,4 @@ +dirname-about = Strip last component from file name +dirname-usage = dirname [OPTION] NAME... +dirname-after-help = Output each NAME with its last non-slash component and trailing slashes + removed; if NAME contains no /'s, output '.' (meaning the current directory). diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index de8740f89..02a6ea938 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -7,12 +7,10 @@ use clap::{Arg, ArgAction, Command}; use std::path::Path; use uucore::display::print_verbatim; use uucore::error::{UResult, UUsageError}; +use uucore::format_usage; use uucore::line_ending::LineEnding; -use uucore::{format_usage, help_about, help_section, help_usage}; -const ABOUT: &str = help_about!("dirname.md"); -const USAGE: &str = help_usage!("dirname.md"); -const AFTER_HELP: &str = help_section!("after help", "dirname.md"); +use uucore::locale::get_message; mod options { pub const ZERO: &str = "zero"; @@ -21,7 +19,9 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; + let matches = uu_app() + .after_help(get_message("dirname-after-help")) + .try_get_matches_from(args)?; let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO)); @@ -61,9 +61,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) - .about(ABOUT) + .about(get_message("dirname-about")) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) + .override_usage(format_usage(&get_message("dirname-usage"))) .args_override_self(true) .infer_long_args(true) .arg( diff --git a/src/uu/du/du.md b/src/uu/du/du.md deleted file mode 100644 index ae3319ad6..000000000 --- a/src/uu/du/du.md +++ /dev/null @@ -1,24 +0,0 @@ -# du - -``` -du [OPTION]... [FILE]... -du [OPTION]... --files0-from=F -``` - -Estimate file space usage - -## After Help - -Display values are in units of the first available SIZE from --block-size, -and the DU_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables. -Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set). - -SIZE is an integer and optional unit (example: 10M is 10*1024*1024). -Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB,... (powers -of 1000). - -PATTERN allows some advanced exclusions. For example, the following syntaxes -are supported: -`?` will match only one character -`*` will match zero or more characters -`{a,b}` will match a or b diff --git a/src/uu/du/locales/en-US.ftl b/src/uu/du/locales/en-US.ftl new file mode 100644 index 000000000..9f409ffa3 --- /dev/null +++ b/src/uu/du/locales/en-US.ftl @@ -0,0 +1,16 @@ +du-about = Estimate file space usage +du-usage = du [OPTION]... [FILE]... + du [OPTION]... --files0-from=F +du-after-help = Display values are in units of the first available SIZE from --block-size, + and the DU_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables. + Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set). + + SIZE is an integer and optional unit (example: 10M is 10*1024*1024). + Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB,... (powers + of 1000). + + PATTERN allows some advanced exclusions. For example, the following syntaxes + are supported: + ? will match only one character + { "*" } will match zero or more characters + {"{"}a,b{"}"} will match a or b diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 0b2688881..08a7c7b91 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -27,10 +27,11 @@ use thiserror::Error; use uucore::display::{Quotable, print_verbatim}; use uucore::error::{FromIo, UError, UResult, USimpleError, set_exit_code}; use uucore::line_ending::LineEnding; +use uucore::locale::get_message; use uucore::parser::parse_glob; use uucore::parser::parse_size::{ParseSizeError, parse_size_u64}; use uucore::parser::shortcut_value_parser::ShortcutValueParser; -use uucore::{format_usage, help_about, help_section, help_usage, show, show_error, show_warning}; +use uucore::{format_usage, show, show_error, show_warning}; #[cfg(windows)] use windows_sys::Win32::Foundation::HANDLE; #[cfg(windows)] @@ -70,10 +71,6 @@ mod options { pub const FILE: &str = "FILE"; } -const ABOUT: &str = help_about!("du.md"); -const AFTER_HELP: &str = help_section!("after help", "du.md"); -const USAGE: &str = help_usage!("du.md"); - struct TraversalOptions { all: bool, separate_dirs: bool, @@ -824,9 +821,9 @@ fn parse_depth(max_depth_str: Option<&str>, summarize: bool) -> UResult Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("du-about")) + .after_help(get_message("du-after-help")) + .override_usage(format_usage(&get_message("du-usage"))) .infer_long_args(true) .disable_help_flag(true) .arg( diff --git a/src/uu/echo/echo.md b/src/uu/echo/echo.md deleted file mode 100644 index f6f6f37ff..000000000 --- a/src/uu/echo/echo.md +++ /dev/null @@ -1,26 +0,0 @@ -# echo - -``` -echo [OPTIONS]... [STRING]... -``` - -Display a line of text - -## After Help - -Echo the STRING(s) to standard output. - -If -e is in effect, the following sequences are recognized: - -- `\` backslash -- `\a` alert (BEL) -- `\b` backspace -- `\c` produce no further output -- `\e` escape -- `\f` form feed -- `\n` new line -- `\r` carriage return -- `\t` horizontal tab -- `\v` vertical tab -- `\0NNN` byte with octal value NNN (1 to 3 digits) -- `\xHH` byte with hexadecimal value HH (1 to 2 digits) diff --git a/src/uu/echo/locales/en-US.ftl b/src/uu/echo/locales/en-US.ftl new file mode 100644 index 000000000..05bf06cd2 --- /dev/null +++ b/src/uu/echo/locales/en-US.ftl @@ -0,0 +1,18 @@ +echo-about = Display a line of text +echo-usage = echo [OPTIONS]... [STRING]... +echo-after-help = Echo the STRING(s) to standard output. + + If -e is in effect, the following sequences are recognized: + + - \ backslash + - \a alert (BEL) + - \b backspace + - \c produce no further output + - \e escape + - \f form feed + - \n new line + - \r carriage return + - \t horizontal tab + - \v vertical tab + - \0NNN byte with octal value NNN (1 to 3 digits) + - \xHH byte with hexadecimal value HH (1 to 2 digits) diff --git a/src/uu/echo/src/echo.rs b/src/uu/echo/src/echo.rs index 4df766348..d1306dd3e 100644 --- a/src/uu/echo/src/echo.rs +++ b/src/uu/echo/src/echo.rs @@ -10,11 +10,9 @@ use std::ffi::{OsStr, OsString}; use std::io::{self, StdoutLock, Write}; use uucore::error::{UResult, USimpleError}; use uucore::format::{FormatChar, OctalParsing, parse_escape_only}; -use uucore::{format_usage, help_about, help_section, help_usage}; +use uucore::format_usage; -const ABOUT: &str = help_about!("echo.md"); -const USAGE: &str = help_usage!("echo.md"); -const AFTER_HELP: &str = help_section!("after help", "echo.md"); +use uucore::locale::get_message; mod options { pub const STRING: &str = "STRING"; @@ -141,9 +139,9 @@ pub fn uu_app() -> Command { .trailing_var_arg(true) .allow_hyphen_values(true) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("echo-about")) + .after_help(get_message("echo-after-help")) + .override_usage(format_usage(&get_message("echo-usage"))) .arg( Arg::new(options::NO_NEWLINE) .short('n') diff --git a/src/uu/env/env.md b/src/uu/env/env.md deleted file mode 100644 index fc3341a61..000000000 --- a/src/uu/env/env.md +++ /dev/null @@ -1,13 +0,0 @@ -# env - -``` -env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...] -``` - - -Set each NAME to VALUE in the environment and run COMMAND - - -## After Help - -A mere - implies -i. If no COMMAND, print the resulting environment. diff --git a/src/uu/env/locales/en-US.ftl b/src/uu/env/locales/en-US.ftl new file mode 100644 index 000000000..4204cb2e4 --- /dev/null +++ b/src/uu/env/locales/en-US.ftl @@ -0,0 +1,3 @@ +env-about = Set each NAME to VALUE in the environment and run COMMAND +env-usage = env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...] +env-after-help = A mere - implies -i. If no COMMAND, print the resulting environment. diff --git a/src/uu/env/src/env.rs b/src/uu/env/src/env.rs index 51479b590..dbf5f1d56 100644 --- a/src/uu/env/src/env.rs +++ b/src/uu/env/src/env.rs @@ -36,7 +36,7 @@ use uucore::error::{ExitCode, UError, UResult, USimpleError, UUsageError}; use uucore::line_ending::LineEnding; #[cfg(unix)] use uucore::signals::signal_by_name_or_value; -use uucore::{format_usage, help_about, help_section, help_usage, show_warning}; +use uucore::{format_usage, show_warning}; use thiserror::Error; @@ -74,9 +74,7 @@ impl From for EnvError { } } -const ABOUT: &str = help_about!("env.md"); -const USAGE: &str = help_usage!("env.md"); -const AFTER_HELP: &str = help_section!("after help", "env.md"); +use uucore::locale::get_message; mod options { pub const IGNORE_ENVIRONMENT: &str = "ignore-environment"; @@ -222,9 +220,9 @@ fn load_config_file(opts: &mut Options) -> UResult<()> { pub fn uu_app() -> Command { Command::new(crate_name!()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .about(get_message("env-about")) + .override_usage(format_usage(&get_message("env-usage"))) + .after_help(get_message("env-after-help")) .infer_long_args(true) .trailing_var_arg(true) .arg( diff --git a/src/uu/expand/expand.md b/src/uu/expand/expand.md deleted file mode 100644 index df7294c30..000000000 --- a/src/uu/expand/expand.md +++ /dev/null @@ -1,8 +0,0 @@ -# expand - -``` -expand [OPTION]... [FILE]... -``` - -Convert tabs in each `FILE` to spaces, writing to standard output. -With no `FILE`, or when `FILE` is `-`, read standard input. diff --git a/src/uu/expand/locales/en-US.ftl b/src/uu/expand/locales/en-US.ftl new file mode 100644 index 000000000..ad15acf39 --- /dev/null +++ b/src/uu/expand/locales/en-US.ftl @@ -0,0 +1,3 @@ +expand-about = Convert tabs in each FILE to spaces, writing to standard output. + With no FILE, or when FILE is -, read standard input. +expand-usage = expand [OPTION]... [FILE]... diff --git a/src/uu/expand/src/expand.rs b/src/uu/expand/src/expand.rs index 4c37393b4..2e8d1b296 100644 --- a/src/uu/expand/src/expand.rs +++ b/src/uu/expand/src/expand.rs @@ -16,10 +16,9 @@ use thiserror::Error; use unicode_width::UnicodeWidthChar; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult, set_exit_code}; -use uucore::{format_usage, help_about, help_usage, show_error}; +use uucore::{format_usage, show_error}; -const ABOUT: &str = help_about!("expand.md"); -const USAGE: &str = help_usage!("expand.md"); +use uucore::locale::get_message; pub mod options { pub static TABS: &str = "tabs"; @@ -253,9 +252,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) + .about(get_message("expand-about")) .after_help(LONG_HELP) - .override_usage(format_usage(USAGE)) + .override_usage(format_usage(&get_message("expand-usage"))) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/expr/expr.md b/src/uu/expr/expr.md deleted file mode 100644 index ab0824651..000000000 --- a/src/uu/expr/expr.md +++ /dev/null @@ -1,53 +0,0 @@ -# expr - -``` -expr [EXPRESSION] -expr [OPTIONS] -``` - -Print the value of `EXPRESSION` to standard output - -## After help - -Print the value of `EXPRESSION` to standard output. A blank line below -separates increasing precedence groups. - -`EXPRESSION` may be: - -- `ARG1 | ARG2`: `ARG1` if it is neither null nor 0, otherwise `ARG2` -- `ARG1 & ARG2`: `ARG1` if neither argument is null or 0, otherwise 0 -- `ARG1 < ARG2`: `ARG1` is less than `ARG2` -- `ARG1 <= ARG2`: `ARG1` is less than or equal to `ARG2` -- `ARG1 = ARG2`: `ARG1` is equal to `ARG2` -- `ARG1 != ARG2`: `ARG1` is unequal to `ARG2` -- `ARG1 >= ARG2`: `ARG1` is greater than or equal to `ARG2` -- `ARG1 > ARG2`: `ARG1` is greater than `ARG2` -- `ARG1 + ARG2`: arithmetic sum of `ARG1` and `ARG2` -- `ARG1 - ARG2`: arithmetic difference of `ARG1` and `ARG2` -- `ARG1 * ARG2`: arithmetic product of `ARG1` and `ARG2` -- `ARG1 / ARG2`: arithmetic quotient of `ARG1` divided by `ARG2` -- `ARG1 % ARG2`: arithmetic remainder of `ARG1` divided by `ARG2` -- `STRING : REGEXP`: anchored pattern match of `REGEXP` in `STRING` -- `match STRING REGEXP`: same as `STRING : REGEXP` -- `substr STRING POS LENGTH`: substring of `STRING`, `POS` counted from 1 -- `index STRING CHARS`: index in `STRING` where any `CHARS` is found, or 0 -- `length STRING`: length of `STRING` -- `+ TOKEN`: interpret `TOKEN` as a string, even if it is a keyword like `match` - or an operator like `/` -- `( EXPRESSION )`: value of `EXPRESSION` - -Beware that many operators need to be escaped or quoted for shells. -Comparisons are arithmetic if both ARGs are numbers, else lexicographical. -Pattern matches return the string matched between \( and \) or null; if -\( and \) are not used, they return the number of characters matched or 0. - -Exit status is `0` if `EXPRESSION` is neither null nor `0`, `1` if `EXPRESSION` -is null or `0`, `2` if `EXPRESSION` is syntactically invalid, and `3` if an -error occurred. - -Environment variables: - -- `EXPR_DEBUG_TOKENS=1`: dump expression's tokens -- `EXPR_DEBUG_RPN=1`: dump expression represented in reverse polish notation -- `EXPR_DEBUG_SYA_STEP=1`: dump each parser step -- `EXPR_DEBUG_AST=1`: dump expression represented abstract syntax tree diff --git a/src/uu/expr/locales/en-US.ftl b/src/uu/expr/locales/en-US.ftl new file mode 100644 index 000000000..f334d58ee --- /dev/null +++ b/src/uu/expr/locales/en-US.ftl @@ -0,0 +1,45 @@ +expr-about = Print the value of EXPRESSION to standard output +expr-usage = expr [EXPRESSION] + expr [OPTIONS] +expr-after-help = Print the value of EXPRESSION to standard output. A blank line below + separates increasing precedence groups. + + EXPRESSION may be: + + - ARG1 | ARG2: ARG1 if it is neither null nor 0, otherwise ARG2 + - ARG1 & ARG2: ARG1 if neither argument is null or 0, otherwise 0 + - ARG1 < ARG2: ARG1 is less than ARG2 + - ARG1 <= ARG2: ARG1 is less than or equal to ARG2 + - ARG1 = ARG2: ARG1 is equal to ARG2 + - ARG1 != ARG2: ARG1 is unequal to ARG2 + - ARG1 >= ARG2: ARG1 is greater than or equal to ARG2 + - ARG1 > ARG2: ARG1 is greater than ARG2 + - ARG1 + ARG2: arithmetic sum of ARG1 and ARG2 + - ARG1 - ARG2: arithmetic difference of ARG1 and ARG2 + - ARG1 * ARG2: arithmetic product of ARG1 and ARG2 + - ARG1 / ARG2: arithmetic quotient of ARG1 divided by ARG2 + - ARG1 % ARG2: arithmetic remainder of ARG1 divided by ARG2 + - STRING : REGEXP: anchored pattern match of REGEXP in STRING + - match STRING REGEXP: same as STRING : REGEXP + - substr STRING POS LENGTH: substring of STRING, POS counted from 1 + - index STRING CHARS: index in STRING where any CHARS is found, or 0 + - length STRING: length of STRING + - + TOKEN: interpret TOKEN as a string, even if it is a keyword like match + or an operator like / + - ( EXPRESSION ): value of EXPRESSION + + Beware that many operators need to be escaped or quoted for shells. + Comparisons are arithmetic if both ARGs are numbers, else lexicographical. + Pattern matches return the string matched between \( and \) or null; if + \( and \) are not used, they return the number of characters matched or 0. + + Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION + is null or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an + error occurred. + + Environment variables: + + - EXPR_DEBUG_TOKENS=1: dump expression's tokens + - EXPR_DEBUG_RPN=1: dump expression represented in reverse polish notation + - EXPR_DEBUG_SYA_STEP=1: dump each parser step + - EXPR_DEBUG_AST=1: dump expression represented abstract syntax tree diff --git a/src/uu/expr/src/expr.rs b/src/uu/expr/src/expr.rs index 6a4f9487b..e43b5a362 100644 --- a/src/uu/expr/src/expr.rs +++ b/src/uu/expr/src/expr.rs @@ -6,10 +6,11 @@ use clap::{Arg, ArgAction, Command}; use syntax_tree::{AstNode, is_truthy}; use thiserror::Error; +use uucore::locale::get_message; use uucore::{ display::Quotable, error::{UError, UResult}, - format_usage, help_about, help_section, help_usage, + format_usage, }; mod syntax_tree; @@ -67,9 +68,9 @@ impl UError for ExprError { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(help_about!("expr.md")) - .override_usage(format_usage(help_usage!("expr.md"))) - .after_help(help_section!("after help", "expr.md")) + .about(get_message("expr-about")) + .override_usage(format_usage(&get_message("expr-usage"))) + .after_help(get_message("expr-after-help")) .infer_long_args(true) .disable_help_flag(true) .disable_version_flag(true) diff --git a/src/uu/factor/factor.md b/src/uu/factor/factor.md deleted file mode 100644 index ccce4f252..000000000 --- a/src/uu/factor/factor.md +++ /dev/null @@ -1,8 +0,0 @@ -# factor - -``` -factor [OPTION]... [NUMBER]... -``` - -Print the prime factors of the given NUMBER(s). -If none are specified, read from standard input. diff --git a/src/uu/factor/locales/en-US.ftl b/src/uu/factor/locales/en-US.ftl new file mode 100644 index 000000000..07e7920c5 --- /dev/null +++ b/src/uu/factor/locales/en-US.ftl @@ -0,0 +1,3 @@ +factor-about = Print the prime factors of the given NUMBER(s). + If none are specified, read from standard input. +factor-usage = factor [OPTION]... [NUMBER]... diff --git a/src/uu/factor/src/factor.rs b/src/uu/factor/src/factor.rs index 2c8d1661c..4820190f4 100644 --- a/src/uu/factor/src/factor.rs +++ b/src/uu/factor/src/factor.rs @@ -14,10 +14,9 @@ use num_bigint::BigUint; use num_traits::FromPrimitive; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, set_exit_code}; -use uucore::{format_usage, help_about, help_usage, show_error, show_warning}; +use uucore::{format_usage, show_error, show_warning}; -const ABOUT: &str = help_about!("factor.md"); -const USAGE: &str = help_usage!("factor.md"); +use uucore::locale::get_message; mod options { pub static EXPONENTS: &str = "exponents"; @@ -122,8 +121,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("factor-about")) + .override_usage(format_usage(&get_message("factor-usage"))) .infer_long_args(true) .disable_help_flag(true) .args_override_self(true) diff --git a/src/uu/false/false.md b/src/uu/false/false.md deleted file mode 100644 index 3f0594767..000000000 --- a/src/uu/false/false.md +++ /dev/null @@ -1,11 +0,0 @@ -# false - -``` -false -``` - -Returns false, an unsuccessful exit status. - -Immediately returns with the exit status `1`. When invoked with one of the recognized options it -will try to write the help or version text. Any IO error during this operation is diagnosed, yet -the program will also return `1`. diff --git a/src/uu/false/locales/en-US.ftl b/src/uu/false/locales/en-US.ftl new file mode 100644 index 000000000..8b642a69f --- /dev/null +++ b/src/uu/false/locales/en-US.ftl @@ -0,0 +1,5 @@ +false-about = Returns false, an unsuccessful exit status. + + Immediately returns with the exit status 1. When invoked with one of the recognized options it + will try to write the help or version text. Any IO error during this operation is diagnosed, yet + the program will also return 1. diff --git a/src/uu/false/src/false.rs b/src/uu/false/src/false.rs index adf3593ea..b8bf3a825 100644 --- a/src/uu/false/src/false.rs +++ b/src/uu/false/src/false.rs @@ -5,9 +5,8 @@ use clap::{Arg, ArgAction, Command}; use std::{ffi::OsString, io::Write}; use uucore::error::{UResult, set_exit_code}; -use uucore::help_about; -const ABOUT: &str = help_about!("false.md"); +use uucore::locale::get_message; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { @@ -46,7 +45,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) + .about(get_message("false-about")) // We provide our own help and version options, to ensure maximum compatibility with GNU. .disable_help_flag(true) .disable_version_flag(true) diff --git a/src/uu/fmt/fmt.md b/src/uu/fmt/fmt.md deleted file mode 100644 index 6ed7d3048..000000000 --- a/src/uu/fmt/fmt.md +++ /dev/null @@ -1,7 +0,0 @@ -# fmt - -``` -fmt [-WIDTH] [OPTION]... [FILE]... -``` - -Reformat paragraphs from input files (or stdin) to stdout. diff --git a/src/uu/fmt/locales/en-US.ftl b/src/uu/fmt/locales/en-US.ftl new file mode 100644 index 000000000..c572e7f5c --- /dev/null +++ b/src/uu/fmt/locales/en-US.ftl @@ -0,0 +1,2 @@ +fmt-about = Reformat paragraphs from input files (or stdin) to stdout. +fmt-usage = fmt [-WIDTH] [OPTION]... [FILE]... diff --git a/src/uu/fmt/src/fmt.rs b/src/uu/fmt/src/fmt.rs index 8366af6cd..bb79c2c59 100644 --- a/src/uu/fmt/src/fmt.rs +++ b/src/uu/fmt/src/fmt.rs @@ -10,16 +10,15 @@ use std::fs::File; use std::io::{BufReader, BufWriter, Read, Stdout, Write, stdin, stdout}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; use linebreak::break_lines; use parasplit::ParagraphStream; +use uucore::locale::get_message; mod linebreak; mod parasplit; -const ABOUT: &str = help_about!("fmt.md"); -const USAGE: &str = help_usage!("fmt.md"); const MAX_WIDTH: usize = 2500; const DEFAULT_GOAL: usize = 70; const DEFAULT_WIDTH: usize = 75; @@ -336,8 +335,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("fmt-about")) + .override_usage(format_usage(&get_message("fmt-usage"))) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/fold/fold.md b/src/uu/fold/fold.md deleted file mode 100644 index 13062c858..000000000 --- a/src/uu/fold/fold.md +++ /dev/null @@ -1,8 +0,0 @@ -# fold - -``` -fold [OPTION]... [FILE]... -``` - -Writes each file (or standard input if no files are given) -to standard output whilst breaking long lines diff --git a/src/uu/fold/locales/en-US.ftl b/src/uu/fold/locales/en-US.ftl new file mode 100644 index 000000000..5d5bb40a6 --- /dev/null +++ b/src/uu/fold/locales/en-US.ftl @@ -0,0 +1,3 @@ +fold-about = Writes each file (or standard input if no files are given) + to standard output whilst breaking long lines +fold-usage = fold [OPTION]... [FILE]... diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 0aba9c57e..465f96433 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -11,13 +11,11 @@ use std::io::{BufRead, BufReader, Read, stdin}; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; const TAB_WIDTH: usize = 8; -const USAGE: &str = help_usage!("fold.md"); -const ABOUT: &str = help_about!("fold.md"); - mod options { pub const BYTES: &str = "bytes"; pub const SPACES: &str = "spaces"; @@ -60,8 +58,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("fold-usage"))) + .about(get_message("fold-about")) .infer_long_args(true) .arg( Arg::new(options::BYTES) diff --git a/src/uu/groups/groups.md b/src/uu/groups/groups.md deleted file mode 100644 index 1d11d5e46..000000000 --- a/src/uu/groups/groups.md +++ /dev/null @@ -1,8 +0,0 @@ -# groups - -``` -groups [OPTION]... [USERNAME]... -``` - -Print group memberships for each `USERNAME` or, if no `USERNAME` is specified, for -the current process (which may differ if the groups data‐base has changed). diff --git a/src/uu/groups/locales/en-US.ftl b/src/uu/groups/locales/en-US.ftl new file mode 100644 index 000000000..ec6cc8855 --- /dev/null +++ b/src/uu/groups/locales/en-US.ftl @@ -0,0 +1,3 @@ +groups-about = Print group memberships for each USERNAME or, if no USERNAME is specified, for + the current process (which may differ if the groups data‐base has changed). +groups-usage = groups [OPTION]... [USERNAME]... diff --git a/src/uu/groups/src/groups.rs b/src/uu/groups/src/groups.rs index 6f7fbf5fe..54f5afbe3 100644 --- a/src/uu/groups/src/groups.rs +++ b/src/uu/groups/src/groups.rs @@ -10,16 +10,15 @@ use uucore::{ display::Quotable, entries::{Locate, Passwd, get_groups_gnu, gid2grp}, error::{UError, UResult}, - format_usage, help_about, help_usage, show, + format_usage, show, }; use clap::{Arg, ArgAction, Command}; +use uucore::locale::get_message; mod options { pub const USERS: &str = "USERNAME"; } -const ABOUT: &str = help_about!("groups.md"); -const USAGE: &str = help_usage!("groups.md"); #[derive(Debug, Error)] enum GroupsError { @@ -82,8 +81,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("groups-about")) + .override_usage(format_usage(&get_message("groups-usage"))) .infer_long_args(true) .arg( Arg::new(options::USERS) diff --git a/src/uu/hashsum/hashsum.md b/src/uu/hashsum/hashsum.md deleted file mode 100644 index 35ec840a3..000000000 --- a/src/uu/hashsum/hashsum.md +++ /dev/null @@ -1,7 +0,0 @@ -# hashsum - -``` -hashsum -- [OPTIONS]... [FILE]... -``` - -Compute and check message digests. diff --git a/src/uu/hashsum/locales/en-US.ftl b/src/uu/hashsum/locales/en-US.ftl new file mode 100644 index 000000000..790171034 --- /dev/null +++ b/src/uu/hashsum/locales/en-US.ftl @@ -0,0 +1,2 @@ +hashsum-about = Compute and check message digests. +hashsum-usage = hashsum -- [OPTIONS]... [FILE]... diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index cd8ca912d..621ec5a0b 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -26,12 +26,11 @@ use uucore::checksum::digest_reader; use uucore::checksum::escape_filename; use uucore::checksum::perform_checksum_validation; use uucore::error::{FromIo, UResult}; +use uucore::format_usage; +use uucore::locale::get_message; use uucore::sum::{Digest, Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256}; -use uucore::{format_usage, help_about, help_usage}; const NAME: &str = "hashsum"; -const ABOUT: &str = help_about!("hashsum.md"); -const USAGE: &str = help_usage!("hashsum.md"); struct Options { algoname: &'static str, @@ -318,8 +317,8 @@ pub fn uu_app_common() -> Command { const TEXT_HELP: &str = "read in text mode (default)"; Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("hashsum-about")) + .override_usage(format_usage(&get_message("hashsum-usage"))) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/head/head.md b/src/uu/head/head.md deleted file mode 100644 index 476f3affc..000000000 --- a/src/uu/head/head.md +++ /dev/null @@ -1,11 +0,0 @@ -# head - -``` -head [FLAG]... [FILE]... -``` - -Print the first 10 lines of each `FILE` to standard output. -With more than one `FILE`, precede each with a header giving the file name. -With no `FILE`, or when `FILE` is `-`, read standard input. - -Mandatory arguments to long flags are mandatory for short flags too. diff --git a/src/uu/head/locales/en-US.ftl b/src/uu/head/locales/en-US.ftl new file mode 100644 index 000000000..4b702b6bc --- /dev/null +++ b/src/uu/head/locales/en-US.ftl @@ -0,0 +1,6 @@ +head-about = Print the first 10 lines of each FILE to standard output. + With more than one FILE, precede each with a header giving the file name. + With no FILE, or when FILE is -, read standard input. + + Mandatory arguments to long flags are mandatory for short flags too. +head-usage = head [FLAG]... [FILE]... diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index 573926a7b..f6711d960 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -16,13 +16,10 @@ use thiserror::Error; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult}; use uucore::line_ending::LineEnding; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; const BUF_SIZE: usize = 65536; -const ABOUT: &str = help_about!("head.md"); -const USAGE: &str = help_usage!("head.md"); - mod options { pub const BYTES_NAME: &str = "BYTES"; pub const LINES_NAME: &str = "LINES"; @@ -38,6 +35,7 @@ mod take; use take::copy_all_but_n_bytes; use take::copy_all_but_n_lines; use take::take_lines; +use uucore::locale::get_message; #[derive(Error, Debug)] enum HeadError { @@ -72,8 +70,8 @@ type HeadResult = Result; pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("head-about")) + .override_usage(format_usage(&get_message("head-usage"))) .infer_long_args(true) .arg( Arg::new(options::BYTES_NAME) diff --git a/src/uu/hostid/hostid.md b/src/uu/hostid/hostid.md deleted file mode 100644 index 940cf5e5d..000000000 --- a/src/uu/hostid/hostid.md +++ /dev/null @@ -1,7 +0,0 @@ -# hostid - -``` -hostid [options] -``` - -Print the numeric identifier (in hexadecimal) for the current host diff --git a/src/uu/hostid/locales/en-US.ftl b/src/uu/hostid/locales/en-US.ftl new file mode 100644 index 000000000..25abe94f7 --- /dev/null +++ b/src/uu/hostid/locales/en-US.ftl @@ -0,0 +1,2 @@ +hostid-about = Print the numeric identifier (in hexadecimal) for the current host +hostid-usage = hostid [options] diff --git a/src/uu/hostid/src/hostid.rs b/src/uu/hostid/src/hostid.rs index a01151dde..aa29bd8fa 100644 --- a/src/uu/hostid/src/hostid.rs +++ b/src/uu/hostid/src/hostid.rs @@ -7,10 +7,9 @@ use clap::Command; use libc::{c_long, gethostid}; -use uucore::{error::UResult, format_usage, help_about, help_usage}; +use uucore::{error::UResult, format_usage}; -const USAGE: &str = help_usage!("hostid.md"); -const ABOUT: &str = help_about!("hostid.md"); +use uucore::locale::get_message; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { @@ -22,8 +21,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("hostid-about")) + .override_usage(format_usage(&get_message("hostid-usage"))) .infer_long_args(true) } diff --git a/src/uu/hostname/hostname.md b/src/uu/hostname/hostname.md deleted file mode 100644 index f9e852c4b..000000000 --- a/src/uu/hostname/hostname.md +++ /dev/null @@ -1,7 +0,0 @@ -# hostname - -``` -hostname [OPTION]... [HOSTNAME] -``` - -Display or set the system's host name. diff --git a/src/uu/hostname/locales/en-US.ftl b/src/uu/hostname/locales/en-US.ftl new file mode 100644 index 000000000..8ad9ab52e --- /dev/null +++ b/src/uu/hostname/locales/en-US.ftl @@ -0,0 +1,2 @@ +hostname-about = Display or set the system's host name. +hostname-usage = hostname [OPTION]... [HOSTNAME] diff --git a/src/uu/hostname/src/hostname.rs b/src/uu/hostname/src/hostname.rs index 29b2bb6ba..05252883e 100644 --- a/src/uu/hostname/src/hostname.rs +++ b/src/uu/hostname/src/hostname.rs @@ -15,15 +15,13 @@ use clap::{Arg, ArgAction, ArgMatches, Command}; #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] use dns_lookup::lookup_host; +use uucore::locale::get_message; use uucore::{ error::{FromIo, UResult}, - format_usage, help_about, help_usage, + format_usage, }; -const ABOUT: &str = help_about!("hostname.md"); -const USAGE: &str = help_usage!("hostname.md"); - static OPT_DOMAIN: &str = "domain"; static OPT_IP_ADDRESS: &str = "ip-address"; static OPT_FQDN: &str = "fqdn"; @@ -76,8 +74,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("hostname-about")) + .override_usage(format_usage(&get_message("hostname-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_DOMAIN) diff --git a/src/uu/id/id.md b/src/uu/id/id.md deleted file mode 100644 index bb7330314..000000000 --- a/src/uu/id/id.md +++ /dev/null @@ -1,18 +0,0 @@ -# id - -``` -id [OPTION]... [USER]... -``` - -Print user and group information for each specified `USER`, -or (when `USER` omitted) for the current user. - -## After help - -The id utility displays the user and group names and numeric IDs, of the -calling process, to the standard output. If the real and effective IDs are -different, both are displayed, otherwise only the real ID is displayed. - -If a user (login name or user ID) is specified, the user and group IDs of -that user are displayed. In this case, the real and effective IDs are -assumed to be the same. diff --git a/src/uu/id/locales/en-US.ftl b/src/uu/id/locales/en-US.ftl new file mode 100644 index 000000000..fd7b8348b --- /dev/null +++ b/src/uu/id/locales/en-US.ftl @@ -0,0 +1,10 @@ +id-about = Print user and group information for each specified USER, + or (when USER omitted) for the current user. +id-usage = id [OPTION]... [USER]... +id-after-help = The id utility displays the user and group names and numeric IDs, of the + calling process, to the standard output. If the real and effective IDs are + different, both are displayed, otherwise only the real ID is displayed. + + If a user (login name or user ID) is specified, the user and group IDs of + that user are displayed. In this case, the real and effective IDs are + assumed to be the same. diff --git a/src/uu/id/src/id.rs b/src/uu/id/src/id.rs index 314d12d68..a08314748 100644 --- a/src/uu/id/src/id.rs +++ b/src/uu/id/src/id.rs @@ -42,8 +42,9 @@ use uucore::error::{USimpleError, set_exit_code}; pub use uucore::libc; use uucore::libc::{getlogin, uid_t}; use uucore::line_ending::LineEnding; +use uucore::locale::get_message; use uucore::process::{getegid, geteuid, getgid, getuid}; -use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +use uucore::{format_usage, show_error}; macro_rules! cstr2cow { ($v:expr) => { @@ -59,10 +60,6 @@ macro_rules! cstr2cow { }; } -const ABOUT: &str = help_about!("id.md"); -const USAGE: &str = help_usage!("id.md"); -const AFTER_HELP: &str = help_section!("after help", "id.md"); - #[cfg(not(feature = "selinux"))] static CONTEXT_HELP_TEXT: &str = "print only the security context of the process (not enabled)"; #[cfg(feature = "selinux")] @@ -119,7 +116,9 @@ struct State { #[uucore::main] #[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; + let matches = uu_app() + .after_help(get_message("id-after-help")) + .try_get_matches_from(args)?; let users: Vec = matches .get_many::(options::ARG_USERS) @@ -327,8 +326,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("id-about")) + .override_usage(format_usage(&get_message("id-usage"))) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/install/install.md b/src/uu/install/install.md deleted file mode 100644 index ac6a70f42..000000000 --- a/src/uu/install/install.md +++ /dev/null @@ -1,8 +0,0 @@ -# install - -``` -install [OPTION]... [FILE]... -``` - -Copy SOURCE to DEST or multiple SOURCE(s) to the existing -DIRECTORY, while setting permission modes and owner/group diff --git a/src/uu/install/locales/en-US.ftl b/src/uu/install/locales/en-US.ftl new file mode 100644 index 000000000..b5781abfb --- /dev/null +++ b/src/uu/install/locales/en-US.ftl @@ -0,0 +1,3 @@ +install-about = Copy SOURCE to DEST or multiple SOURCE(s) to the existing + DIRECTORY, while setting permission modes and owner/group +install-usage = install [OPTION]... [FILE]... diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index c4590240b..4d93a3fc4 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -27,12 +27,13 @@ use uucore::perms::{Verbosity, VerbosityLevel, wrap_chown}; use uucore::process::{getegid, geteuid}; #[cfg(feature = "selinux")] use uucore::selinux::{contexts_differ, set_selinux_security_context}; -use uucore::{format_usage, help_about, help_usage, show, show_error, show_if_err}; +use uucore::{format_usage, show, show_error, show_if_err}; #[cfg(unix)] use std::os::unix::fs::{FileTypeExt, MetadataExt}; #[cfg(unix)] use std::os::unix::prelude::OsStrExt; +use uucore::locale::get_message; const DEFAULT_MODE: u32 = 0o755; const DEFAULT_STRIP_PROGRAM: &str = "strip"; @@ -140,9 +141,6 @@ impl Behavior { } } -const ABOUT: &str = help_about!("install.md"); -const USAGE: &str = help_usage!("install.md"); - static OPT_COMPARE: &str = "compare"; static OPT_DIRECTORY: &str = "directory"; static OPT_IGNORED: &str = "ignored"; @@ -185,8 +183,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("install-about")) + .override_usage(format_usage(&get_message("install-usage"))) .infer_long_args(true) .arg(backup_control::arguments::backup()) .arg(backup_control::arguments::backup_no_args()) @@ -516,7 +514,11 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { return Err(UUsageError::new(1, "missing file operand")); } if b.no_target_dir && paths.len() > 2 { - return Err(InstallError::ExtraOperand(paths[2].clone(), format_usage(USAGE)).into()); + return Err(InstallError::ExtraOperand( + paths[2].clone(), + format_usage(&get_message("install-usage")), + ) + .into()); } // get the target from either "-t foo" param or from the last given paths argument diff --git a/src/uu/join/join.md b/src/uu/join/join.md deleted file mode 100644 index 04275342a..000000000 --- a/src/uu/join/join.md +++ /dev/null @@ -1,10 +0,0 @@ -# join - -``` -join [OPTION]... FILE1 FILE2 -``` - -For each pair of input lines with identical join fields, write a line to -standard output. The default join field is the first, delimited by blanks. - -When `FILE1` or `FILE2` (not both) is `-`, read standard input. diff --git a/src/uu/join/locales/en-US.ftl b/src/uu/join/locales/en-US.ftl new file mode 100644 index 000000000..e5d005384 --- /dev/null +++ b/src/uu/join/locales/en-US.ftl @@ -0,0 +1,5 @@ +join-about = For each pair of input lines with identical join fields, write a line to + standard output. The default join field is the first, delimited by blanks. + + When FILE1 or FILE2 (not both) is -, read standard input. +join-usage = join [OPTION]... FILE1 FILE2 diff --git a/src/uu/join/src/join.rs b/src/uu/join/src/join.rs index 0c6816cb6..e676dadaa 100644 --- a/src/uu/join/src/join.rs +++ b/src/uu/join/src/join.rs @@ -18,11 +18,10 @@ use std::os::unix::ffi::OsStrExt; use thiserror::Error; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult, USimpleError, set_exit_code}; +use uucore::format_usage; use uucore::line_ending::LineEnding; -use uucore::{format_usage, help_about, help_usage}; -const ABOUT: &str = help_about!("join.md"); -const USAGE: &str = help_usage!("join.md"); +use uucore::locale::get_message; #[derive(Debug, Error)] enum JoinError { @@ -855,8 +854,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("join-about")) + .override_usage(format_usage(&get_message("join-usage"))) .infer_long_args(true) .arg( Arg::new("a") diff --git a/src/uu/kill/kill.md b/src/uu/kill/kill.md deleted file mode 100644 index 1e3e2b3d0..000000000 --- a/src/uu/kill/kill.md +++ /dev/null @@ -1,7 +0,0 @@ -# kill - -``` -kill [OPTIONS]... PID... -``` - -Send signal to processes or list information about signals. diff --git a/src/uu/kill/locales/en-US.ftl b/src/uu/kill/locales/en-US.ftl new file mode 100644 index 000000000..3038adaed --- /dev/null +++ b/src/uu/kill/locales/en-US.ftl @@ -0,0 +1,2 @@ +kill-about = Send signal to processes or list information about signals. +kill-usage = kill [OPTIONS]... PID... diff --git a/src/uu/kill/src/kill.rs b/src/uu/kill/src/kill.rs index 8d8aa0b61..6c67aede9 100644 --- a/src/uu/kill/src/kill.rs +++ b/src/uu/kill/src/kill.rs @@ -12,10 +12,9 @@ use std::io::Error; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; use uucore::signals::{ALL_SIGNALS, signal_by_name_or_value, signal_name_by_value}; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; -static ABOUT: &str = help_about!("kill.md"); -const USAGE: &str = help_usage!("kill.md"); +use uucore::locale::get_message; // When the -l option is selected, the program displays the type of signal related to a certain // value or string. In case of a value, the program should control the lower 8 bits, but there is @@ -104,8 +103,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("kill-about")) + .override_usage(format_usage(&get_message("kill-usage"))) .infer_long_args(true) .allow_negative_numbers(true) .arg( diff --git a/src/uu/link/link.md b/src/uu/link/link.md deleted file mode 100644 index ea6a531b9..000000000 --- a/src/uu/link/link.md +++ /dev/null @@ -1,7 +0,0 @@ -# link - -``` -link FILE1 FILE2 -``` - -Call the link function to create a link named FILE2 to an existing FILE1. diff --git a/src/uu/link/locales/en-US.ftl b/src/uu/link/locales/en-US.ftl new file mode 100644 index 000000000..7a18c0900 --- /dev/null +++ b/src/uu/link/locales/en-US.ftl @@ -0,0 +1,2 @@ +link-about = Call the link function to create a link named FILE2 to an existing FILE1. +link-usage = link FILE1 FILE2 diff --git a/src/uu/link/src/link.rs b/src/uu/link/src/link.rs index 31f1239d8..5ff1760ba 100644 --- a/src/uu/link/src/link.rs +++ b/src/uu/link/src/link.rs @@ -9,10 +9,9 @@ use std::fs::hard_link; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UResult}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; -static ABOUT: &str = help_about!("link.md"); -const USAGE: &str = help_usage!("link.md"); +use uucore::locale::get_message; pub mod options { pub static FILES: &str = "FILES"; @@ -36,8 +35,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("link-about")) + .override_usage(format_usage(&get_message("link-usage"))) .infer_long_args(true) .arg( Arg::new(options::FILES) diff --git a/src/uu/ln/ln.md b/src/uu/ln/ln.md deleted file mode 100644 index 6bd6ee016..000000000 --- a/src/uu/ln/ln.md +++ /dev/null @@ -1,21 +0,0 @@ -# ln - -``` -ln [OPTION]... [-T] TARGET LINK_NAME -ln [OPTION]... TARGET -ln [OPTION]... TARGET... DIRECTORY -ln [OPTION]... -t DIRECTORY TARGET... -``` - -Make links between files. - -## After Help - -In the 1st form, create a link to TARGET with the name LINK_NAME. -In the 2nd form, create a link to TARGET in the current directory. -In the 3rd and 4th forms, create links to each TARGET in DIRECTORY. -Create hard links by default, symbolic links with --symbolic. -By default, each destination (name of new link) should not already exist. -When creating hard links, each TARGET must exist. Symbolic links -can hold arbitrary text; if later resolved, a relative link is -interpreted in relation to its parent directory. diff --git a/src/uu/ln/locales/en-US.ftl b/src/uu/ln/locales/en-US.ftl new file mode 100644 index 000000000..7de0c171e --- /dev/null +++ b/src/uu/ln/locales/en-US.ftl @@ -0,0 +1,13 @@ +ln-about = Make links between files. +ln-usage = ln [OPTION]... [-T] TARGET LINK_NAME + ln [OPTION]... TARGET + ln [OPTION]... TARGET... DIRECTORY + ln [OPTION]... -t DIRECTORY TARGET... +ln-after-help = In the 1st form, create a link to TARGET with the name LINK_NAME. + In the 2nd form, create a link to TARGET in the current directory. + In the 3rd and 4th forms, create links to each TARGET in DIRECTORY. + Create hard links by default, symbolic links with --symbolic. + By default, each destination (name of new link) should not already exist. + When creating hard links, each TARGET must exist. Symbolic links + can hold arbitrary text; if later resolved, a relative link is + interpreted in relation to its parent directory. diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index c46407648..960085200 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -9,7 +9,7 @@ use clap::{Arg, ArgAction, Command}; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult}; use uucore::fs::{make_path_relative_to, paths_refer_to_same_file}; -use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show_error}; +use uucore::{format_usage, prompt_yes, show_error}; use std::borrow::Cow; use std::collections::HashSet; @@ -24,6 +24,7 @@ use std::os::windows::fs::{symlink_dir, symlink_file}; use std::path::{Path, PathBuf}; use uucore::backup_control::{self, BackupMode}; use uucore::fs::{MissingHandling, ResolveMode, canonicalize}; +use uucore::locale::get_message; pub struct Settings { overwrite: OverwriteMode, @@ -70,10 +71,6 @@ impl UError for LnError { } } -const ABOUT: &str = help_about!("ln.md"); -const USAGE: &str = help_usage!("ln.md"); -const AFTER_HELP: &str = help_section!("after help", "ln.md"); - mod options { pub const FORCE: &str = "force"; //pub const DIRECTORY: &str = "directory"; @@ -93,7 +90,8 @@ static ARG_FILES: &str = "files"; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let after_help = format!( - "{AFTER_HELP}\n\n{}", + "{}\n\n{}", + get_message("ln-after-help"), backup_control::BACKUP_CONTROL_LONG_HELP ); @@ -144,8 +142,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("ln-about")) + .override_usage(format_usage(&get_message("ln-usage"))) .infer_long_args(true) .arg(backup_control::arguments::backup()) .arg(backup_control::arguments::backup_no_args()) diff --git a/src/uu/logname/locales/en-US.ftl b/src/uu/logname/locales/en-US.ftl new file mode 100644 index 000000000..038b757bc --- /dev/null +++ b/src/uu/logname/locales/en-US.ftl @@ -0,0 +1 @@ +logname-about = Print user's login name diff --git a/src/uu/logname/logname.md b/src/uu/logname/logname.md deleted file mode 100644 index b997c206b..000000000 --- a/src/uu/logname/logname.md +++ /dev/null @@ -1,7 +0,0 @@ -# logname - -``` -logname -``` - -Print user's login name diff --git a/src/uu/logname/src/logname.rs b/src/uu/logname/src/logname.rs index 5437bbae3..1ed1efb5f 100644 --- a/src/uu/logname/src/logname.rs +++ b/src/uu/logname/src/logname.rs @@ -7,7 +7,8 @@ use clap::Command; use std::ffi::CStr; -use uucore::{error::UResult, format_usage, help_about, help_usage, show_error}; +use uucore::locale::get_message; +use uucore::{error::UResult, show_error}; unsafe extern "C" { // POSIX requires using getlogin (or equivalent code) @@ -25,9 +26,6 @@ fn get_userlogin() -> Option { } } -const ABOUT: &str = help_about!("logname.md"); -const USAGE: &str = help_usage!("logname.md"); - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let _ = uu_app().try_get_matches_from(args)?; @@ -43,7 +41,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(uucore::util_name()) + .about(get_message("logname-about")) .infer_long_args(true) } diff --git a/src/uu/ls/locales/en-US.ftl b/src/uu/ls/locales/en-US.ftl new file mode 100644 index 000000000..b21aefa22 --- /dev/null +++ b/src/uu/ls/locales/en-US.ftl @@ -0,0 +1,4 @@ +ls-about = List directory contents. + Ignore files and directories starting with a '.' by default +ls-usage = ls [OPTION]... [FILE]... +ls-after-help = The TIME_STYLE argument can be full-iso, long-iso, iso, locale or +FORMAT. FORMAT is interpreted like in date. Also the TIME_STYLE environment variable sets the default style to use. diff --git a/src/uu/ls/ls.md b/src/uu/ls/ls.md deleted file mode 100644 index 01eec7e50..000000000 --- a/src/uu/ls/ls.md +++ /dev/null @@ -1,12 +0,0 @@ -# ls - -``` -ls [OPTION]... [FILE]... -``` - -List directory contents. -Ignore files and directories starting with a '.' by default - -## After help - -The TIME_STYLE argument can be full-iso, long-iso, iso, locale or +FORMAT. FORMAT is interpreted like in date. Also the TIME_STYLE environment variable sets the default style to use. diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index b2c98689d..f3884f302 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -37,8 +37,11 @@ use jiff::{Timestamp, Zoned}; use lscolors::LsColors; use term_grid::{DEFAULT_SEPARATOR_SIZE, Direction, Filling, Grid, GridOptions, SPACES_IN_TAB}; use thiserror::Error; +#[cfg(unix)] +use uucore::entries; use uucore::error::USimpleError; use uucore::format::human::{SizeFormat, human_readable}; +use uucore::fs::FileInformation; #[cfg(all(unix, not(any(target_os = "android", target_os = "macos"))))] use uucore::fsxattr::has_acl; #[cfg(unix)] @@ -57,6 +60,7 @@ use uucore::libc::{S_IXGRP, S_IXOTH, S_IXUSR}; ))] use uucore::libc::{dev_t, major, minor}; use uucore::line_ending::LineEnding; +use uucore::locale::get_message; use uucore::quoting_style::{self, QuotingStyle, escape_name}; use uucore::{ display::Quotable, @@ -68,9 +72,7 @@ use uucore::{ parser::shortcut_value_parser::ShortcutValueParser, version_cmp::version_cmp, }; -use uucore::{ - help_about, help_section, help_usage, parser::parse_glob, show, show_error, show_warning, -}; +use uucore::{parser::parse_glob, show, show_error, show_warning}; mod dired; use dired::{DiredOutput, is_dired_arg_present}; @@ -82,10 +84,6 @@ static CONTEXT_HELP_TEXT: &str = "print any security context of each file (not e #[cfg(feature = "selinux")] static CONTEXT_HELP_TEXT: &str = "print any security context of each file"; -const ABOUT: &str = help_about!("ls.md"); -const AFTER_HELP: &str = help_section!("after help", "ls.md"); -const USAGE: &str = help_usage!("ls.md"); - pub mod options { pub mod format { pub static ONE_LINE: &str = "1"; @@ -1179,8 +1177,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("ls-usage"))) + .about(get_message("ls-about")) .infer_long_args(true) .disable_help_flag(true) .args_override_self(true) @@ -1869,7 +1867,7 @@ pub fn uu_app() -> Command { .value_hint(clap::ValueHint::AnyPath) .value_parser(ValueParser::os_string()), ) - .after_help(AFTER_HELP) + .after_help(get_message("ls-after-help")) } /// Represents a Path along with it's associated data. @@ -3016,10 +3014,6 @@ fn get_inode(metadata: &Metadata) -> String { // Currently getpwuid is `linux` target only. If it's broken state.out into // a posix-compliant attribute this can be updated... -#[cfg(unix)] -use uucore::entries; -use uucore::fs::FileInformation; - #[cfg(unix)] fn display_uname<'a>(metadata: &Metadata, config: &Config, state: &'a mut ListState) -> &'a String { let uid = metadata.uid(); diff --git a/src/uu/mkdir/locales/en-US.ftl b/src/uu/mkdir/locales/en-US.ftl new file mode 100644 index 000000000..042329244 --- /dev/null +++ b/src/uu/mkdir/locales/en-US.ftl @@ -0,0 +1,3 @@ +mkdir-about = Create the given DIRECTORY(ies) if they do not exist +mkdir-usage = mkdir [OPTION]... DIRECTORY... +mkdir-after-help = Each MODE is of the form [ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+. diff --git a/src/uu/mkdir/mkdir.md b/src/uu/mkdir/mkdir.md deleted file mode 100644 index f5dbb2544..000000000 --- a/src/uu/mkdir/mkdir.md +++ /dev/null @@ -1,13 +0,0 @@ -# mkdir - - - -``` -mkdir [OPTION]... DIRECTORY... -``` - -Create the given DIRECTORY(ies) if they do not exist - -## After Help - -Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+`. diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index adef62eee..7fceb36ce 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -13,17 +13,14 @@ use std::path::{Path, PathBuf}; #[cfg(not(windows))] use uucore::error::FromIo; use uucore::error::{UResult, USimpleError}; +use uucore::locale::get_message; #[cfg(not(windows))] use uucore::mode; use uucore::{display::Quotable, fs::dir_strip_dot_for_creation}; -use uucore::{format_usage, help_about, help_section, help_usage, show_if_err}; +use uucore::{format_usage, show_if_err}; static DEFAULT_PERM: u32 = 0o777; -const ABOUT: &str = help_about!("mkdir.md"); -const USAGE: &str = help_usage!("mkdir.md"); -const AFTER_HELP: &str = help_section!("after help", "mkdir.md"); - mod options { pub const MODE: &str = "mode"; pub const PARENTS: &str = "parents"; @@ -103,7 +100,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // Linux-specific options, not implemented // opts.optflag("Z", "context", "set SELinux security context" + // " of each created directory to CTX"), - let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; + let matches = uu_app() + .after_help(get_message("mkdir-after-help")) + .try_get_matches_from(args)?; let dirs = matches .get_many::(options::DIRS) @@ -133,8 +132,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("mkdir-about")) + .override_usage(format_usage(&get_message("mkdir-usage"))) .infer_long_args(true) .arg( Arg::new(options::MODE) diff --git a/src/uu/mkfifo/locales/en-US.ftl b/src/uu/mkfifo/locales/en-US.ftl new file mode 100644 index 000000000..aee4bba92 --- /dev/null +++ b/src/uu/mkfifo/locales/en-US.ftl @@ -0,0 +1,2 @@ +mkfifo-about = Create a FIFO with the given name. +mkfifo-usage = mkfifo [OPTION]... NAME... diff --git a/src/uu/mkfifo/mkfifo.md b/src/uu/mkfifo/mkfifo.md deleted file mode 100644 index b63437829..000000000 --- a/src/uu/mkfifo/mkfifo.md +++ /dev/null @@ -1,7 +0,0 @@ -# mkfifo - -``` -mkfifo [OPTION]... NAME... -``` - -Create a FIFO with the given name. diff --git a/src/uu/mkfifo/src/mkfifo.rs b/src/uu/mkfifo/src/mkfifo.rs index 24c057ebc..ea5880438 100644 --- a/src/uu/mkfifo/src/mkfifo.rs +++ b/src/uu/mkfifo/src/mkfifo.rs @@ -10,10 +10,9 @@ use std::fs; use std::os::unix::fs::PermissionsExt; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; -static USAGE: &str = help_usage!("mkfifo.md"); -static ABOUT: &str = help_about!("mkfifo.md"); +use uucore::locale::get_message; mod options { pub static MODE: &str = "mode"; @@ -86,8 +85,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("mkfifo-usage"))) + .about(get_message("mkfifo-about")) .infer_long_args(true) .arg( Arg::new(options::MODE) diff --git a/src/uu/mknod/locales/en-US.ftl b/src/uu/mknod/locales/en-US.ftl new file mode 100644 index 000000000..c0e391381 --- /dev/null +++ b/src/uu/mknod/locales/en-US.ftl @@ -0,0 +1,17 @@ +mknod-about = Create the special file NAME of the given TYPE. +mknod-usage = mknod [OPTION]... NAME TYPE [MAJOR MINOR] +mknod-after-help = Mandatory arguments to long options are mandatory for short options too. + -m, --mode=MODE set file permission bits to MODE, not a=rw - umask + + Both MAJOR and MINOR must be specified when TYPE is b, c, or u, and they + must be omitted when TYPE is p. If MAJOR or MINOR begins with 0x or 0X, + it is interpreted as hexadecimal; otherwise, if it begins with 0, as octal; + otherwise, as decimal. TYPE may be: + + - b create a block (buffered) special file + - c, u create a character (unbuffered) special file + - p create a FIFO + + NOTE: your shell may have its own version of mknod, which usually supersedes + the version described here. Please refer to your shell's documentation + for details about the options it supports. diff --git a/src/uu/mknod/mknod.md b/src/uu/mknod/mknod.md deleted file mode 100644 index 78da97025..000000000 --- a/src/uu/mknod/mknod.md +++ /dev/null @@ -1,25 +0,0 @@ -# mknod - -``` -mknod [OPTION]... NAME TYPE [MAJOR MINOR] -``` - -Create the special file NAME of the given TYPE. - -## After Help - -Mandatory arguments to long options are mandatory for short options too. -`-m`, `--mode=MODE` set file permission bits to `MODE`, not `a=rw - umask` - -Both `MAJOR` and `MINOR` must be specified when `TYPE` is `b`, `c`, or `u`, and they -must be omitted when `TYPE` is `p`. If `MAJOR` or `MINOR` begins with `0x` or `0X`, -it is interpreted as hexadecimal; otherwise, if it begins with 0, as octal; -otherwise, as decimal. `TYPE` may be: - -* `b` create a block (buffered) special file -* `c`, `u` create a character (unbuffered) special file -* `p` create a FIFO - -NOTE: your shell may have its own version of mknod, which usually supersedes -the version described here. Please refer to your shell's documentation -for details about the options it supports. diff --git a/src/uu/mknod/src/mknod.rs b/src/uu/mknod/src/mknod.rs index 076e639cc..94aa043ca 100644 --- a/src/uu/mknod/src/mknod.rs +++ b/src/uu/mknod/src/mknod.rs @@ -12,11 +12,9 @@ use std::ffi::CString; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError, UUsageError, set_exit_code}; -use uucore::{format_usage, help_about, help_section, help_usage}; +use uucore::format_usage; -const ABOUT: &str = help_about!("mknod.md"); -const USAGE: &str = help_usage!("mknod.md"); -const AFTER_HELP: &str = help_section!("after help", "mknod.md"); +use uucore::locale::get_message; const MODE_RW_UGO: mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; @@ -159,9 +157,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) - .about(ABOUT) + .override_usage(format_usage(&get_message("mknod-usage"))) + .after_help(get_message("mknod-after-help")) + .about(get_message("mknod-about")) .infer_long_args(true) .arg( Arg::new(options::MODE) diff --git a/src/uu/mktemp/locales/en-US.ftl b/src/uu/mktemp/locales/en-US.ftl new file mode 100644 index 000000000..0e290ad97 --- /dev/null +++ b/src/uu/mktemp/locales/en-US.ftl @@ -0,0 +1,2 @@ +mktemp-about = Create a temporary file or directory. +mktemp-usage = mktemp [OPTION]... [TEMPLATE] diff --git a/src/uu/mktemp/mktemp.md b/src/uu/mktemp/mktemp.md deleted file mode 100644 index 75b56d667..000000000 --- a/src/uu/mktemp/mktemp.md +++ /dev/null @@ -1,7 +0,0 @@ -# mktemp - -``` -mktemp [OPTION]... [TEMPLATE] -``` - -Create a temporary file or directory. diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index d689115a6..ec6495084 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -8,7 +8,7 @@ use clap::{Arg, ArgAction, ArgMatches, Command, builder::ValueParser}; use uucore::display::{Quotable, println_verbatim}; use uucore::error::{FromIo, UError, UResult, UUsageError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; use std::env; use std::ffi::OsStr; @@ -25,8 +25,7 @@ use rand::Rng; use tempfile::Builder; use thiserror::Error; -const ABOUT: &str = help_about!("mktemp.md"); -const USAGE: &str = help_usage!("mktemp.md"); +use uucore::locale::get_message; static DEFAULT_TEMPLATE: &str = "tmp.XXXXXXXXXX"; @@ -347,8 +346,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("mktemp-about")) + .override_usage(format_usage(&get_message("mktemp-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_DIRECTORY) diff --git a/src/uu/more/locales/en-US.ftl b/src/uu/more/locales/en-US.ftl new file mode 100644 index 000000000..9d2d24c86 --- /dev/null +++ b/src/uu/more/locales/en-US.ftl @@ -0,0 +1,2 @@ +more-about = Display the contents of a text file +more-usage = more [OPTIONS] FILE... diff --git a/src/uu/more/more.md b/src/uu/more/more.md deleted file mode 100644 index e63ca1a87..000000000 --- a/src/uu/more/more.md +++ /dev/null @@ -1,8 +0,0 @@ -# more - -``` -more [OPTIONS] FILE... -``` - -Display the contents of a text file - diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 97d911f4f..fc2689448 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -23,11 +23,10 @@ use crossterm::{ }; use uucore::error::{UResult, USimpleError, UUsageError}; +use uucore::format_usage; use uucore::{display::Quotable, show}; -use uucore::{format_usage, help_about, help_usage}; -const ABOUT: &str = help_about!("more.md"); -const USAGE: &str = help_usage!("more.md"); +use uucore::locale::get_message; const BELL: char = '\x07'; // Printing this character will ring the bell // The prompt to be displayed at the top of the screen when viewing multiple files, @@ -155,8 +154,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("more-about")) + .override_usage(format_usage(&get_message("more-usage"))) .version(uucore::crate_version!()) .infer_long_args(true) .arg( diff --git a/src/uu/mv/locales/en-US.ftl b/src/uu/mv/locales/en-US.ftl new file mode 100644 index 000000000..7e8b2bd28 --- /dev/null +++ b/src/uu/mv/locales/en-US.ftl @@ -0,0 +1,16 @@ +mv-about = Move SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. +mv-usage = mv [OPTION]... [-T] SOURCE DEST + mv [OPTION]... SOURCE... DIRECTORY + mv [OPTION]... -t DIRECTORY SOURCE... +mv-after-help = When specifying more than one of -i, -f, -n, only the final one will take effect. + + Do not move a non-directory that has an existing destination with the same or newer modification timestamp; + instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is + to the source timestamp truncated to the resolutions of the destination file system and of the system calls used + to update timestamps; this avoids duplicate work if several mv -u commands are executed with the same source + and destination. This option is ignored if the -n or --no-clobber option is also specified. which gives more control + over which existing files in the destination are replaced, and its value can be one of the following: + + - all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. + - none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. + - older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file. diff --git a/src/uu/mv/mv.md b/src/uu/mv/mv.md deleted file mode 100644 index 6fcee4697..000000000 --- a/src/uu/mv/mv.md +++ /dev/null @@ -1,23 +0,0 @@ -# mv - -``` -mv [OPTION]... [-T] SOURCE DEST -mv [OPTION]... SOURCE... DIRECTORY -mv [OPTION]... -t DIRECTORY SOURCE... -``` -Move `SOURCE` to `DEST`, or multiple `SOURCE`(s) to `DIRECTORY`. - -## After Help - -When specifying more than one of -i, -f, -n, only the final one will take effect. - -Do not move a non-directory that has an existing destination with the same or newer modification timestamp; -instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is -to the source timestamp truncated to the resolutions of the destination file system and of the system calls used -to update timestamps; this avoids duplicate work if several `mv -u` commands are executed with the same source -and destination. This option is ignored if the `-n` or `--no-clobber` option is also specified. which gives more control -over which existing files in the destination are replaced, and its value can be one of the following: - -* `all` This is the default operation when an `--update` option is not specified, and results in all existing files in the destination being replaced. -* `none` This is similar to the `--no-clobber` option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. -* `older` This is the default operation when `--update` is specified, and results in files being replaced if they’re older than the corresponding source file. diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index c7f920204..82af08b05 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -40,7 +40,7 @@ use uucore::update_control; // These are exposed for projects (e.g. nushell) that want to create an `Options` value, which // requires these enums pub use uucore::{backup_control::BackupMode, update_control::UpdateMode}; -use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show}; +use uucore::{format_usage, prompt_yes, show}; use fs_extra::dir::{ CopyOptions as DirCopyOptions, TransitProcess, TransitProcessResult, get_size as dir_get_size, @@ -48,6 +48,7 @@ use fs_extra::dir::{ }; use crate::error::MvError; +use uucore::locale::get_message; /// Options contains all the possible behaviors and flags for mv. /// @@ -123,10 +124,6 @@ pub enum OverwriteMode { Force, } -const ABOUT: &str = help_about!("mv.md"); -const USAGE: &str = help_usage!("mv.md"); -const AFTER_HELP: &str = help_section!("after help", "mv.md"); - static OPT_FORCE: &str = "force"; static OPT_INTERACTIVE: &str = "interactive"; static OPT_NO_CLOBBER: &str = "no-clobber"; @@ -205,10 +202,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("mv-about")) + .override_usage(format_usage(&get_message("mv-usage"))) .after_help(format!( - "{AFTER_HELP}\n\n{}", + "{}\n\n{}", + get_message("mv-after-help"), backup_control::BACKUP_CONTROL_LONG_HELP )) .infer_long_args(true) diff --git a/src/uu/nice/locales/en-US.ftl b/src/uu/nice/locales/en-US.ftl new file mode 100644 index 000000000..d243ef94e --- /dev/null +++ b/src/uu/nice/locales/en-US.ftl @@ -0,0 +1,5 @@ +nice-about = Run COMMAND with an adjusted niceness, which affects process scheduling. + With no COMMAND, print the current niceness. Niceness values range from at + least -20 (most favorable to the process) to 19 (least favorable to the + process). +nice-usage = nice [OPTIONS] [COMMAND [ARGS]] diff --git a/src/uu/nice/nice.md b/src/uu/nice/nice.md deleted file mode 100644 index 872c239ca..000000000 --- a/src/uu/nice/nice.md +++ /dev/null @@ -1,10 +0,0 @@ -# nice - -``` -nice [OPTIONS] [COMMAND [ARGS]] -``` - -Run `COMMAND` with an adjusted niceness, which affects process scheduling. -With no `COMMAND`, print the current niceness. Niceness values range from at -least -20 (most favorable to the process) to 19 (least favorable to the -process). diff --git a/src/uu/nice/src/nice.rs b/src/uu/nice/src/nice.rs index 05ae2fa94..bb86d7778 100644 --- a/src/uu/nice/src/nice.rs +++ b/src/uu/nice/src/nice.rs @@ -11,9 +11,10 @@ use std::io::{Error, Write}; use std::ptr; use clap::{Arg, ArgAction, Command}; +use uucore::locale::get_message; use uucore::{ error::{UClapError, UResult, USimpleError, UUsageError, set_exit_code}, - format_usage, help_about, help_usage, show_error, + format_usage, show_error, }; pub mod options { @@ -21,9 +22,6 @@ pub mod options { pub static COMMAND: &str = "COMMAND"; } -const ABOUT: &str = help_about!("nice.md"); -const USAGE: &str = help_usage!("nice.md"); - fn is_prefix_of(maybe_prefix: &str, target: &str, min_match: usize) -> bool { if maybe_prefix.len() < min_match || maybe_prefix.len() > target.len() { return false; @@ -186,8 +184,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("nice-about")) + .override_usage(format_usage(&get_message("nice-usage"))) .trailing_var_arg(true) .infer_long_args(true) .version(uucore::crate_version!()) diff --git a/src/uu/nl/locales/en-US.ftl b/src/uu/nl/locales/en-US.ftl new file mode 100644 index 000000000..7880de562 --- /dev/null +++ b/src/uu/nl/locales/en-US.ftl @@ -0,0 +1,15 @@ +nl-about = Number lines of files +nl-usage = nl [OPTION]... [FILE]... +nl-after-help = STYLE is one of: + + - a number all lines + - t number only nonempty lines + - n number no lines + - pBRE number only lines that contain a match for the basic regular + expression, BRE + + FORMAT is one of: + + - ln left justified, no leading zeros + - rn right justified, no leading zeros + - rz right justified, leading zeros diff --git a/src/uu/nl/nl.md b/src/uu/nl/nl.md deleted file mode 100644 index bf3952cb2..000000000 --- a/src/uu/nl/nl.md +++ /dev/null @@ -1,23 +0,0 @@ -# nl - -``` -nl [OPTION]... [FILE]... -``` - -Number lines of files - -## After Help - -`STYLE` is one of: - -* `a` number all lines -* `t` number only nonempty lines -* `n` number no lines -* `pBRE` number only lines that contain a match for the basic regular - expression, `BRE` - -`FORMAT` is one of: - -* `ln` left justified, no leading zeros -* `rn` right justified, no leading zeros -* `rz` right justified, leading zeros diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index 6380417e0..0b6397dfe 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -8,14 +8,11 @@ use std::fs::File; use std::io::{BufRead, BufReader, Read, stdin}; use std::path::Path; use uucore::error::{FromIo, UResult, USimpleError, set_exit_code}; -use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +use uucore::locale::get_message; +use uucore::{format_usage, show_error}; mod helper; -const ABOUT: &str = help_about!("nl.md"); -const AFTER_HELP: &str = help_section!("after help", "nl.md"); -const USAGE: &str = help_usage!("nl.md"); - // Settings store options used by nl to produce its output. pub struct Settings { // The variables corresponding to the options -h, -b, and -f. @@ -222,10 +219,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) - .about(ABOUT) + .about(get_message("nl-about")) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .override_usage(format_usage(&get_message("nl-usage"))) + .after_help(get_message("nl-after-help")) .infer_long_args(true) .disable_help_flag(true) .arg( diff --git a/src/uu/nohup/locales/en-US.ftl b/src/uu/nohup/locales/en-US.ftl new file mode 100644 index 000000000..f209a7a90 --- /dev/null +++ b/src/uu/nohup/locales/en-US.ftl @@ -0,0 +1,7 @@ +nohup-about = Run COMMAND ignoring hangup signals. +nohup-usage = nohup COMMAND [ARG]... + nohup OPTION +nohup-after-help = If standard input is terminal, it'll be replaced with /dev/null. + If standard output is terminal, it'll be appended to nohup.out instead, + or $HOME/nohup.out, if nohup.out open failed. + If standard error is terminal, it'll be redirected to stdout. diff --git a/src/uu/nohup/nohup.md b/src/uu/nohup/nohup.md deleted file mode 100644 index 65ffaec87..000000000 --- a/src/uu/nohup/nohup.md +++ /dev/null @@ -1,15 +0,0 @@ -# nohup - -``` -nohup COMMAND [ARG]... -nohup OPTION -``` - -Run COMMAND ignoring hangup signals. - -## After Help - -If standard input is terminal, it'll be replaced with /dev/null. -If standard output is terminal, it'll be appended to nohup.out instead, -or $HOME/nohup.out, if nohup.out open failed. -If standard error is terminal, it'll be redirected to stdout. diff --git a/src/uu/nohup/src/nohup.rs b/src/uu/nohup/src/nohup.rs index 73003a164..a855b01f1 100644 --- a/src/uu/nohup/src/nohup.rs +++ b/src/uu/nohup/src/nohup.rs @@ -17,11 +17,9 @@ use std::path::{Path, PathBuf}; use thiserror::Error; use uucore::display::Quotable; use uucore::error::{UClapError, UError, UResult, set_exit_code}; -use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +use uucore::{format_usage, show_error}; -const ABOUT: &str = help_about!("nohup.md"); -const AFTER_HELP: &str = help_section!("after help", "nohup.md"); -const USAGE: &str = help_usage!("nohup.md"); +use uucore::locale::get_message; static NOHUP_OUT: &str = "nohup.out"; // exit codes that match the GNU implementation static EXIT_CANCELED: i32 = 125; @@ -92,9 +90,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("nohup-about")) + .after_help(get_message("nohup-after-help")) + .override_usage(format_usage(&get_message("nohup-usage"))) .arg( Arg::new(options::CMD) .hide(true) diff --git a/src/uu/nproc/locales/en-US.ftl b/src/uu/nproc/locales/en-US.ftl new file mode 100644 index 000000000..42522997e --- /dev/null +++ b/src/uu/nproc/locales/en-US.ftl @@ -0,0 +1,4 @@ +nproc-about = Print the number of cores available to the current process. + If the OMP_NUM_THREADS or OMP_THREAD_LIMIT environment variables are set, then + they will determine the minimum and maximum returned value respectively. +nproc-usage = nproc [OPTIONS]... diff --git a/src/uu/nproc/nproc.md b/src/uu/nproc/nproc.md deleted file mode 100644 index fee958a92..000000000 --- a/src/uu/nproc/nproc.md +++ /dev/null @@ -1,9 +0,0 @@ -# nproc - -``` -nproc [OPTIONS]... -``` - -Print the number of cores available to the current process. -If the `OMP_NUM_THREADS` or `OMP_THREAD_LIMIT` environment variables are set, then -they will determine the minimum and maximum returned value respectively. diff --git a/src/uu/nproc/src/nproc.rs b/src/uu/nproc/src/nproc.rs index a3a80724d..beed92834 100644 --- a/src/uu/nproc/src/nproc.rs +++ b/src/uu/nproc/src/nproc.rs @@ -9,7 +9,8 @@ use clap::{Arg, ArgAction, Command}; use std::{env, thread}; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; #[cfg(any(target_os = "linux", target_os = "android"))] pub const _SC_NPROCESSORS_CONF: libc::c_int = 83; @@ -23,9 +24,6 @@ pub const _SC_NPROCESSORS_CONF: libc::c_int = 1001; static OPT_ALL: &str = "all"; static OPT_IGNORE: &str = "ignore"; -const ABOUT: &str = help_about!("nproc.md"); -const USAGE: &str = help_usage!("nproc.md"); - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; @@ -94,8 +92,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("nproc-about")) + .override_usage(format_usage(&get_message("nproc-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_ALL) diff --git a/src/uu/numfmt/locales/en-US.ftl b/src/uu/numfmt/locales/en-US.ftl new file mode 100644 index 000000000..588a835a4 --- /dev/null +++ b/src/uu/numfmt/locales/en-US.ftl @@ -0,0 +1,36 @@ +numfmt-about = Convert numbers from/to human-readable strings +numfmt-usage = numfmt [OPTION]... [NUMBER]... +numfmt-after-help = UNIT options: + + - none: no auto-scaling is done; suffixes will trigger an error + - auto: accept optional single/two letter suffix: + + 1K = 1000, 1Ki = 1024, 1M = 1000000, 1Mi = 1048576, + + - si: accept optional single letter suffix: + + 1K = 1000, 1M = 1000000, ... + + - iec: accept optional single letter suffix: + + 1K = 1024, 1M = 1048576, ... + + - iec-i: accept optional two-letter suffix: + + 1Ki = 1024, 1Mi = 1048576, ... + + - FIELDS supports cut(1) style field ranges: + + N N'th field, counted from 1 + N- from N'th field, to end of line + N-M from N'th to M'th field (inclusive) + -M from first to M'th field (inclusive) + - all fields + + Multiple fields/ranges can be separated with commas + + FORMAT must be suitable for printing one floating-point argument %f. + Optional quote (%'f) will enable --grouping (if supported by current locale). + Optional width value (%10f) will pad output. Optional zero (%010f) width + will zero pad the number. Optional negative values (%-10f) will left align. + Optional precision (%.1f) will override the input determined precision. diff --git a/src/uu/numfmt/numfmt.md b/src/uu/numfmt/numfmt.md deleted file mode 100644 index 7c75736c1..000000000 --- a/src/uu/numfmt/numfmt.md +++ /dev/null @@ -1,46 +0,0 @@ -# numfmt - - - -``` -numfmt [OPTION]... [NUMBER]... -``` - -Convert numbers from/to human-readable strings - -## After Help - -`UNIT` options: - -- `none`: no auto-scaling is done; suffixes will trigger an error -- `auto`: accept optional single/two letter suffix: - - 1K = 1000, 1Ki = 1024, 1M = 1000000, 1Mi = 1048576, - -- `si`: accept optional single letter suffix: - - 1K = 1000, 1M = 1000000, ... - -- `iec`: accept optional single letter suffix: - - 1K = 1024, 1M = 1048576, ... - -- `iec-i`: accept optional two-letter suffix: - - 1Ki = 1024, 1Mi = 1048576, ... - -- `FIELDS` supports `cut(1)` style field ranges: - - N N'th field, counted from 1 - N- from N'th field, to end of line - N-M from N'th to M'th field (inclusive) - -M from first to M'th field (inclusive) - - all fields - -Multiple fields/ranges can be separated with commas - -`FORMAT` must be suitable for printing one floating-point argument `%f`. -Optional quote (`%'f`) will enable --grouping (if supported by current locale). -Optional width value (`%10f`) will pad output. Optional zero (`%010f`) width -will zero pad the number. Optional negative values (`%-10f`) will left align. -Optional precision (`%.1f`) will override the input determined precision. diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index cfa7c30d8..de977d035 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -15,19 +15,16 @@ use std::str::FromStr; use units::{IEC_BASES, SI_BASES}; use uucore::display::Quotable; use uucore::error::UResult; +use uucore::locale::get_message; use uucore::parser::shortcut_value_parser::ShortcutValueParser; use uucore::ranges::Range; -use uucore::{format_usage, help_about, help_section, help_usage, show, show_error}; +use uucore::{format_usage, show, show_error}; pub mod errors; pub mod format; pub mod options; mod units; -const ABOUT: &str = help_about!("numfmt.md"); -const AFTER_HELP: &str = help_section!("after help", "numfmt.md"); -const USAGE: &str = help_usage!("numfmt.md"); - fn handle_args<'a>(args: impl Iterator, options: &NumfmtOptions) -> UResult<()> { for l in args { format_and_handle_validation(l, options)?; @@ -277,9 +274,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("numfmt-about")) + .after_help(get_message("numfmt-after-help")) + .override_usage(format_usage(&get_message("numfmt-usage"))) .allow_negative_numbers(true) .infer_long_args(true) .arg( diff --git a/src/uu/od/locales/en-US.ftl b/src/uu/od/locales/en-US.ftl new file mode 100644 index 000000000..d451b3091 --- /dev/null +++ b/src/uu/od/locales/en-US.ftl @@ -0,0 +1,41 @@ +od-about = Dump files in octal and other formats +od-usage = od [OPTION]... [--] [FILENAME]... + od [-abcdDefFhHiIlLoOsxX] [FILENAME] [[+][0x]OFFSET[.][b]] + od --traditional [OPTION]... [FILENAME] [[+][0x]OFFSET[.][b] [[+][0x]LABEL[.][b]]] +od-after-help = Displays data in various human-readable formats. If multiple formats are + specified, the output will contain all formats in the order they appear on the + command line. Each format will be printed on a new line. Only the line + containing the first format will be prefixed with the offset. + + If no filename is specified, or it is "-", stdin will be used. After a "--", no + more options will be recognized. This allows for filenames starting with a "-". + + If a filename is a valid number which can be used as an offset in the second + form, you can force it to be recognized as a filename if you include an option + like "-j0", which is only valid in the first form. + + RADIX is one of o,d,x,n for octal, decimal, hexadecimal or none. + + BYTES is decimal by default, octal if prefixed with a "0", or hexadecimal if + prefixed with "0x". The suffixes b, KB, K, MB, M, GB, G, will multiply the + number with 512, 1000, 1024, 1000^2, 1024^2, 1000^3, 1024^3, 1000^2, 1024^2. + + OFFSET and LABEL are octal by default, hexadecimal if prefixed with "0x" or + decimal if a "." suffix is added. The "b" suffix will multiply with 512. + + TYPE contains one or more format specifications consisting of: + a for printable 7-bits ASCII + c for utf-8 characters or octal for undefined characters + d[SIZE] for signed decimal + f[SIZE] for floating point + o[SIZE] for octal + u[SIZE] for unsigned decimal + x[SIZE] for hexadecimal + SIZE is the number of bytes which can be the number 1, 2, 4, 8 or 16, + or C, I, S, L for 1, 2, 4, 8 bytes for integer types, + or F, D, L for 4, 8, 16 bytes for floating point. + Any type specification can have a "z" suffix, which will add a ASCII dump at + the end of the line. + + If an error occurred, a diagnostic message will be printed to stderr, and the + exit code will be non-zero. diff --git a/src/uu/od/od.md b/src/uu/od/od.md deleted file mode 100644 index 5cd9ac3b5..000000000 --- a/src/uu/od/od.md +++ /dev/null @@ -1,49 +0,0 @@ -# od - -``` -od [OPTION]... [--] [FILENAME]... -od [-abcdDefFhHiIlLoOsxX] [FILENAME] [[+][0x]OFFSET[.][b]] -od --traditional [OPTION]... [FILENAME] [[+][0x]OFFSET[.][b] [[+][0x]LABEL[.][b]]] -``` - -Dump files in octal and other formats - -## After Help - -Displays data in various human-readable formats. If multiple formats are -specified, the output will contain all formats in the order they appear on the -command line. Each format will be printed on a new line. Only the line -containing the first format will be prefixed with the offset. - -If no filename is specified, or it is "-", stdin will be used. After a "--", no -more options will be recognized. This allows for filenames starting with a "-". - -If a filename is a valid number which can be used as an offset in the second -form, you can force it to be recognized as a filename if you include an option -like "-j0", which is only valid in the first form. - -RADIX is one of o,d,x,n for octal, decimal, hexadecimal or none. - -BYTES is decimal by default, octal if prefixed with a "0", or hexadecimal if -prefixed with "0x". The suffixes b, KB, K, MB, M, GB, G, will multiply the -number with 512, 1000, 1024, 1000^2, 1024^2, 1000^3, 1024^3, 1000^2, 1024^2. - -OFFSET and LABEL are octal by default, hexadecimal if prefixed with "0x" or -decimal if a "." suffix is added. The "b" suffix will multiply with 512. - -TYPE contains one or more format specifications consisting of: - a for printable 7-bits ASCII - c for utf-8 characters or octal for undefined characters - d[SIZE] for signed decimal - f[SIZE] for floating point - o[SIZE] for octal - u[SIZE] for unsigned decimal - x[SIZE] for hexadecimal -SIZE is the number of bytes which can be the number 1, 2, 4, 8 or 16, - or C, I, S, L for 1, 2, 4, 8 bytes for integer types, - or F, D, L for 4, 8, 16 bytes for floating point. -Any type specification can have a "z" suffix, which will add a ASCII dump at - the end of the line. - -If an error occurred, a diagnostic message will be printed to stderr, and the -exit code will be non-zero. diff --git a/src/uu/od/src/od.rs b/src/uu/od/src/od.rs index 652a0ce3f..a84adece2 100644 --- a/src/uu/od/src/od.rs +++ b/src/uu/od/src/od.rs @@ -44,16 +44,13 @@ use clap::ArgAction; use clap::{Arg, ArgMatches, Command, parser::ValueSource}; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError}; +use uucore::locale::get_message; use uucore::parser::parse_size::ParseSizeError; use uucore::parser::shortcut_value_parser::ShortcutValueParser; -use uucore::{format_usage, help_about, help_section, help_usage, show_error, show_warning}; +use uucore::{format_usage, show_error, show_warning}; const PEEK_BUFFER_SIZE: usize = 4; // utf-8 can be 4 bytes -const ABOUT: &str = help_about!("od.md"); -const USAGE: &str = help_usage!("od.md"); -const AFTER_HELP: &str = help_section!("after help", "od.md"); - pub(crate) mod options { pub const HELP: &str = "help"; pub const ADDRESS_RADIX: &str = "address-radix"; @@ -253,9 +250,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .about(get_message("od-about")) + .override_usage(format_usage(&get_message("od-usage"))) + .after_help(get_message("od-after-help")) .trailing_var_arg(true) .dont_delimit_trailing_values(true) .infer_long_args(true) diff --git a/src/uu/paste/locales/en-US.ftl b/src/uu/paste/locales/en-US.ftl new file mode 100644 index 000000000..15c39b0a6 --- /dev/null +++ b/src/uu/paste/locales/en-US.ftl @@ -0,0 +1,3 @@ +paste-about = Write lines consisting of the sequentially corresponding lines from each + FILE, separated by TABs, to standard output. +paste-usage = paste [OPTIONS] [FILE]... diff --git a/src/uu/paste/paste.md b/src/uu/paste/paste.md deleted file mode 100644 index 741605888..000000000 --- a/src/uu/paste/paste.md +++ /dev/null @@ -1,8 +0,0 @@ -# paste - -``` -paste [OPTIONS] [FILE]... -``` - -Write lines consisting of the sequentially corresponding lines from each -`FILE`, separated by `TAB`s, to standard output. diff --git a/src/uu/paste/src/paste.rs b/src/uu/paste/src/paste.rs index 98679b746..9bb94294f 100644 --- a/src/uu/paste/src/paste.rs +++ b/src/uu/paste/src/paste.rs @@ -11,11 +11,10 @@ use std::iter::Cycle; use std::rc::Rc; use std::slice::Iter; use uucore::error::{UResult, USimpleError}; +use uucore::format_usage; use uucore::line_ending::LineEnding; -use uucore::{format_usage, help_about, help_usage}; -const ABOUT: &str = help_about!("paste.md"); -const USAGE: &str = help_usage!("paste.md"); +use uucore::locale::get_message; mod options { pub const DELIMITER: &str = "delimiters"; @@ -43,8 +42,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("paste-about")) + .override_usage(format_usage(&get_message("paste-usage"))) .infer_long_args(true) .arg( Arg::new(options::SERIAL) diff --git a/src/uu/pathchk/locales/en-US.ftl b/src/uu/pathchk/locales/en-US.ftl new file mode 100644 index 000000000..c75b17262 --- /dev/null +++ b/src/uu/pathchk/locales/en-US.ftl @@ -0,0 +1,2 @@ +pathchk-about = Check whether file names are valid or portable +pathchk-usage = pathchk [OPTION]... NAME... diff --git a/src/uu/pathchk/pathchk.md b/src/uu/pathchk/pathchk.md deleted file mode 100644 index 2e5eca959..000000000 --- a/src/uu/pathchk/pathchk.md +++ /dev/null @@ -1,7 +0,0 @@ -# pathchk - -``` -pathchk [OPTION]... NAME... -``` - -Check whether file names are valid or portable diff --git a/src/uu/pathchk/src/pathchk.rs b/src/uu/pathchk/src/pathchk.rs index 183d67a0b..cdd6418c4 100644 --- a/src/uu/pathchk/src/pathchk.rs +++ b/src/uu/pathchk/src/pathchk.rs @@ -10,7 +10,8 @@ use std::fs; use std::io::{ErrorKind, Write}; use uucore::display::Quotable; use uucore::error::{UResult, UUsageError, set_exit_code}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; // operating mode enum Mode { @@ -20,9 +21,6 @@ enum Mode { Both, // a combination of `Basic` and `Extra` } -const ABOUT: &str = help_about!("pathchk.md"); -const USAGE: &str = help_usage!("pathchk.md"); - mod options { pub const POSIX: &str = "posix"; pub const POSIX_SPECIAL: &str = "posix-special"; @@ -80,8 +78,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("pathchk-about")) + .override_usage(format_usage(&get_message("pathchk-usage"))) .infer_long_args(true) .arg( Arg::new(options::POSIX) diff --git a/src/uu/pinky/locales/en-US.ftl b/src/uu/pinky/locales/en-US.ftl new file mode 100644 index 000000000..d3b62d123 --- /dev/null +++ b/src/uu/pinky/locales/en-US.ftl @@ -0,0 +1,6 @@ +pinky-about = Displays brief user information on Unix-based systems +pinky-usage = pinky [OPTION]... [USER]... +pinky-about-musl-warning = Warning: When built with musl libc, the `pinky` utility may show incomplete + or missing user information due to musl's stub implementation of `utmpx` + functions. This limitation affects the ability to retrieve accurate details + about logged-in users. diff --git a/src/uu/pinky/pinky.md b/src/uu/pinky/pinky.md deleted file mode 100644 index 965ae4cd0..000000000 --- a/src/uu/pinky/pinky.md +++ /dev/null @@ -1,7 +0,0 @@ -# pinky - -``` -pinky [OPTION]... [USER]... -``` - -Displays brief user information on Unix-based systems diff --git a/src/uu/pinky/src/pinky.rs b/src/uu/pinky/src/pinky.rs index 8246f8655..3f0f13d97 100644 --- a/src/uu/pinky/src/pinky.rs +++ b/src/uu/pinky/src/pinky.rs @@ -6,24 +6,11 @@ // spell-checker:ignore (ToDO) BUFSIZE gecos fullname, mesg iobuf use clap::{Arg, ArgAction, Command}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; mod platform; -#[cfg(target_env = "musl")] -const ABOUT: &str = concat!( - help_about!("pinky.md"), - "\n\nWarning: When built with musl libc, the `pinky` utility may show incomplete \n", - "or missing user information due to musl's stub implementation of `utmpx` \n", - "functions. This limitation affects the ability to retrieve accurate details \n", - "about logged-in users." -); - -#[cfg(not(target_env = "musl"))] -const ABOUT: &str = help_about!("pinky.md"); - -const USAGE: &str = help_usage!("pinky.md"); - mod options { pub const LONG_FORMAT: &str = "long_format"; pub const OMIT_HOME_DIR: &str = "omit_home_dir"; @@ -42,10 +29,15 @@ mod options { use platform::uumain; pub fn uu_app() -> Command { + #[cfg(not(target_env = "musl"))] + let about = get_message("pinky-about"); + #[cfg(target_env = "musl")] + let about = get_message("pinky-about") + &get_message("pinky-about-musl-warning"); + Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(about) + .override_usage(format_usage(&get_message("pinky-usage"))) .infer_long_args(true) .disable_help_flag(true) .arg( diff --git a/src/uu/pr/locales/en-US.ftl b/src/uu/pr/locales/en-US.ftl new file mode 100644 index 000000000..cd11a164d --- /dev/null +++ b/src/uu/pr/locales/en-US.ftl @@ -0,0 +1,19 @@ +pr-about = Write content of given file or standard input to standard output with pagination filter +pr-usage = pr [OPTION]... [FILE]... +pr-after-help = +PAGE Begin output at page number page of the formatted input. + -COLUMN Produce multi-column output. See --column + + The pr utility is a printing and pagination filter for text files. + When multiple input files are specified, each is read, formatted, and written to standard output. + By default, the input is separated into 66-line pages, each with + + - A 5-line header with the page number, date, time, and the pathname of the file. + - A 5-line trailer consisting of blank lines. + + If standard output is associated with a terminal, diagnostic messages are suppressed until the pr + utility has completed processing. + + When multiple column output is specified, text columns are of equal width. + By default, text columns are separated by at least one . + Input lines that do not fit into a text column are truncated. + Lines are not truncated under single column output. diff --git a/src/uu/pr/pr.md b/src/uu/pr/pr.md deleted file mode 100644 index cd2f552f3..000000000 --- a/src/uu/pr/pr.md +++ /dev/null @@ -1,27 +0,0 @@ -# pr - -``` -pr [OPTION]... [FILE]... -``` - -Write content of given file or standard input to standard output with pagination filter - -## After help - -`+PAGE` Begin output at page number page of the formatted input. -`-COLUMN` Produce multi-column output. See `--column` - -The pr utility is a printing and pagination filter for text files. -When multiple input files are specified, each is read, formatted, and written to standard output. -By default, the input is separated into 66-line pages, each with - -* A 5-line header with the page number, date, time, and the pathname of the file. -* A 5-line trailer consisting of blank lines. - -If standard output is associated with a terminal, diagnostic messages are suppressed until the pr -utility has completed processing. - -When multiple column output is specified, text columns are of equal width. -By default, text columns are separated by at least one ``. -Input lines that do not fit into a text column are truncated. -Lines are not truncated under single column output. diff --git a/src/uu/pr/src/pr.rs b/src/uu/pr/src/pr.rs index e24f9cf18..4ca97e784 100644 --- a/src/uu/pr/src/pr.rs +++ b/src/uu/pr/src/pr.rs @@ -18,11 +18,9 @@ use thiserror::Error; use uucore::display::Quotable; use uucore::error::UResult; -use uucore::{format_usage, help_about, help_section, help_usage}; +use uucore::format_usage; -const ABOUT: &str = help_about!("pr.md"); -const USAGE: &str = help_usage!("pr.md"); -const AFTER_HELP: &str = help_section!("after help", "pr.md"); +use uucore::locale::get_message; const TAB: char = '\t'; const LINES_PER_PAGE: usize = 66; const LINES_PER_PAGE_FOR_FORM_FEED: usize = 63; @@ -153,9 +151,9 @@ enum PrError { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("pr-about")) + .after_help(get_message("pr-after-help")) + .override_usage(format_usage(&get_message("pr-usage"))) .infer_long_args(true) .args_override_self(true) .disable_help_flag(true) diff --git a/src/uu/printenv/locales/en-US.ftl b/src/uu/printenv/locales/en-US.ftl new file mode 100644 index 000000000..b60962e1a --- /dev/null +++ b/src/uu/printenv/locales/en-US.ftl @@ -0,0 +1,2 @@ +printenv-about = Display the values of the specified environment VARIABLE(s), or (with no VARIABLE) display name and value pairs for them all. +printenv-usage = printenv [OPTION]... [VARIABLE]... diff --git a/src/uu/printenv/printenv.md b/src/uu/printenv/printenv.md deleted file mode 100644 index f67d46a23..000000000 --- a/src/uu/printenv/printenv.md +++ /dev/null @@ -1,7 +0,0 @@ -# printenv - -``` -printenv [OPTION]... [VARIABLE]... -``` - -Display the values of the specified environment VARIABLE(s), or (with no VARIABLE) display name and value pairs for them all. diff --git a/src/uu/printenv/src/printenv.rs b/src/uu/printenv/src/printenv.rs index 4584a09b8..15e39a678 100644 --- a/src/uu/printenv/src/printenv.rs +++ b/src/uu/printenv/src/printenv.rs @@ -5,10 +5,9 @@ use clap::{Arg, ArgAction, Command}; use std::env; -use uucore::{error::UResult, format_usage, help_about, help_usage}; +use uucore::{error::UResult, format_usage}; -const ABOUT: &str = help_about!("printenv.md"); -const USAGE: &str = help_usage!("printenv.md"); +use uucore::locale::get_message; static OPT_NULL: &str = "null"; @@ -56,8 +55,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("printenv-about")) + .override_usage(format_usage(&get_message("printenv-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_NULL) diff --git a/src/uu/printf/locales/en-US.ftl b/src/uu/printf/locales/en-US.ftl new file mode 100644 index 000000000..6f58a0775 --- /dev/null +++ b/src/uu/printf/locales/en-US.ftl @@ -0,0 +1,249 @@ +printf-about = Print output based off of the format string and proceeding arguments. +printf-usage = printf FORMAT [ARGUMENT]... + printf OPTION +printf-after-help = basic anonymous string templating: + + prints format string at least once, repeating as long as there are remaining arguments + output prints escaped literals in the format string as character literals + output replaces anonymous fields with the next unused argument, formatted according to the field. + + Prints the , replacing escaped character sequences with character literals + and substitution field sequences with passed arguments + + literally, with the exception of the below + escaped character sequences, and the substitution sequences described further down. + + ### ESCAPE SEQUENCES + + The following escape sequences, organized here in alphabetical order, + will print the corresponding character literal: + + - \" double quote + + - \\ backslash + + - \\a alert (BEL) + + - \\b backspace + + - \\c End-of-Input + + - \\e escape + + - \\f form feed + + - \\n new line + + - \\r carriage return + + - \\t horizontal tab + + - \\v vertical tab + + - \\NNN byte with value expressed in octal value NNN (1 to 3 digits) + values greater than 256 will be treated + + - \\xHH byte with value expressed in hexadecimal value NN (1 to 2 digits) + + - \\uHHHH Unicode (IEC 10646) character with value expressed in hexadecimal value HHHH (4 digits) + + - \\uHHHH Unicode character with value expressed in hexadecimal value HHHH (8 digits) + + - %% a single % + + ### SUBSTITUTIONS + + #### SUBSTITUTION QUICK REFERENCE + + Fields + + - %s: string + - %b: string parsed for literals second parameter is max length + + - %c: char no second parameter + + - %i or %d: 64-bit integer + - %u: 64 bit unsigned integer + - %x or %X: 64-bit unsigned integer as hex + - %o: 64-bit unsigned integer as octal + second parameter is min-width, integer + output below that width is padded with leading zeroes + + - %q: ARGUMENT is printed in a format that can be reused as shell input, escaping non-printable + characters with the proposed POSIX $'' syntax. + + - %f or %F: decimal floating point value + - %e or %E: scientific notation floating point value + - %g or %G: shorter of specially interpreted decimal or SciNote floating point value. + second parameter is + -max places after decimal point for floating point output + -max number of significant digits for scientific notation output + + parameterizing fields + + examples: + + printf '%4.3i' 7 + + It has a first parameter of 4 and a second parameter of 3 and will result in ' 007' + + printf '%.1s' abcde + + It has no first parameter and a second parameter of 1 and will result in 'a' + + printf '%4c' q + + It has a first parameter of 4 and no second parameter and will result in ' q' + + The first parameter of a field is the minimum width to pad the output to + if the output is less than this absolute value of this width, + it will be padded with leading spaces, or, if the argument is negative, + with trailing spaces. the default is zero. + + The second parameter of a field is particular to the output field type. + defaults can be found in the full substitution help below + + special prefixes to numeric arguments + + - 0: (e.g. 010) interpret argument as octal (integer output fields only) + - 0x: (e.g. 0xABC) interpret argument as hex (numeric output fields only) + - \': (e.g. \'a) interpret argument as a character constant + + #### HOW TO USE SUBSTITUTIONS + + Substitutions are used to pass additional argument(s) into the FORMAT string, to be formatted a + particular way. E.g. + + printf 'the letter %X comes before the letter %X' 10 11 + + will print + + the letter A comes before the letter B + + because the substitution field %X means + 'take an integer argument and write it as a hexadecimal number' + + Passing more arguments than are in the format string will cause the format string to be + repeated for the remaining substitutions + + printf 'it is %i F in %s \n' 22 Portland 25 Boston 27 New York + + will print + + it is 22 F in Portland + it is 25 F in Boston + it is 27 F in Boston + + If a format string is printed but there are less arguments remaining + than there are substitution fields, substitution fields without + an argument will default to empty strings, or for numeric fields + the value 0 + + #### AVAILABLE SUBSTITUTIONS + + This program, like GNU coreutils printf, + interprets a modified subset of the POSIX C printf spec, + a quick reference to substitutions is below. + + #### STRING SUBSTITUTIONS + + All string fields have a 'max width' parameter + %.3s means 'print no more than three characters of the original input' + + - %s: string + + - %b: escaped string - the string will be checked for any escaped literals from + the escaped literal list above, and translate them to literal characters. + e.g. \\n will be transformed into a newline character. + One special rule about %b mode is that octal literals are interpreted differently + In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN + instead of \\NNN. (Although, for legacy reasons, octal literals in the form of \\NNN will + still be interpreted and not throw a warning, you will have problems if you use this for a + literal whose code begins with zero, as it will be viewed as in \\0NNN form.) + + - %q: escaped string - the string in a format that can be reused as input by most shells. + Non-printable characters are escaped with the POSIX proposed ‘$''’ syntax, + and shell meta-characters are quoted appropriately. + This is an equivalent format to ls --quoting=shell-escape output. + + #### CHAR SUBSTITUTIONS + + The character field does not have a secondary parameter. + + - %c: a single character + + #### INTEGER SUBSTITUTIONS + + All integer fields have a 'pad with zero' parameter + %.4i means an integer which if it is less than 4 digits in length, + is padded with leading zeros until it is 4 digits in length. + + - %d or %i: 64-bit integer + + - %u: 64-bit unsigned integer + + - %x or %X: 64-bit unsigned integer printed in Hexadecimal (base 16) + %X instead of %x means to use uppercase letters for 'a' through 'f' + + - %o: 64-bit unsigned integer printed in octal (base 8) + + #### FLOATING POINT SUBSTITUTIONS + + All floating point fields have a 'max decimal places / max significant digits' parameter + %.10f means a decimal floating point with 7 decimal places past 0 + %.10e means a scientific notation number with 10 significant digits + %.10g means the same behavior for decimal and Sci. Note, respectively, and provides the shortest + of each's output. + + Like with GNU coreutils, the value after the decimal point is these outputs is parsed as a + double first before being rendered to text. For both implementations do not expect meaningful + precision past the 18th decimal place. When using a number of decimal places that is 18 or + higher, you can expect variation in output between GNU coreutils printf and this printf at the + 18th decimal place of +/- 1 + + - %f: floating point value presented in decimal, truncated and displayed to 6 decimal places by + default. There is not past-double behavior parity with Coreutils printf, values are not + estimated or adjusted beyond input values. + + - %e or %E: floating point value presented in scientific notation + 7 significant digits by default + %E means use to use uppercase E for the mantissa. + + - %g or %G: floating point value presented in the shortest of decimal and scientific notation + behaves differently from %f and %E, please see posix printf spec for full details, + some examples of different behavior: + Sci Note has 6 significant digits by default + Trailing zeroes are removed + Instead of being truncated, digit after last is rounded + + Like other behavior in this utility, the design choices of floating point + behavior in this utility is selected to reproduce in exact + the behavior of GNU coreutils' printf from an inputs and outputs standpoint. + + ### USING PARAMETERS + + Most substitution fields can be parameterized using up to 2 numbers that can + be passed to the field, between the % sign and the field letter. + + The 1st parameter always indicates the minimum width of output, it is useful for creating + columnar output. Any output that would be less than this minimum width is padded with + leading spaces + The 2nd parameter is proceeded by a dot. + You do not have to use parameters + + ### SPECIAL FORMS OF INPUT + + For numeric input, the following additional forms of input are accepted besides decimal: + + Octal (only with integer): if the argument begins with a 0 the proceeding characters + will be interpreted as octal (base 8) for integer fields + + Hexadecimal: if the argument begins with 0x the proceeding characters will be interpreted + will be interpreted as hex (base 16) for any numeric fields + for float fields, hexadecimal input results in a precision + limit (in converting input past the decimal point) of 10^-15 + + Character Constant: if the argument begins with a single quote character, the first byte + of the next character will be interpreted as an 8-bit unsigned integer. If there are + additional bytes, they will throw an error (unless the environment variable POSIXLY_CORRECT + is set) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md deleted file mode 100644 index 791cc8be1..000000000 --- a/src/uu/printf/printf.md +++ /dev/null @@ -1,273 +0,0 @@ - - -# printf - -``` -printf FORMAT [ARGUMENT]... -printf OPTION -``` - -Print output based off of the format string and proceeding arguments. - -## After Help - -basic anonymous string templating: - -prints format string at least once, repeating as long as there are remaining arguments -output prints escaped literals in the format string as character literals -output replaces anonymous fields with the next unused argument, formatted according to the field. - -Prints the `,` replacing escaped character sequences with character literals -and substitution field sequences with passed arguments - -literally, with the exception of the below -escaped character sequences, and the substitution sequences described further down. - -### ESCAPE SEQUENCES - -The following escape sequences, organized here in alphabetical order, -will print the corresponding character literal: - -* `\"` double quote - -* `\\\\` backslash - -* `\\a` alert (BEL) - -* `\\b` backspace - -* `\\c` End-of-Input - -* `\\e` escape - -* `\\f` form feed - -* `\\n` new line - -* `\\r` carriage return - -* `\\t` horizontal tab - -* `\\v` vertical tab - -* `\\NNN` byte with value expressed in octal value NNN (1 to 3 digits) - values greater than 256 will be treated - -* `\\xHH` byte with value expressed in hexadecimal value NN (1 to 2 digits) - -* `\\uHHHH` Unicode (IEC 10646) character with value expressed in hexadecimal value HHHH (4 digits) - -* `\\uHHHH` Unicode character with value expressed in hexadecimal value HHHH (8 digits) - -* `%%` a single % - -### SUBSTITUTIONS - -#### SUBSTITUTION QUICK REFERENCE - -Fields - -* `%s`: string -* `%b`: string parsed for literals second parameter is max length - -* `%c`: char no second parameter - -* `%i` or `%d`: 64-bit integer -* `%u`: 64 bit unsigned integer -* `%x` or `%X`: 64-bit unsigned integer as hex -* `%o`: 64-bit unsigned integer as octal - second parameter is min-width, integer - output below that width is padded with leading zeroes - -* `%q`: ARGUMENT is printed in a format that can be reused as shell input, escaping non-printable - characters with the proposed POSIX $'' syntax. - -* `%f` or `%F`: decimal floating point value -* `%e` or `%E`: scientific notation floating point value -* `%g` or `%G`: shorter of specially interpreted decimal or SciNote floating point value. - second parameter is - `-max` places after decimal point for floating point output - `-max` number of significant digits for scientific notation output - -parameterizing fields - -examples: - -``` -printf '%4.3i' 7 -``` - -It has a first parameter of 4 and a second parameter of 3 and will result in ' 007' - -``` -printf '%.1s' abcde -``` - -It has no first parameter and a second parameter of 1 and will result in 'a' - -``` -printf '%4c' q -``` - -It has a first parameter of 4 and no second parameter and will result in ' q' - -The first parameter of a field is the minimum width to pad the output to -if the output is less than this absolute value of this width, -it will be padded with leading spaces, or, if the argument is negative, -with trailing spaces. the default is zero. - -The second parameter of a field is particular to the output field type. -defaults can be found in the full substitution help below - -special prefixes to numeric arguments - -* `0`: (e.g. 010) interpret argument as octal (integer output fields only) -* `0x`: (e.g. 0xABC) interpret argument as hex (numeric output fields only) -* `\'`: (e.g. \'a) interpret argument as a character constant - -#### HOW TO USE SUBSTITUTIONS - -Substitutions are used to pass additional argument(s) into the FORMAT string, to be formatted a -particular way. E.g. - -``` -printf 'the letter %X comes before the letter %X' 10 11 -``` - -will print - -``` -the letter A comes before the letter B -``` - -because the substitution field `%X` means -'take an integer argument and write it as a hexadecimal number' - -Passing more arguments than are in the format string will cause the format string to be -repeated for the remaining substitutions - -``` -printf 'it is %i F in %s \n' 22 Portland 25 Boston 27 New York -``` - -will print - -``` -it is 22 F in Portland -it is 25 F in Boston -it is 27 F in Boston -``` - -If a format string is printed but there are less arguments remaining -than there are substitution fields, substitution fields without -an argument will default to empty strings, or for numeric fields -the value 0 - -#### AVAILABLE SUBSTITUTIONS - -This program, like GNU coreutils printf, -interprets a modified subset of the POSIX C printf spec, -a quick reference to substitutions is below. - -#### STRING SUBSTITUTIONS - -All string fields have a 'max width' parameter -`%.3s` means 'print no more than three characters of the original input' - -* `%s`: string - -* `%b`: escaped string - the string will be checked for any escaped literals from - the escaped literal list above, and translate them to literal characters. - e.g. `\\n` will be transformed into a newline character. - One special rule about `%b` mode is that octal literals are interpreted differently - In arguments passed by `%b`, pass octal-interpreted literals must be in the form of `\\0NNN` - instead of `\\NNN`. (Although, for legacy reasons, octal literals in the form of `\\NNN` will - still be interpreted and not throw a warning, you will have problems if you use this for a - literal whose code begins with zero, as it will be viewed as in `\\0NNN` form.) - -* `%q`: escaped string - the string in a format that can be reused as input by most shells. - Non-printable characters are escaped with the POSIX proposed ‘$''’ syntax, - and shell meta-characters are quoted appropriately. - This is an equivalent format to ls --quoting=shell-escape output. - -#### CHAR SUBSTITUTIONS - -The character field does not have a secondary parameter. - -* `%c`: a single character - -#### INTEGER SUBSTITUTIONS - -All integer fields have a 'pad with zero' parameter -`%.4i` means an integer which if it is less than 4 digits in length, -is padded with leading zeros until it is 4 digits in length. - -* `%d` or `%i`: 64-bit integer - -* `%u`: 64-bit unsigned integer - -* `%x` or `%X`: 64-bit unsigned integer printed in Hexadecimal (base 16) - `%X` instead of `%x` means to use uppercase letters for 'a' through 'f' - -* `%o`: 64-bit unsigned integer printed in octal (base 8) - -#### FLOATING POINT SUBSTITUTIONS - -All floating point fields have a 'max decimal places / max significant digits' parameter -`%.10f` means a decimal floating point with 7 decimal places past 0 -`%.10e` means a scientific notation number with 10 significant digits -`%.10g` means the same behavior for decimal and Sci. Note, respectively, and provides the shortest -of each's output. - -Like with GNU coreutils, the value after the decimal point is these outputs is parsed as a -double first before being rendered to text. For both implementations do not expect meaningful -precision past the 18th decimal place. When using a number of decimal places that is 18 or -higher, you can expect variation in output between GNU coreutils printf and this printf at the -18th decimal place of +/- 1 - -* `%f`: floating point value presented in decimal, truncated and displayed to 6 decimal places by - default. There is not past-double behavior parity with Coreutils printf, values are not - estimated or adjusted beyond input values. - -* `%e` or `%E`: floating point value presented in scientific notation - 7 significant digits by default - `%E` means use to use uppercase E for the mantissa. - -* `%g` or `%G`: floating point value presented in the shortest of decimal and scientific notation - behaves differently from `%f` and `%E`, please see posix printf spec for full details, - some examples of different behavior: - Sci Note has 6 significant digits by default - Trailing zeroes are removed - Instead of being truncated, digit after last is rounded - -Like other behavior in this utility, the design choices of floating point -behavior in this utility is selected to reproduce in exact -the behavior of GNU coreutils' printf from an inputs and outputs standpoint. - -### USING PARAMETERS - -Most substitution fields can be parameterized using up to 2 numbers that can -be passed to the field, between the % sign and the field letter. - -The 1st parameter always indicates the minimum width of output, it is useful for creating -columnar output. Any output that would be less than this minimum width is padded with -leading spaces -The 2nd parameter is proceeded by a dot. -You do not have to use parameters - -### SPECIAL FORMS OF INPUT - -For numeric input, the following additional forms of input are accepted besides decimal: - -Octal (only with integer): if the argument begins with a 0 the proceeding characters -will be interpreted as octal (base 8) for integer fields - -Hexadecimal: if the argument begins with 0x the proceeding characters will be interpreted -will be interpreted as hex (base 16) for any numeric fields -for float fields, hexadecimal input results in a precision -limit (in converting input past the decimal point) of 10^-15 - -Character Constant: if the argument begins with a single quote character, the first byte -of the next character will be interpreted as an 8-bit unsigned integer. If there are -additional bytes, they will throw an error (unless the environment variable POSIXLY_CORRECT -is set) diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs index 887ad4107..a28fc6aae 100644 --- a/src/uu/printf/src/printf.rs +++ b/src/uu/printf/src/printf.rs @@ -7,13 +7,11 @@ use std::io::stdout; use std::ops::ControlFlow; use uucore::error::{UResult, UUsageError}; use uucore::format::{FormatArgument, FormatArguments, FormatItem, parse_spec_and_escape}; -use uucore::{format_usage, help_about, help_section, help_usage, os_str_as_bytes, show_warning}; +use uucore::locale::get_message; +use uucore::{format_usage, os_str_as_bytes, show_warning}; const VERSION: &str = "version"; const HELP: &str = "help"; -const USAGE: &str = help_usage!("printf.md"); -const ABOUT: &str = help_about!("printf.md"); -const AFTER_HELP: &str = help_section!("after help", "printf.md"); mod options { pub const FORMAT: &str = "FORMAT"; @@ -81,9 +79,9 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .allow_hyphen_values(true) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("printf-about")) + .after_help(get_message("printf-after-help")) + .override_usage(format_usage(&get_message("printf-usage"))) .disable_help_flag(true) .disable_version_flag(true) .arg( diff --git a/src/uu/ptx/locales/en-US.ftl b/src/uu/ptx/locales/en-US.ftl new file mode 100644 index 000000000..87bc95530 --- /dev/null +++ b/src/uu/ptx/locales/en-US.ftl @@ -0,0 +1,6 @@ +ptx-about = Produce a permuted index of file contents + Output a permuted index, including context, of the words in the input files. + Mandatory arguments to long options are mandatory for short options too. + With no FILE, or when FILE is -, read standard input. Default is '-F /'. +ptx-usage = ptx [OPTION]... [INPUT]... + ptx -G [OPTION]... [INPUT [OUTPUT]] diff --git a/src/uu/ptx/ptx.md b/src/uu/ptx/ptx.md deleted file mode 100644 index b8717776c..000000000 --- a/src/uu/ptx/ptx.md +++ /dev/null @@ -1,11 +0,0 @@ -# ptx - -``` -ptx [OPTION]... [INPUT]... -ptx -G [OPTION]... [INPUT [OUTPUT]] -``` - -Produce a permuted index of file contents -Output a permuted index, including context, of the words in the input files. -Mandatory arguments to long options are mandatory for short options too. -With no FILE, or when FILE is -, read standard input. Default is '-F /'. \ No newline at end of file diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index bb5b29282..856183a54 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -17,10 +17,9 @@ use regex::Regex; use thiserror::Error; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult, UUsageError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; -const USAGE: &str = help_usage!("ptx.md"); -const ABOUT: &str = help_about!("ptx.md"); +use uucore::locale::get_message; #[derive(Debug)] enum OutFormat { @@ -765,9 +764,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) - .about(ABOUT) + .about(get_message("ptx-about")) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) + .override_usage(format_usage(&get_message("ptx-usage"))) .infer_long_args(true) .arg( Arg::new(options::FILE) diff --git a/src/uu/pwd/locales/en-US.ftl b/src/uu/pwd/locales/en-US.ftl new file mode 100644 index 000000000..52a4a2283 --- /dev/null +++ b/src/uu/pwd/locales/en-US.ftl @@ -0,0 +1,2 @@ +pwd-about = Display the full filename of the current working directory. +pwd-usage = pwd [OPTION]... [FILE]... diff --git a/src/uu/pwd/pwd.md b/src/uu/pwd/pwd.md deleted file mode 100644 index 89ccee2db..000000000 --- a/src/uu/pwd/pwd.md +++ /dev/null @@ -1,7 +0,0 @@ -# pwd - -``` -pwd [OPTION]... [FILE]... -``` - -Display the full filename of the current working directory. diff --git a/src/uu/pwd/src/pwd.rs b/src/uu/pwd/src/pwd.rs index b924af241..f1f398d9b 100644 --- a/src/uu/pwd/src/pwd.rs +++ b/src/uu/pwd/src/pwd.rs @@ -8,13 +8,12 @@ use clap::{Arg, Command}; use std::env; use std::io; use std::path::PathBuf; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; use uucore::display::println_verbatim; use uucore::error::{FromIo, UResult}; -const ABOUT: &str = help_about!("pwd.md"); -const USAGE: &str = help_usage!("pwd.md"); +use uucore::locale::get_message; const OPT_LOGICAL: &str = "logical"; const OPT_PHYSICAL: &str = "physical"; @@ -141,8 +140,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("pwd-about")) + .override_usage(format_usage(&get_message("pwd-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_LOGICAL) diff --git a/src/uu/readlink/locales/en-US.ftl b/src/uu/readlink/locales/en-US.ftl new file mode 100644 index 000000000..ddb806651 --- /dev/null +++ b/src/uu/readlink/locales/en-US.ftl @@ -0,0 +1,2 @@ +readlink-about = Print value of a symbolic link or canonical file name. +readlink-usage = readlink [OPTION]... [FILE]... diff --git a/src/uu/readlink/readlink.md b/src/uu/readlink/readlink.md deleted file mode 100644 index 7215acbec..000000000 --- a/src/uu/readlink/readlink.md +++ /dev/null @@ -1,7 +0,0 @@ -# readlink - -``` -readlink [OPTION]... [FILE]... -``` - -Print value of a symbolic link or canonical file name. diff --git a/src/uu/readlink/src/readlink.rs b/src/uu/readlink/src/readlink.rs index 211422e03..f41e076a3 100644 --- a/src/uu/readlink/src/readlink.rs +++ b/src/uu/readlink/src/readlink.rs @@ -13,10 +13,9 @@ use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::fs::{MissingHandling, ResolveMode, canonicalize}; use uucore::line_ending::LineEnding; -use uucore::{format_usage, help_about, help_usage, show_error}; +use uucore::{format_usage, show_error}; -const ABOUT: &str = help_about!("readlink.md"); -const USAGE: &str = help_usage!("readlink.md"); +use uucore::locale::get_message; const OPT_CANONICALIZE: &str = "canonicalize"; const OPT_CANONICALIZE_MISSING: &str = "canonicalize-missing"; const OPT_CANONICALIZE_EXISTING: &str = "canonicalize-existing"; @@ -102,8 +101,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("readlink-about")) + .override_usage(format_usage(&get_message("readlink-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_CANONICALIZE) diff --git a/src/uu/realpath/locales/en-US.ftl b/src/uu/realpath/locales/en-US.ftl new file mode 100644 index 000000000..90910bf53 --- /dev/null +++ b/src/uu/realpath/locales/en-US.ftl @@ -0,0 +1,2 @@ +realpath-about = Print the resolved path +realpath-usage = realpath [OPTION]... FILE... diff --git a/src/uu/realpath/realpath.md b/src/uu/realpath/realpath.md deleted file mode 100644 index 25e4a3726..000000000 --- a/src/uu/realpath/realpath.md +++ /dev/null @@ -1,7 +0,0 @@ -# realpath - -``` -realpath [OPTION]... FILE... -``` - -Print the resolved path diff --git a/src/uu/realpath/src/realpath.rs b/src/uu/realpath/src/realpath.rs index 94532b755..4868ba68a 100644 --- a/src/uu/realpath/src/realpath.rs +++ b/src/uu/realpath/src/realpath.rs @@ -11,19 +11,16 @@ use std::{ path::{Path, PathBuf}, }; use uucore::fs::make_path_relative_to; +use uucore::locale::get_message; use uucore::{ display::{Quotable, print_verbatim}, error::{FromIo, UClapError, UResult}, format_usage, fs::{MissingHandling, ResolveMode, canonicalize}, - help_about, help_usage, line_ending::LineEnding, show_if_err, }; -static ABOUT: &str = help_about!("realpath.md"); -const USAGE: &str = help_usage!("realpath.md"); - static OPT_QUIET: &str = "quiet"; static OPT_STRIP: &str = "strip"; static OPT_ZERO: &str = "zero"; @@ -89,8 +86,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("realpath-about")) + .override_usage(format_usage(&get_message("realpath-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_QUIET) diff --git a/src/uu/rm/locales/en-US.ftl b/src/uu/rm/locales/en-US.ftl new file mode 100644 index 000000000..31f0d0083 --- /dev/null +++ b/src/uu/rm/locales/en-US.ftl @@ -0,0 +1,14 @@ +rm-about = Remove (unlink) the FILE(s) +rm-usage = rm [OPTION]... FILE... +rm-after-help = By default, rm does not remove directories. Use the --recursive (-r or -R) + option to remove each listed directory, too, along with all of its contents + + To remove a file whose name starts with a '-', for example '-foo', + use one of these commands: + rm -- -foo + + rm ./-foo + + Note that if you use rm to remove a file, it might be possible to recover + some of its contents, given sufficient expertise and/or time. For greater + assurance that the contents are truly unrecoverable, consider using shred. diff --git a/src/uu/rm/rm.md b/src/uu/rm/rm.md deleted file mode 100644 index 7acc46363..000000000 --- a/src/uu/rm/rm.md +++ /dev/null @@ -1,22 +0,0 @@ -# rm - -``` -rm [OPTION]... FILE... -``` - -Remove (unlink) the FILE(s) - -## After Help - -By default, rm does not remove directories. Use the --recursive (-r or -R) -option to remove each listed directory, too, along with all of its contents - -To remove a file whose name starts with a '-', for example '-foo', -use one of these commands: -rm -- -foo - -rm ./-foo - -Note that if you use rm to remove a file, it might be possible to recover -some of its contents, given sufficient expertise and/or time. For greater -assurance that the contents are truly unrecoverable, consider using shred. diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 3f48e311b..9e07bc077 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -18,9 +18,8 @@ use std::path::MAIN_SEPARATOR; use std::path::{Path, PathBuf}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; -use uucore::{ - format_usage, help_about, help_section, help_usage, os_str_as_bytes, prompt_yes, show_error, -}; +use uucore::locale::get_message; +use uucore::{format_usage, os_str_as_bytes, prompt_yes, show_error}; #[derive(Eq, PartialEq, Clone, Copy)] /// Enum, determining when the `rm` will prompt the user about the file deletion @@ -90,10 +89,6 @@ impl Default for Options { } } -const ABOUT: &str = help_about!("rm.md"); -const USAGE: &str = help_usage!("rm.md"); -const AFTER_HELP: &str = help_section!("after help", "rm.md"); - static OPT_DIR: &str = "dir"; static OPT_INTERACTIVE: &str = "interactive"; static OPT_FORCE: &str = "force"; @@ -202,9 +197,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .about(get_message("rm-about")) + .override_usage(format_usage(&get_message("rm-usage"))) + .after_help(get_message("rm-after-help")) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/rmdir/locales/en-US.ftl b/src/uu/rmdir/locales/en-US.ftl new file mode 100644 index 000000000..e2c1ca0ec --- /dev/null +++ b/src/uu/rmdir/locales/en-US.ftl @@ -0,0 +1,2 @@ +rmdir-about = Remove the DIRECTORY(ies), if they are empty. +rmdir-usage = rmdir [OPTION]... DIRECTORY... diff --git a/src/uu/rmdir/rmdir.md b/src/uu/rmdir/rmdir.md deleted file mode 100644 index 16f7bf82b..000000000 --- a/src/uu/rmdir/rmdir.md +++ /dev/null @@ -1,7 +0,0 @@ -# rmdir - -``` -rmdir [OPTION]... DIRECTORY... -``` - -Remove the DIRECTORY(ies), if they are empty. diff --git a/src/uu/rmdir/src/rmdir.rs b/src/uu/rmdir/src/rmdir.rs index 8c9dc12b6..228b085ec 100644 --- a/src/uu/rmdir/src/rmdir.rs +++ b/src/uu/rmdir/src/rmdir.rs @@ -14,10 +14,9 @@ use std::path::Path; use uucore::display::Quotable; use uucore::error::{UResult, set_exit_code, strip_errno}; -use uucore::{format_usage, help_about, help_usage, show_error, util_name}; +use uucore::{format_usage, show_error, util_name}; -static ABOUT: &str = help_about!("rmdir.md"); -const USAGE: &str = help_usage!("rmdir.md"); +use uucore::locale::get_message; static OPT_IGNORE_FAIL_NON_EMPTY: &str = "ignore-fail-on-non-empty"; static OPT_PARENTS: &str = "parents"; static OPT_VERBOSE: &str = "verbose"; @@ -165,8 +164,8 @@ struct Opts { pub fn uu_app() -> Command { Command::new(util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("rmdir-about")) + .override_usage(format_usage(&get_message("rmdir-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_IGNORE_FAIL_NON_EMPTY) diff --git a/src/uu/runcon/locales/en-US.ftl b/src/uu/runcon/locales/en-US.ftl new file mode 100644 index 000000000..37d977a5b --- /dev/null +++ b/src/uu/runcon/locales/en-US.ftl @@ -0,0 +1,10 @@ +runcon-about = Run command with specified security context under SELinux enabled systems. +runcon-usage = runcon CONTEXT COMMAND [ARG...] + runcon [-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [ARG...] +runcon-after-help = Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, ROLE, TYPE, and USER. + + If none of --compute, --type, --user, --role or --range is specified, then the first argument is used as the complete context. + + Note that only carefully-chosen contexts are likely to successfully run. + + If neither CONTEXT nor COMMAND is specified, the current security context is printed. diff --git a/src/uu/runcon/runcon.md b/src/uu/runcon/runcon.md deleted file mode 100644 index 53884b703..000000000 --- a/src/uu/runcon/runcon.md +++ /dev/null @@ -1,18 +0,0 @@ -# runcon - -``` -runcon CONTEXT COMMAND [ARG...] -runcon [-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [ARG...] -``` - -Run command with specified security context under SELinux enabled systems. - -## After Help - -Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, ROLE, TYPE, and USER. - -If none of --compute, --type, --user, --role or --range is specified, then the first argument is used as the complete context. - -Note that only carefully-chosen contexts are likely to successfully run. - -If neither CONTEXT nor COMMAND is specified, the current security context is printed. diff --git a/src/uu/runcon/src/runcon.rs b/src/uu/runcon/src/runcon.rs index 658aa33b2..ee67a9220 100644 --- a/src/uu/runcon/src/runcon.rs +++ b/src/uu/runcon/src/runcon.rs @@ -10,7 +10,7 @@ use uucore::error::{UClapError, UError, UResult}; use clap::{Arg, ArgAction, Command}; use selinux::{OpaqueSecurityContext, SecurityClass, SecurityContext}; -use uucore::{format_usage, help_about, help_section, help_usage}; +use uucore::format_usage; use std::borrow::Cow; use std::ffi::{CStr, CString, OsStr, OsString}; @@ -23,9 +23,7 @@ mod errors; use errors::error_exit_status; use errors::{Error, Result, RunconError}; -const ABOUT: &str = help_about!("runcon.md"); -const USAGE: &str = help_usage!("runcon.md"); -const DESCRIPTION: &str = help_section!("after help", "runcon.md"); +use uucore::locale::get_message; pub mod options { pub const COMPUTE: &str = "compute"; @@ -90,9 +88,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(DESCRIPTION) - .override_usage(format_usage(USAGE)) + .about(get_message("runcon-about")) + .after_help(get_message("runcon-after-help")) + .override_usage(format_usage(&get_message("runcon-usage"))) .infer_long_args(true) .arg( Arg::new(options::COMPUTE) diff --git a/src/uu/seq/locales/en-US.ftl b/src/uu/seq/locales/en-US.ftl new file mode 100644 index 000000000..818ebc86c --- /dev/null +++ b/src/uu/seq/locales/en-US.ftl @@ -0,0 +1,4 @@ +seq-about = Display numbers from FIRST to LAST, in steps of INCREMENT. +seq-usage = seq [OPTION]... LAST + seq [OPTION]... FIRST LAST + seq [OPTION]... FIRST INCREMENT LAST diff --git a/src/uu/seq/seq.md b/src/uu/seq/seq.md deleted file mode 100644 index d747e4a02..000000000 --- a/src/uu/seq/seq.md +++ /dev/null @@ -1,9 +0,0 @@ -# seq - -``` -seq [OPTION]... LAST -seq [OPTION]... FIRST LAST -seq [OPTION]... FIRST INCREMENT LAST -``` - -Display numbers from FIRST to LAST, in steps of INCREMENT. diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index af7ca2f84..2dd5f17b8 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -15,7 +15,7 @@ use uucore::error::{FromIo, UResult}; use uucore::extendedbigdecimal::ExtendedBigDecimal; use uucore::format::num_format::FloatVariant; use uucore::format::{Format, num_format}; -use uucore::{fast_inc::fast_inc, format_usage, help_about, help_usage}; +use uucore::{fast_inc::fast_inc, format_usage}; mod error; @@ -28,8 +28,7 @@ mod numberparse; use crate::error::SeqError; use crate::number::PreciseNumber; -const ABOUT: &str = help_about!("seq.md"); -const USAGE: &str = help_usage!("seq.md"); +use uucore::locale::get_message; const OPT_SEPARATOR: &str = "separator"; const OPT_TERMINATOR: &str = "terminator"; @@ -222,8 +221,8 @@ pub fn uu_app() -> Command { .trailing_var_arg(true) .infer_long_args(true) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("seq-about")) + .override_usage(format_usage(&get_message("seq-usage"))) .arg( Arg::new(OPT_SEPARATOR) .short('s') diff --git a/src/uu/shred/locales/en-US.ftl b/src/uu/shred/locales/en-US.ftl new file mode 100644 index 000000000..90245a08f --- /dev/null +++ b/src/uu/shred/locales/en-US.ftl @@ -0,0 +1,37 @@ +shred-about = Overwrite the specified FILE(s) repeatedly, in order to make it harder for even + very expensive hardware probing to recover the data. +shred-usage = shred [OPTION]... FILE... +shred-after-help = Delete FILE(s) if --remove (-u) is specified. The default is not to remove + the files because it is common to operate on device files like /dev/hda, and + those files usually should not be removed. + + CAUTION: Note that shred relies on a very important assumption: that the file + system overwrites data in place. This is the traditional way to do things, but + many modern file system designs do not satisfy this assumption. The following + are examples of file systems on which shred is not effective, or is not + guaranteed to be effective in all file system modes: + + - log-structured or journal file systems, such as those supplied with + AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.) + + - file systems that write redundant data and carry on even if some writes + fail, such as RAID-based file systems + + - file systems that make snapshots, such as Network Appliance's NFS server + + - file systems that cache in temporary locations, such as NFS + version 3 clients + + - compressed file systems + + In the case of ext3 file systems, the above disclaimer applies (and shred is + thus of limited effectiveness) only in data=journal mode, which journals file + data in addition to just metadata. In both the data=ordered (default) and + data=writeback modes, shred works as usual. Ext3 journal modes can be changed + by adding the data=something option to the mount options for a particular + file system in the /etc/fstab file, as documented in the mount man page (`man + mount`). + + In addition, file system backups and remote mirrors may contain copies of + the file that cannot be removed, and that will allow a shredded file to be + recovered later. diff --git a/src/uu/shred/shred.md b/src/uu/shred/shred.md deleted file mode 100644 index 6d6398cce..000000000 --- a/src/uu/shred/shred.md +++ /dev/null @@ -1,47 +0,0 @@ -# shred - - - -``` -shred [OPTION]... FILE... -``` - -Overwrite the specified FILE(s) repeatedly, in order to make it harder for even -very expensive hardware probing to recover the data. - -## After help - -Delete `FILE(s)` if `--remove` (`-u`) is specified. The default is not to remove -the files because it is common to operate on device files like `/dev/hda`, and -those files usually should not be removed. - -CAUTION: Note that shred relies on a very important assumption: that the file -system overwrites data in place. This is the traditional way to do things, but -many modern file system designs do not satisfy this assumption. The following -are examples of file systems on which shred is not effective, or is not -guaranteed to be effective in all file system modes: - - * log-structured or journal file systems, such as those supplied with - AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.) - - * file systems that write redundant data and carry on even if some writes - fail, such as RAID-based file systems - - * file systems that make snapshots, such as Network Appliance's NFS server - - * file systems that cache in temporary locations, such as NFS - version 3 clients - - * compressed file systems - -In the case of ext3 file systems, the above disclaimer applies (and shred is -thus of limited effectiveness) only in `data=journal` mode, which journals file -data in addition to just metadata. In both the `data=ordered` (default) and -`data=writeback` modes, shred works as usual. Ext3 journal modes can be changed -by adding the `data=something` option to the mount options for a particular -file system in the `/etc/fstab` file, as documented in the mount man page (`man -mount`). - -In addition, file system backups and remote mirrors may contain copies of -the file that cannot be removed, and that will allow a shredded file to be -recovered later. diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 30777e28a..0cfafd862 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -18,11 +18,9 @@ use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::parser::parse_size::parse_size_u64; use uucore::parser::shortcut_value_parser::ShortcutValueParser; -use uucore::{format_usage, help_about, help_section, help_usage, show_error, show_if_err}; +use uucore::{format_usage, show_error, show_if_err}; -const ABOUT: &str = help_about!("shred.md"); -const USAGE: &str = help_usage!("shred.md"); -const AFTER_HELP: &str = help_section!("after help", "shred.md"); +use uucore::locale::get_message; pub mod options { pub const FORCE: &str = "force"; @@ -316,9 +314,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("shred-about")) + .after_help(get_message("shred-after-help")) + .override_usage(format_usage(&get_message("shred-usage"))) .infer_long_args(true) .arg( Arg::new(options::FORCE) diff --git a/src/uu/shuf/locales/en-US.ftl b/src/uu/shuf/locales/en-US.ftl new file mode 100644 index 000000000..5348f1f7e --- /dev/null +++ b/src/uu/shuf/locales/en-US.ftl @@ -0,0 +1,6 @@ +shuf-about = Shuffle the input by outputting a random permutation of input lines. + Each output permutation is equally likely. + With no FILE, or when FILE is -, read standard input. +shuf-usage = shuf [OPTION]... [FILE] + shuf -e [OPTION]... [ARG]... + shuf -i LO-HI [OPTION]... diff --git a/src/uu/shuf/shuf.md b/src/uu/shuf/shuf.md deleted file mode 100644 index 7bc1e0a6d..000000000 --- a/src/uu/shuf/shuf.md +++ /dev/null @@ -1,11 +0,0 @@ -# shuf - -``` -shuf [OPTION]... [FILE] -shuf -e [OPTION]... [ARG]... -shuf -i LO-HI [OPTION]... -``` - -Shuffle the input by outputting a random permutation of input lines. -Each output permutation is equally likely. -With no FILE, or when FILE is -, read standard input. diff --git a/src/uu/shuf/src/shuf.rs b/src/uu/shuf/src/shuf.rs index 9c08ea28d..db4463615 100644 --- a/src/uu/shuf/src/shuf.rs +++ b/src/uu/shuf/src/shuf.rs @@ -19,7 +19,8 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use uucore::display::{OsWrite, Quotable}; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; mod rand_read_adapter; @@ -29,9 +30,6 @@ enum Mode { InputRange(RangeInclusive), } -static USAGE: &str = help_usage!("shuf.md"); -static ABOUT: &str = help_about!("shuf.md"); - struct Options { head_count: usize, output: Option, @@ -143,9 +141,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) - .about(ABOUT) + .about(get_message("shuf-about")) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) + .override_usage(format_usage(&get_message("shuf-usage"))) .infer_long_args(true) .arg( Arg::new(options::ECHO) diff --git a/src/uu/sleep/locales/en-US.ftl b/src/uu/sleep/locales/en-US.ftl new file mode 100644 index 000000000..c9e7925ba --- /dev/null +++ b/src/uu/sleep/locales/en-US.ftl @@ -0,0 +1,8 @@ +sleep-about = Pause for NUMBER seconds. +sleep-usage = sleep NUMBER[SUFFIX]... + sleep OPTION +sleep-after-help = Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), + 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementations + that require NUMBER be an integer, here NUMBER may be an arbitrary floating + point number. Given two or more arguments, pause for the amount of time + specified by the sum of their values. diff --git a/src/uu/sleep/sleep.md b/src/uu/sleep/sleep.md deleted file mode 100644 index b5c07fb49..000000000 --- a/src/uu/sleep/sleep.md +++ /dev/null @@ -1,16 +0,0 @@ -# sleep - -``` -sleep NUMBER[SUFFIX]... -sleep OPTION -``` - -Pause for NUMBER seconds. - -## After Help - -Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), -'m' for minutes, 'h' for hours or 'd' for days. Unlike most implementations -that require NUMBER be an integer, here NUMBER may be an arbitrary floating -point number. Given two or more arguments, pause for the amount of time -specified by the sum of their values. diff --git a/src/uu/sleep/src/sleep.rs b/src/uu/sleep/src/sleep.rs index 2b533eade..9b307b1e8 100644 --- a/src/uu/sleep/src/sleep.rs +++ b/src/uu/sleep/src/sleep.rs @@ -8,16 +8,14 @@ use std::time::Duration; use uucore::{ error::{UResult, USimpleError, UUsageError}, - format_usage, help_about, help_section, help_usage, + format_usage, parser::parse_time, show_error, }; use clap::{Arg, ArgAction, Command}; -static ABOUT: &str = help_about!("sleep.md"); -const USAGE: &str = help_usage!("sleep.md"); -static AFTER_HELP: &str = help_section!("after help", "sleep.md"); +use uucore::locale::get_message; mod options { pub const NUMBER: &str = "NUMBER"; @@ -47,9 +45,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("sleep-about")) + .after_help(get_message("sleep-after-help")) + .override_usage(format_usage(&get_message("sleep-usage"))) .infer_long_args(true) .arg( Arg::new(options::NUMBER) diff --git a/src/uu/sort/locales/en-US.ftl b/src/uu/sort/locales/en-US.ftl new file mode 100644 index 000000000..7b53e9df0 --- /dev/null +++ b/src/uu/sort/locales/en-US.ftl @@ -0,0 +1,11 @@ +sort-about = Display sorted concatenation of all FILE(s). With no FILE, or when FILE is -, read standard input. +sort-usage = sort [OPTION]... [FILE]... +sort-after-help = The key format is FIELD[.CHAR][OPTIONS][,FIELD[.CHAR]][OPTIONS]. + + Fields by default are separated by the first whitespace after a non-whitespace character. Use -t to specify a custom separator. + In the default case, whitespace is appended at the beginning of each field. Custom separators however are not included in fields. + + FIELD and CHAR both start at 1 (i.e. they are 1-indexed). If there is no end specified after a comma, the end will be the end of the line. + If CHAR is set 0, it means the end of the field. CHAR defaults to 1 for the start position and to 0 for the end position. + + Valid options are: MbdfhnRrV. They override the global options for this key. diff --git a/src/uu/sort/sort.md b/src/uu/sort/sort.md deleted file mode 100644 index 1d1aa5d5f..000000000 --- a/src/uu/sort/sort.md +++ /dev/null @@ -1,21 +0,0 @@ - - -# sort - -``` -sort [OPTION]... [FILE]... -``` - -Display sorted concatenation of all FILE(s). With no FILE, or when FILE is -, read standard input. - -## After help - -The key format is `FIELD[.CHAR][OPTIONS][,FIELD[.CHAR]][OPTIONS]`. - -Fields by default are separated by the first whitespace after a non-whitespace character. Use `-t` to specify a custom separator. -In the default case, whitespace is appended at the beginning of each field. Custom separators however are not included in fields. - -`FIELD` and `CHAR` both start at 1 (i.e. they are 1-indexed). If there is no end specified after a comma, the end will be the end of the line. -If `CHAR` is set 0, it means the end of the field. `CHAR` defaults to 1 for the start position and to 0 for the end position. - -Valid options are: `MbdfhnRrV`. They override the global options for this key. diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 7de7eb1ed..c97d07a6a 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -48,13 +48,11 @@ use uucore::line_ending::LineEnding; use uucore::parser::parse_size::{ParseSizeError, Parser}; use uucore::parser::shortcut_value_parser::ShortcutValueParser; use uucore::version_cmp::version_cmp; -use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +use uucore::{format_usage, show_error}; use crate::tmp_dir::TmpDirWrapper; -const ABOUT: &str = help_about!("sort.md"); -const USAGE: &str = help_usage!("sort.md"); -const AFTER_HELP: &str = help_section!("after help", "sort.md"); +use uucore::locale::get_message; mod options { pub mod modes { @@ -1340,9 +1338,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("sort-about")) + .after_help(get_message("sort-after-help")) + .override_usage(format_usage(&get_message("sort-usage"))) .infer_long_args(true) .disable_help_flag(true) .disable_version_flag(true) diff --git a/src/uu/split/locales/en-US.ftl b/src/uu/split/locales/en-US.ftl new file mode 100644 index 000000000..0b870d633 --- /dev/null +++ b/src/uu/split/locales/en-US.ftl @@ -0,0 +1,16 @@ +split-about = Create output files containing consecutive or interleaved sections of input +split-usage = split [OPTION]... [INPUT [PREFIX]] +split-after-help = Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is -, read standard input. + + The SIZE argument is an integer and optional unit (example: 10K is 10*1024). + Units are K,M,G,T,P,E,Z,Y,R,Q (powers of 1024) or KB,MB,... (powers of 1000). + Binary prefixes can be used, too: KiB=K, MiB=M, and so on. + + CHUNKS may be: + + - N split into N files based on size of input + - K/N output Kth of N to stdout + - l/N split into N files without splitting lines/records + - l/K/N output Kth of N to stdout without splitting lines/records + - r/N like 'l' but use round robin distribution + - r/K/N likewise but only output Kth of N to stdout diff --git a/src/uu/split/split.md b/src/uu/split/split.md deleted file mode 100644 index 836e3a0c6..000000000 --- a/src/uu/split/split.md +++ /dev/null @@ -1,26 +0,0 @@ - - -# split - -``` -split [OPTION]... [INPUT [PREFIX]] -``` - -Create output files containing consecutive or interleaved sections of input - -## After Help - -Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is -, read standard input. - -The SIZE argument is an integer and optional unit (example: 10K is 10*1024). -Units are K,M,G,T,P,E,Z,Y,R,Q (powers of 1024) or KB,MB,... (powers of 1000). -Binary prefixes can be used, too: KiB=K, MiB=M, and so on. - -CHUNKS may be: - -- N split into N files based on size of input -- K/N output Kth of N to stdout -- l/N split into N files without splitting lines/records -- l/K/N output Kth of N to stdout without splitting lines/records -- r/N like 'l' but use round robin distribution -- r/K/N likewise but only output Kth of N to stdout diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index 64548ea38..e026aaa2e 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -24,8 +24,9 @@ use uucore::display::Quotable; use uucore::error::{FromIo, UIoError, UResult, USimpleError, UUsageError}; use uucore::parser::parse_size::parse_size_u64; +use uucore::format_usage; +use uucore::locale::get_message; use uucore::uio_error; -use uucore::{format_usage, help_about, help_section, help_usage}; static OPT_BYTES: &str = "bytes"; static OPT_LINE_BYTES: &str = "line-bytes"; @@ -46,10 +47,6 @@ static OPT_IO_BLKSIZE: &str = "-io-blksize"; static ARG_INPUT: &str = "input"; static ARG_PREFIX: &str = "prefix"; -const ABOUT: &str = help_about!("split.md"); -const USAGE: &str = help_usage!("split.md"); -const AFTER_HELP: &str = help_section!("after help", "split.md"); - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let (args, obs_lines) = handle_obsolete(args); @@ -229,9 +226,9 @@ fn handle_preceding_options( pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(AFTER_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("split-about")) + .after_help(get_message("split-after-help")) + .override_usage(format_usage(&get_message("split-usage"))) .infer_long_args(true) // strategy (mutually exclusive) .arg( diff --git a/src/uu/stat/locales/en-US.ftl b/src/uu/stat/locales/en-US.ftl new file mode 100644 index 000000000..440e80e34 --- /dev/null +++ b/src/uu/stat/locales/en-US.ftl @@ -0,0 +1,54 @@ +stat-about = Display file or file system status. +stat-usage = stat [OPTION]... FILE... +stat-after-help = Valid format sequences for files (without `--file-system`): + + -`%a`: access rights in octal (note '#' and '0' printf flags) + -`%A`: access rights in human readable form + -`%b`: number of blocks allocated (see %B) + -`%B`: the size in bytes of each block reported by %b + -`%C`: SELinux security context string + -`%d`: device number in decimal + -`%D`: device number in hex + -`%f`: raw mode in hex + -`%F`: file type + -`%g`: group ID of owner + -`%G`: group name of owner + -`%h`: number of hard links + -`%i`: inode number + -`%m`: mount point + -`%n`: file name + -`%N`: quoted file name with dereference (follow) if symbolic link + -`%o`: optimal I/O transfer size hint + -`%s`: total size, in bytes + -`%t`: major device type in hex, for character/block device special files + -`%T`: minor device type in hex, for character/block device special files + -`%u`: user ID of owner + -`%U`: user name of owner + -`%w`: time of file birth, human-readable; - if unknown + -`%W`: time of file birth, seconds since Epoch; 0 if unknown + -`%x`: time of last access, human-readable + -`%X`: time of last access, seconds since Epoch + -`%y`: time of last data modification, human-readable + + -`%Y`: time of last data modification, seconds since Epoch + -`%z`: time of last status change, human-readable + -`%Z`: time of last status change, seconds since Epoch + + Valid format sequences for file systems: + + -`%a`: free blocks available to non-superuser + -`%b`: total data blocks in file system + -`%c`: total file nodes in file system + -`%d`: free file nodes in file system + -`%f`: free blocks in file system + -`%i`: file system ID in hex + -`%l`: maximum length of filenames + -`%n`: file name + -`%s`: block size (for faster transfers) + -`%S`: fundamental block size (for block counts) + -`%t`: file system type in hex + -`%T`: file system type in human readable form + + NOTE: your shell may have its own version of stat, which usually supersedes + the version described here. Please refer to your shell's documentation + for details about the options it supports. diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 16a96c380..2d8871d40 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -13,9 +13,7 @@ use uucore::fsext::{ BirthTime, FsMeta, StatFs, pretty_filetype, pretty_fstype, read_fs_list, statfs, }; use uucore::libc::mode_t; -use uucore::{ - entries, format_usage, help_about, help_section, help_usage, show_error, show_warning, -}; +use uucore::{entries, format_usage, show_error, show_warning}; use chrono::{DateTime, Local}; use clap::{Arg, ArgAction, ArgMatches, Command}; @@ -28,9 +26,7 @@ use std::os::unix::prelude::OsStrExt; use std::path::Path; use std::{env, fs}; -const ABOUT: &str = help_about!("stat.md"); -const USAGE: &str = help_usage!("stat.md"); -const LONG_USAGE: &str = help_section!("long usage", "stat.md"); +use uucore::locale::get_message; mod options { pub const DEREFERENCE: &str = "dereference"; @@ -1135,7 +1131,9 @@ impl Stater { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; + let matches = uu_app() + .after_help(get_message("stat-after-help")) + .try_get_matches_from(args)?; let stater = Stater::new(&matches)?; let exit_status = stater.exec(); @@ -1149,8 +1147,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("stat-about")) + .override_usage(format_usage(&get_message("stat-usage"))) .infer_long_args(true) .arg( Arg::new(options::DEREFERENCE) diff --git a/src/uu/stat/stat.md b/src/uu/stat/stat.md deleted file mode 100644 index ac63edd18..000000000 --- a/src/uu/stat/stat.md +++ /dev/null @@ -1,61 +0,0 @@ -# stat - -``` -stat [OPTION]... FILE... -``` - -Display file or file system status. - -## Long Usage - -Valid format sequences for files (without `--file-system`): - -- `%a`: access rights in octal (note '#' and '0' printf flags) -- `%A`: access rights in human readable form -- `%b`: number of blocks allocated (see %B) -- `%B`: the size in bytes of each block reported by %b -- `%C`: SELinux security context string -- `%d`: device number in decimal -- `%D`: device number in hex -- `%f`: raw mode in hex -- `%F`: file type -- `%g`: group ID of owner -- `%G`: group name of owner -- `%h`: number of hard links -- `%i`: inode number -- `%m`: mount point -- `%n`: file name -- `%N`: quoted file name with dereference (follow) if symbolic link -- `%o`: optimal I/O transfer size hint -- `%s`: total size, in bytes -- `%t`: major device type in hex, for character/block device special files -- `%T`: minor device type in hex, for character/block device special files -- `%u`: user ID of owner -- `%U`: user name of owner -- `%w`: time of file birth, human-readable; - if unknown -- `%W`: time of file birth, seconds since Epoch; 0 if unknown -- `%x`: time of last access, human-readable -- `%X`: time of last access, seconds since Epoch -- `%y`: time of last data modification, human-readable -- `%Y`: time of last data modification, seconds since Epoch -- `%z`: time of last status change, human-readable -- `%Z`: time of last status change, seconds since Epoch - -Valid format sequences for file systems: - -- `%a`: free blocks available to non-superuser -- `%b`: total data blocks in file system -- `%c`: total file nodes in file system -- `%d`: free file nodes in file system -- `%f`: free blocks in file system -- `%i`: file system ID in hex -- `%l`: maximum length of filenames -- `%n`: file name -- `%s`: block size (for faster transfers) -- `%S`: fundamental block size (for block counts) -- `%t`: file system type in hex -- `%T`: file system type in human readable form - -NOTE: your shell may have its own version of stat, which usually supersedes -the version described here. Please refer to your shell's documentation -for details about the options it supports. diff --git a/src/uu/stdbuf/locales/en-US.ftl b/src/uu/stdbuf/locales/en-US.ftl new file mode 100644 index 000000000..fb968f985 --- /dev/null +++ b/src/uu/stdbuf/locales/en-US.ftl @@ -0,0 +1,16 @@ +stdbuf-about = Run COMMAND, with modified buffering operations for its standard streams. + + Mandatory arguments to long options are mandatory for short options too. +stdbuf-usage = stdbuf [OPTION]... COMMAND +stdbuf-after-help = If MODE is 'L' the corresponding stream will be line buffered. + This option is invalid with standard input. + + If MODE is '0' the corresponding stream will be unbuffered. + + Otherwise, MODE is a number which may be followed by one of the following: + + KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y. + In this case the corresponding stream will be fully buffered with the buffer size set to MODE bytes. + + NOTE: If COMMAND adjusts the buffering of its standard streams (tee does for e.g.) then that will override corresponding settings changed by stdbuf. + Also some filters (like dd and cat etc.) don't use streams for I/O, and are thus unaffected by stdbuf settings. diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index fa6b2e630..9c2698a97 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -14,12 +14,10 @@ use std::process; use tempfile::TempDir; use tempfile::tempdir; use uucore::error::{FromIo, UClapError, UResult, USimpleError, UUsageError}; +use uucore::format_usage; use uucore::parser::parse_size::parse_size_u64; -use uucore::{format_usage, help_about, help_section, help_usage}; -const ABOUT: &str = help_about!("stdbuf.md"); -const USAGE: &str = help_usage!("stdbuf.md"); -const LONG_HELP: &str = help_section!("after help", "stdbuf.md"); +use uucore::locale::get_message; mod options { pub const INPUT: &str = "input"; @@ -204,9 +202,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .after_help(LONG_HELP) - .override_usage(format_usage(USAGE)) + .about(get_message("stdbuf-about")) + .after_help(get_message("stdbuf-after-help")) + .override_usage(format_usage(&get_message("stdbuf-usage"))) .trailing_var_arg(true) .infer_long_args(true) .arg( diff --git a/src/uu/stdbuf/stdbuf.md b/src/uu/stdbuf/stdbuf.md deleted file mode 100644 index e0062e627..000000000 --- a/src/uu/stdbuf/stdbuf.md +++ /dev/null @@ -1,24 +0,0 @@ -# stdbuf - -``` -stdbuf [OPTION]... COMMAND -``` - -Run `COMMAND`, with modified buffering operations for its standard streams. - -Mandatory arguments to long options are mandatory for short options too. - -## After Help - -If `MODE` is 'L' the corresponding stream will be line buffered. -This option is invalid with standard input. - -If `MODE` is '0' the corresponding stream will be unbuffered. - -Otherwise, `MODE` is a number which may be followed by one of the following: - -KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y. -In this case the corresponding stream will be fully buffered with the buffer size set to `MODE` bytes. - -NOTE: If `COMMAND` adjusts the buffering of its standard streams (`tee` does for e.g.) then that will override corresponding settings changed by `stdbuf`. -Also some filters (like `dd` and `cat` etc.) don't use streams for I/O, and are thus unaffected by `stdbuf` settings. diff --git a/src/uu/stty/locales/en-US.ftl b/src/uu/stty/locales/en-US.ftl new file mode 100644 index 000000000..06249f06a --- /dev/null +++ b/src/uu/stty/locales/en-US.ftl @@ -0,0 +1,4 @@ +stty-about = Print or change terminal characteristics. +stty-usage = stty [-F DEVICE | --file=DEVICE] [SETTING]... + stty [-F DEVICE | --file=DEVICE] [-a|--all] + stty [-F DEVICE | --file=DEVICE] [-g|--save] diff --git a/src/uu/stty/src/stty.rs b/src/uu/stty/src/stty.rs index 4e2ceaa3f..5b5a9948c 100644 --- a/src/uu/stty/src/stty.rs +++ b/src/uu/stty/src/stty.rs @@ -21,7 +21,8 @@ use std::os::fd::{AsFd, BorrowedFd}; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::{AsRawFd, RawFd}; use uucore::error::{UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; #[cfg(not(any( target_os = "freebsd", @@ -34,9 +35,6 @@ use uucore::{format_usage, help_about, help_usage}; use flags::BAUD_RATES; use flags::{CONTROL_CHARS, CONTROL_FLAGS, INPUT_FLAGS, LOCAL_FLAGS, OUTPUT_FLAGS}; -const USAGE: &str = help_usage!("stty.md"); -const SUMMARY: &str = help_about!("stty.md"); - #[derive(Clone, Copy, Debug)] pub struct Flag { name: &'static str, @@ -476,8 +474,8 @@ fn apply_baud_rate_flag(termios: &mut Termios, input: &str) -> ControlFlow pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(SUMMARY) + .override_usage(format_usage(&get_message("stty-usage"))) + .about(get_message("stty-about")) .infer_long_args(true) .arg( Arg::new(options::ALL) diff --git a/src/uu/stty/stty.md b/src/uu/stty/stty.md deleted file mode 100644 index 6aa1decf5..000000000 --- a/src/uu/stty/stty.md +++ /dev/null @@ -1,9 +0,0 @@ -# stty - -``` -stty [-F DEVICE | --file=DEVICE] [SETTING]... -stty [-F DEVICE | --file=DEVICE] [-a|--all] -stty [-F DEVICE | --file=DEVICE] [-g|--save] -``` - -Print or change terminal characteristics. diff --git a/src/uu/sum/locales/en-US.ftl b/src/uu/sum/locales/en-US.ftl new file mode 100644 index 000000000..0d3f34b65 --- /dev/null +++ b/src/uu/sum/locales/en-US.ftl @@ -0,0 +1,4 @@ +sum-about = Checksum and count the blocks in a file. + + With no FILE, or when FILE is -, read standard input. +sum-usage = sum [OPTION]... [FILE]... diff --git a/src/uu/sum/src/sum.rs b/src/uu/sum/src/sum.rs index 1aec0ef98..0f5e6c664 100644 --- a/src/uu/sum/src/sum.rs +++ b/src/uu/sum/src/sum.rs @@ -11,10 +11,9 @@ use std::io::{ErrorKind, Read, Write, stdin, stdout}; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; -const USAGE: &str = help_usage!("sum.md"); -const ABOUT: &str = help_about!("sum.md"); +use uucore::locale::get_message; fn bsd_sum(mut reader: impl Read) -> std::io::Result<(usize, u16)> { let mut buf = [0; 4096]; @@ -138,8 +137,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("sum-usage"))) + .about(get_message("sum-about")) .infer_long_args(true) .arg( Arg::new(options::FILE) diff --git a/src/uu/sum/sum.md b/src/uu/sum/sum.md deleted file mode 100644 index 93dbdbf62..000000000 --- a/src/uu/sum/sum.md +++ /dev/null @@ -1,9 +0,0 @@ -# sum - -``` -sum [OPTION]... [FILE]... -``` - -Checksum and count the blocks in a file. - -With no FILE, or when FILE is -, read standard input. diff --git a/src/uu/sync/locales/en-US.ftl b/src/uu/sync/locales/en-US.ftl new file mode 100644 index 000000000..bb7bfe3a5 --- /dev/null +++ b/src/uu/sync/locales/en-US.ftl @@ -0,0 +1,2 @@ +sync-about = Synchronize cached writes to persistent storage +sync-usage = sync [OPTION]... FILE... diff --git a/src/uu/sync/src/sync.rs b/src/uu/sync/src/sync.rs index b0221d3d7..47db35c32 100644 --- a/src/uu/sync/src/sync.rs +++ b/src/uu/sync/src/sync.rs @@ -17,10 +17,9 @@ use uucore::display::Quotable; #[cfg(any(target_os = "linux", target_os = "android"))] use uucore::error::FromIo; use uucore::error::{UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; -const ABOUT: &str = help_about!("sync.md"); -const USAGE: &str = help_usage!("sync.md"); +use uucore::locale::get_message; pub mod options { pub static FILE_SYSTEM: &str = "file-system"; @@ -222,8 +221,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("sync-about")) + .override_usage(format_usage(&get_message("sync-usage"))) .infer_long_args(true) .arg( Arg::new(options::FILE_SYSTEM) diff --git a/src/uu/sync/sync.md b/src/uu/sync/sync.md deleted file mode 100644 index 2fdd36339..000000000 --- a/src/uu/sync/sync.md +++ /dev/null @@ -1,7 +0,0 @@ -# sync - -``` -sync [OPTION]... FILE... -``` - -Synchronize cached writes to persistent storage diff --git a/src/uu/tac/locales/en-US.ftl b/src/uu/tac/locales/en-US.ftl new file mode 100644 index 000000000..28a3621f2 --- /dev/null +++ b/src/uu/tac/locales/en-US.ftl @@ -0,0 +1,2 @@ +tac-about = Write each file to standard output, last line first. +tac-usage = tac [OPTION]... [FILE]... diff --git a/src/uu/tac/src/tac.rs b/src/uu/tac/src/tac.rs index 4496c2ce1..0cb2009a9 100644 --- a/src/uu/tac/src/tac.rs +++ b/src/uu/tac/src/tac.rs @@ -17,12 +17,11 @@ use std::{ use uucore::display::Quotable; use uucore::error::UError; use uucore::error::UResult; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; use crate::error::TacError; -static USAGE: &str = help_usage!("tac.md"); -static ABOUT: &str = help_about!("tac.md"); +use uucore::locale::get_message; mod options { pub static BEFORE: &str = "before"; @@ -58,8 +57,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("tac-usage"))) + .about(get_message("tac-about")) .infer_long_args(true) .arg( Arg::new(options::BEFORE) diff --git a/src/uu/tac/tac.md b/src/uu/tac/tac.md deleted file mode 100644 index 6787b3f49..000000000 --- a/src/uu/tac/tac.md +++ /dev/null @@ -1,7 +0,0 @@ -# tac - -``` -tac [OPTION]... [FILE]... -``` - -Write each file to standard output, last line first. diff --git a/src/uu/tail/locales/en-US.ftl b/src/uu/tail/locales/en-US.ftl new file mode 100644 index 000000000..8d6394838 --- /dev/null +++ b/src/uu/tail/locales/en-US.ftl @@ -0,0 +1,6 @@ +tail-about = Print the last 10 lines of each FILE to standard output. + With more than one FILE, precede each with a header giving the file name. + With no FILE, or when FILE is -, read standard input. + + Mandatory arguments to long flags are mandatory for short flags too. +tail-usage = tail [FLAG]... [FILE]... diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index 61448388c..374beffd0 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -16,10 +16,9 @@ use uucore::error::{UResult, USimpleError, UUsageError}; use uucore::parser::parse_size::{ParseSizeError, parse_size_u64}; use uucore::parser::parse_time; use uucore::parser::shortcut_value_parser::ShortcutValueParser; -use uucore::{format_usage, help_about, help_usage, show_warning}; +use uucore::{format_usage, show_warning}; -const ABOUT: &str = help_about!("tail.md"); -const USAGE: &str = help_usage!("tail.md"); +use uucore::locale::get_message; pub mod options { pub mod verbosity { @@ -464,8 +463,8 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("tail-about")) + .override_usage(format_usage(&get_message("tail-usage"))) .infer_long_args(true) .arg( Arg::new(options::BYTES) diff --git a/src/uu/tail/tail.md b/src/uu/tail/tail.md deleted file mode 100644 index fefe7f6ee..000000000 --- a/src/uu/tail/tail.md +++ /dev/null @@ -1,11 +0,0 @@ -# tail - -``` -tail [FLAG]... [FILE]... -``` - -Print the last 10 lines of each FILE to standard output. -With more than one FILE, precede each with a header giving the file name. -With no FILE, or when FILE is -, read standard input. - -Mandatory arguments to long flags are mandatory for short flags too. diff --git a/src/uu/tee/locales/en-US.ftl b/src/uu/tee/locales/en-US.ftl new file mode 100644 index 000000000..2f0286958 --- /dev/null +++ b/src/uu/tee/locales/en-US.ftl @@ -0,0 +1,3 @@ +tee-about = Copy standard input to each FILE, and also to standard output. +tee-usage = tee [OPTION]... [FILE]... +tee-after-help = If a FILE is -, it refers to a file named - . diff --git a/src/uu/tee/src/tee.rs b/src/uu/tee/src/tee.rs index b16caeb93..e5269caf2 100644 --- a/src/uu/tee/src/tee.rs +++ b/src/uu/tee/src/tee.rs @@ -12,16 +12,14 @@ use std::path::PathBuf; use uucore::display::Quotable; use uucore::error::UResult; use uucore::parser::shortcut_value_parser::ShortcutValueParser; -use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +use uucore::{format_usage, show_error}; // spell-checker:ignore nopipe #[cfg(unix)] use uucore::signals::{enable_pipe_errors, ignore_interrupts}; -const ABOUT: &str = help_about!("tee.md"); -const USAGE: &str = help_usage!("tee.md"); -const AFTER_HELP: &str = help_section!("after help", "tee.md"); +use uucore::locale::get_message; mod options { pub const APPEND: &str = "append"; @@ -97,9 +95,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .about(get_message("tee-about")) + .override_usage(format_usage(&get_message("tee-usage"))) + .after_help(get_message("tee-after-help")) .infer_long_args(true) // Since we use value-specific help texts for "--output-error", clap's "short help" and "long help" differ. // However, this is something that the GNU tests explicitly test for, so we *always* show the long help instead. diff --git a/src/uu/tee/tee.md b/src/uu/tee/tee.md deleted file mode 100644 index 8bf097cec..000000000 --- a/src/uu/tee/tee.md +++ /dev/null @@ -1,11 +0,0 @@ -# tee - -``` -tee [OPTION]... [FILE]... -``` - -Copy standard input to each FILE, and also to standard output. - -## After Help - -If a FILE is -, it refers to a file named - . diff --git a/src/uu/test/locales/en-US.ftl b/src/uu/test/locales/en-US.ftl new file mode 100644 index 000000000..0f7a67394 --- /dev/null +++ b/src/uu/test/locales/en-US.ftl @@ -0,0 +1,71 @@ +test-about = Check file types and compare values. +test-usage = test EXPRESSION + test + {"[ EXPRESSION ]"} + {"[ ]"} + {"[ OPTION ]"} +test-after-help = Exit with the status determined by EXPRESSION. + + An omitted EXPRESSION defaults to false. + Otherwise, EXPRESSION is true or false and sets exit status. + + It is one of: + + - ( EXPRESSION ) EXPRESSION is true + - ! EXPRESSION EXPRESSION is false + - EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true + - EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true + + String operations: + - -n STRING the length of STRING is nonzero + - STRING equivalent to -n STRING + - -z STRING the length of STRING is zero + - STRING1 = STRING2 the strings are equal + - STRING1 != STRING2 the strings are not equal + + Integer comparisons: + - INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2 + - INTEGER1 -ge INTEGER2 INTEGER1 is greater than or equal to INTEGER2 + - INTEGER1 -gt INTEGER2 INTEGER1 is greater than INTEGER2 + - INTEGER1 -le INTEGER2 INTEGER1 is less than or equal to INTEGER2 + - INTEGER1 -lt INTEGER2 INTEGER1 is less than INTEGER2 + - INTEGER1 -ne INTEGER2 INTEGER1 is not equal to INTEGER2 + + File operations: + - FILE1 -ef FILE2 FILE1 and FILE2 have the same device and inode numbers + - FILE1 -nt FILE2 FILE1 is newer (modification date) than FILE2 + - FILE1 -ot FILE2 FILE1 is older than FILE2 + + - -b FILE FILE exists and is block special + - -c FILE FILE exists and is character special + - -d FILE FILE exists and is a directory + - -e FILE FILE exists + - -f FILE FILE exists and is a regular file + - -g FILE FILE exists and is set-group-ID + - -G FILE FILE exists and is owned by the effective group ID + - -h FILE FILE exists and is a symbolic link (same as -L) + - -k FILE FILE exists and has its sticky bit set + - -L FILE FILE exists and is a symbolic link (same as -h) + - -N FILE FILE exists and has been modified since it was last read + - -O FILE FILE exists and is owned by the effective user ID + - -p FILE FILE exists and is a named pipe + - -r FILE FILE exists and read permission is granted + - -s FILE FILE exists and has a size greater than zero + - -S FILE FILE exists and is a socket + - -t FD file descriptor FD is opened on a terminal + - -u FILE FILE exists and its set-user-ID bit is set + - -w FILE FILE exists and write permission is granted + - -x FILE FILE exists and execute (or search) permission is granted + + Except for -h and -L, all FILE-related tests dereference (follow) symbolic links. + Beware that parentheses need to be escaped (e.g., by backslashes) for shells. + INTEGER may also be -l STRING, which evaluates to the length of STRING. + + NOTE: Binary -a and -o are inherently ambiguous. + Use test EXPR1 && test EXPR2 or test EXPR1 || test EXPR2 instead. + + NOTE: [ honors the --help and --version options, but test does not. + test treats each of those as it treats any other nonempty STRING. + + NOTE: your shell may have its own version of test and/or [, which usually supersedes the version described here. + Please refer to your shell's documentation for details about the options it supports. diff --git a/src/uu/test/src/test.rs b/src/uu/test/src/test.rs index e71e7b191..674e70dd3 100644 --- a/src/uu/test/src/test.rs +++ b/src/uu/test/src/test.rs @@ -17,35 +17,27 @@ use std::fs; use std::os::unix::fs::MetadataExt; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError}; +use uucore::format_usage; #[cfg(not(windows))] use uucore::process::{getegid, geteuid}; -use uucore::{format_usage, help_about, help_section}; -const ABOUT: &str = help_about!("test.md"); +use uucore::locale::get_message; // The help_usage method replaces util name (the first word) with {}. // And, The format_usage method replaces {} with execution_phrase ( e.g. test or [ ). // However, This test command has two util names. // So, we use test or [ instead of {} so that the usage string is correct. -const USAGE: &str = "\ -test EXPRESSION -[ -[ EXPRESSION ] -[ ] -[ OPTION -]"; // We use after_help so that this comes after the usage string (it would come before if we used about) -const AFTER_HELP: &str = help_section!("after help", "test.md"); pub fn uu_app() -> Command { // Disable printing of -h and -v as valid alternatives for --help and --version, // since we don't recognize -h and -v as help/version flags. Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .about(get_message("test-about")) + .override_usage(format_usage(&get_message("test-usage"))) + .after_help(get_message("test-after-help")) } #[uucore::main] diff --git a/src/uu/test/test.md b/src/uu/test/test.md deleted file mode 100644 index e67eb1824..000000000 --- a/src/uu/test/test.md +++ /dev/null @@ -1,79 +0,0 @@ -# test - -``` -test EXPRESSION -test -[ EXPRESSION ] -[ ] -[ OPTION -``` - -Check file types and compare values. - -## After Help - -Exit with the status determined by `EXPRESSION`. - -An omitted `EXPRESSION` defaults to false. -Otherwise, `EXPRESSION` is true or false and sets exit status. - -It is one of: - -* ( EXPRESSION ) `EXPRESSION` is true -* ! EXPRESSION `EXPRESSION` is false -* EXPRESSION1 -a EXPRESSION2 both `EXPRESSION1` and `EXPRESSION2` are true -* EXPRESSION1 -o EXPRESSION2 either `EXPRESSION1` or `EXPRESSION2` is true - -String operations: -* -n STRING the length of `STRING` is nonzero -* STRING equivalent to -n `STRING` -* -z STRING the length of `STRING` is zero -* STRING1 = STRING2 the strings are equal -* STRING1 != STRING2 the strings are not equal - -Integer comparisons: -* INTEGER1 -eq INTEGER2 `INTEGER1` is equal to `INTEGER2` -* INTEGER1 -ge INTEGER2 `INTEGER1` is greater than or equal to `INTEGER2` -* INTEGER1 -gt INTEGER2 `INTEGER1` is greater than `INTEGER2` -* INTEGER1 -le INTEGER2 `INTEGER1` is less than or equal to `INTEGER2` -* INTEGER1 -lt INTEGER2 `INTEGER1` is less than `INTEGER2` -* INTEGER1 -ne INTEGER2 `INTEGER1` is not equal to `INTEGER2` - -File operations: -* FILE1 -ef FILE2 `FILE1` and `FILE2` have the same device and inode numbers -* FILE1 -nt FILE2 `FILE1` is newer (modification date) than `FILE2` -* FILE1 -ot FILE2 `FILE1` is older than `FILE2` - -* -b FILE `FILE` exists and is block special -* -c FILE `FILE` exists and is character special -* -d FILE `FILE` exists and is a directory -* -e FILE `FILE` exists -* -f FILE `FILE` exists and is a regular file -* -g FILE `FILE` exists and is set-group-ID -* -G FILE `FILE` exists and is owned by the effective group ID -* -h FILE `FILE` exists and is a symbolic link (same as -L) -* -k FILE `FILE` exists and has its sticky bit set -* -L FILE `FILE` exists and is a symbolic link (same as -h) -* -N FILE `FILE` exists and has been modified since it was last read -* -O FILE `FILE` exists and is owned by the effective user ID -* -p FILE `FILE` exists and is a named pipe -* -r FILE `FILE` exists and read permission is granted -* -s FILE `FILE` exists and has a size greater than zero -* -S FILE `FILE` exists and is a socket -* -t FD `file` descriptor `FD` is opened on a terminal -* -u FILE `FILE` exists and its set-user-ID bit is set -* -w FILE `FILE` exists and write permission is granted -* -x FILE `FILE` exists and execute (or search) permission is granted - -Except for `-h` and `-L`, all FILE-related tests dereference (follow) symbolic links. -Beware that parentheses need to be escaped (e.g., by backslashes) for shells. -`INTEGER` may also be -l `STRING`, which evaluates to the length of `STRING`. - -NOTE: Binary `-a` and `-o` are inherently ambiguous. -Use `test EXPR1 && test EXPR2` or `test EXPR1 || test EXPR2` instead. - -NOTE: `[` honors the `--help` and `--version` options, but test does not. -test treats each of those as it treats any other nonempty `STRING`. - -NOTE: your shell may have its own version of `test` and/or `[`, which usually supersedes the version described here. -Please refer to your shell's documentation for details about the options it supports. diff --git a/src/uu/timeout/locales/en-US.ftl b/src/uu/timeout/locales/en-US.ftl new file mode 100644 index 000000000..57126de1e --- /dev/null +++ b/src/uu/timeout/locales/en-US.ftl @@ -0,0 +1,2 @@ +timeout-about = Start COMMAND, and kill it if still running after DURATION. +timeout-usage = timeout [OPTION] DURATION COMMAND... diff --git a/src/uu/timeout/src/timeout.rs b/src/uu/timeout/src/timeout.rs index 9de335801..35232d3e4 100644 --- a/src/uu/timeout/src/timeout.rs +++ b/src/uu/timeout/src/timeout.rs @@ -17,17 +17,15 @@ use uucore::error::{UClapError, UResult, USimpleError, UUsageError}; use uucore::parser::parse_time; use uucore::process::ChildExt; +use uucore::locale::get_message; #[cfg(unix)] use uucore::signals::enable_pipe_errors; use uucore::{ - format_usage, help_about, help_usage, show_error, + format_usage, show_error, signals::{signal_by_name_or_value, signal_name_by_value}, }; -const ABOUT: &str = help_about!("timeout.md"); -const USAGE: &str = help_usage!("timeout.md"); - pub mod options { pub static FOREGROUND: &str = "foreground"; pub static KILL_AFTER: &str = "kill-after"; @@ -122,8 +120,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new("timeout") .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("timeout-about")) + .override_usage(format_usage(&get_message("timeout-usage"))) .arg( Arg::new(options::FOREGROUND) .long(options::FOREGROUND) diff --git a/src/uu/timeout/timeout.md b/src/uu/timeout/timeout.md deleted file mode 100644 index f992ab327..000000000 --- a/src/uu/timeout/timeout.md +++ /dev/null @@ -1,7 +0,0 @@ -# timeout - -``` -timeout [OPTION] DURATION COMMAND... -``` - -Start `COMMAND`, and kill it if still running after `DURATION`. diff --git a/src/uu/touch/locales/en-US.ftl b/src/uu/touch/locales/en-US.ftl new file mode 100644 index 000000000..a3e6d6e3e --- /dev/null +++ b/src/uu/touch/locales/en-US.ftl @@ -0,0 +1,2 @@ +touch-about = Update the access and modification times of each FILE to the current time. +touch-usage = touch [OPTION]... [USER] diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 6749933f0..c12c50530 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -23,9 +23,10 @@ use std::path::{Path, PathBuf}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; use uucore::parser::shortcut_value_parser::ShortcutValueParser; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; use crate::error::TouchError; +use uucore::locale::get_message; /// Options contains all the possible behaviors and flags for touch. /// @@ -83,9 +84,6 @@ pub enum Source { Now, } -const ABOUT: &str = help_about!("touch.md"); -const USAGE: &str = help_usage!("touch.md"); - pub mod options { // Both SOURCES and sources are needed as we need to be able to refer to the ArgGroup. pub static SOURCES: &str = "sources"; @@ -258,8 +256,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("touch-about")) + .override_usage(format_usage(&get_message("touch-usage"))) .infer_long_args(true) .disable_help_flag(true) .arg( diff --git a/src/uu/touch/touch.md b/src/uu/touch/touch.md deleted file mode 100644 index 8ce35b686..000000000 --- a/src/uu/touch/touch.md +++ /dev/null @@ -1,7 +0,0 @@ -# touch - -``` -touch [OPTION]... [USER] -``` - -Update the access and modification times of each `FILE` to the current time. diff --git a/src/uu/tr/locales/en-US.ftl b/src/uu/tr/locales/en-US.ftl new file mode 100644 index 000000000..931c6265b --- /dev/null +++ b/src/uu/tr/locales/en-US.ftl @@ -0,0 +1,3 @@ +tr-about = Translate or delete characters +tr-usage = tr [OPTION]... SET1 [SET2] +tr-after-help = Translate, squeeze, and/or delete characters from standard input, writing to standard output. diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index 10a636fd7..5259990bf 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -18,11 +18,9 @@ use std::io::{BufWriter, Write, stdin, stdout}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::fs::is_stdin_directory; -use uucore::{format_usage, help_about, help_section, help_usage, os_str_as_bytes, show}; +use uucore::{format_usage, os_str_as_bytes, show}; -const ABOUT: &str = help_about!("tr.md"); -const AFTER_HELP: &str = help_section!("after help", "tr.md"); -const USAGE: &str = help_usage!("tr.md"); +use uucore::locale::get_message; mod options { pub const COMPLEMENT: &str = "complement"; @@ -34,7 +32,9 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; + let matches = uu_app() + .after_help(get_message("tr-after-help")) + .try_get_matches_from(args)?; let delete_flag = matches.get_flag(options::DELETE); let complement_flag = matches.get_flag(options::COMPLEMENT); @@ -164,8 +164,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("tr-about")) + .override_usage(format_usage(&get_message("tr-usage"))) .infer_long_args(true) .trailing_var_arg(true) .arg( diff --git a/src/uu/tr/tr.md b/src/uu/tr/tr.md deleted file mode 100644 index 93349eeaa..000000000 --- a/src/uu/tr/tr.md +++ /dev/null @@ -1,11 +0,0 @@ -# tr - -``` -tr [OPTION]... SET1 [SET2] -``` - -Translate or delete characters - -## After help - -Translate, squeeze, and/or delete characters from standard input, writing to standard output. diff --git a/src/uu/true/locales/en-US.ftl b/src/uu/true/locales/en-US.ftl new file mode 100644 index 000000000..e75e9e670 --- /dev/null +++ b/src/uu/true/locales/en-US.ftl @@ -0,0 +1,5 @@ +true-about = Returns true, a successful exit status. + + Immediately returns with the exit status 0, except when invoked with one of the recognized + options. In those cases it will try to write the help or version text. Any IO error during this + operation causes the program to return 1 instead. diff --git a/src/uu/true/src/true.rs b/src/uu/true/src/true.rs index 29dae0ba6..4036024a4 100644 --- a/src/uu/true/src/true.rs +++ b/src/uu/true/src/true.rs @@ -5,9 +5,8 @@ use clap::{Arg, ArgAction, Command}; use std::{ffi::OsString, io::Write}; use uucore::error::{UResult, set_exit_code}; -use uucore::help_about; -const ABOUT: &str = help_about!("true.md"); +use uucore::locale::get_message; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { @@ -43,7 +42,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) + .about(get_message("true-about")) // We provide our own help and version options, to ensure maximum compatibility with GNU. .disable_help_flag(true) .disable_version_flag(true) diff --git a/src/uu/true/true.md b/src/uu/true/true.md deleted file mode 100644 index b21c9616e..000000000 --- a/src/uu/true/true.md +++ /dev/null @@ -1,11 +0,0 @@ -# true - -``` -true -``` - -Returns true, a successful exit status. - -Immediately returns with the exit status `0`, except when invoked with one of the recognized -options. In those cases it will try to write the help or version text. Any IO error during this -operation causes the program to return `1` instead. diff --git a/src/uu/truncate/locales/en-US.ftl b/src/uu/truncate/locales/en-US.ftl new file mode 100644 index 000000000..b3ae2fcc4 --- /dev/null +++ b/src/uu/truncate/locales/en-US.ftl @@ -0,0 +1,18 @@ +truncate-about = Shrink or extend the size of each file to the specified size. +truncate-usage = truncate [OPTION]... [FILE]... +truncate-after-help = SIZE is an integer with an optional prefix and optional unit. + The available units (K, M, G, T, P, E, Z, and Y) use the following format: + 'KB' => 1000 (kilobytes) + 'K' => 1024 (kibibytes) + 'MB' => 1000*1000 (megabytes) + 'M' => 1024*1024 (mebibytes) + 'GB' => 1000*1000*1000 (gigabytes) + 'G' => 1024*1024*1024 (gibibytes) + SIZE may also be prefixed by one of the following to adjust the size of each + file based on its current size: + '+' => extend by + '-' => reduce by + '<' => at most + '>' => at least + '/' => round down to multiple of + '%' => round up to multiple of diff --git a/src/uu/truncate/src/truncate.rs b/src/uu/truncate/src/truncate.rs index 056163fa3..461ed8057 100644 --- a/src/uu/truncate/src/truncate.rs +++ b/src/uu/truncate/src/truncate.rs @@ -12,8 +12,9 @@ use std::os::unix::fs::FileTypeExt; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; +use uucore::format_usage; +use uucore::locale::get_message; use uucore::parser::parse_size::{ParseSizeError, parse_size_u64}; -use uucore::{format_usage, help_about, help_section, help_usage}; #[derive(Debug, Eq, PartialEq)] enum TruncateMode { @@ -71,10 +72,6 @@ impl TruncateMode { } } -const ABOUT: &str = help_about!("truncate.md"); -const AFTER_HELP: &str = help_section!("after help", "truncate.md"); -const USAGE: &str = help_usage!("truncate.md"); - pub mod options { pub static IO_BLOCKS: &str = "io-blocks"; pub static NO_CREATE: &str = "no-create"; @@ -86,7 +83,7 @@ pub mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app() - .after_help(AFTER_HELP) + .after_help(get_message("truncate-after-help")) .try_get_matches_from(args) .map_err(|e| { e.print().expect("Error writing clap::Error"); @@ -117,8 +114,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("truncate-about")) + .override_usage(format_usage(&get_message("truncate-usage"))) .infer_long_args(true) .arg( Arg::new(options::IO_BLOCKS) diff --git a/src/uu/truncate/truncate.md b/src/uu/truncate/truncate.md deleted file mode 100644 index d60a6b7b2..000000000 --- a/src/uu/truncate/truncate.md +++ /dev/null @@ -1,26 +0,0 @@ -# truncate - -``` -truncate [OPTION]... [FILE]... -``` - -Shrink or extend the size of each file to the specified size. - -## After help - -SIZE is an integer with an optional prefix and optional unit. -The available units (K, M, G, T, P, E, Z, and Y) use the following format: - 'KB' => 1000 (kilobytes) - 'K' => 1024 (kibibytes) - 'MB' => 1000*1000 (megabytes) - 'M' => 1024*1024 (mebibytes) - 'GB' => 1000*1000*1000 (gigabytes) - 'G' => 1024*1024*1024 (gibibytes) -SIZE may also be prefixed by one of the following to adjust the size of each -file based on its current size: - '+' => extend by - '-' => reduce by - '<' => at most - '>' => at least - '/' => round down to multiple of - '%' => round up to multiple of diff --git a/src/uu/tsort/locales/en-US.ftl b/src/uu/tsort/locales/en-US.ftl new file mode 100644 index 000000000..12cafe40c --- /dev/null +++ b/src/uu/tsort/locales/en-US.ftl @@ -0,0 +1,5 @@ +tsort-about = Topological sort the strings in FILE. + Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline), ordering them based on dependencies in a directed acyclic graph (DAG). + Useful for scheduling and determining execution order. + If FILE is not passed in, stdin is used instead. +tsort-usage = tsort [OPTIONS] FILE diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index 3f7e89e99..3a3a3c51c 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -9,10 +9,9 @@ use std::path::Path; use thiserror::Error; use uucore::display::Quotable; use uucore::error::{UError, UResult}; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; -const ABOUT: &str = help_about!("tsort.md"); -const USAGE: &str = help_usage!("tsort.md"); +use uucore::locale::get_message; mod options { pub const FILE: &str = "file"; @@ -76,8 +75,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("tsort-usage"))) + .about(get_message("tsort-about")) .infer_long_args(true) .arg( Arg::new(options::FILE) diff --git a/src/uu/tsort/tsort.md b/src/uu/tsort/tsort.md deleted file mode 100644 index 5effbf1e7..000000000 --- a/src/uu/tsort/tsort.md +++ /dev/null @@ -1,10 +0,0 @@ -# tsort - -``` -tsort [OPTIONS] FILE -``` - -Topological sort the strings in FILE. -Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline), ordering them based on dependencies in a directed acyclic graph (DAG). -Useful for scheduling and determining execution order. -If FILE is not passed in, stdin is used instead. diff --git a/src/uu/tty/locales/en-US.ftl b/src/uu/tty/locales/en-US.ftl new file mode 100644 index 000000000..8d480ec4a --- /dev/null +++ b/src/uu/tty/locales/en-US.ftl @@ -0,0 +1,2 @@ +tty-about = Print the file name of the terminal connected to standard input. +tty-usage = tty [OPTION]... diff --git a/src/uu/tty/src/tty.rs b/src/uu/tty/src/tty.rs index 35dc1f086..7cad08ba8 100644 --- a/src/uu/tty/src/tty.rs +++ b/src/uu/tty/src/tty.rs @@ -10,10 +10,9 @@ use clap::{Arg, ArgAction, Command}; use std::io::{IsTerminal, Write}; use uucore::error::{UResult, set_exit_code}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; -const ABOUT: &str = help_about!("tty.md"); -const USAGE: &str = help_usage!("tty.md"); +use uucore::locale::get_message; mod options { pub const SILENT: &str = "silent"; @@ -58,8 +57,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("tty-about")) + .override_usage(format_usage(&get_message("tty-usage"))) .infer_long_args(true) .arg( Arg::new(options::SILENT) diff --git a/src/uu/tty/tty.md b/src/uu/tty/tty.md deleted file mode 100644 index 230399a20..000000000 --- a/src/uu/tty/tty.md +++ /dev/null @@ -1,7 +0,0 @@ -# tty - -``` -tty [OPTION]... -``` - -Print the file name of the terminal connected to standard input. diff --git a/src/uu/uname/locales/en-US.ftl b/src/uu/uname/locales/en-US.ftl new file mode 100644 index 000000000..78faa1c35 --- /dev/null +++ b/src/uu/uname/locales/en-US.ftl @@ -0,0 +1,3 @@ +uname-about = Print certain system information. + With no OPTION, same as -s. +uname-usage = uname [OPTION]... diff --git a/src/uu/uname/src/uname.rs b/src/uu/uname/src/uname.rs index 2e2b5f42f..cc3a4f471 100644 --- a/src/uu/uname/src/uname.rs +++ b/src/uu/uname/src/uname.rs @@ -7,14 +7,12 @@ use clap::{Arg, ArgAction, Command}; use platform_info::*; +use uucore::locale::get_message; use uucore::{ error::{UResult, USimpleError}, - format_usage, help_about, help_usage, + format_usage, }; -const ABOUT: &str = help_about!("uname.md"); -const USAGE: &str = help_usage!("uname.md"); - pub mod options { pub static ALL: &str = "all"; pub static KERNEL_NAME: &str = "kernel-name"; @@ -146,8 +144,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("uname-about")) + .override_usage(format_usage(&get_message("uname-usage"))) .infer_long_args(true) .arg( Arg::new(options::ALL) diff --git a/src/uu/uname/uname.md b/src/uu/uname/uname.md deleted file mode 100644 index b90c54cfc..000000000 --- a/src/uu/uname/uname.md +++ /dev/null @@ -1,8 +0,0 @@ -# uname - -``` -uname [OPTION]... -``` - -Print certain system information. -With no OPTION, same as -s. diff --git a/src/uu/unexpand/locales/en-US.ftl b/src/uu/unexpand/locales/en-US.ftl new file mode 100644 index 000000000..b66a71494 --- /dev/null +++ b/src/uu/unexpand/locales/en-US.ftl @@ -0,0 +1,3 @@ +unexpand-about = Convert blanks in each FILE to tabs, writing to standard output. + With no FILE, or when FILE is -, read standard input. +unexpand-usage = unexpand [OPTION]... [FILE]... diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index fb17b971d..1b075dd2f 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -15,10 +15,9 @@ use thiserror::Error; use unicode_width::UnicodeWidthChar; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult, USimpleError}; -use uucore::{format_usage, help_about, help_usage, show}; +use uucore::{format_usage, show}; -const USAGE: &str = help_usage!("unexpand.md"); -const ABOUT: &str = help_about!("unexpand.md"); +use uucore::locale::get_message; const DEFAULT_TABSTOP: usize = 8; @@ -157,8 +156,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .override_usage(format_usage(USAGE)) - .about(ABOUT) + .override_usage(format_usage(&get_message("unexpand-usage"))) + .about(get_message("unexpand-about")) .infer_long_args(true) .arg( Arg::new(options::FILE) diff --git a/src/uu/unexpand/unexpand.md b/src/uu/unexpand/unexpand.md deleted file mode 100644 index 6fc69b93a..000000000 --- a/src/uu/unexpand/unexpand.md +++ /dev/null @@ -1,8 +0,0 @@ -# unexpand - -``` -unexpand [OPTION]... [FILE]... -``` - -Convert blanks in each `FILE` to tabs, writing to standard output. -With no `FILE`, or when `FILE` is `-`, read standard input. diff --git a/src/uu/uniq/locales/en-US.ftl b/src/uu/uniq/locales/en-US.ftl new file mode 100644 index 000000000..4ede870d1 --- /dev/null +++ b/src/uu/uniq/locales/en-US.ftl @@ -0,0 +1,7 @@ +uniq-about = Report or omit repeated lines. +uniq-usage = uniq [OPTION]... [INPUT [OUTPUT]] +uniq-after-help = Filter adjacent matching lines from INPUT (or standard input), + writing to OUTPUT (or standard output). + + Note: uniq does not detect repeated lines unless they are adjacent. + You may want to sort the input first, or use sort -u without uniq. diff --git a/src/uu/uniq/src/uniq.rs b/src/uu/uniq/src/uniq.rs index 2d54a5082..00ca6751b 100644 --- a/src/uu/uniq/src/uniq.rs +++ b/src/uu/uniq/src/uniq.rs @@ -13,13 +13,11 @@ use std::io::{BufRead, BufReader, BufWriter, Write, stdin, stdout}; use std::num::IntErrorKind; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult, USimpleError}; +use uucore::format_usage; use uucore::parser::shortcut_value_parser::ShortcutValueParser; use uucore::posix::{OBSOLETE, posix_version}; -use uucore::{format_usage, help_about, help_section, help_usage}; -const ABOUT: &str = help_about!("uniq.md"); -const USAGE: &str = help_usage!("uniq.md"); -const AFTER_HELP: &str = help_section!("after help", "uniq.md"); +use uucore::locale::get_message; pub mod options { pub static ALL_REPEATED: &str = "all-repeated"; @@ -593,10 +591,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("uniq-about")) + .override_usage(format_usage(&get_message("uniq-usage"))) .infer_long_args(true) - .after_help(AFTER_HELP) + .after_help(get_message("uniq-after-help")) .arg( Arg::new(options::ALL_REPEATED) .short('D') diff --git a/src/uu/uniq/uniq.md b/src/uu/uniq/uniq.md deleted file mode 100644 index 20de52395..000000000 --- a/src/uu/uniq/uniq.md +++ /dev/null @@ -1,15 +0,0 @@ -# uniq - -``` -uniq [OPTION]... [INPUT [OUTPUT]] -``` - -Report or omit repeated lines. - -## After help - -Filter adjacent matching lines from `INPUT` (or standard input), -writing to `OUTPUT` (or standard output). - -Note: `uniq` does not detect repeated lines unless they are adjacent. -You may want to sort the input first, or use `sort -u` without `uniq`. diff --git a/src/uu/unlink/locales/en-US.ftl b/src/uu/unlink/locales/en-US.ftl new file mode 100644 index 000000000..e819d905e --- /dev/null +++ b/src/uu/unlink/locales/en-US.ftl @@ -0,0 +1,3 @@ +unlink-about = Unlink the file at FILE. +unlink-usage = unlink FILE + unlink OPTION diff --git a/src/uu/unlink/src/unlink.rs b/src/uu/unlink/src/unlink.rs index 09a1b0f12..418e59b6e 100644 --- a/src/uu/unlink/src/unlink.rs +++ b/src/uu/unlink/src/unlink.rs @@ -12,10 +12,9 @@ use clap::{Arg, Command}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; -const ABOUT: &str = help_about!("unlink.md"); -const USAGE: &str = help_usage!("unlink.md"); +use uucore::locale::get_message; static OPT_PATH: &str = "FILE"; #[uucore::main] @@ -30,8 +29,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("unlink-about")) + .override_usage(format_usage(&get_message("unlink-usage"))) .infer_long_args(true) .arg( Arg::new(OPT_PATH) diff --git a/src/uu/unlink/unlink.md b/src/uu/unlink/unlink.md deleted file mode 100644 index 14b023b8b..000000000 --- a/src/uu/unlink/unlink.md +++ /dev/null @@ -1,8 +0,0 @@ -# unlink - -``` -unlink FILE -unlink OPTION -``` - -Unlink the file at `FILE`. diff --git a/src/uu/uptime/locales/en-US.ftl b/src/uu/uptime/locales/en-US.ftl new file mode 100644 index 000000000..6746ee712 --- /dev/null +++ b/src/uu/uptime/locales/en-US.ftl @@ -0,0 +1,7 @@ +uptime-about = Display the current time, the length of time the system has been up, + the number of users on the system, and the average number of jobs + in the run queue over the last 1, 5 and 15 minutes. +uptime-usage = uptime [OPTION]... +uptime-about-musl-warning = Warning: When built with musl libc, the `uptime` utility may show '0 users' + due to musl's stub implementation of utmpx functions. Boot time and load averages + are still calculated using alternative mechanisms. diff --git a/src/uu/uptime/src/uptime.rs b/src/uu/uptime/src/uptime.rs index e001a64a8..3bf1b8d79 100644 --- a/src/uu/uptime/src/uptime.rs +++ b/src/uu/uptime/src/uptime.rs @@ -16,25 +16,13 @@ use uucore::uptime::*; use clap::{Arg, ArgAction, Command, ValueHint, builder::ValueParser}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; #[cfg(unix)] #[cfg(not(target_os = "openbsd"))] use uucore::utmpx::*; -#[cfg(target_env = "musl")] -const ABOUT: &str = concat!( - help_about!("uptime.md"), - "\n\nWarning: When built with musl libc, the `uptime` utility may show '0 users' \n", - "due to musl's stub implementation of utmpx functions. Boot time and load averages \n", - "are still calculated using alternative mechanisms." -); - -#[cfg(not(target_env = "musl"))] -const ABOUT: &str = help_about!("uptime.md"); - -const USAGE: &str = help_usage!("uptime.md"); - pub mod options { pub static SINCE: &str = "since"; pub static PATH: &str = "path"; @@ -76,10 +64,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } pub fn uu_app() -> Command { + #[cfg(not(target_env = "musl"))] + let about = get_message("uptime-about"); + #[cfg(target_env = "musl")] + let about = get_message("uptime-about") + &get_message("uptime-about-musl-warning"); + let cmd = Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(about) + .override_usage(format_usage(&get_message("uptime-usage"))) .infer_long_args(true) .arg( Arg::new(options::SINCE) diff --git a/src/uu/uptime/uptime.md b/src/uu/uptime/uptime.md deleted file mode 100644 index fd9c8fd2f..000000000 --- a/src/uu/uptime/uptime.md +++ /dev/null @@ -1,9 +0,0 @@ -# uptime - -``` -uptime [OPTION]... -``` - -Display the current time, the length of time the system has been up, -the number of users on the system, and the average number of jobs -in the run queue over the last 1, 5 and 15 minutes. diff --git a/src/uu/users/locales/en-US.ftl b/src/uu/users/locales/en-US.ftl new file mode 100644 index 000000000..d35a99383 --- /dev/null +++ b/src/uu/users/locales/en-US.ftl @@ -0,0 +1,4 @@ +users-about = Print the user names of users currently logged in to the current host. +users-usage = users [FILE] +users-about-musl-warning = Warning: When built with musl libc, the `users` utility may show '0 users', + due to musl's stub implementation of utmpx functions. diff --git a/src/uu/users/src/users.rs b/src/uu/users/src/users.rs index 192ed0b57..19b6c7c6d 100644 --- a/src/uu/users/src/users.rs +++ b/src/uu/users/src/users.rs @@ -11,24 +11,14 @@ use std::path::Path; use clap::builder::ValueParser; use clap::{Arg, Command}; use uucore::error::UResult; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; #[cfg(target_os = "openbsd")] use utmp_classic::{UtmpEntry, parse_from_path}; #[cfg(not(target_os = "openbsd"))] use uucore::utmpx::{self, Utmpx}; -#[cfg(target_env = "musl")] -const ABOUT: &str = concat!( - help_about!("users.md"), - "\n\nWarning: When built with musl libc, the `users` utility may show '0 users' \n", - "due to musl's stub implementation of utmpx functions." -); - -#[cfg(not(target_env = "musl"))] -const ABOUT: &str = help_about!("users.md"); - -const USAGE: &str = help_usage!("users.md"); +use uucore::locale::get_message; #[cfg(target_os = "openbsd")] const OPENBSD_UTMP_FILE: &str = "/var/run/utmp"; @@ -95,10 +85,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } pub fn uu_app() -> Command { + #[cfg(not(target_env = "musl"))] + let about = get_message("users-about"); + #[cfg(target_env = "musl")] + let about = get_message("users-about") + &get_message("users-about-musl-warning"); + Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(about) + .override_usage(format_usage(&get_message("users-usage"))) .infer_long_args(true) .arg( Arg::new(ARG_FILE) diff --git a/src/uu/users/users.md b/src/uu/users/users.md deleted file mode 100644 index 7b126a0f0..000000000 --- a/src/uu/users/users.md +++ /dev/null @@ -1,7 +0,0 @@ -# users - -``` -users [FILE] -``` - -Print the user names of users currently logged in to the current host. diff --git a/src/uu/vdir/locales/en-US.ftl b/src/uu/vdir/locales/en-US.ftl new file mode 100644 index 000000000..f0d63274e --- /dev/null +++ b/src/uu/vdir/locales/en-US.ftl @@ -0,0 +1,5 @@ +vdir-about = List directory contents. + Ignore files and directories starting with a '.' by default. + + Mandatory arguments to long options are mandatory for short options too. +vdir-usage = vdir [OPTION]... [FILE]... diff --git a/src/uu/vdir/vdir.md b/src/uu/vdir/vdir.md deleted file mode 100644 index c7a0cae36..000000000 --- a/src/uu/vdir/vdir.md +++ /dev/null @@ -1,10 +0,0 @@ -# vdir - -``` -vdir [OPTION]... [FILE]... -``` - -List directory contents. -Ignore files and directories starting with a '.' by default. - -Mandatory arguments to long options are mandatory for short options too. diff --git a/src/uu/wc/locales/en-US.ftl b/src/uu/wc/locales/en-US.ftl new file mode 100644 index 000000000..7eb458ec2 --- /dev/null +++ b/src/uu/wc/locales/en-US.ftl @@ -0,0 +1,3 @@ +wc-about = Display newline, word, and byte counts for each FILE, and a total line if + more than one FILE is specified. With no FILE, or when FILE is -, read standard input. +wc-usage = wc [OPTION]... [FILE]... diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 47abfe210..f3414bb43 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -24,10 +24,11 @@ use clap::{Arg, ArgAction, ArgMatches, Command, builder::ValueParser}; use thiserror::Error; use unicode_width::UnicodeWidthChar; use utf8::{BufReadDecoder, BufReadDecoderError}; +use uucore::locale::get_message; use uucore::{ error::{FromIo, UError, UResult}, - format_usage, help_about, help_usage, + format_usage, parser::shortcut_value_parser::ShortcutValueParser, quoting_style::{self, QuotingStyle}, show, @@ -113,9 +114,6 @@ impl<'a> Settings<'a> { } } -const ABOUT: &str = help_about!("wc.md"); -const USAGE: &str = help_usage!("wc.md"); - mod options { pub static BYTES: &str = "bytes"; pub static CHAR: &str = "chars"; @@ -397,8 +395,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("wc-about")) + .override_usage(format_usage(&get_message("wc-usage"))) .infer_long_args(true) .args_override_self(true) .arg( diff --git a/src/uu/wc/wc.md b/src/uu/wc/wc.md deleted file mode 100644 index c7aaf8545..000000000 --- a/src/uu/wc/wc.md +++ /dev/null @@ -1,8 +0,0 @@ -# wc - -``` -wc [OPTION]... [FILE]... -``` - -Display newline, word, and byte counts for each FILE, and a total line if -more than one FILE is specified. With no FILE, or when FILE is -, read standard input. diff --git a/src/uu/who/locales/en-US.ftl b/src/uu/who/locales/en-US.ftl new file mode 100644 index 000000000..7ed207f72 --- /dev/null +++ b/src/uu/who/locales/en-US.ftl @@ -0,0 +1,5 @@ +who-about = Print information about users who are currently logged in. +who-usage = who [OPTION]... [ FILE | ARG1 ARG2 ] +who-about-musl-warning = Note: When built with musl libc, the `who` utility will not display any + information about logged-in users. This is due to musl's stub implementation + of `utmpx` functions, which prevents access to the necessary data. diff --git a/src/uu/who/src/who.rs b/src/uu/who/src/who.rs index 2203bbbd1..ea3cc9873 100644 --- a/src/uu/who/src/who.rs +++ b/src/uu/who/src/who.rs @@ -6,7 +6,8 @@ // spell-checker:ignore (ToDO) ttyname hostnames runlevel mesg wtmp statted boottime deadprocs initspawn clockchange curr runlvline pidstr exitstr hoststr use clap::{Arg, ArgAction, Command}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::format_usage; +use uucore::locale::get_message; mod platform; @@ -28,19 +29,6 @@ mod options { pub const FILE: &str = "FILE"; // if length=1: FILE, if length=2: ARG1 ARG2 } -#[cfg(target_env = "musl")] -const ABOUT: &str = concat!( - help_about!("who.md"), - "\n\nNote: When built with musl libc, the `who` utility will not display any \n", - "information about logged-in users. This is due to musl's stub implementation \n", - "of `utmpx` functions, which prevents access to the necessary data." -); - -#[cfg(not(target_env = "musl"))] -const ABOUT: &str = help_about!("who.md"); - -const USAGE: &str = help_usage!("who.md"); - #[cfg(target_os = "linux")] static RUNLEVEL_HELP: &str = "print current runlevel"; #[cfg(not(target_os = "linux"))] @@ -50,10 +38,15 @@ static RUNLEVEL_HELP: &str = "print current runlevel (This is meaningless on non use platform::uumain; pub fn uu_app() -> Command { + #[cfg(not(target_env = "musl"))] + let about = get_message("who-about"); + #[cfg(target_env = "musl")] + let about = get_message("who-about") + &get_message("who-about-musl-warning"); + Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(about) + .override_usage(format_usage(&get_message("who-usage"))) .infer_long_args(true) .arg( Arg::new(options::ALL) diff --git a/src/uu/who/who.md b/src/uu/who/who.md deleted file mode 100644 index 6adc26597..000000000 --- a/src/uu/who/who.md +++ /dev/null @@ -1,8 +0,0 @@ -# who - -``` -who [OPTION]... [ FILE | ARG1 ARG2 ] -``` - -Print information about users who are currently logged in. - diff --git a/src/uu/whoami/locales/en-US.ftl b/src/uu/whoami/locales/en-US.ftl new file mode 100644 index 000000000..aedac774c --- /dev/null +++ b/src/uu/whoami/locales/en-US.ftl @@ -0,0 +1 @@ +whoami-about = Print the current username. diff --git a/src/uu/whoami/src/whoami.rs b/src/uu/whoami/src/whoami.rs index a1fe6e622..701d3a107 100644 --- a/src/uu/whoami/src/whoami.rs +++ b/src/uu/whoami/src/whoami.rs @@ -9,13 +9,10 @@ use clap::Command; use uucore::display::println_verbatim; use uucore::error::{FromIo, UResult}; -use uucore::{format_usage, help_about, help_usage}; +use uucore::locale::get_message; mod platform; -const ABOUT: &str = help_about!("whoami.md"); -const USAGE: &str = help_usage!("whoami.md"); - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { uu_app().try_get_matches_from(args)?; @@ -32,7 +29,7 @@ pub fn whoami() -> UResult { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("whoami-about")) + .override_usage(uucore::util_name()) .infer_long_args(true) } diff --git a/src/uu/whoami/whoami.md b/src/uu/whoami/whoami.md deleted file mode 100644 index 6106d24ee..000000000 --- a/src/uu/whoami/whoami.md +++ /dev/null @@ -1,7 +0,0 @@ -# whoami - -``` -whoami -``` - -Print the current username. diff --git a/src/uu/yes/locales/en-US.ftl b/src/uu/yes/locales/en-US.ftl new file mode 100644 index 000000000..d4d0806b1 --- /dev/null +++ b/src/uu/yes/locales/en-US.ftl @@ -0,0 +1,2 @@ +yes-about = Repeatedly display a line with STRING (or 'y') +yes-usage = yes [STRING]... diff --git a/src/uu/yes/src/yes.rs b/src/uu/yes/src/yes.rs index df77be289..add3f7027 100644 --- a/src/uu/yes/src/yes.rs +++ b/src/uu/yes/src/yes.rs @@ -10,12 +10,11 @@ use std::error::Error; use std::ffi::OsString; use std::io::{self, Write}; use uucore::error::{UResult, USimpleError}; +use uucore::format_usage; #[cfg(unix)] use uucore::signals::enable_pipe_errors; -use uucore::{format_usage, help_about, help_usage}; -const ABOUT: &str = help_about!("yes.md"); -const USAGE: &str = help_usage!("yes.md"); +use uucore::locale::get_message; // it's possible that using a smaller or larger buffer might provide better performance on some // systems, but honestly this is good enough @@ -39,8 +38,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(uucore::crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) + .about(get_message("yes-about")) + .override_usage(format_usage(&get_message("yes-usage"))) .arg( Arg::new("STRING") .value_parser(ValueParser::os_string()) diff --git a/src/uu/yes/yes.md b/src/uu/yes/yes.md deleted file mode 100644 index ad2da7dc9..000000000 --- a/src/uu/yes/yes.md +++ /dev/null @@ -1,7 +0,0 @@ -# yes - -``` -yes [STRING]... -``` - -Repeatedly display a line with STRING (or 'y') diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 7395df343..cd4f2e1c0 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -60,6 +60,7 @@ selinux = { workspace = true, optional = true } # Fluent dependencies fluent-bundle = { workspace = true } fluent = { workspace = true } +fluent-syntax = { workspace = true } unic-langid = { workspace = true } thiserror = { workspace = true } [target.'cfg(unix)'.dependencies] diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index 8dc49cadd..469c52444 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -143,6 +143,25 @@ pub fn disable_rust_signal_handlers() -> Result<(), Errno> { Ok(()) } +pub fn get_canonical_util_name(util_name: &str) -> &str { + // remove the "uu_" prefix + let util_name = &util_name[3..]; + match util_name { + // uu_test aliases - '[' is an alias for test + "[" => "test", + + // hashsum aliases - all these hash commands are aliases for hashsum + "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" + | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" + | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => "hashsum", + + "dir" => "ls", // dir is an alias for ls + + // Default case - return the util name as is + _ => util_name, + } +} + /// Execute utility code for `util`. /// /// This macro expands to a main function that invokes the `uumain` function in `util` @@ -152,8 +171,21 @@ macro_rules! bin { ($util:ident) => { pub fn main() { use std::io::Write; + use uucore::locale; // suppress extraneous error output for SIGPIPE failures/panics uucore::panic::mute_sigpipe_panic(); + locale::setup_localization(uucore::get_canonical_util_name(stringify!($util))) + .unwrap_or_else(|err| { + match err { + uucore::locale::LocalizationError::ParseResource { + error: err_msg, + snippet, + } => eprintln!("Localization parse error at {snippet}: {err_msg}"), + other => eprintln!("Could not init the localization system: {other}"), + } + std::process::exit(99) + }); + // execute utility code let code = $util::uumain(uucore::args_os()); // (defensively) flush stdout for utility prior to exit; see diff --git a/src/uucore/src/lib/mods/locale.rs b/src/uucore/src/lib/mods/locale.rs index 7bd3c0988..3c69ba314 100644 --- a/src/uucore/src/lib/mods/locale.rs +++ b/src/uucore/src/lib/mods/locale.rs @@ -6,6 +6,7 @@ use crate::error::UError; use fluent::{FluentArgs, FluentBundle, FluentResource}; +use fluent_syntax::parser::ParserError; use std::collections::HashMap; use std::fs; use std::path::{Path, PathBuf}; @@ -21,8 +22,14 @@ pub enum LocalizationError { source: std::io::Error, path: PathBuf, }, - #[error("Parse error: {0}")] - Parse(String), + #[error("Parse-locale error: {0}")] + ParseLocale(String), + #[error("Resource parse error at '{snippet}': {error:?}")] + ParseResource { + #[source] + error: ParserError, + snippet: String, + }, #[error("Bundle error: {0}")] Bundle(String), #[error("Locales directory not found: {0}")] @@ -140,13 +147,21 @@ fn create_bundle( path: locale_path.clone(), })?; - let resource = FluentResource::try_new(ftl_file).map_err(|_| { - LocalizationError::Parse(format!( - "Failed to parse localization resource for {}: {}", - locale, - locale_path.display() - )) - })?; + let resource = FluentResource::try_new(ftl_file.clone()).map_err( + |(_partial_resource, mut errs): (FluentResource, Vec)| { + let first_err = errs.remove(0); + // Attempt to extract the snippet from the original ftl_file + let snippet = if let Some(range) = first_err.slice.clone() { + ftl_file.get(range).unwrap_or("").to_string() + } else { + String::new() + }; + LocalizationError::ParseResource { + error: first_err, + snippet, + } + }, + )?; let mut bundle = FluentBundle::new(vec![locale.clone()]); @@ -253,9 +268,9 @@ fn detect_system_locale() -> Result { .next() .unwrap_or(DEFAULT_LOCALE) .to_string(); - - LanguageIdentifier::from_str(&locale_str) - .map_err(|_| LocalizationError::Parse(format!("Failed to parse locale: {}", locale_str))) + LanguageIdentifier::from_str(&locale_str).map_err(|_| { + LocalizationError::ParseLocale(format!("Failed to parse locale: {}", locale_str)) + }) } /// Sets up localization using the system locale with English fallback. @@ -453,7 +468,7 @@ invalid-syntax = This is { $missing #[test] fn test_localization_error_uerror_impl() { - let error = LocalizationError::Parse("test error".to_string()); + let error = LocalizationError::Bundle("some error".to_string()); assert_eq!(error.code(), 1); } @@ -492,10 +507,14 @@ invalid-syntax = This is { $missing let result = create_bundle(&locale, temp_dir.path()); assert!(result.is_err()); - if let Err(LocalizationError::Parse(_)) = result { - // Expected parse error + if let Err(LocalizationError::ParseResource { + error: _parser_err, + snippet: _, + }) = result + { + // Expected ParseResource variant } else { - panic!("Expected parse error"); + panic!("Expected ParseResource error"); } } @@ -1034,12 +1053,32 @@ invalid-syntax = This is { $missing assert!(error_string.contains("I/O error loading")); assert!(error_string.contains("/test/path.ftl")); - let parse_error = LocalizationError::Parse("Syntax error".to_string()); - let parse_string = format!("{}", parse_error); - assert!(parse_string.contains("Parse error: Syntax error")); - let bundle_error = LocalizationError::Bundle("Bundle creation failed".to_string()); let bundle_string = format!("{}", bundle_error); assert!(bundle_string.contains("Bundle error: Bundle creation failed")); } + + #[test] + fn test_parse_resource_error_includes_snippet() { + let temp_dir = create_test_locales_dir(); + let locale = LanguageIdentifier::from_str("es-ES").unwrap(); + + let result = create_bundle(&locale, temp_dir.path()); + assert!(result.is_err()); + + if let Err(LocalizationError::ParseResource { + error: _err, + snippet, + }) = result + { + // The snippet should contain exactly the invalid text from es-ES.ftl + assert!( + snippet.contains("This is { $missing"), + "snippet was `{}` but did not include the invalid text", + snippet + ); + } else { + panic!("Expected LocalizationError::ParseResource with snippet"); + } + } } diff --git a/tests/test_util_name.rs b/tests/test_util_name.rs index 7a8a076e8..cd0356edc 100644 --- a/tests/test_util_name.rs +++ b/tests/test_util_name.rs @@ -41,7 +41,7 @@ fn execution_phrase_double() { assert!( String::from_utf8(output.stderr) .unwrap() - .contains(&format!("Usage: {} ls", scenario.bin_path.display())) + .contains(&"Usage: ls".to_string()) ); }