Skip to content
19 changes: 6 additions & 13 deletions src/uu/head/src/head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ use std::os::fd::AsFd;
use std::path::Path;
use std::path::PathBuf;
use uucore::diagnostics::OptionValue;
use uucore::display::{Quotable, print_verbatim};
use uucore::display::Quotable;
use uucore::error::{FromIo, UError, UResult, USimpleError, strip_errno};
use uucore::line_ending::LineEnding;
use uucore::parser::parse_signed_num::number_offset;
use uucore::parser::parse_size::ParseSizeError;
use uucore::quoting_style::{QuotingStyle, locale_aware_escape_name};
use uucore::quoting_style::locale_aware_shell_escape;
use uucore::show;
use uucore::translate;

Expand Down Expand Up @@ -449,11 +449,8 @@ fn uu_head(options: &HeadOptions) -> UResult<()> {
if !first {
writeln!(stdout)?;
}
let name = locale_aware_escape_name(
translate!("head-name-stdin").as_ref(),
QuotingStyle::SHELL_ESCAPE,
);
writeln!(stdout, "==> {} <==", name.to_string_lossy())?;
let name = locale_aware_shell_escape(translate!("head-name-stdin"));
writeln!(stdout, "==> {name} <==")?;
}
let stdin = io::stdin();

Expand Down Expand Up @@ -503,12 +500,8 @@ fn uu_head(options: &HeadOptions) -> UResult<()> {
if !first {
writeln!(stdout)?;
}
write!(stdout, "==> ")?;
print_verbatim(locale_aware_escape_name(
file.as_ref(),
QuotingStyle::SHELL_ESCAPE,
))?;
writeln!(stdout, " <==")?;
let name = locale_aware_shell_escape(file);
writeln!(stdout, "==> {name} <==")?;
first = false;
}
Ok(())
Expand Down
1 change: 0 additions & 1 deletion src/uu/ls/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ ls-help-full-time = like -l --time-style=full-iso
ls-help-context = print any security context of each file
ls-help-group-directories-first = group directories before files; can be augmented with
a --sort option, but any use of --sort=none (-U) disables grouping
ls-invalid-quoting-style = {$program}: Ignoring invalid value of environment variable QUOTING_STYLE: '{$style}'
ls-invalid-columns-width = ignoring invalid width in environment variable COLUMNS: {$width}
ls-invalid-ignore-pattern = Invalid pattern for ignore: {$pattern}
ls-invalid-hide-pattern = Invalid pattern for hide: {$pattern}
Expand Down
1 change: 0 additions & 1 deletion src/uu/ls/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ ls-help-full-time = comme -l --time-style=full-iso
ls-help-context = afficher tout contexte de sécurité de chaque fichier
ls-help-group-directories-first = grouper les répertoires avant les fichiers ; peut être augmenté avec
une option --sort, mais toute utilisation de --sort=none (-U) désactive le groupement
ls-invalid-quoting-style = {$program} : Ignorer la valeur invalide de la variable d'environnement QUOTING_STYLE : '{$style}'
ls-invalid-columns-width = ignorer la largeur invalide dans la variable d'environnement COLUMNS : {$width}
ls-invalid-ignore-pattern = Motif invalide pour ignore : {$pattern}
ls-invalid-hide-pattern = Motif invalide pour hide : {$pattern}
Expand Down
127 changes: 25 additions & 102 deletions src/uu/ls/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use std::{
borrow::Cow,
ffi::{OsStr, OsString},
io::{self, IsTerminal, Write as _, stdout},
io::{IsTerminal, stdout},
num::IntErrorKind,
};

Expand All @@ -18,16 +18,23 @@ use lscolors::LsColors;
use term_grid::SPACES_IN_TAB;

use uucore::{
diagnostics::OptionValue, display::Quotable, error::UResult, format::human::SizeFormat,
fsext::MetadataTimeField, line_ending::LineEnding, parser::parse_block_size,
parser::parse_glob, parser::parse_size::parse_size_non_zero_u64, quoting_style::QuotingStyle,
show_error, show_warning, time::format, translate,
diagnostics::OptionValue,
display::Quotable,
error::UResult,
format::human::SizeFormat,
fsext::MetadataTimeField,
line_ending::LineEnding,
parser::{parse_block_size, parse_glob, parse_size::parse_size_non_zero_u64},
quoting_style::{QuotingStyle, quoting_style_from_env},
show_error, show_warning,
time::format,
translate,
};

use crate::{
LsError,
colors::{LsColorsParseError, validate_ls_colors_env},
display::{Format, IndicatorStyle, LocaleQuoting, LongFormat},
display::{Format, IndicatorStyle, LongFormat},
options::QUOTING_STYLE,
};

Expand Down Expand Up @@ -226,7 +233,6 @@ pub struct Config {
// Dir and vdir needs access to this field
pub quoting_style: QuotingStyle,
pub(crate) show_control_chars: bool,
pub(crate) locale_quoting: Option<LocaleQuoting>,
pub(crate) indicator_style: Option<IndicatorStyle>,
pub(crate) time_format_recent: String, // Time format for recent dates
pub(crate) time_format_older: Option<String>, // Time format for older dates (optional, if not present, time_format_recent is used)
Expand Down Expand Up @@ -497,73 +503,6 @@ 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 to show control characters.
///
/// # Returns
///
/// * An option with None if the style string is invalid, or a `QuotingStyle` wrapped in `Some`.
struct QuotingStyleSpec {
style: QuotingStyle,
fixed_control: bool,
locale: Option<LocaleQuoting>,
}

impl QuotingStyleSpec {
fn new(style: QuotingStyle) -> Self {
Self {
style,
fixed_control: false,
locale: None,
}
}

fn with_locale(style: QuotingStyle, locale: LocaleQuoting) -> Self {
Self {
style,
fixed_control: true,
locale: Some(locale),
}
}
}
fn match_quoting_style_name(
style: &str,
show_control: bool,
) -> Option<(QuotingStyle, Option<LocaleQuoting>)> {
let spec = match style {
"literal" => QuotingStyleSpec::new(QuotingStyle::Literal {
show_control: false,
}),
"shell" => QuotingStyleSpec::new(QuotingStyle::SHELL),
"shell-always" => QuotingStyleSpec::new(QuotingStyle::SHELL_QUOTE),
"shell-escape" => QuotingStyleSpec::new(QuotingStyle::SHELL_ESCAPE),
"shell-escape-always" => QuotingStyleSpec::new(QuotingStyle::SHELL_ESCAPE_QUOTE),
"c" => QuotingStyleSpec::new(QuotingStyle::C_DOUBLE),
"escape" => QuotingStyleSpec::new(QuotingStyle::C_NO_QUOTES),
"locale" => QuotingStyleSpec {
style: QuotingStyle::Literal {
show_control: false,
},
fixed_control: true,
locale: Some(LocaleQuoting::Single),
},
"clocale" => QuotingStyleSpec::with_locale(QuotingStyle::C_DOUBLE, LocaleQuoting::Double),
_ => return None,
};

let style = if spec.fixed_control {
spec.style
} else {
spec.style.show_control(show_control)
};

Some((style, spec.locale))
}

/// 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.
Expand All @@ -580,45 +519,32 @@ fn extract_quoting_style(
options: &clap::ArgMatches,
show_control: bool,
mode: ProgramMode,
) -> (QuotingStyle, Option<LocaleQuoting>) {
) -> QuotingStyle {
let opt_quoting_style = options.get_one::<String>(QUOTING_STYLE);

if let Some(style) = opt_quoting_style {
match match_quoting_style_name(style, show_control) {
Some(pair) => pair,
match QuotingStyle::parse(style) {
Some(qs) => qs.show_control(show_control),
None => unreachable!("Should have been caught by Clap"),
}
} else if options.get_flag(options::quoting::LITERAL) {
(QuotingStyle::Literal { show_control }, None)
QuotingStyle::Literal { show_control }
} else if options.get_flag(options::quoting::ESCAPE) {
(QuotingStyle::C_NO_QUOTES, None)
QuotingStyle::Escape
} else if options.get_flag(options::quoting::C) {
(QuotingStyle::C_DOUBLE, None)
QuotingStyle::C_DOUBLE
} else {
// If set, the QUOTING_STYLE environment variable specifies a default style.
// Value may not be valid UTF-8.
if let Some(os_style) = std::env::var_os("QUOTING_STYLE") {
let style = os_style.to_string_lossy();
if let Some(pair) = match_quoting_style_name(&style, show_control) {
return pair;
}
let _ = writeln!(
io::stderr(),
"{}",
translate!(
"ls-invalid-quoting-style",
"program" => std::env::args().next().unwrap_or_else(|| "ls".to_string()),
"style" => style
)
);
if let Some(qs) = quoting_style_from_env() {
Comment thread
RenjiSann marked this conversation as resolved.
return qs.show_control(show_control);
}

match mode {
ProgramMode::Dir | ProgramMode::Vdir => (QuotingStyle::C_NO_QUOTES, None),
ProgramMode::Dir | ProgramMode::Vdir => QuotingStyle::Escape,
ProgramMode::Ls if stdout().is_terminal() => {
(QuotingStyle::SHELL_ESCAPE.show_control(show_control), None)
QuotingStyle::SHELL_ESCAPE.show_control(show_control)
}
ProgramMode::Ls => (QuotingStyle::Literal { show_control }, None),
ProgramMode::Ls => QuotingStyle::Literal { show_control },
}
}
}
Expand Down Expand Up @@ -866,8 +792,7 @@ impl Config {
|| !stdout().is_terminal()
};

let (mut quoting_style, mut locale_quoting) =
extract_quoting_style(options, show_control, mode);
let mut quoting_style = extract_quoting_style(options, show_control, mode);
let indicator_style = extract_indicator_style(options);

let mut ignore_patterns: Vec<Pattern> = Vec::new();
Expand Down Expand Up @@ -959,7 +884,6 @@ impl Config {

if zero_idx > last_of(&zero_quoting_style_opts) {
quoting_style = QuotingStyle::Literal { show_control };
locale_quoting = None;
}

if needs_color && let Err(err) = validate_ls_colors_env() {
Expand Down Expand Up @@ -1046,7 +970,6 @@ impl Config {
width,
quoting_style,
show_control_chars: options.get_flag(options::SHOW_CONTROL_CHARS),
locale_quoting,
indicator_style,
time_format_recent,
time_format_older,
Expand Down
34 changes: 1 addition & 33 deletions src/uu/ls/src/dired.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@
/// Overall, the module ensures each entry in the DIRED output has the correct
/// byte position, considering additional lines or padding affecting positions.
///
use crate::display::LocaleQuoting;
use crate::{Config, LsError};
use std::fmt;
use std::io::{BufWriter, Stdout, Write};
use uucore::error::UResult;
use uucore::quoting_style::{Quotes, QuotingStyle};

#[derive(Debug, Clone, PartialEq)]
pub struct BytePosition {
Expand Down Expand Up @@ -128,42 +126,12 @@ pub fn print_dired_output(
writeln!(
out,
"//DIRED-OPTIONS// --quoting-style={}",
dired_quoting_style_name(config)
config.quoting_style
)
.map_err(LsError::WriteError)?;
Ok(())
}

/// The canonical `--quoting-style` name for the `//DIRED-OPTIONS//` trailer.
/// `QuotingStyle`'s `Display` impl collapses distinct style names together and adds suffixes GNU's trailer never uses, so this maps the config directly instead.
fn dired_quoting_style_name(config: &Config) -> &'static str {
match config.locale_quoting {
Some(LocaleQuoting::Single) => return "locale",
Some(LocaleQuoting::Double) => return "clocale",
None => {}
}
match config.quoting_style {
QuotingStyle::Literal { .. } => "literal",
QuotingStyle::C {
quotes: Quotes::None,
} => "escape",
// `Quotes::Single` is never produced by ls's own option parsing
// (only reachable through `locale_quoting`, handled above), but
// `c` is the closest canonical name if that ever changes.
QuotingStyle::C { .. } => "c",
QuotingStyle::Shell {
escape,
always_quote,
..
} => match (escape, always_quote) {
(false, false) => "shell",
(false, true) => "shell-always",
(true, false) => "shell-escape",
(true, true) => "shell-escape-always",
},
}
}

/// Helper function to print positions with a given prefix.
fn print_positions(
out: &mut BufWriter<Stdout>,
Expand Down
Loading
Loading