diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 952083d2a..d56929be8 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -621,7 +621,52 @@ fn extract_hyperlink(options: &clap::ArgMatches) -> bool { } } +/// Match the argument given to --quoting-style or the QUOTING_STYLE env variable. +/// +/// # Arguments +/// +/// * `style`: the actual argument string +/// * `show_control` - A boolean value representing whether or not to show control characters. +/// +/// # Returns +/// +/// * An option with None if the style string is invalid, or a `QuotingStyle` wrapped in `Some`. +fn match_quoting_style_name(style: &str, show_control: bool) -> Option { + match style { + "literal" => Some(QuotingStyle::Literal { show_control }), + "shell" => Some(QuotingStyle::Shell { + escape: false, + always_quote: false, + show_control, + }), + "shell-always" => Some(QuotingStyle::Shell { + escape: false, + always_quote: true, + show_control, + }), + "shell-escape" => Some(QuotingStyle::Shell { + escape: true, + always_quote: false, + show_control, + }), + "shell-escape-always" => Some(QuotingStyle::Shell { + escape: true, + always_quote: true, + show_control, + }), + "c" => Some(QuotingStyle::C { + quotes: quoting_style::Quotes::Double, + }), + "escape" => Some(QuotingStyle::C { + quotes: quoting_style::Quotes::None, + }), + _ => None, + } +} + /// Extracts the quoting style to use based on the options provided. +/// If no options are given, it looks if a default quoting style is provided +/// through the QUOTING_STYLE environment variable. /// /// # Arguments /// @@ -632,38 +677,12 @@ fn extract_hyperlink(options: &clap::ArgMatches) -> bool { /// /// A QuotingStyle variant representing the quoting style to use. fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> QuotingStyle { - let opt_quoting_style = options.get_one::(options::QUOTING_STYLE).cloned(); + let opt_quoting_style = options.get_one::(options::QUOTING_STYLE); if let Some(style) = opt_quoting_style { - match style.as_str() { - "literal" => QuotingStyle::Literal { show_control }, - "shell" => QuotingStyle::Shell { - escape: false, - always_quote: false, - show_control, - }, - "shell-always" => QuotingStyle::Shell { - escape: false, - always_quote: true, - show_control, - }, - "shell-escape" => QuotingStyle::Shell { - escape: true, - always_quote: false, - show_control, - }, - "shell-escape-always" => QuotingStyle::Shell { - escape: true, - always_quote: true, - show_control, - }, - "c" => QuotingStyle::C { - quotes: quoting_style::Quotes::Double, - }, - "escape" => QuotingStyle::C { - quotes: quoting_style::Quotes::None, - }, - _ => unreachable!("Should have been caught by Clap"), + match match_quoting_style_name(style, show_control) { + Some(qs) => qs, + None => unreachable!("Should have been caught by Clap"), } } else if options.get_flag(options::quoting::LITERAL) { QuotingStyle::Literal { show_control } @@ -675,16 +694,32 @@ fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> Quot QuotingStyle::C { quotes: quoting_style::Quotes::Double, } - } else if options.get_flag(options::DIRED) || !std::io::stdout().is_terminal() { - // By default, `ls` uses Literal quoting when - // writing to a non-terminal file descriptor + } else if options.get_flag(options::DIRED) { QuotingStyle::Literal { show_control } } else { - // TODO: use environment variable if available - QuotingStyle::Shell { - escape: true, - always_quote: false, - show_control, + // If set, the QUOTING_STYLE environment variable specifies a default style. + if let Ok(style) = std::env::var("QUOTING_STYLE") { + match match_quoting_style_name(style.as_str(), show_control) { + Some(qs) => return qs, + None => eprintln!( + "{}: Ignoring invalid value of environment variable QUOTING_STYLE: '{}'", + std::env::args().next().unwrap_or("ls".to_string()), + style + ), + } + } + + // By default, `ls` uses Literal quoting when + // writing to a non-terminal file descriptor + if !std::io::stdout().is_terminal() { + QuotingStyle::Literal { show_control } + } else { + // TODO: use environment variable if available + QuotingStyle::Shell { + escape: true, + always_quote: false, + show_control, + } } } }