Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .vscode/cspell.dictionaries/jargon.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,5 @@ Hijri
Nowruz
charmap
hijri

ctype
clocale
8 changes: 8 additions & 0 deletions src/uu/ls/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ fn locale_quote(name: &OsStr, style: LocaleQuoting) -> OsString {
quoted.push_str("\\\\");
} else if c.is_ascii() && c.is_control() {
push_basic_escape(&mut quoted, c as u8);
} else if c.is_control() {
// Non-ASCII control characters (the C1 range, e.g.
// U+0085 NEL) are not printable; octal-escape their
// UTF-8 bytes like GNU does for non-printable chars.
let mut buf = [0u8; 4];
for &byte in c.encode_utf8(&mut buf).as_bytes() {
let _ = write!(quoted, "\\{byte:03o}");
}
} else {
quoted.push(c);
}
Expand Down
6 changes: 6 additions & 0 deletions tests/by-util/test_ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2794,6 +2794,7 @@ mod quoting {
at.touch("it's");
at.touch("say \"hi\"");
at.touch("tab\there");
at.touch("nel\u{0085}here");

let out = ucmd
.env("LC_ALL", "en_US.UTF-8")
Expand All @@ -2820,6 +2821,11 @@ mod quoting {
out.contains(&format!("{lq}tab\\there{rq}")),
"{style}: tab should be escaped as \\t: {out:?}"
);
// Non-ASCII (C1) control characters are octal-escaped by byte.
assert!(
out.contains(&format!("{lq}nel\\302\\205here{rq}")),
"{style}: U+0085 should be octal-escaped: {out:?}"
);
}

// In the C locale, locale uses ASCII single quotes and clocale uses
Expand Down
Loading