summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlocale.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qlocale.cpp')
-rw-r--r--src/corelib/tools/qlocale.cpp86
1 files changed, 51 insertions, 35 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index a072ea411c..5598dfe237 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -64,6 +64,9 @@
#include "qstringbuilder.h"
#include "private/qnumeric_p.h"
#include <cmath>
+#ifndef QT_NO_SYSTEMLOCALE
+# include "qmutex.h"
+#endif
#ifdef Q_OS_WIN
# include <qt_windows.h>
# include <time.h>
@@ -107,31 +110,32 @@ QLocale::Language QLocalePrivate::codeToLanguage(QStringView code) Q_DECL_NOTHRO
return QLocale::Language((c - language_code_list)/3);
}
- // legacy codes
- if (uc1 == 'n' && uc2 == 'o' && uc3 == 0) { // no -> nb
- Q_STATIC_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal);
- return QLocale::Norwegian;
- }
- if (uc1 == 't' && uc2 == 'l' && uc3 == 0) { // tl -> fil
- Q_STATIC_ASSERT(QLocale::Tagalog == QLocale::Filipino);
- return QLocale::Tagalog;
- }
- if (uc1 == 's' && uc2 == 'h' && uc3 == 0) { // sh -> sr[_Latn]
- Q_STATIC_ASSERT(QLocale::SerboCroatian == QLocale::Serbian);
- return QLocale::SerboCroatian;
- }
- if (uc1 == 'm' && uc2 == 'o' && uc3 == 0) { // mo -> ro
- Q_STATIC_ASSERT(QLocale::Moldavian == QLocale::Romanian);
- return QLocale::Moldavian;
+ if (uc3 == 0) {
+ // legacy codes
+ if (uc1 == 'n' && uc2 == 'o') { // no -> nb
+ Q_STATIC_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal);
+ return QLocale::Norwegian;
+ }
+ if (uc1 == 't' && uc2 == 'l') { // tl -> fil
+ Q_STATIC_ASSERT(QLocale::Tagalog == QLocale::Filipino);
+ return QLocale::Tagalog;
+ }
+ if (uc1 == 's' && uc2 == 'h') { // sh -> sr[_Latn]
+ Q_STATIC_ASSERT(QLocale::SerboCroatian == QLocale::Serbian);
+ return QLocale::SerboCroatian;
+ }
+ if (uc1 == 'm' && uc2 == 'o') { // mo -> ro
+ Q_STATIC_ASSERT(QLocale::Moldavian == QLocale::Romanian);
+ return QLocale::Moldavian;
+ }
+ // Android uses the following deprecated codes
+ if (uc1 == 'i' && uc2 == 'w') // iw -> he
+ return QLocale::Hebrew;
+ if (uc1 == 'i' && uc2 == 'n') // in -> id
+ return QLocale::Indonesian;
+ if (uc1 == 'j' && uc2 == 'i') // ji -> yi
+ return QLocale::Yiddish;
}
- // Android uses the following deprecated codes
- if (uc1 == 'i' && uc2 == 'w' && uc3 == 0) // iw -> he
- return QLocale::Hebrew;
- if (uc1 == 'i' && uc2 == 'n' && uc3 == 0) // in -> id
- return QLocale::Indonesian;
- if (uc1 == 'j' && uc2 == 'i' && uc3 == 0) // ji -> yi
- return QLocale::Yiddish;
-
return QLocale::C;
}
@@ -593,8 +597,6 @@ static QLocalePrivate *c_private()
}
#ifndef QT_NO_SYSTEMLOCALE
-
-
/******************************************************************************
** Default system locale behavior
*/
@@ -683,14 +685,24 @@ void QLocalePrivate::updateSystemPrivate()
if (!res.isNull())
system_data->m_plus = res.toString().at(0).unicode();
}
-#endif
+#endif // !QT_NO_SYSTEMLOCALE
static const QLocaleData *systemData()
{
#ifndef QT_NO_SYSTEMLOCALE
- // copy over the information from the fallback locale and modify
- if (!system_data || system_data->m_language_id == 0)
- QLocalePrivate::updateSystemPrivate();
+ /*
+ Copy over the information from the fallback locale and modify.
+
+ This modifies (cross-thread) global state, so take care to only call it in
+ one thread.
+ */
+ {
+ static QBasicMutex systemDataMutex;
+ systemDataMutex.lock();
+ if (!system_data || system_data->m_language_id == 0)
+ QLocalePrivate::updateSystemPrivate();
+ systemDataMutex.unlock();
+ }
return system_data;
#else
@@ -3151,11 +3163,15 @@ QString QLocaleData::longLongToString(const QChar zero, const QChar group,
negative = false; // neither are negative numbers
}
- QString num_str;
- if (base == 10)
- num_str = qlltoa(l, base, zero);
- else
- num_str = qulltoa(l, base, zero);
+QT_WARNING_PUSH
+ /* "unary minus operator applied to unsigned type, result still unsigned" */
+QT_WARNING_DISABLE_MSVC(4146)
+ /*
+ Negating std::numeric_limits<qlonglong>::min() hits undefined behavior, so
+ taking an absolute value has to cast to unsigned to change sign.
+ */
+ QString num_str = qulltoa(negative ? -qulonglong(l) : qulonglong(l), base, zero);
+QT_WARNING_POP
uint cnt_thousand_sep = 0;
if (flags & ThousandsGroup && base == 10) {