diff options
Diffstat (limited to 'src/corelib/kernel/qcoreapplication.cpp')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 95 |
1 files changed, 66 insertions, 29 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 4d69ca9a17..7f53931a3d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -31,6 +31,7 @@ #include <private/qthread_p.h> #if QT_CONFIG(thread) #include <qthreadpool.h> +#include <private/qthreadpool_p.h> #endif #endif #include <qelapsedtimer.h> @@ -302,7 +303,7 @@ void Q_CORE_EXPORT qt_call_post_routines() if (list.isEmpty()) break; - for (QtCleanUpFunction f : qAsConst(list)) + for (QtCleanUpFunction f : std::as_const(list)) f(); } } @@ -547,24 +548,47 @@ QString qAppName() 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 + // 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). + 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"); -#else - // 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"; }; - - 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); +# 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 *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; + 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) @@ -572,23 +596,30 @@ void QCoreApplicationPrivate::initLocale() 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 that locale doesn't exist, try some fallbacks: 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 + + if (newLocale.isEmpty()) { + // Failed to set a UTF-8 locale. + qWarning("Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n" + "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 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" + "If this causes problems, reconfigure your locale. See the locale(1) manual\n" + "for more information.", + oldLocale.constData(), charEncoding, newLocale.constData()); + } } -#endif -#endif +# endif // Platform choice +#endif // Unix } @@ -783,7 +814,7 @@ void QCoreApplicationPrivate::init() // have been removed. Once the original list is exhausted we know all the remaining // items have been added. QStringList newPaths(q->libraryPaths()); - for (qsizetype i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) { + for (qsizetype i = manualPaths->size(), j = appPaths->size(); i > 0 || j > 0; qt_noop()) { if (--j < 0) { newPaths.prepend((*manualPaths)[--i]); } else if (--i < 0) { @@ -853,8 +884,10 @@ QCoreApplication::~QCoreApplication() #if QT_CONFIG(thread) // Synchronize and stop the global thread pool threads. QThreadPool *globalThreadPool = nullptr; + QThreadPool *guiThreadPool = nullptr; QT_TRY { globalThreadPool = QThreadPool::globalInstance(); + guiThreadPool = QThreadPoolPrivate::qtGuiInstance(); } QT_CATCH (...) { // swallow the exception, since destructors shouldn't throw } @@ -862,6 +895,10 @@ QCoreApplication::~QCoreApplication() globalThreadPool->waitForDone(); delete globalThreadPool; } + if (guiThreadPool) { + guiThreadPool->waitForDone(); + delete guiThreadPool; + } #endif #ifndef QT_NO_QOBJECT @@ -2138,12 +2175,12 @@ static void replacePercentN(QString *result, int n) qsizetype len = 0; while ((percentPos = result->indexOf(u'%', percentPos + len)) != -1) { len = 1; - if (percentPos + len == result->length()) + if (percentPos + len == result->size()) break; QString fmt; if (result->at(percentPos + len) == u'L') { ++len; - if (percentPos + len == result->length()) + if (percentPos + len == result->size()) break; fmt = "%L1"_L1; } else { @@ -2153,7 +2190,7 @@ static void replacePercentN(QString *result, int n) fmt = fmt.arg(n); ++len; result->replace(percentPos, len, fmt); - len = fmt.length(); + len = fmt.size(); } } } |