summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qcoreapplication.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2019-11-22 14:05:25 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2020-05-05 15:34:15 +0200
commit419f42903154489e2dace8d1eba183036275448b (patch)
treeddd30764c42290d88df2ff9fa1995c4abe0e73ab /src/corelib/kernel/qcoreapplication.cpp
parenta206f52acd175800688b9f4cce8e56df2632dab2 (diff)
QCoreApplication: force the process locale codec to UTF-8
As discussed in the mailing list and in the Qt Contributor Summit 2019. Tested on Linux, macOS and FreeBSD, showing these fallbacks: OS environment setlocale() call FreeBSD empty "C.UTF-8" FreeBSD LC_ALL=C "C.UTF-8" Linux empty "C.UTF-8" Linux LC_ALL=C "C.UTF-8" Linux LANG=en_US "en_US.UTF-8" Linux LANG=de_DE@euro "de_DE.UTF-8" Linux LANG=en_GB.iso885915 "en_GB.UTF-8" Linux LANG=hy_AM.armscii8 "hy_AM.UTF-8" Linux LANG=ja_JP.sjis "ja_JP.UTF-8" Linux LANG=ru_RU.koi8r "ru_RU.UTF-8" macOS empty "UTF-8" macOS LC_ALL=C "UTF-8" Versions tested: FreeBSD 12.1, Linux w/ glibc 2.30, macOS 10.14.2. See * https://wiki.qt.io/Qt_Contributor_Summit_2019_-_QtCore * https://lists.qt-project.org/pipermail/development/2019-October/037791.html Change-Id: Ia2aa807ffa8a4c798425fffd15d97ddb4f35b0ae Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/kernel/qcoreapplication.cpp')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index fe3aa454ab..0c5e6cdb4a 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -112,6 +112,7 @@
#ifdef Q_OS_UNIX
# include <locale.h>
+# include <langinfo.h>
# include <unistd.h>
# include <sys/types.h>
#endif
@@ -338,9 +339,6 @@ void Q_CORE_EXPORT qt_call_post_routines()
}
-// initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
-static bool qt_locale_initialized = false;
-
#ifndef QT_NO_QOBJECT
// app starting up if false
@@ -590,11 +588,45 @@ QString qAppName()
void QCoreApplicationPrivate::initLocale()
{
+#if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
+ static bool qt_locale_initialized = false;
if (qt_locale_initialized)
return;
qt_locale_initialized = true;
-#if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
- setlocale(LC_ALL, "");
+
+#ifdef Q_OS_ANDROID
+ // Android's Bionic didn't get nl_langinfo until NDK 15 (Android 8.0),
+ // which is too new for Qt, so we just assume it's always UTF-8.
+ auto nl_langinfo = [](int) { return "UTF-8"; };
+#endif
+
+ const char *locale = setlocale(LC_ALL, "");
+ const char *codec = nl_langinfo(CODESET);
+ if (Q_UNLIKELY(strcmp(codec, "UTF-8") != 0 && strcmp(codec, "utf8") != 0)) {
+ QByteArray oldLocale = locale;
+ QByteArray newLocale = setlocale(LC_CTYPE, nullptr);
+ if (int dot = newLocale.indexOf('.'); dot != -1)
+ newLocale.truncate(dot); // remove encoding, if any
+ if (int at = newLocale.indexOf('@'); at != -1)
+ newLocale.truncate(at); // remove variant, as the old de_DE@euro
+ newLocale += ".UTF-8";
+ newLocale = setlocale(LC_CTYPE, newLocale);
+
+ // if locale doesn't exist, try some fallbacks
+# ifdef 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");
+
+ qWarning("Detected system locale encoding (%s, locale \"%s\") is not UTF-8.\n"
+ "Qt shall use a UTF-8 locale (\"%s\") instead. If this causes problems,\n"
+ "reconfigure your locale. See the locale(1) manual for more information.",
+ codec, oldLocale.constData(), newLocale.constData());
+ }
#endif
}