Skip to content

locale: honor LC_ALL and LC_MESSAGES precedence over LANG#13331

Open
costajohnt wants to merge 2 commits into
uutils:mainfrom
costajohnt:fix/8922-lc-all-locale-precedence
Open

locale: honor LC_ALL and LC_MESSAGES precedence over LANG#13331
costajohnt wants to merge 2 commits into
uutils:mainfrom
costajohnt:fix/8922-lc-all-locale-precedence

Conversation

@costajohnt

Copy link
Copy Markdown

Fixes #8922.

Locale detection only read LANG, so LC_ALL and LC_MESSAGES were ignored. GNU honors all three, so LC_ALL=fr_FR.UTF-8 sleep --help prints French there but English in uutils.

This applies the POSIX message-locale precedence LC_ALL > LC_MESSAGES > LANG: the first of those that is set and non-empty wins (a set-but-empty value is treated as unset), otherwise it falls back to the existing en-US default. The winning value keeps the same .<encoding> stripping as before (fr_FR.UTF-8 -> fr_FR), so the LANG-only path is unchanged.

The precedence lives in a small pure helper that takes the env lookup as an argument, so it can be unit-tested without mutating process-global env vars (which race under parallel test threads):

fn resolve_locale_string(lookup: impl Fn(&str) -> Option<String>) -> String

detect_system_locale just calls it with std::env::var.

Behavior change

Anyone who has LC_ALL or LC_MESSAGES set to something other than LANG will now get that locale for messages instead of LANG. That is the intended fix for #8922, but noting it since it is user-visible.

Tests

Seven unit tests on the helper: LC_ALL wins, LC_MESSAGES when LC_ALL is unset, LANG still works, empty treated as unset, LC_ALL over LANG, LC_ALL over LC_MESSAGES, and nothing-set fallback.

cargo test, cargo clippy --workspace --all-targets --all-features -- -D warnings, and cargo fmt --check all pass.

detect_system_locale() only read LANG, ignoring LC_ALL and LC_MESSAGES.
POSIX message-locale precedence is LC_ALL > LC_MESSAGES > LANG: the first
of those that is set and non-empty wins (set-but-empty is treated as
unset), falling back to en-US when none qualify.

Extract the precedence + encoding-stripping into a pure resolve_locale_string
helper that takes an env lookup closure, so the logic is unit-tested without
mutating process-global env vars (which race under parallel test threads).
detect_system_locale() passes std::env::var through it, preserving the exact
old string handling (only which variable supplies the value changed).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

l10n: LC_ALL is ignored

1 participant