mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
echo: print help if not posixly corrent and only argument is --help
This commit is contained in:
parent
f1436f3949
commit
3ea679a29e
3 changed files with 30 additions and 32 deletions
|
@ -626,7 +626,6 @@ unused_qualifications = "warn"
|
||||||
all = { level = "warn", priority = -1 }
|
all = { level = "warn", priority = -1 }
|
||||||
cargo = { level = "warn", priority = -1 }
|
cargo = { level = "warn", priority = -1 }
|
||||||
pedantic = { level = "warn", priority = -1 }
|
pedantic = { level = "warn", priority = -1 }
|
||||||
match_bool = "allow" # 8310
|
|
||||||
cargo_common_metadata = "allow" # 3240
|
cargo_common_metadata = "allow" # 3240
|
||||||
multiple_crate_versions = "allow" # 2314
|
multiple_crate_versions = "allow" # 2314
|
||||||
missing_errors_doc = "allow" # 1504
|
missing_errors_doc = "allow" # 1504
|
||||||
|
|
|
@ -11,6 +11,7 @@ use std::io::{self, StdoutLock, Write};
|
||||||
use uucore::error::{UResult, USimpleError};
|
use uucore::error::{UResult, USimpleError};
|
||||||
use uucore::format::{FormatChar, OctalParsing, parse_escape_only};
|
use uucore::format::{FormatChar, OctalParsing, parse_escape_only};
|
||||||
use uucore::format_usage;
|
use uucore::format_usage;
|
||||||
|
use uucore::os_str_as_bytes;
|
||||||
|
|
||||||
use uucore::locale::get_message;
|
use uucore::locale::get_message;
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ fn is_flag(arg: &OsStr, options: &mut Options) -> bool {
|
||||||
///
|
///
|
||||||
/// - Vector of non-flag arguments.
|
/// - Vector of non-flag arguments.
|
||||||
/// - [`Options`], describing how teh arguments should be interpreted.
|
/// - [`Options`], describing how teh arguments should be interpreted.
|
||||||
fn filter_flags(mut args: impl uucore::Args) -> (Vec<OsString>, Options) {
|
fn filter_flags(mut args: impl Iterator<Item = OsString>) -> (Vec<OsString>, Options) {
|
||||||
let mut arguments = Vec::with_capacity(args.size_hint().0);
|
let mut arguments = Vec::with_capacity(args.size_hint().0);
|
||||||
let mut options = Options::default();
|
let mut options = Options::default();
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ fn filter_flags(mut args: impl uucore::Args) -> (Vec<OsString>, Options) {
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
// args[0] is the name of the binary.
|
// args[0] is the name of the binary.
|
||||||
let mut args = args.skip(1).peekable();
|
let args: Vec<OsString> = args.skip(1).collect();
|
||||||
|
|
||||||
// Check POSIX compatibility mode
|
// Check POSIX compatibility mode
|
||||||
//
|
//
|
||||||
|
@ -139,14 +140,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
// > representation. For example, echo -e '\x2dn'.
|
// > representation. For example, echo -e '\x2dn'.
|
||||||
let is_posixly_correct = env::var_os("POSIXLY_CORRECT").is_some();
|
let is_posixly_correct = env::var_os("POSIXLY_CORRECT").is_some();
|
||||||
|
|
||||||
let (args, options) = match is_posixly_correct {
|
let (args, options) = if is_posixly_correct {
|
||||||
// if POSIXLY_CORRECT is not set we filter the flags normally
|
if args.first().is_some_and(|arg| arg == "-n") {
|
||||||
false => filter_flags(args),
|
|
||||||
|
|
||||||
true if args.peek().is_some_and(|arg| arg == "-n") => {
|
|
||||||
// if POSIXLY_CORRECT is set and the first argument is the "-n" flag
|
// if POSIXLY_CORRECT is set and the first argument is the "-n" flag
|
||||||
// we filter flags normally but 'escaped' is activated nonetheless.
|
// we filter flags normally but 'escaped' is activated nonetheless.
|
||||||
let (args, _) = filter_flags(args);
|
let (args, _) = filter_flags(args.into_iter());
|
||||||
(
|
(
|
||||||
args,
|
args,
|
||||||
Options {
|
Options {
|
||||||
|
@ -154,13 +152,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
..Options::posixly_correct_default()
|
..Options::posixly_correct_default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
|
|
||||||
true => {
|
|
||||||
// if POSIXLY_CORRECT is set and the first argument is not the "-n" flag
|
// if POSIXLY_CORRECT is set and the first argument is not the "-n" flag
|
||||||
// we just collect all arguments as every argument is considered an argument.
|
// we just collect all arguments as no arguments are interpreted as flags.
|
||||||
(args.collect(), Options::posixly_correct_default())
|
(args, Options::posixly_correct_default())
|
||||||
}
|
}
|
||||||
|
} else if args.len() == 1 && args[0] == "--help" {
|
||||||
|
// If POSIXLY_CORRECT is not set and the first argument
|
||||||
|
// is `--help`, GNU coreutils prints the help message.
|
||||||
|
//
|
||||||
|
// Verify this using:
|
||||||
|
//
|
||||||
|
// POSIXLY_CORRECT=1 echo --help
|
||||||
|
// echo --help
|
||||||
|
uu_app().print_help()?;
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
|
// if POSIXLY_CORRECT is not set we filter the flags normally
|
||||||
|
filter_flags(args.into_iter())
|
||||||
};
|
};
|
||||||
|
|
||||||
execute(&mut io::stdout().lock(), args, options)?;
|
execute(&mut io::stdout().lock(), args, options)?;
|
||||||
|
@ -211,9 +220,8 @@ pub fn uu_app() -> Command {
|
||||||
|
|
||||||
fn execute(stdout: &mut StdoutLock, args: Vec<OsString>, options: Options) -> UResult<()> {
|
fn execute(stdout: &mut StdoutLock, args: Vec<OsString>, options: Options) -> UResult<()> {
|
||||||
for (i, arg) in args.into_iter().enumerate() {
|
for (i, arg) in args.into_iter().enumerate() {
|
||||||
let Some(bytes) = bytes_from_os_string(arg.as_os_str()) else {
|
let bytes = os_str_as_bytes(arg.as_os_str())
|
||||||
return Err(USimpleError::new(1, get_message("echo-error-non-utf8")));
|
.map_err(|_| USimpleError::new(1, get_message("echo-error-non-utf8")))?;
|
||||||
};
|
|
||||||
|
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
stdout.write_all(b" ")?;
|
stdout.write_all(b" ")?;
|
||||||
|
@ -236,18 +244,3 @@ fn execute(stdout: &mut StdoutLock, args: Vec<OsString>, options: Options) -> UR
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bytes_from_os_string(input: &OsStr) -> Option<&[u8]> {
|
|
||||||
#[cfg(target_family = "unix")]
|
|
||||||
{
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
|
||||||
|
|
||||||
Some(input.as_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_family = "unix"))]
|
|
||||||
{
|
|
||||||
// TODO: Verify that this works correctly on these platforms
|
|
||||||
input.to_str().map(|st| st.as_bytes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -514,6 +514,12 @@ fn partial_help_argument() {
|
||||||
new_ucmd!().arg("--he").succeeds().stdout_is("--he\n");
|
new_ucmd!().arg("--he").succeeds().stdout_is("--he\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn only_help_argument_prints_help() {
|
||||||
|
assert_ne!(new_ucmd!().arg("--help").succeeds().stdout(), b"--help\n");
|
||||||
|
assert_ne!(new_ucmd!().arg("--help").succeeds().stdout(), b"--help"); // This one is just in case.
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multibyte_escape_unicode() {
|
fn multibyte_escape_unicode() {
|
||||||
// spell-checker:disable-next-line
|
// spell-checker:disable-next-line
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue