Simplify and relax UTF-8 locale override machinery for Darwin
There's no need to try the various permutations of the language and region specific locales, as they all point back to the same CTYPE in /usr/share/locale/UTF-8/LC_CTYPE In addition, processes started from launchd come with an empty locale environment (LC_ALL/LC_*/LANG), and hence will default to the "C"/POSIX locale, even after picking up the environment. This primarily applies to applications launched from Finder, but also affects processes launched as background services. And since a child process will inherit its parent's environment the empty locale environment is propagated when running apps from IDEs such as Qt Creator or Xcode, or commands in an SSH login session (as sshd is a background service), unless the environment has been explicitly set up by the shell (Zsh). Since neither of these situations is the result of user misconfiguration, it makes little sense to spit our a warning. We however still warn if we detect that the character encoding has changed from the default "C" encoding, or if the encoding is "C", but we detect that the user has modified any of the relevant locale environment variables, as this indicates either a change in the system default behavior, or that the user has explicitly requested a "C" locale, which is wrong. Done-with: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Fixes: QTBUG-111443 Pick-to: 6.5.0 6.5 6.4 6.2 Change-Id: I6fd14d1f8adddc2914d6ff4d3b5ad34a3871ef82 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
fff9395c28
commit
ac6c7aa12f
@ -625,7 +625,20 @@ void QCoreApplicationPrivate::initLocale()
|
||||
const char *charEncoding = nl_langinfo(CODESET);
|
||||
if (Q_UNLIKELY(qstricmp(charEncoding, "UTF-8") != 0 && qstricmp(charEncoding, "utf8") != 0)) {
|
||||
const QByteArray oldLocale = setlocale(LC_ALL, nullptr);
|
||||
QByteArray newLocale = setlocale(LC_CTYPE, nullptr);
|
||||
QByteArray newLocale;
|
||||
bool warnOnOverride = true;
|
||||
# if defined(Q_OS_DARWIN)
|
||||
// Don't warn unless the char encoding has been changed from the
|
||||
// default "C" encoding, or the user touched any of the locale
|
||||
// environment variables to force the "C" char encoding.
|
||||
warnOnOverride = qstrcmp(setlocale(LC_CTYPE, nullptr), "C") != 0
|
||||
|| getenv("LC_ALL") || getenv("LC_CTYPE") || getenv("LANG");
|
||||
|
||||
// No need to try language or region specific CTYPEs, as they
|
||||
// all point back to the same generic UTF-8 CTYPE.
|
||||
newLocale = setlocale(LC_CTYPE, "UTF-8");
|
||||
# else
|
||||
newLocale = setlocale(LC_CTYPE, nullptr);
|
||||
if (qsizetype dot = newLocale.indexOf('.'); dot != -1)
|
||||
newLocale.truncate(dot); // remove encoding, if any
|
||||
if (qsizetype at = newLocale.indexOf('@'); at != -1)
|
||||
@ -634,14 +647,11 @@ void QCoreApplicationPrivate::initLocale()
|
||||
newLocale = setlocale(LC_CTYPE, newLocale);
|
||||
|
||||
// If that locale doesn't exist, try some fallbacks:
|
||||
# if defined(Q_OS_DARWIN)
|
||||
if (newLocale.isEmpty())
|
||||
newLocale = setlocale(LC_CTYPE, "UTF-8");
|
||||
# endif
|
||||
if (newLocale.isEmpty())
|
||||
newLocale = setlocale(LC_CTYPE, "C.UTF-8");
|
||||
if (newLocale.isEmpty())
|
||||
newLocale = setlocale(LC_CTYPE, "C.utf8");
|
||||
# endif
|
||||
|
||||
if (newLocale.isEmpty()) {
|
||||
// Failed to set a UTF-8 locale.
|
||||
@ -649,7 +659,7 @@ void QCoreApplicationPrivate::initLocale()
|
||||
"Qt depends on a UTF-8 locale, but has failed to switch to one.\n"
|
||||
"If this causes problems, reconfigure your locale. See the locale(1) manual\n"
|
||||
"for more information.", oldLocale.constData(), charEncoding);
|
||||
} else {
|
||||
} else if (warnOnOverride) {
|
||||
// Let the user know we over-rode their configuration.
|
||||
qWarning("Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n"
|
||||
"Qt depends on a UTF-8 locale, and has switched to \"%s\" instead.\n"
|
||||
|
Loading…
Reference in New Issue
Block a user