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 }
|
||||
cargo = { level = "warn", priority = -1 }
|
||||
pedantic = { level = "warn", priority = -1 }
|
||||
match_bool = "allow" # 8310
|
||||
cargo_common_metadata = "allow" # 3240
|
||||
multiple_crate_versions = "allow" # 2314
|
||||
missing_errors_doc = "allow" # 1504
|
||||
|
|
|
@ -11,6 +11,7 @@ use std::io::{self, StdoutLock, Write};
|
|||
use uucore::error::{UResult, USimpleError};
|
||||
use uucore::format::{FormatChar, OctalParsing, parse_escape_only};
|
||||
use uucore::format_usage;
|
||||
use uucore::os_str_as_bytes;
|
||||
|
||||
use uucore::locale::get_message;
|
||||
|
||||
|
@ -99,7 +100,7 @@ fn is_flag(arg: &OsStr, options: &mut Options) -> bool {
|
|||
///
|
||||
/// - Vector of non-flag arguments.
|
||||
/// - [`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 options = Options::default();
|
||||
|
||||
|
@ -124,7 +125,7 @@ fn filter_flags(mut args: impl uucore::Args) -> (Vec<OsString>, Options) {
|
|||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
// 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
|
||||
//
|
||||
|
@ -139,14 +140,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
// > representation. For example, echo -e '\x2dn'.
|
||||
let is_posixly_correct = env::var_os("POSIXLY_CORRECT").is_some();
|
||||
|
||||
let (args, options) = match is_posixly_correct {
|
||||
// if POSIXLY_CORRECT is not set we filter the flags normally
|
||||
false => filter_flags(args),
|
||||
|
||||
true if args.peek().is_some_and(|arg| arg == "-n") => {
|
||||
let (args, options) = if is_posixly_correct {
|
||||
if args.first().is_some_and(|arg| arg == "-n") {
|
||||
// if POSIXLY_CORRECT is set and the first argument is the "-n" flag
|
||||
// we filter flags normally but 'escaped' is activated nonetheless.
|
||||
let (args, _) = filter_flags(args);
|
||||
let (args, _) = filter_flags(args.into_iter());
|
||||
(
|
||||
args,
|
||||
Options {
|
||||
|
@ -154,13 +152,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
..Options::posixly_correct_default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
true => {
|
||||
} else {
|
||||
// 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.
|
||||
(args.collect(), Options::posixly_correct_default())
|
||||
// we just collect all arguments as no arguments are interpreted as flags.
|
||||
(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)?;
|
||||
|
@ -211,9 +220,8 @@ pub fn uu_app() -> Command {
|
|||
|
||||
fn execute(stdout: &mut StdoutLock, args: Vec<OsString>, options: Options) -> UResult<()> {
|
||||
for (i, arg) in args.into_iter().enumerate() {
|
||||
let Some(bytes) = bytes_from_os_string(arg.as_os_str()) else {
|
||||
return Err(USimpleError::new(1, get_message("echo-error-non-utf8")));
|
||||
};
|
||||
let bytes = os_str_as_bytes(arg.as_os_str())
|
||||
.map_err(|_| USimpleError::new(1, get_message("echo-error-non-utf8")))?;
|
||||
|
||||
if i > 0 {
|
||||
stdout.write_all(b" ")?;
|
||||
|
@ -236,18 +244,3 @@ fn execute(stdout: &mut StdoutLock, args: Vec<OsString>, options: Options) -> UR
|
|||
|
||||
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");
|
||||
}
|
||||
|
||||
#[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]
|
||||
fn multibyte_escape_unicode() {
|
||||
// spell-checker:disable-next-line
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue