uucore: retrieve the Locale encoding from env variables

This commit is contained in:
Dorian Peron
2025-06-25 00:47:51 +02:00
parent 05eb7ee374
commit 231b0e5c59
7 changed files with 687 additions and 120 deletions
Generated
+304 -54
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -1,7 +1,7 @@
# coreutils (uutils)
# * see the repository LICENSE, README, and CONTRIBUTING files for more information
# spell-checker:ignore (libs) bigdecimal datetime serde bincode gethostid kqueue libselinux mangen memmap uuhelp startswith constness expl
# spell-checker:ignore (libs) bigdecimal datetime serde bincode gethostid kqueue libselinux mangen memmap uuhelp startswith constness expl unnested
[package]
name = "coreutils"
@@ -313,6 +313,8 @@ gcd = "2.3"
glob = "0.3.1"
half = "2.4.1"
hostname = "0.4"
icu_collator = "2.0.0"
icu_locale = "2.0.0"
indicatif = "0.17.8"
itertools = "0.14.0"
jiff = { version = "0.2.10", default-features = false, features = [
+308 -64
View File
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -27,6 +27,10 @@ dns-lookup = { workspace = true, optional = true }
dunce = { version = "1.0.4", optional = true }
wild = "2.2.1"
glob = { workspace = true, optional = true }
icu_collator = { workspace = true, optional = true, features = [
"compiled_data",
] }
icu_locale = { workspace = true, optional = true, features = ["compiled_data"] }
itertools = { workspace = true, optional = true }
time = { workspace = true, optional = true, features = [
"formatting",
@@ -106,6 +110,7 @@ format = [
"num-traits",
"quoting-style",
]
i18n = ["icu_collator", "icu_locale"]
mode = ["libc"]
perms = ["entries", "libc", "walkdir"]
buf-copy = []
@@ -113,7 +118,7 @@ parser = ["extendedbigdecimal", "glob", "num-traits"]
pipes = []
process = ["libc"]
proc-info = ["tty", "walkdir"]
quoting-style = []
quoting-style = ["i18n"]
ranges = []
ringbuffer = []
selinux = ["dep:selinux"]
+2
View File
@@ -26,6 +26,8 @@ pub mod format;
pub mod fs;
#[cfg(feature = "fsext")]
pub mod fsext;
#[cfg(feature = "i18n")]
pub mod i18n;
#[cfg(feature = "lines")]
pub mod lines;
#[cfg(feature = "parser")]
+62
View File
@@ -0,0 +1,62 @@
use std::sync::OnceLock;
use icu_locale::{Locale, locale};
/// The encoding specified by the locale, if specified
/// Currently only supports ASCII and UTF-8 for the sake of simplicity.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum UEncoding {
Ascii,
Utf8,
}
const DEFAULT_LOCALE: Locale = locale!("en-US-posix");
/// Deduce the locale from the current environment
fn get_collating_locale() -> &'static (Locale, UEncoding) {
static COLLATING_LOCALE: OnceLock<(Locale, UEncoding)> = OnceLock::new();
COLLATING_LOCALE.get_or_init(|| {
// Look at 3 environment variables in the following order
//
// 1. LC_ALL
// 2. LC_COLLATE
// 3. LANG
//
// Or fallback on Posix locale, with ASCII encoding.
let locale_var = std::env::var("LC_ALL")
.or_else(|_| std::env::var("LC_COLLATE"))
.or_else(|_| std::env::var("LANG"));
if let Ok(locale_var_str) = locale_var {
let mut split = locale_var_str.split(&['.', '@']);
if let Some(simple) = split.next() {
let bcp47 = simple.replace("_", "-");
let locale = Locale::try_from_str(&bcp47).unwrap_or(DEFAULT_LOCALE);
// If locale parsing failed, parse the encoding part of the
// locale. Treat the special case of the given locale being "C"
// which becomes the default locale.
let encoding = if (locale != DEFAULT_LOCALE || bcp47 == "C")
&& split.next() == Some("UTF-8")
{
UEncoding::Utf8
} else {
UEncoding::Ascii
};
return (locale, encoding);
} else {
return (DEFAULT_LOCALE, UEncoding::Ascii);
};
}
// Default POSIX locale representing LC_ALL=C
(DEFAULT_LOCALE, UEncoding::Ascii)
})
}
/// Return the encoding deduced from the locale environment variable.
pub fn get_locale_encoding() -> UEncoding {
get_collating_locale().1
}
+2
View File
@@ -51,6 +51,8 @@ pub use crate::features::fast_inc;
pub use crate::features::format;
#[cfg(feature = "fs")]
pub use crate::features::fs;
#[cfg(feature = "i18n")]
pub use crate::features::i18n;
#[cfg(feature = "lines")]
pub use crate::features::lines;
#[cfg(feature = "parser")]