Tidy up QCoreApplicationPrivate::initLocale()'s #if-ery

Explain each exception cleanly and as itself, thereby avoiding the
need for long and tangled #if-ery conditions.

Make sure to setlocale(LC_ALL, "") everywhere we think we have
initialized the locale, including Integrity - it plainly has
setlocale(), since we call it for LC_CTYPE - since we should at least
give it the chance to set its implementation-defined default locale,
instead of the standard-defined POSIX locale in use on entry to
main().

Done-with: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Pick-to: 6.5.0 6.5 6.4 6.2
Change-Id: Iab00984ba45dfc9a324b6a3c12e3d330b655a5a9
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Edward Welbourne 2023-02-27 16:40:59 +01:00
parent 7cf6c57648
commit 91bea4470e

View File

@ -598,22 +598,30 @@ void QCoreApplicationPrivate::initConsole()
void QCoreApplicationPrivate::initLocale()
{
#if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
#if defined(QT_BOOTSTRAPPED)
// Don't try to control bootstrap library locale or encoding.
#elif defined(Q_OS_UNIX)
Q_CONSTINIT static bool qt_locale_initialized = false;
if (qt_locale_initialized)
return;
qt_locale_initialized = true;
# ifdef Q_OS_INTEGRITY
setlocale(LC_CTYPE, "UTF-8");
# else
# if defined(Q_OS_QNX) || (defined(Q_OS_ANDROID) && __ANDROID_API__ < __ANDROID_API_O__)
// Android 6 still lacks nl_langinfo(), as does QNX, so we just assume it's
// always UTF-8 on these platforms.
auto nl_langinfo = [](int) { return "UTF-8"; };
# endif // QNX or Android NDK < 26, "O".
// By default the portable "C"/POSIX locale is selected and active.
// Apply the locale from the environment, via setlocale(), which will
// read LC_ALL, LC_<category>, and LANG, in order (for each category).
const char *locale = setlocale(LC_ALL, "");
// Next, let's ensure that LC_CTYPE is UTF-8, since QStringConverter's
// QLocal8Bit hard-codes this, and we need to be consistent.
# if defined(Q_OS_INTEGRITY)
setlocale(LC_CTYPE, "UTF-8");
# elif defined(Q_OS_QNX)
// QNX has no nl_langinfo, so we can't check.
// FIXME: Shouldn't we still setlocale("UTF-8")?
# elif defined(Q_OS_ANDROID) && __ANDROID_API__ < __ANDROID_API_O__
// Android 6 still lacks nl_langinfo(), so we can't check.
// FIXME: Shouldn't we still setlocale("UTF-8")?
# else
const char *codec = nl_langinfo(CODESET);
if (Q_UNLIKELY(qstricmp(codec, "UTF-8") != 0 && qstricmp(codec, "utf8") != 0)) {
QByteArray oldLocale = locale;
@ -625,8 +633,8 @@ void QCoreApplicationPrivate::initLocale()
newLocale += ".UTF-8";
newLocale = setlocale(LC_CTYPE, newLocale);
// if locale doesn't exist, try some fallbacks
# ifdef Q_OS_DARWIN
// If that locale doesn't exist, try some fallbacks:
# if defined(Q_OS_DARWIN)
if (newLocale.isEmpty())
newLocale = setlocale(LC_CTYPE, "UTF-8");
# endif
@ -640,7 +648,7 @@ void QCoreApplicationPrivate::initLocale()
"reconfigure your locale. See the locale(1) manual for more information.",
codec, oldLocale.constData(), newLocale.constData());
}
# endif // Integrity
# endif // Platform choice
#endif // Unix
}