Merge remote-tracking branch 'origin/master' into api_changes
[profile/ivi/qtbase.git] / src / corelib / tools / qlocale.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #if !defined(QWS) && defined(Q_OS_MAC)
43 #   include "private/qcore_mac_p.h"
44 #   include <CoreFoundation/CoreFoundation.h>
45 #endif
46
47 #include "qglobal.h"
48
49 #include "qplatformdefs.h"
50
51 #include "qdatastream.h"
52 #include "qdebug.h"
53 #include "qstring.h"
54 #include "qlocale.h"
55 #include "qlocale_p.h"
56 #include "qlocale_tools_p.h"
57 #include "qdatetime_p.h"
58 #include "qnamespace.h"
59 #include "qdatetime.h"
60 #include "qstringlist.h"
61 #include "qvariant.h"
62 #include "qstringbuilder.h"
63 #include "private/qnumeric_p.h"
64 #include "private/qsystemlibrary_p.h"
65 #ifdef Q_OS_WIN
66 #   include <qt_windows.h>
67 #   include <time.h>
68 #endif
69
70 QT_BEGIN_NAMESPACE
71
72 #ifndef QT_NO_SYSTEMLOCALE
73 static QSystemLocale *_systemLocale = 0;
74 class QSystemLocaleSingleton: public QSystemLocale
75 {
76 public:
77     QSystemLocaleSingleton() : QSystemLocale(true) {}
78 };
79
80 Q_GLOBAL_STATIC(QSystemLocaleSingleton, QSystemLocale_globalSystemLocale)
81 static QLocalePrivate *system_lp = 0;
82 Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
83 #endif
84
85 #ifdef QT_USE_ICU
86 extern bool qt_initIcu(const QString &localeName);
87 extern bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale);
88 extern bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale);
89 #endif
90
91 /******************************************************************************
92 ** Helpers for accessing Qt locale database
93 */
94
95 QT_BEGIN_INCLUDE_NAMESPACE
96 #include "qlocale_data_p.h"
97 QT_END_INCLUDE_NAMESPACE
98
99 QLocale::Language QLocalePrivate::codeToLanguage(const QString &code)
100 {
101     int len = code.length();
102     if (len != 2 && len != 3)
103         return QLocale::C;
104     ushort uc1 = len-- > 0 ? code[0].toLower().unicode() : 0;
105     ushort uc2 = len-- > 0 ? code[1].toLower().unicode() : 0;
106     ushort uc3 = len-- > 0 ? code[2].toLower().unicode() : 0;
107
108     if (uc1 == 'n' && uc2 == 'o' && uc3 == 0)
109         uc2 = 'b';
110
111     const unsigned char *c = language_code_list;
112     for (; *c != 0; c += 3) {
113         if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
114             return QLocale::Language((c - language_code_list)/3);
115     }
116
117     return QLocale::C;
118 }
119
120 QLocale::Script QLocalePrivate::codeToScript(const QString &code)
121 {
122     int len = code.length();
123     if (len != 4)
124         return QLocale::AnyScript;
125
126     // script is titlecased in our data
127     unsigned char c0 = code.at(0).toUpper().toLatin1();
128     unsigned char c1 = code.at(1).toLower().toLatin1();
129     unsigned char c2 = code.at(2).toLower().toLatin1();
130     unsigned char c3 = code.at(3).toLower().toLatin1();
131
132     const unsigned char *c = script_code_list;
133     for (int i = 0; i < QLocale::LastScript; ++i, c += 4) {
134         if (c0 == c[0] && c1 == c[1] && c2 == c[2] && c3 == c[3])
135             return QLocale::Script(i);
136     }
137     return QLocale::AnyScript;
138 }
139
140 QLocale::Country QLocalePrivate::codeToCountry(const QString &code)
141 {
142     int len = code.length();
143     if (len != 2 && len != 3)
144         return QLocale::AnyCountry;
145     ushort uc1 = len-- > 0 ? code[0].toUpper().unicode() : 0;
146     ushort uc2 = len-- > 0 ? code[1].toUpper().unicode() : 0;
147     ushort uc3 = len-- > 0 ? code[2].toUpper().unicode() : 0;
148
149     const unsigned char *c = country_code_list;
150     for (; *c != 0; c += 3) {
151         if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
152             return QLocale::Country((c - country_code_list)/3);
153     }
154
155     return QLocale::AnyCountry;
156 }
157
158 QString QLocalePrivate::languageCode() const
159 {
160     if (m_language_id == QLocale::AnyLanguage)
161         return QString();
162     if (m_language_id == QLocale::C)
163         return QLatin1String("C");
164
165     const unsigned char *c = language_code_list + 3*(uint(m_language_id));
166
167     QString code(c[2] == 0 ? 2 : 3, Qt::Uninitialized);
168
169     code[0] = ushort(c[0]);
170     code[1] = ushort(c[1]);
171     if (c[2] != 0)
172         code[2] = ushort(c[2]);
173
174     return code;
175 }
176
177 QString QLocalePrivate::scriptCode() const
178 {
179     if (m_script_id == QLocale::AnyScript || m_script_id > QLocale::LastScript)
180         return QString();
181     const unsigned char *c = script_code_list + 4*(uint(m_script_id));
182     return QString::fromLatin1((const char *)c, 4);
183 }
184
185 QString QLocalePrivate::countryCode() const
186 {
187     if (m_country_id == QLocale::AnyCountry)
188         return QString();
189
190     const unsigned char *c = country_code_list + 3*(uint(m_country_id));
191
192     QString code(c[2] == 0 ? 2 : 3, Qt::Uninitialized);
193
194     code[0] = ushort(c[0]);
195     code[1] = ushort(c[1]);
196     if (c[2] != 0)
197         code[2] = ushort(c[2]);
198
199     return code;
200 }
201
202 QString QLocalePrivate::bcp47Name() const
203 {
204     if (m_language_id == QLocale::AnyLanguage)
205         return QString();
206     if (m_language_id == QLocale::C)
207         return QLatin1String("C");
208     const unsigned char *lang = language_code_list + 3*(uint(m_language_id));
209     const unsigned char *script =
210             (m_script_id != QLocale::AnyScript ? script_code_list + 4*(uint(m_script_id)) : 0);
211     const unsigned char *country =
212             (m_country_id != QLocale::AnyCountry  ? country_code_list + 3*(uint(m_country_id)) : 0);
213     char len = (lang[2] != 0 ? 3 : 2) + (script ? 4+1 : 0) + (country ? (country[2] != 0 ? 3 : 2)+1 : 0);
214     QString name(len, Qt::Uninitialized);
215     QChar *uc = name.data();
216     *uc++ = ushort(lang[0]);
217     *uc++ = ushort(lang[1]);
218     if (lang[2] != 0)
219         *uc++ = ushort(lang[2]);
220     if (script) {
221         *uc++ = QLatin1Char('-');
222         *uc++ = ushort(script[0]);
223         *uc++ = ushort(script[1]);
224         *uc++ = ushort(script[2]);
225         *uc++ = ushort(script[3]);
226     }
227     if (country) {
228         *uc++ = QLatin1Char('-');
229         *uc++ = ushort(country[0]);
230         *uc++ = ushort(country[1]);
231         if (country[2] != 0)
232             *uc++ = ushort(country[2]);
233     }
234     return name;
235 }
236
237 const QLocalePrivate *QLocalePrivate::findLocale(QLocale::Language language, QLocale::Script script, QLocale::Country country)
238 {
239     const unsigned language_id = language;
240     const unsigned script_id = script;
241     const unsigned country_id = country;
242
243     uint idx = locale_index[language_id];
244
245     const QLocalePrivate *d = locale_data + idx;
246
247     if (idx == 0) // default language has no associated country
248         return d;
249
250     if (script == QLocale::AnyScript && country == QLocale::AnyCountry)
251         return d;
252
253     Q_ASSERT(d->languageId() == language_id);
254
255     if (country == QLocale::AnyCountry) {
256         while (d->m_language_id == language_id && d->m_script_id != script_id)
257             ++d;
258         if (d->m_language_id == language_id && d->m_script_id == script_id)
259             return d;
260     } else if (script == QLocale::AnyScript) {
261         while (d->m_language_id == language_id) {
262             if (d->m_script_id == script_id && d->m_country_id == country_id)
263                 return d;
264             ++d;
265         }
266     } else {
267         // both script and country are explicitly specified
268         while (d->m_language_id == language_id) {
269             if (d->m_script_id == script_id && d->m_country_id == country_id)
270                 return d;
271             ++d;
272         }
273     }
274
275     return locale_data + idx;
276 }
277
278 static bool parse_locale_tag(const QString &input, int &i, QString *result, const QString &separators)
279 {
280     *result = QString(8, Qt::Uninitialized); // worst case according to BCP47
281     QChar *pch = result->data();
282     const QChar *uc = input.data() + i;
283     const int l = input.length();
284     int size = 0;
285     for (; i < l && size < 8; ++i, ++size) {
286         if (separators.contains(*uc))
287             break;
288         if (! ((uc->unicode() >= 'a' && uc->unicode() <= 'z') ||
289                (uc->unicode() >= 'A' && uc->unicode() <= 'Z') ||
290                (uc->unicode() >= '0' && uc->unicode() <= '9')) ) // latin only
291             return false;
292         *pch++ = *uc++;
293     }
294     result->truncate(size);
295     return true;
296 }
297
298 bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QString &cntry)
299 {
300     const int length = name.length();
301
302     lang = script = cntry = QString();
303
304     const QString separators = QLatin1String("_-.@");
305     enum ParserState { NoState, LangState, ScriptState, CountryState };
306     ParserState state = LangState;
307     for (int i = 0; i < length && state != NoState; ) {
308         QString value;
309         if (!parse_locale_tag(name, i, &value, separators) ||value.isEmpty())
310             break;
311         QChar sep = i < length ? name.at(i) : QChar();
312         switch (state) {
313         case LangState:
314             if (!sep.isNull() && !separators.contains(sep)) {
315                 state = NoState;
316                 break;
317             }
318             lang = value;
319             if (i == length) {
320                 // just language was specified
321                 state = NoState;
322                 break;
323             }
324             state = ScriptState;
325             break;
326         case ScriptState: {
327             QString scripts = QString::fromLatin1((const char *)script_code_list, sizeof(script_code_list));
328             if (value.length() == 4 && scripts.indexOf(value) % 4 == 0) {
329                 // script name is always 4 characters
330                 script = value;
331                 state = CountryState;
332             } else {
333                 // it wasn't a script, maybe it is a country then?
334                 cntry = value;
335                 state = NoState;
336             }
337             break;
338         }
339         case CountryState:
340             cntry = value;
341             state = NoState;
342             break;
343         case NoState:
344             // shouldn't happen
345             qWarning("QLocale: This should never happen");
346             break;
347         }
348         ++i;
349     }
350     return lang.length() == 2 || lang.length() == 3;
351 }
352
353 void QLocalePrivate::getLangAndCountry(const QString &name, QLocale::Language &lang,
354                                        QLocale::Script &script, QLocale::Country &cntry)
355 {
356     lang = QLocale::C;
357     script = QLocale::AnyScript;
358     cntry = QLocale::AnyCountry;
359
360     QString lang_code;
361     QString script_code;
362     QString cntry_code;
363     if (!qt_splitLocaleName(name, lang_code, script_code, cntry_code))
364         return;
365
366     lang = QLocalePrivate::codeToLanguage(lang_code);
367     if (lang == QLocale::C)
368         return;
369     script = QLocalePrivate::codeToScript(script_code);
370     cntry = QLocalePrivate::codeToCountry(cntry_code);
371 }
372
373 static const QLocalePrivate *findLocale(const QString &name)
374 {
375     QLocale::Language lang;
376     QLocale::Script script;
377     QLocale::Country cntry;
378     QLocalePrivate::getLangAndCountry(name, lang, script, cntry);
379
380     return QLocalePrivate::findLocale(lang, script, cntry);
381 }
382
383 QString qt_readEscapedFormatString(const QString &format, int *idx)
384 {
385     int &i = *idx;
386
387     Q_ASSERT(format.at(i) == QLatin1Char('\''));
388     ++i;
389     if (i == format.size())
390         return QString();
391     if (format.at(i).unicode() == '\'') { // "''" outside of a quoted stirng
392         ++i;
393         return QLatin1String("'");
394     }
395
396     QString result;
397
398     while (i < format.size()) {
399         if (format.at(i).unicode() == '\'') {
400             if (i + 1 < format.size() && format.at(i + 1).unicode() == '\'') {
401                 // "''" inside of a quoted string
402                 result.append(QLatin1Char('\''));
403                 i += 2;
404             } else {
405                 break;
406             }
407         } else {
408             result.append(format.at(i++));
409         }
410     }
411     if (i < format.size())
412         ++i;
413
414     return result;
415 }
416
417 int qt_repeatCount(const QString &s, int i)
418 {
419     QChar c = s.at(i);
420     int j = i + 1;
421     while (j < s.size() && s.at(j) == c)
422         ++j;
423     return j - i;
424 }
425
426 static const QLocalePrivate *default_lp = 0;
427 static uint default_number_options = 0;
428
429 #ifndef QT_NO_SYSTEMLOCALE
430
431
432 /******************************************************************************
433 ** Default system locale behavior
434 */
435
436 /*!
437   Constructs a QSystemLocale object. The constructor will automatically
438   install this object as the system locale and remove any earlier installed
439   system locales.
440 */
441 QSystemLocale::QSystemLocale()
442 {
443     delete _systemLocale;
444     _systemLocale = this;
445
446     if (system_lp)
447         system_lp->m_language_id = 0;
448 }
449
450 /*! \internal */
451 QSystemLocale::QSystemLocale(bool)
452 { }
453
454 /*!
455   Deletes the object.
456 */
457 QSystemLocale::~QSystemLocale()
458 {
459     if (_systemLocale == this) {
460         _systemLocale = 0;
461
462         if (system_lp)
463             system_lp->m_language_id = 0;
464     }
465 }
466
467 static const QSystemLocale *systemLocale()
468 {
469     if (_systemLocale)
470         return _systemLocale;
471     return QSystemLocale_globalSystemLocale();
472 }
473
474 void QLocalePrivate::updateSystemPrivate()
475 {
476     const QSystemLocale *sys_locale = systemLocale();
477     if (!system_lp)
478         system_lp = globalLocalePrivate();
479
480     // tell the object that the system locale has changed.
481     sys_locale->query(QSystemLocale::LocaleChanged, QVariant());
482
483     *system_lp = *sys_locale->fallbackLocale().d();
484
485     QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
486     if (!res.isNull()) {
487         system_lp->m_language_id = res.toInt();
488         system_lp->m_script_id = QLocale::AnyScript; // default for compatibility
489     }
490     res = sys_locale->query(QSystemLocale::CountryId, QVariant());
491     if (!res.isNull()) {
492         system_lp->m_country_id = res.toInt();
493         system_lp->m_script_id = QLocale::AnyScript; // default for compatibility
494     }
495     res = sys_locale->query(QSystemLocale::ScriptId, QVariant());
496     if (!res.isNull())
497         system_lp->m_script_id = res.toInt();
498
499     res = sys_locale->query(QSystemLocale::DecimalPoint, QVariant());
500     if (!res.isNull())
501         system_lp->m_decimal = res.toString().at(0).unicode();
502
503     res = sys_locale->query(QSystemLocale::GroupSeparator, QVariant());
504     if (!res.isNull())
505         system_lp->m_group = res.toString().at(0).unicode();
506
507     res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant());
508     if (!res.isNull())
509         system_lp->m_zero = res.toString().at(0).unicode();
510
511     res = sys_locale->query(QSystemLocale::NegativeSign, QVariant());
512     if (!res.isNull())
513         system_lp->m_minus = res.toString().at(0).unicode();
514
515     res = sys_locale->query(QSystemLocale::PositiveSign, QVariant());
516     if (!res.isNull())
517         system_lp->m_plus = res.toString().at(0).unicode();
518
519 #ifdef QT_USE_ICU
520     if (!default_lp)
521         qt_initIcu(system_lp->bcp47Name());
522 #endif
523
524 }
525 #endif
526
527 static const QLocalePrivate *systemPrivate()
528 {
529 #ifndef QT_NO_SYSTEMLOCALE
530     // copy over the information from the fallback locale and modify
531     if (!system_lp || system_lp->m_language_id == 0)
532         QLocalePrivate::updateSystemPrivate();
533
534     return system_lp;
535 #else
536     return locale_data;
537 #endif
538 }
539
540 static const QLocalePrivate *defaultPrivate()
541 {
542     if (!default_lp)
543         default_lp = systemPrivate();
544     return default_lp;
545 }
546
547 static QString getLocaleListData(const ushort *data, int size, int index)
548 {
549     static const ushort separator = ';';
550     while (index && size > 0) {
551         while (*data != separator)
552             ++data, --size;
553         --index;
554         ++data;
555         --size;
556     }
557     const ushort *end = data;
558     while (size > 0 && *end != separator)
559         ++end, --size;
560     if (end-data == 0)
561         return QString();
562     return QString::fromRawData(reinterpret_cast<const QChar*>(data), end-data);
563 }
564
565 static inline QString getLocaleData(const ushort *data, int size)
566 {
567     return size ? QString::fromRawData(reinterpret_cast<const QChar*>(data), size) : QString();
568 }
569
570
571 #ifndef QT_NO_DATASTREAM
572 QDataStream &operator<<(QDataStream &ds, const QLocale &l)
573 {
574     ds << l.name();
575     return ds;
576 }
577
578 QDataStream &operator>>(QDataStream &ds, QLocale &l)
579 {
580     QString s;
581     ds >> s;
582     l = QLocale(s);
583     return ds;
584 }
585 #endif // QT_NO_DATASTREAM
586
587
588 static const int locale_data_size = sizeof(locale_data)/sizeof(QLocalePrivate) - 1;
589
590 static const QLocalePrivate *dataPointerHelper(quint16 index)
591 {
592 #ifndef QT_NO_SYSTEMLOCALE
593     Q_ASSERT(index <= locale_data_size);
594     if (index == locale_data_size)
595         return system_lp;
596 #else
597     Q_ASSERT(index < locale_data_size);
598 #endif
599
600     return &locale_data[index];
601 }
602
603 static quint16 localePrivateIndex(const QLocalePrivate *p)
604 {
605 #ifndef QT_NO_SYSTEMLOCALE
606     Q_ASSERT((p >= locale_data && p - locale_data < locale_data_size)
607              || (p != 0 && p == system_lp));
608     quint16 index = p == system_lp ? locale_data_size : p - locale_data;
609 #else
610     Q_ASSERT(p >= locale_data && p - locale_data < locale_data_size);
611     quint16 index = p - locale_data;
612 #endif
613
614     return index;
615 }
616
617 /*!
618     Constructs a QLocale object with the specified \a name,
619     which has the format
620     "language[_script][_country][.codeset][@modifier]" or "C", where:
621
622     \list
623     \li language is a lowercase, two-letter, ISO 639 language code,
624     \li script is a titlecase, four-letter, ISO 15924 script code,
625     \li country is an uppercase, two- or three-letter, ISO 3166 country code (also "419" as defined by United Nations),
626     \li and codeset and modifier are ignored.
627     \endlist
628
629     The separator can be either underscore or a minus sign.
630
631     If the string violates the locale format, or language is not
632     a valid ISO 369 code, the "C" locale is used instead. If country
633     is not present, or is not a valid ISO 3166 code, the most
634     appropriate country is chosen for the specified language.
635
636     The language, script and country codes are converted to their respective
637     \c Language, \c Script and \c Country enums. After this conversion is
638     performed the constructor behaves exactly like QLocale(Country, Script,
639     Language).
640
641     This constructor is much slower than QLocale(Country, Script, Language).
642
643     \sa bcp47Name()
644 */
645
646 QLocale::QLocale(const QString &name)
647     : v(0)
648 {
649     p.numberOptions = 0;
650     p.index = localePrivateIndex(findLocale(name));
651 }
652
653 /*!
654     Constructs a QLocale object initialized with the default locale. If
655     no default locale was set using setDefaultLocale(), this locale will
656     be the same as the one returned by system().
657
658     \sa setDefault()
659 */
660
661 QLocale::QLocale()
662     : v(0)
663 {
664     p.numberOptions = default_number_options;
665     p.index = localePrivateIndex(defaultPrivate());
666 }
667
668 /*!
669     Constructs a QLocale object with the specified \a language and \a
670     country.
671
672     \list
673     \li If the language/country pair is found in the database, it is used.
674     \li If the language is found but the country is not, or if the country
675        is \c AnyCountry, the language is used with the most
676        appropriate available country (for example, Germany for German),
677     \li If neither the language nor the country are found, QLocale
678        defaults to the default locale (see setDefault()).
679     \endlist
680
681     The language and country that are actually used can be queried
682     using language() and country().
683
684     \sa setDefault() language() country()
685 */
686
687 QLocale::QLocale(Language language, Country country)
688     : v(0)
689 {
690     const QLocalePrivate *d = QLocalePrivate::findLocale(language, QLocale::AnyScript, country);
691
692     // If not found, should default to system
693     if (d->languageId() == QLocale::C && language != QLocale::C) {
694         p.numberOptions = default_number_options;
695         p.index = localePrivateIndex(defaultPrivate());
696     } else {
697         p.numberOptions = 0;
698         p.index = localePrivateIndex(d);
699     }
700 }
701 \
702 /*!
703     \since 4.8
704
705     Constructs a QLocale object with the specified \a language, \a script and
706     \a country.
707
708     \list
709     \li If the language/script/country is found in the database, it is used.
710     \li If both \a script is AnyScript and \a country is AnyCountry, the
711        language is used with the most appropriate available script and country
712        (for example, Germany for German),
713     \li If either \a script is AnyScript or \a country is AnyCountry, the
714        language is used with the first locale that matches the given \a script
715        and \a country.
716     \li If neither the language nor the country are found, QLocale
717        defaults to the default locale (see setDefault()).
718     \endlist
719
720     The language, script and country that are actually used can be queried
721     using language(), script() and country().
722
723     \sa setDefault() language() script() country()
724 */
725
726 QLocale::QLocale(Language language, Script script, Country country)
727     : v(0)
728 {
729     const QLocalePrivate *d = QLocalePrivate::findLocale(language, script, country);
730
731     // If not found, should default to system
732     if (d->languageId() == QLocale::C && language != QLocale::C) {
733         p.numberOptions = default_number_options;
734         p.index = localePrivateIndex(defaultPrivate());
735     } else {
736         p.numberOptions = 0;
737         p.index = localePrivateIndex(d);
738     }
739 }
740
741 /*!
742     Constructs a QLocale object as a copy of \a other.
743 */
744
745 QLocale::QLocale(const QLocale &other)
746 {
747     v = other.v;
748 }
749
750 const QLocalePrivate *QLocale::d() const
751 {
752     return dataPointerHelper(p.index);
753 }
754
755 /*!
756     Assigns \a other to this QLocale object and returns a reference
757     to this QLocale object.
758 */
759
760 QLocale &QLocale::operator=(const QLocale &other)
761 {
762     v = other.v;
763     return *this;
764 }
765
766 bool QLocale::operator==(const QLocale &other) const
767 {
768     return d() == other.d() && numberOptions() == other.numberOptions();
769 }
770
771 bool QLocale::operator!=(const QLocale &other) const
772 {
773     return d() != other.d() || numberOptions() != other.numberOptions();
774 }
775
776 /*!
777     \since 4.2
778
779     Sets the \a options related to number conversions for this
780     QLocale instance.
781 */
782 void QLocale::setNumberOptions(NumberOptions options)
783 {
784     p.numberOptions = options;
785 }
786
787 /*!
788     \since 4.2
789
790     Returns the options related to number conversions for this
791     QLocale instance.
792
793     By default, no options are set for the standard locales.
794 */
795 QLocale::NumberOptions QLocale::numberOptions() const
796 {
797     return static_cast<NumberOption>(p.numberOptions);
798 }
799
800 /*!
801     \since 4.8
802
803     Returns \a str quoted according to the current locale using the given
804     quotation \a style.
805 */
806 QString QLocale::quoteString(const QString &str, QuotationStyle style) const
807 {
808     return quoteString(&str, style);
809 }
810
811 /*!
812     \since 4.8
813
814     \overload
815 */
816 QString QLocale::quoteString(const QStringRef &str, QuotationStyle style) const
817 {
818 #ifndef QT_NO_SYSTEMLOCALE
819     if (d() == systemPrivate()) {
820         QVariant res;
821         if (style == QLocale::AlternateQuotation)
822             res = systemLocale()->query(QSystemLocale::StringToAlternateQuotation, QVariant::fromValue(str));
823         if (res.isNull() || style == QLocale::StandardQuotation)
824             res = systemLocale()->query(QSystemLocale::StringToStandardQuotation, QVariant::fromValue(str));
825         if (!res.isNull())
826             return res.toString();
827     }
828 #endif
829
830     if (style == QLocale::StandardQuotation)
831         return QChar(d()->m_quotation_start) % str % QChar(d()->m_quotation_end);
832     else
833         return QChar(d()->m_alternate_quotation_start) % str % QChar(d()->m_alternate_quotation_end);
834 }
835
836 /*!
837     \since 4.8
838
839     Returns a string that represents a join of a given \a list of strings with
840     a separator defined by the locale.
841 */
842 QString QLocale::createSeparatedList(const QStringList &list) const
843 {
844 #ifndef QT_NO_SYSTEMLOCALE
845     if (d() == systemPrivate()) {
846         QVariant res;
847         res = systemLocale()->query(QSystemLocale::ListToSeparatedString, QVariant::fromValue(list));
848
849         if (!res.isNull())
850             return res.toString();
851     }
852 #endif
853
854     const int size = list.size();
855     if (size == 1) {
856         return list.at(0);
857     } else if (size == 2) {
858         QString format = getLocaleData(list_pattern_part_data + d()->m_list_pattern_part_two_idx, d()->m_list_pattern_part_two_size);
859         return format.arg(list.at(0), list.at(1));
860     } else if (size > 2) {
861         QString formatStart = getLocaleData(list_pattern_part_data + d()->m_list_pattern_part_start_idx, d()->m_list_pattern_part_start_size);
862         QString formatMid = getLocaleData(list_pattern_part_data + d()->m_list_pattern_part_mid_idx, d()->m_list_pattern_part_mid_size);
863         QString formatEnd = getLocaleData(list_pattern_part_data + d()->m_list_pattern_part_end_idx, d()->m_list_pattern_part_end_size);
864         QString result = formatStart.arg(list.at(0), list.at(1));
865         for (int i = 2; i < size - 1; ++i)
866             result = formatMid.arg(result, list.at(i));
867         result = formatEnd.arg(result, list.at(size - 1));
868         return result;
869     }
870
871     return QString();
872 }
873
874 /*!
875     \nonreentrant
876
877     Sets the global default locale to \a locale. These
878     values are used when a QLocale object is constructed with
879     no arguments. If this function is not called, the system's
880     locale is used.
881
882     \warning In a multithreaded application, the default locale
883     should be set at application startup, before any non-GUI threads
884     are created.
885
886     \sa system() c()
887 */
888
889 void QLocale::setDefault(const QLocale &locale)
890 {
891     default_lp = locale.d();
892     default_number_options = locale.numberOptions();
893
894 #ifdef QT_USE_ICU
895     qt_initIcu(locale.bcp47Name());
896 #endif
897 }
898
899 /*!
900     Returns the language of this locale.
901
902     \sa script(), country(), languageToString(), bcp47Name()
903 */
904 QLocale::Language QLocale::language() const
905 {
906     return Language(d()->languageId());
907 }
908
909 /*!
910     \since 4.8
911
912     Returns the script of this locale.
913
914     \sa language(), country(), languageToString(), scriptToString(), bcp47Name()
915 */
916 QLocale::Script QLocale::script() const
917 {
918     return Script(d()->m_script_id);
919 }
920
921 /*!
922     Returns the country of this locale.
923
924     \sa language(), script(), countryToString(), bcp47Name()
925 */
926 QLocale::Country QLocale::country() const
927 {
928     return Country(d()->countryId());
929 }
930
931 /*!
932     Returns the language and country of this locale as a
933     string of the form "language_country", where
934     language is a lowercase, two-letter ISO 639 language code,
935     and country is an uppercase, two- or three-letter ISO 3166 country code.
936
937     Note that even if QLocale object was constructed with an explicit script,
938     name() will not contain it for compatibility reasons. Use bcp47Name() instead
939     if you need a full locale name.
940
941     \sa QLocale(), language(), script(), country(), bcp47Name()
942 */
943
944 QString QLocale::name() const
945 {
946     Language l = language();
947
948     QString result = d()->languageCode();
949
950     if (l == C)
951         return result;
952
953     Country c = country();
954     if (c == AnyCountry)
955         return result;
956
957     result.append(QLatin1Char('_'));
958     result.append(d()->countryCode());
959
960     return result;
961 }
962
963 /*!
964     \since 4.8
965
966     Returns the dash-separated language, script and country (and possibly other BCP47 fields)
967     of this locale as a string.
968
969     Unlike the uiLanguages() the returned value of the bcp47Name() represents
970     the locale name of the QLocale data but not the language the user-interface
971     should be in.
972
973     This function tries to conform the locale name to BCP47.
974
975     \sa language(), country(), script(), uiLanguages()
976 */
977 QString QLocale::bcp47Name() const
978 {
979     return d()->bcp47Name();
980 }
981
982 /*!
983     Returns a QString containing the name of \a language.
984
985     \sa countryToString(), scriptToString(), bcp47Name()
986 */
987
988 QString QLocale::languageToString(Language language)
989 {
990     if (uint(language) > uint(QLocale::LastLanguage))
991         return QLatin1String("Unknown");
992     return QLatin1String(language_name_list + language_name_index[language]);
993 }
994
995 /*!
996     Returns a QString containing the name of \a country.
997
998     \sa languageToString(), scriptToString(), country(), bcp47Name()
999 */
1000
1001 QString QLocale::countryToString(Country country)
1002 {
1003     if (uint(country) > uint(QLocale::LastCountry))
1004         return QLatin1String("Unknown");
1005     return QLatin1String(country_name_list + country_name_index[country]);
1006 }
1007
1008 /*!
1009     \since 4.8
1010
1011     Returns a QString containing the name of \a script.
1012
1013     \sa languageToString(), countryToString(), script(), bcp47Name()
1014 */
1015 QString QLocale::scriptToString(QLocale::Script script)
1016 {
1017     if (uint(script) > uint(QLocale::LastScript))
1018         return QLatin1String("Unknown");
1019     return QLatin1String(script_name_list + script_name_index[script]);
1020 }
1021
1022 /*!
1023     Returns the short int represented by the localized string \a s.
1024
1025     If the conversion fails the function returns 0.
1026
1027     If \a ok is not 0, failure is reported by setting *ok to false, and
1028     success by setting *ok to true.
1029
1030     This function ignores leading and trailing whitespace.
1031
1032     \sa toUShort(), toString()
1033 */
1034
1035 short QLocale::toShort(const QString &s, bool *ok) const
1036 {
1037     qlonglong i = toLongLong(s, ok);
1038     if (i < SHRT_MIN || i > SHRT_MAX) {
1039         if (ok != 0)
1040             *ok = false;
1041         return 0;
1042     }
1043     return short(i);
1044 }
1045
1046 /*!
1047     Returns the unsigned short int represented by the localized string \a s.
1048
1049     If the conversion fails the function returns 0.
1050
1051     If \a ok is not 0, failure is reported by setting *ok to false, and
1052     success by setting *ok to true.
1053
1054     This function ignores leading and trailing whitespace.
1055
1056     \sa toShort(), toString()
1057 */
1058
1059 ushort QLocale::toUShort(const QString &s, bool *ok) const
1060 {
1061     qulonglong i = toULongLong(s, ok);
1062     if (i > USHRT_MAX) {
1063         if (ok != 0)
1064             *ok = false;
1065         return 0;
1066     }
1067     return ushort(i);
1068 }
1069
1070 /*!
1071     Returns the int represented by the localized string \a s.
1072
1073     If the conversion fails the function returns 0.
1074
1075     If \a ok is not 0, failure is reported by setting *ok to false, and
1076     success by setting *ok to true.
1077
1078     This function ignores leading and trailing whitespace.
1079
1080     \sa toUInt(), toString()
1081 */
1082
1083 int QLocale::toInt(const QString &s, bool *ok) const
1084 {
1085     qlonglong i = toLongLong(s, ok);
1086     if (i < INT_MIN || i > INT_MAX) {
1087         if (ok != 0)
1088             *ok = false;
1089         return 0;
1090     }
1091     return int(i);
1092 }
1093
1094 /*!
1095     Returns the unsigned int represented by the localized string \a s.
1096
1097     If the conversion fails the function returns 0.
1098
1099     If \a ok is not 0, failure is reported by setting *ok to false, and
1100     success by setting *ok to true.
1101
1102     This function ignores leading and trailing whitespace.
1103
1104     \sa toInt(), toString()
1105 */
1106
1107 uint QLocale::toUInt(const QString &s, bool *ok) const
1108 {
1109     qulonglong i = toULongLong(s, ok);
1110     if (i > UINT_MAX) {
1111         if (ok != 0)
1112             *ok = false;
1113         return 0;
1114     }
1115     return uint(i);
1116 }
1117
1118 /*!
1119     Returns the long long int represented by the localized string \a s.
1120
1121     If the conversion fails the function returns 0.
1122
1123     If \a ok is not 0, failure is reported by setting *ok to false, and
1124     success by setting *ok to true.
1125
1126     This function ignores leading and trailing whitespace.
1127
1128     \sa toInt(), toULongLong(), toDouble(), toString()
1129 */
1130
1131
1132 qlonglong QLocale::toLongLong(const QString &s, bool *ok) const
1133 {
1134     QLocalePrivate::GroupSeparatorMode mode
1135         = p.numberOptions & RejectGroupSeparator
1136             ? QLocalePrivate::FailOnGroupSeparators
1137             : QLocalePrivate::ParseGroupSeparators;
1138
1139     return d()->stringToLongLong(s, 10, ok, mode);
1140 }
1141
1142 /*!
1143     Returns the unsigned long long int represented by the localized
1144     string \a s.
1145
1146     If the conversion fails the function returns 0.
1147
1148     If \a ok is not 0, failure is reported by setting *ok to false, and
1149     success by setting *ok to true.
1150
1151     This function ignores leading and trailing whitespace.
1152
1153     \sa toLongLong(), toInt(), toDouble(), toString()
1154 */
1155
1156 qulonglong QLocale::toULongLong(const QString &s, bool *ok) const
1157 {
1158     QLocalePrivate::GroupSeparatorMode mode
1159         = p.numberOptions & RejectGroupSeparator
1160             ? QLocalePrivate::FailOnGroupSeparators
1161             : QLocalePrivate::ParseGroupSeparators;
1162
1163     return d()->stringToUnsLongLong(s, 10, ok, mode);
1164 }
1165
1166 /*!
1167     Returns the float represented by the localized string \a s, or 0.0
1168     if the conversion failed.
1169
1170     If \a ok is not 0, reports failure by setting
1171     *ok to false and success by setting *ok to true.
1172
1173     This function ignores leading and trailing whitespace.
1174
1175     \sa toDouble(), toInt(), toString()
1176 */
1177
1178 #define QT_MAX_FLOAT 3.4028234663852886e+38
1179
1180 float QLocale::toFloat(const QString &s, bool *ok) const
1181 {
1182     bool myOk;
1183     double d = toDouble(s, &myOk);
1184     if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
1185         if (ok != 0)
1186             *ok = false;
1187         return 0.0;
1188     }
1189     if (ok != 0)
1190         *ok = true;
1191     return float(d);
1192 }
1193
1194 /*!
1195     Returns the double represented by the localized string \a s, or
1196     0.0 if the conversion failed.
1197
1198     If \a ok is not 0, reports failure by setting
1199     *ok to false and success by setting *ok to true.
1200
1201     Unlike QString::toDouble(), this function does not fall back to
1202     the "C" locale if the string cannot be interpreted in this
1203     locale.
1204
1205     \snippet doc/src/snippets/code/src_corelib_tools_qlocale.cpp 3
1206
1207     Notice that the last conversion returns 1234.0, because '.' is the
1208     thousands group separator in the German locale.
1209
1210     This function ignores leading and trailing whitespace.
1211
1212     \sa toFloat(), toInt(), toString()
1213 */
1214
1215 double QLocale::toDouble(const QString &s, bool *ok) const
1216 {
1217     QLocalePrivate::GroupSeparatorMode mode
1218         = p.numberOptions & RejectGroupSeparator
1219             ? QLocalePrivate::FailOnGroupSeparators
1220             : QLocalePrivate::ParseGroupSeparators;
1221
1222     return d()->stringToDouble(s, ok, mode);
1223 }
1224
1225 /*!
1226     Returns a localized string representation of \a i.
1227
1228     \sa toLongLong()
1229 */
1230
1231 QString QLocale::toString(qlonglong i) const
1232 {
1233     int flags = p.numberOptions & OmitGroupSeparator
1234                     ? 0
1235                     : QLocalePrivate::ThousandsGroup;
1236
1237     return d()->longLongToString(i, -1, 10, -1, flags);
1238 }
1239
1240 /*!
1241     \overload
1242
1243     \sa toULongLong()
1244 */
1245
1246 QString QLocale::toString(qulonglong i) const
1247 {
1248     int flags = p.numberOptions & OmitGroupSeparator
1249                     ? 0
1250                     : QLocalePrivate::ThousandsGroup;
1251
1252     return d()->unsLongLongToString(i, -1, 10, -1, flags);
1253 }
1254
1255 /*!
1256     Returns a localized string representation of the given \a date in the
1257     specified \a format.
1258     If \a format is an empty string, an empty string is returned.
1259 */
1260
1261 QString QLocale::toString(const QDate &date, const QString &format) const
1262 {
1263     return d()->dateTimeToString(format, &date, 0, this);
1264 }
1265
1266 /*!
1267     Returns a localized string representation of the given \a date according
1268     to the specified \a format.
1269 */
1270
1271 QString QLocale::toString(const QDate &date, FormatType format) const
1272 {
1273     if (!date.isValid())
1274         return QString();
1275
1276 #ifndef QT_NO_SYSTEMLOCALE
1277     if (d() == systemPrivate()) {
1278         QVariant res = systemLocale()->query(format == LongFormat
1279                                              ? QSystemLocale::DateToStringLong : QSystemLocale::DateToStringShort,
1280                                              date);
1281         if (!res.isNull())
1282             return res.toString();
1283     }
1284 #endif
1285
1286     QString format_str = dateFormat(format);
1287     return toString(date, format_str);
1288 }
1289
1290 static bool timeFormatContainsAP(const QString &format)
1291 {
1292     int i = 0;
1293     while (i < format.size()) {
1294         if (format.at(i).unicode() == '\'') {
1295             qt_readEscapedFormatString(format, &i);
1296             continue;
1297         }
1298
1299         if (format.at(i).toLower().unicode() == 'a')
1300             return true;
1301
1302         ++i;
1303     }
1304     return false;
1305 }
1306
1307 static QString timeZone()
1308 {
1309 #if defined(Q_OS_WINCE)
1310     TIME_ZONE_INFORMATION info;
1311     DWORD res = GetTimeZoneInformation(&info);
1312     if (res == TIME_ZONE_ID_UNKNOWN)
1313         return QString();
1314     return QString::fromWCharArray(info.StandardName);
1315 #elif defined(Q_OS_WIN)
1316     _tzset();
1317 # if defined(_MSC_VER) && _MSC_VER >= 1400
1318     size_t returnSize = 0;
1319     char timeZoneName[512];
1320     if (_get_tzname(&returnSize, timeZoneName, 512, 1))
1321         return QString();
1322     return QString::fromLocal8Bit(timeZoneName);
1323 # else
1324     return QString::fromLocal8Bit(_tzname[1]);
1325 # endif
1326 #elif defined(Q_OS_VXWORKS)
1327     return QString();
1328 #else
1329     tzset();
1330     return QString::fromLocal8Bit(tzname[1]);
1331 #endif
1332 }
1333
1334 /*!
1335     Returns a localized string representation of the given \a time according
1336     to the specified \a format.
1337     If \a format is an empty string, an empty string is returned.
1338 */
1339 QString QLocale::toString(const QTime &time, const QString &format) const
1340 {
1341     return d()->dateTimeToString(format, 0, &time, this);
1342 }
1343
1344 /*!
1345     \since 4.4
1346
1347     Returns a localized string representation of the given \a dateTime according
1348     to the specified \a format.
1349     If \a format is an empty string, an empty string is returned.
1350 */
1351
1352 QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
1353 {
1354     const QDate dt = dateTime.date();
1355     const QTime tm = dateTime.time();
1356     return d()->dateTimeToString(format, &dt, &tm, this);
1357 }
1358
1359 /*!
1360     \since 4.4
1361
1362     Returns a localized string representation of the given \a dateTime according
1363     to the specified \a format.
1364 */
1365
1366 QString QLocale::toString(const QDateTime &dateTime, FormatType format) const
1367 {
1368     if (!dateTime.isValid())
1369         return QString();
1370
1371 #ifndef QT_NO_SYSTEMLOCALE
1372     if (d() == systemPrivate()) {
1373         QVariant res = systemLocale()->query(format == LongFormat
1374                                              ? QSystemLocale::DateTimeToStringLong
1375                                              : QSystemLocale::DateTimeToStringShort,
1376                                              dateTime);
1377         if (!res.isNull())
1378             return res.toString();
1379     }
1380 #endif
1381
1382     const QString format_str = dateTimeFormat(format);
1383     return toString(dateTime, format_str);
1384 }
1385
1386
1387 /*!
1388     Returns a localized string representation of the given \a time in the
1389     specified \a format.
1390 */
1391
1392 QString QLocale::toString(const QTime &time, FormatType format) const
1393 {
1394     if (!time.isValid())
1395         return QString();
1396
1397 #ifndef QT_NO_SYSTEMLOCALE
1398     if (d() == systemPrivate()) {
1399         QVariant res = systemLocale()->query(format == LongFormat
1400                                              ? QSystemLocale::TimeToStringLong : QSystemLocale::TimeToStringShort,
1401                                              time);
1402         if (!res.isNull())
1403             return res.toString();
1404     }
1405 #endif
1406
1407     QString format_str = timeFormat(format);
1408     return toString(time, format_str);
1409 }
1410
1411 /*!
1412     \since 4.1
1413
1414     Returns the date format used for the current locale.
1415
1416     If \a format is LongFormat the format will be a long version.
1417     Otherwise it uses a shorter version.
1418
1419     \sa QDate::toString(), QDate::fromString()
1420 */
1421
1422 QString QLocale::dateFormat(FormatType format) const
1423 {
1424 #ifndef QT_NO_SYSTEMLOCALE
1425     if (d() == systemPrivate()) {
1426         QVariant res = systemLocale()->query(format == LongFormat
1427                                              ? QSystemLocale::DateFormatLong : QSystemLocale::DateFormatShort,
1428                                              QVariant());
1429         if (!res.isNull())
1430             return res.toString();
1431     }
1432 #endif
1433
1434     quint32 idx, size;
1435     switch (format) {
1436     case LongFormat:
1437         idx = d()->m_long_date_format_idx;
1438         size = d()->m_long_date_format_size;
1439         break;
1440     default:
1441         idx = d()->m_short_date_format_idx;
1442         size = d()->m_short_date_format_size;
1443         break;
1444     }
1445     return getLocaleData(date_format_data + idx, size);
1446 }
1447
1448 /*!
1449     \since 4.1
1450
1451     Returns the time format used for the current locale.
1452
1453     If \a format is LongFormat the format will be a long version.
1454     Otherwise it uses a shorter version.
1455
1456     \sa QTime::toString(), QTime::fromString()
1457 */
1458
1459 QString QLocale::timeFormat(FormatType format) const
1460 {
1461 #ifndef QT_NO_SYSTEMLOCALE
1462     if (d() == systemPrivate()) {
1463         QVariant res = systemLocale()->query(format == LongFormat
1464                                              ? QSystemLocale::TimeFormatLong : QSystemLocale::TimeFormatShort,
1465                                              QVariant());
1466         if (!res.isNull())
1467             return res.toString();
1468     }
1469 #endif
1470
1471     quint32 idx, size;
1472     switch (format) {
1473     case LongFormat:
1474         idx = d()->m_long_time_format_idx;
1475         size = d()->m_long_time_format_size;
1476         break;
1477     default:
1478         idx = d()->m_short_time_format_idx;
1479         size = d()->m_short_time_format_size;
1480         break;
1481     }
1482     return getLocaleData(time_format_data + idx, size);
1483 }
1484
1485 /*!
1486     \since 4.4
1487
1488     Returns the date time format used for the current locale.
1489
1490     If \a format is ShortFormat the format will be a short version.
1491     Otherwise it uses a longer version.
1492
1493     \sa QDateTime::toString(), QDateTime::fromString()
1494 */
1495
1496 QString QLocale::dateTimeFormat(FormatType format) const
1497 {
1498 #ifndef QT_NO_SYSTEMLOCALE
1499     if (d() == systemPrivate()) {
1500         QVariant res = systemLocale()->query(format == LongFormat
1501                                              ? QSystemLocale::DateTimeFormatLong
1502                                              : QSystemLocale::DateTimeFormatShort,
1503                                              QVariant());
1504         if (!res.isNull()) {
1505             return res.toString();
1506         }
1507     }
1508 #endif
1509     return dateFormat(format) + QLatin1Char(' ') + timeFormat(format);
1510 }
1511
1512 /*!
1513     \since 4.4
1514
1515     Parses the time string given in \a string and returns the
1516     time. The format of the time string is chosen according to the
1517     \a format parameter (see timeFormat()).
1518
1519     If the time could not be parsed, returns an invalid time.
1520
1521     \sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
1522 */
1523 #ifndef QT_NO_DATESTRING
1524 QTime QLocale::toTime(const QString &string, FormatType format) const
1525 {
1526     return toTime(string, timeFormat(format));
1527 }
1528 #endif
1529
1530 /*!
1531     \since 4.4
1532
1533     Parses the date string given in \a string and returns the
1534     date. The format of the date string is chosen according to the
1535     \a format parameter (see dateFormat()).
1536
1537     If the date could not be parsed, returns an invalid date.
1538
1539     \sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
1540 */
1541 #ifndef QT_NO_DATESTRING
1542 QDate QLocale::toDate(const QString &string, FormatType format) const
1543 {
1544     return toDate(string, dateFormat(format));
1545 }
1546 #endif
1547
1548 /*!
1549     \since 4.4
1550
1551     Parses the date/time string given in \a string and returns the
1552     time. The format of the date/time string is chosen according to the
1553     \a format parameter (see dateTimeFormat()).
1554
1555     If the string could not be parsed, returns an invalid QDateTime.
1556
1557     \sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
1558 */
1559
1560 #ifndef QT_NO_DATESTRING
1561 QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
1562 {
1563     return toDateTime(string, dateTimeFormat(format));
1564 }
1565 #endif
1566
1567 /*!
1568     \since 4.4
1569
1570     Parses the time string given in \a string and returns the
1571     time. See QTime::fromString() for information on what is a valid
1572     format string.
1573
1574     If the time could not be parsed, returns an invalid time.
1575
1576     \sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
1577 */
1578 #ifndef QT_NO_DATESTRING
1579 QTime QLocale::toTime(const QString &string, const QString &format) const
1580 {
1581     QTime time;
1582 #ifndef QT_BOOTSTRAPPED
1583     QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
1584     dt.defaultLocale = *this;
1585     if (dt.parseFormat(format))
1586         dt.fromString(string, 0, &time);
1587 #else
1588     Q_UNUSED(string);
1589     Q_UNUSED(format);
1590 #endif
1591     return time;
1592 }
1593 #endif
1594
1595 /*!
1596     \since 4.4
1597
1598     Parses the date string given in \a string and returns the
1599     date. See QDate::fromString() for information on the expressions
1600     that can be used with this function.
1601
1602     This function searches month names and the names of the days of
1603     the week in the current locale.
1604
1605     If the date could not be parsed, returns an invalid date.
1606
1607     \sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
1608 */
1609 #ifndef QT_NO_DATESTRING
1610 QDate QLocale::toDate(const QString &string, const QString &format) const
1611 {
1612     QDate date;
1613 #ifndef QT_BOOTSTRAPPED
1614     QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
1615     dt.defaultLocale = *this;
1616     if (dt.parseFormat(format))
1617         dt.fromString(string, &date, 0);
1618 #else
1619     Q_UNUSED(string);
1620     Q_UNUSED(format);
1621 #endif
1622     return date;
1623 }
1624 #endif
1625
1626 /*!
1627     \since 4.4
1628
1629     Parses the date/time string given in \a string and returns the
1630     time.  See QDateTime::fromString() for information on the expressions
1631     that can be used with this function.
1632
1633     \note The month and day names used must be given in the user's local
1634     language.
1635
1636     If the string could not be parsed, returns an invalid QDateTime.
1637
1638     \sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
1639 */
1640 #ifndef QT_NO_DATESTRING
1641 QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
1642 {
1643 #ifndef QT_BOOTSTRAPPED
1644     QTime time;
1645     QDate date;
1646
1647     QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
1648     dt.defaultLocale = *this;
1649     if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
1650         return QDateTime(date, time);
1651 #else
1652     Q_UNUSED(string);
1653     Q_UNUSED(format);
1654 #endif
1655     return QDateTime(QDate(), QTime(-1, -1, -1));
1656 }
1657 #endif
1658
1659
1660 /*!
1661     \since 4.1
1662
1663     Returns the decimal point character of this locale.
1664 */
1665 QChar QLocale::decimalPoint() const
1666 {
1667     return d()->decimal();
1668 }
1669
1670 /*!
1671     \since 4.1
1672
1673     Returns the group separator character of this locale.
1674 */
1675 QChar QLocale::groupSeparator() const
1676 {
1677     return d()->group();
1678 }
1679
1680 /*!
1681     \since 4.1
1682
1683     Returns the percent character of this locale.
1684 */
1685 QChar QLocale::percent() const
1686 {
1687     return d()->percent();
1688 }
1689
1690 /*!
1691     \since 4.1
1692
1693     Returns the zero digit character of this locale.
1694 */
1695 QChar QLocale::zeroDigit() const
1696 {
1697     return d()->zero();
1698 }
1699
1700 /*!
1701     \since 4.1
1702
1703     Returns the negative sign character of this locale.
1704 */
1705 QChar QLocale::negativeSign() const
1706 {
1707     return d()->minus();
1708 }
1709
1710 /*!
1711     \since 4.5
1712
1713     Returns the positive sign character of this locale.
1714 */
1715 QChar QLocale::positiveSign() const
1716 {
1717     return d()->plus();
1718 }
1719
1720 /*!
1721     \since 4.1
1722
1723     Returns the exponential character of this locale.
1724 */
1725 QChar QLocale::exponential() const
1726 {
1727     return d()->exponential();
1728 }
1729
1730 static bool qIsUpper(char c)
1731 {
1732     return c >= 'A' && c <= 'Z';
1733 }
1734
1735 static char qToLower(char c)
1736 {
1737     if (c >= 'A' && c <= 'Z')
1738         return c - 'A' + 'a';
1739     else
1740         return c;
1741 }
1742
1743 /*!
1744     \overload
1745
1746     \a f and \a prec have the same meaning as in QString::number(double, char, int).
1747
1748     \sa toDouble()
1749 */
1750
1751 QString QLocale::toString(double i, char f, int prec) const
1752 {
1753     QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
1754     uint flags = 0;
1755
1756     if (qIsUpper(f))
1757         flags = QLocalePrivate::CapitalEorX;
1758     f = qToLower(f);
1759
1760     switch (f) {
1761         case 'f':
1762             form = QLocalePrivate::DFDecimal;
1763             break;
1764         case 'e':
1765             form = QLocalePrivate::DFExponent;
1766             break;
1767         case 'g':
1768             form = QLocalePrivate::DFSignificantDigits;
1769             break;
1770         default:
1771             break;
1772     }
1773
1774     if (!(p.numberOptions & OmitGroupSeparator))
1775         flags |= QLocalePrivate::ThousandsGroup;
1776     return d()->doubleToString(i, prec, form, -1, flags);
1777 }
1778
1779 /*!
1780     \fn QLocale QLocale::c()
1781
1782     Returns a QLocale object initialized to the "C" locale.
1783
1784     \sa system()
1785 */
1786
1787 /*!
1788     Returns a QLocale object initialized to the system locale.
1789
1790     On Windows and Mac, this locale will use the decimal/grouping characters and date/time
1791     formats specified in the system configuration panel.
1792
1793     \sa c()
1794 */
1795
1796 QLocale QLocale::system()
1797 {
1798     QLocale result(C);
1799     result.p.index = localePrivateIndex(systemPrivate());
1800     return result;
1801 }
1802
1803
1804 /*!
1805     \since 4.8
1806
1807     Returns a list of valid locale objects that match the given \a language, \a
1808     script and \a country.
1809
1810     Getting a list of all locales:
1811     QList<QLocale> allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
1812 */
1813 QList<QLocale> QLocale::matchingLocales(QLocale::Language language,
1814                                         QLocale::Script script,
1815                                         QLocale::Country country)
1816 {
1817     if (uint(language) > QLocale::LastLanguage || uint(script) > QLocale::LastScript ||
1818             uint(country) > QLocale::LastCountry)
1819         return QList<QLocale>();
1820
1821     QList<QLocale> result;
1822     const QLocalePrivate *d = locale_data;
1823     if (language == QLocale::AnyLanguage && script == QLocale::AnyScript && country == QLocale::AnyCountry)
1824         result.reserve(locale_data_size);
1825     if (language != QLocale::C)
1826         d += locale_index[language];
1827     while ( (d != locale_data + locale_data_size)
1828             && (language == QLocale::AnyLanguage || d->m_language_id == uint(language))) {
1829         QLocale locale(QLocale::C);
1830         locale.p.index = localePrivateIndex(d);
1831         result.append(locale);
1832         ++d;
1833     }
1834     return result;
1835 }
1836
1837 /*!
1838     \obsolete
1839     \since 4.3
1840
1841     Returns the list of countries that have entires for \a language in Qt's locale
1842     database. If the result is an empty list, then \a language is not represented in
1843     Qt's locale database.
1844
1845     \sa matchingLocales()
1846 */
1847 QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
1848 {
1849     QList<Country> result;
1850
1851     unsigned language_id = language;
1852     uint idx = locale_index[language_id];
1853
1854     if (language == C) {
1855         result << AnyCountry;
1856         return result;
1857     }
1858
1859     const QLocalePrivate *d = locale_data + idx;
1860
1861     while (d->languageId() == language_id) {
1862         result << static_cast<Country>(d->countryId());
1863         ++d;
1864     }
1865
1866     return result;
1867 }
1868
1869 /*!
1870     \since 4.2
1871
1872     Returns the localized name of \a month, in the format specified
1873     by \a type.
1874
1875     \sa dayName(), standaloneMonthName()
1876 */
1877 QString QLocale::monthName(int month, FormatType type) const
1878 {
1879     if (month < 1 || month > 12)
1880         return QString();
1881
1882 #ifndef QT_NO_SYSTEMLOCALE
1883     if (d() == systemPrivate()) {
1884         QVariant res = systemLocale()->query(type == LongFormat
1885                                              ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
1886                                              month);
1887         if (!res.isNull())
1888             return res.toString();
1889     }
1890 #endif
1891
1892     quint32 idx, size;
1893     switch (type) {
1894     case QLocale::LongFormat:
1895         idx = d()->m_long_month_names_idx;
1896         size = d()->m_long_month_names_size;
1897         break;
1898     case QLocale::ShortFormat:
1899         idx = d()->m_short_month_names_idx;
1900         size = d()->m_short_month_names_size;
1901         break;
1902     case QLocale::NarrowFormat:
1903         idx = d()->m_narrow_month_names_idx;
1904         size = d()->m_narrow_month_names_size;
1905         break;
1906     default:
1907         return QString();
1908     }
1909     return getLocaleListData(months_data + idx, size, month - 1);
1910 }
1911
1912 /*!
1913     \since 4.5
1914
1915     Returns the localized name of \a month that is used as a
1916     standalone text, in the format specified by \a type.
1917
1918     If the locale information doesn't specify the standalone month
1919     name then return value is the same as in monthName().
1920
1921     \sa monthName(), standaloneDayName()
1922 */
1923 QString QLocale::standaloneMonthName(int month, FormatType type) const
1924 {
1925     if (month < 1 || month > 12)
1926         return QString();
1927
1928 #ifndef QT_NO_SYSTEMLOCALE
1929     if (d() == systemPrivate()) {
1930         QVariant res = systemLocale()->query(type == LongFormat
1931                                              ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
1932                                              month);
1933         if (!res.isNull())
1934             return res.toString();
1935     }
1936 #endif
1937
1938     quint32 idx, size;
1939     switch (type) {
1940     case QLocale::LongFormat:
1941         idx = d()->m_standalone_long_month_names_idx;
1942         size = d()->m_standalone_long_month_names_size;
1943         break;
1944     case QLocale::ShortFormat:
1945         idx = d()->m_standalone_short_month_names_idx;
1946         size = d()->m_standalone_short_month_names_size;
1947         break;
1948     case QLocale::NarrowFormat:
1949         idx = d()->m_standalone_narrow_month_names_idx;
1950         size = d()->m_standalone_narrow_month_names_size;
1951         break;
1952     default:
1953         return QString();
1954     }
1955     QString name = getLocaleListData(months_data + idx, size, month - 1);
1956     if (name.isEmpty())
1957         return monthName(month, type);
1958     return name;
1959 }
1960
1961 /*!
1962     \since 4.2
1963
1964     Returns the localized name of the \a day (where 1 represents
1965     Monday, 2 represents Tuesday and so on), in the format specified
1966     by \a type.
1967
1968     \sa monthName(), standaloneDayName()
1969 */
1970 QString QLocale::dayName(int day, FormatType type) const
1971 {
1972     if (day < 1 || day > 7)
1973         return QString();
1974
1975 #ifndef QT_NO_SYSTEMLOCALE
1976     if (d() == systemPrivate()) {
1977         QVariant res = systemLocale()->query(type == LongFormat
1978                                              ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
1979                                              day);
1980         if (!res.isNull())
1981             return res.toString();
1982     }
1983 #endif
1984     if (day == 7)
1985         day = 0;
1986
1987     quint32 idx, size;
1988     switch (type) {
1989     case QLocale::LongFormat:
1990         idx = d()->m_long_day_names_idx;
1991         size = d()->m_long_day_names_size;
1992         break;
1993     case QLocale::ShortFormat:
1994         idx = d()->m_short_day_names_idx;
1995         size = d()->m_short_day_names_size;
1996         break;
1997     case QLocale::NarrowFormat:
1998         idx = d()->m_narrow_day_names_idx;
1999         size = d()->m_narrow_day_names_size;
2000         break;
2001     default:
2002         return QString();
2003     }
2004     return getLocaleListData(days_data + idx, size, day);
2005 }
2006
2007 /*!
2008     \since 4.5
2009
2010     Returns the localized name of the \a day (where 1 represents
2011     Monday, 2 represents Tuesday and so on) that is used as a
2012     standalone text, in the format specified by \a type.
2013
2014     If the locale information does not specify the standalone day
2015     name then return value is the same as in dayName().
2016
2017     \sa dayName(), standaloneMonthName()
2018 */
2019 QString QLocale::standaloneDayName(int day, FormatType type) const
2020 {
2021     if (day < 1 || day > 7)
2022         return QString();
2023
2024 #ifndef QT_NO_SYSTEMLOCALE
2025     if (d() == systemPrivate()) {
2026         QVariant res = systemLocale()->query(type == LongFormat
2027                                              ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
2028                                              day);
2029         if (!res.isNull())
2030             return res.toString();
2031     }
2032 #endif
2033     if (day == 7)
2034         day = 0;
2035
2036     quint32 idx, size;
2037     switch (type) {
2038     case QLocale::LongFormat:
2039         idx = d()->m_standalone_long_day_names_idx;
2040         size = d()->m_standalone_long_day_names_size;
2041         break;
2042     case QLocale::ShortFormat:
2043         idx = d()->m_standalone_short_day_names_idx;
2044         size = d()->m_standalone_short_day_names_size;
2045         break;
2046     case QLocale::NarrowFormat:
2047         idx = d()->m_standalone_narrow_day_names_idx;
2048         size = d()->m_standalone_narrow_day_names_size;
2049         break;
2050     default:
2051         return QString();
2052     }
2053     QString name = getLocaleListData(days_data + idx, size, day);
2054     if (name.isEmpty())
2055         return dayName(day == 0 ? 7 : day, type);
2056     return name;
2057 }
2058
2059 /*!
2060     \since 4.8
2061
2062     Returns the first day of the week according to the current locale.
2063 */
2064 Qt::DayOfWeek QLocale::firstDayOfWeek() const
2065 {
2066 #ifndef QT_NO_SYSTEMLOCALE
2067     if (d() == systemPrivate()) {
2068         QVariant res = systemLocale()->query(QSystemLocale::FirstDayOfWeek, QVariant());
2069         if (!res.isNull())
2070             return static_cast<Qt::DayOfWeek>(res.toUInt());
2071     }
2072 #endif
2073     return static_cast<Qt::DayOfWeek>(d()->m_first_day_of_week);
2074 }
2075
2076 QLocale::MeasurementSystem QLocalePrivate::measurementSystem() const
2077 {
2078     for (int i = 0; i < ImperialMeasurementSystemsCount; ++i) {
2079         if (ImperialMeasurementSystems[i].languageId == m_language_id
2080             && ImperialMeasurementSystems[i].countryId == m_country_id) {
2081             return ImperialMeasurementSystems[i].system;
2082         }
2083     }
2084     return QLocale::MetricSystem;
2085 }
2086
2087 /*!
2088     \since 4.8
2089
2090     Returns a list of days that are considered weekdays according to the current locale.
2091 */
2092 QList<Qt::DayOfWeek> QLocale::weekdays() const
2093 {
2094 #ifndef QT_NO_SYSTEMLOCALE
2095     if (d() == systemPrivate()) {
2096         QVariant res = systemLocale()->query(QSystemLocale::Weekdays, QVariant());
2097         if (!res.isNull())
2098             return static_cast<QList<Qt::DayOfWeek> >(res.value<QList<Qt::DayOfWeek> >());
2099     }
2100 #endif
2101     QList<Qt::DayOfWeek> weekdays;
2102     quint16 weekendStart = d()->m_weekend_start;
2103     quint16 weekendEnd = d()->m_weekend_end;
2104     for (int day = Qt::Monday; day <= Qt::Sunday; day++) {
2105         if ((weekendEnd >= weekendStart && (day < weekendStart || day > weekendEnd)) ||
2106             (weekendEnd < weekendStart && (day > weekendEnd && day < weekendStart)))
2107                 weekdays << static_cast<Qt::DayOfWeek>(day);
2108     }
2109     return weekdays;
2110 }
2111
2112 /*!
2113     \since 4.4
2114
2115     Returns the measurement system for the locale.
2116 */
2117 QLocale::MeasurementSystem QLocale::measurementSystem() const
2118 {
2119 #ifndef QT_NO_SYSTEMLOCALE
2120     if (d() == systemPrivate()) {
2121         QVariant res = systemLocale()->query(QSystemLocale::MeasurementSystem, QVariant());
2122         if (!res.isNull())
2123             return MeasurementSystem(res.toInt());
2124     }
2125 #endif
2126
2127     return d()->measurementSystem();
2128 }
2129
2130 /*!
2131   \since 4.7
2132
2133   Returns the text direction of the language.
2134 */
2135 Qt::LayoutDirection QLocale::textDirection() const
2136 {
2137     Language lang = language();
2138     if (lang == QLocale::Arabic ||
2139         lang == QLocale::Hebrew ||
2140         lang == QLocale::Persian ||
2141         lang == QLocale::Urdu ||
2142         lang == QLocale::Syriac)
2143         return Qt::RightToLeft;
2144
2145     return Qt::LeftToRight;
2146 }
2147
2148 /*!
2149   \since 4.8
2150
2151   Returns an uppercase copy of \a str.
2152 */
2153 QString QLocale::toUpper(const QString &str) const
2154 {
2155 #ifdef QT_USE_ICU
2156     {
2157         QString result;
2158         if (qt_u_strToUpper(str, &result, *this))
2159             return result;
2160         // else fall through and use Qt's toUpper
2161     }
2162 #endif
2163     return str.toUpper();
2164 }
2165
2166 /*!
2167   \since 4.8
2168
2169   Returns a lowercase copy of \a str.
2170 */
2171 QString QLocale::toLower(const QString &str) const
2172 {
2173 #ifdef QT_USE_ICU
2174     {
2175         QString result;
2176         if (qt_u_strToLower(str, &result, *this))
2177             return result;
2178         // else fall through and use Qt's toUpper
2179     }
2180 #endif
2181     return str.toLower();
2182 }
2183
2184
2185 /*!
2186     \since 4.5
2187
2188     Returns the localized name of the "AM" suffix for times specified using
2189     the conventions of the 12-hour clock.
2190
2191     \sa pmText()
2192 */
2193 QString QLocale::amText() const
2194 {
2195 #ifndef QT_NO_SYSTEMLOCALE
2196     if (d() == systemPrivate()) {
2197         QVariant res = systemLocale()->query(QSystemLocale::AMText, QVariant());
2198         if (!res.isNull())
2199             return res.toString();
2200     }
2201 #endif
2202     return getLocaleData(am_data + d()->m_am_idx, d()->m_am_size);
2203 }
2204
2205 /*!
2206     \since 4.5
2207
2208     Returns the localized name of the "PM" suffix for times specified using
2209     the conventions of the 12-hour clock.
2210
2211     \sa amText()
2212 */
2213 QString QLocale::pmText() const
2214 {
2215 #ifndef QT_NO_SYSTEMLOCALE
2216     if (d() == systemPrivate()) {
2217         QVariant res = systemLocale()->query(QSystemLocale::PMText, QVariant());
2218         if (!res.isNull())
2219             return res.toString();
2220     }
2221 #endif
2222     return getLocaleData(pm_data + d()->m_pm_idx, d()->m_pm_size);
2223 }
2224
2225
2226 QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *date, const QTime *time,
2227                                          const QLocale *q) const
2228 {
2229     Q_ASSERT(date || time);
2230     if ((date && !date->isValid()) || (time && !time->isValid()))
2231         return QString();
2232     const bool format_am_pm = time && timeFormatContainsAP(format);
2233
2234     enum { AM, PM } am_pm = AM;
2235     int hour12 = time ? time->hour() : -1;
2236     if (time) {
2237         if (hour12 == 0) {
2238             am_pm = AM;
2239             hour12 = 12;
2240         } else if (hour12 < 12) {
2241             am_pm = AM;
2242         } else if (hour12 == 12) {
2243             am_pm = PM;
2244         } else {
2245             am_pm = PM;
2246             hour12 -= 12;
2247         }
2248     }
2249
2250     QString result;
2251
2252     int i = 0;
2253     while (i < format.size()) {
2254         if (format.at(i).unicode() == '\'') {
2255             result.append(qt_readEscapedFormatString(format, &i));
2256             continue;
2257         }
2258
2259         const QChar c = format.at(i);
2260         int repeat = qt_repeatCount(format, i);
2261         bool used = false;
2262         if (date) {
2263             switch (c.unicode()) {
2264             case 'y':
2265                 used = true;
2266                 if (repeat >= 4)
2267                     repeat = 4;
2268                 else if (repeat >= 2)
2269                     repeat = 2;
2270
2271                 switch (repeat) {
2272                 case 4:
2273                     result.append(longLongToString(date->year()));
2274                     break;
2275                 case 2:
2276                     result.append(longLongToString(date->year() % 100, -1, 10, 2,
2277                                                    QLocalePrivate::ZeroPadded));
2278                     break;
2279                 default:
2280                     repeat = 1;
2281                     result.append(c);
2282                     break;
2283                 }
2284                 break;
2285
2286             case 'M':
2287                 used = true;
2288                 repeat = qMin(repeat, 4);
2289                 switch (repeat) {
2290                 case 1:
2291                     result.append(longLongToString(date->month()));
2292                     break;
2293                 case 2:
2294                     result.append(longLongToString(date->month(), -1, 10, 2, QLocalePrivate::ZeroPadded));
2295                     break;
2296                 case 3:
2297                     result.append(q->monthName(date->month(), QLocale::ShortFormat));
2298                     break;
2299                 case 4:
2300                     result.append(q->monthName(date->month(), QLocale::LongFormat));
2301                     break;
2302                 }
2303                 break;
2304
2305             case 'd':
2306                 used = true;
2307                 repeat = qMin(repeat, 4);
2308                 switch (repeat) {
2309                 case 1:
2310                     result.append(longLongToString(date->day()));
2311                     break;
2312                 case 2:
2313                     result.append(longLongToString(date->day(), -1, 10, 2, QLocalePrivate::ZeroPadded));
2314                     break;
2315                 case 3:
2316                     result.append(q->dayName(date->dayOfWeek(), QLocale::ShortFormat));
2317                     break;
2318                 case 4:
2319                     result.append(q->dayName(date->dayOfWeek(), QLocale::LongFormat));
2320                     break;
2321                 }
2322                 break;
2323
2324             default:
2325                 break;
2326             }
2327         }
2328         if (!used && time) {
2329             switch (c.unicode()) {
2330             case 'h': {
2331                 used = true;
2332                 repeat = qMin(repeat, 2);
2333                 const int hour = format_am_pm ? hour12 : time->hour();
2334
2335                 switch (repeat) {
2336                 case 1:
2337                     result.append(longLongToString(hour));
2338                     break;
2339                 case 2:
2340                     result.append(longLongToString(hour, -1, 10, 2, QLocalePrivate::ZeroPadded));
2341                     break;
2342                 }
2343                 break;
2344             }
2345             case 'H':
2346                 used = true;
2347                 repeat = qMin(repeat, 2);
2348                 switch (repeat) {
2349                 case 1:
2350                     result.append(longLongToString(time->hour()));
2351                     break;
2352                 case 2:
2353                     result.append(longLongToString(time->hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
2354                     break;
2355                 }
2356                 break;
2357
2358             case 'm':
2359                 used = true;
2360                 repeat = qMin(repeat, 2);
2361                 switch (repeat) {
2362                 case 1:
2363                     result.append(longLongToString(time->minute()));
2364                     break;
2365                 case 2:
2366                     result.append(longLongToString(time->minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
2367                     break;
2368                 }
2369                 break;
2370
2371             case 's':
2372                 used = true;
2373                 repeat = qMin(repeat, 2);
2374                 switch (repeat) {
2375                 case 1:
2376                     result.append(longLongToString(time->second()));
2377                     break;
2378                 case 2:
2379                     result.append(longLongToString(time->second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
2380                     break;
2381                 }
2382                 break;
2383
2384             case 'a':
2385                 used = true;
2386                 if (i + 1 < format.length() && format.at(i + 1).unicode() == 'p') {
2387                     repeat = 2;
2388                 } else {
2389                     repeat = 1;
2390                 }
2391                 result.append(am_pm == AM ? q->amText().toLower() : q->pmText().toLower());
2392                 break;
2393
2394             case 'A':
2395                 used = true;
2396                 if (i + 1 < format.length() && format.at(i + 1).unicode() == 'P') {
2397                     repeat = 2;
2398                 } else {
2399                     repeat = 1;
2400                 }
2401                 result.append(am_pm == AM ? q->amText().toUpper() : q->pmText().toUpper());
2402                 break;
2403
2404             case 'z':
2405                 used = true;
2406                 if (repeat >= 3) {
2407                     repeat = 3;
2408                 } else {
2409                     repeat = 1;
2410                 }
2411                 switch (repeat) {
2412                 case 1:
2413                     result.append(longLongToString(time->msec()));
2414                     break;
2415                 case 3:
2416                     result.append(longLongToString(time->msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
2417                     break;
2418                 }
2419                 break;
2420
2421             case 't':
2422                 used = true;
2423                 repeat = 1;
2424                 result.append(timeZone());
2425                 break;
2426             default:
2427                 break;
2428             }
2429         }
2430         if (!used) {
2431             result.append(QString(repeat, c));
2432         }
2433         i += repeat;
2434     }
2435
2436     return result;
2437 }
2438
2439 QString QLocalePrivate::doubleToString(double d,
2440                                        int precision,
2441                                        DoubleForm form,
2442                                        int width,
2443                                        unsigned flags) const
2444 {
2445     return QLocalePrivate::doubleToString(zero(), plus(), minus(), exponential(),
2446                                           group(), decimal(),
2447                                           d, precision, form, width, flags);
2448 }
2449
2450 QString QLocalePrivate::doubleToString(const QChar _zero, const QChar plus, const QChar minus,
2451                                        const QChar exponential, const QChar group, const QChar decimal,
2452                                        double d,
2453                                        int precision,
2454                                        DoubleForm form,
2455                                        int width,
2456                                        unsigned flags)
2457 {
2458     if (precision == -1)
2459         precision = 6;
2460     if (width == -1)
2461         width = 0;
2462
2463     bool negative = false;
2464     bool special_number = false; // nan, +/-inf
2465     QString num_str;
2466
2467     // Detect special numbers (nan, +/-inf)
2468     if (qt_is_inf(d)) {
2469         num_str = QString::fromLatin1("inf");
2470         special_number = true;
2471         negative = d < 0;
2472     } else if (qt_is_nan(d)) {
2473         num_str = QString::fromLatin1("nan");
2474         special_number = true;
2475     }
2476
2477     // Handle normal numbers
2478     if (!special_number) {
2479         int decpt, sign;
2480         QString digits;
2481
2482 #ifdef QT_QLOCALE_USES_FCVT
2483         // NOT thread safe!
2484         if (form == DFDecimal) {
2485             digits = QLatin1String(fcvt(d, precision, &decpt, &sign));
2486         } else {
2487             int pr = precision;
2488             if (form == DFExponent)
2489                 ++pr;
2490             else if (form == DFSignificantDigits && pr == 0)
2491                 pr = 1;
2492             digits = QLatin1String(ecvt(d, pr, &decpt, &sign));
2493
2494             // Chop trailing zeros
2495             if (digits.length() > 0) {
2496                 int last_nonzero_idx = digits.length() - 1;
2497                 while (last_nonzero_idx > 0
2498                        && digits.unicode()[last_nonzero_idx] == QLatin1Char('0'))
2499                     --last_nonzero_idx;
2500                 digits.truncate(last_nonzero_idx + 1);
2501             }
2502
2503         }
2504
2505 #else
2506         int mode;
2507         if (form == DFDecimal)
2508             mode = 3;
2509         else
2510             mode = 2;
2511
2512         /* This next bit is a bit quirky. In DFExponent form, the precision
2513            is the number of digits after decpt. So that would suggest using
2514            mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and
2515            precision=0. So we get around this by using mode=2 and reasoning
2516            that we want precision+1 significant digits, since the decimal
2517            point in this mode is always after the first digit. */
2518         int pr = precision;
2519         if (form == DFExponent)
2520             ++pr;
2521
2522         char *rve = 0;
2523         char *buff = 0;
2524         QT_TRY {
2525             digits = QLatin1String(qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff));
2526         } QT_CATCH(...) {
2527             if (buff != 0)
2528                 free(buff);
2529             QT_RETHROW;
2530         }
2531         if (buff != 0)
2532             free(buff);
2533 #endif // QT_QLOCALE_USES_FCVT
2534
2535         if (_zero.unicode() != '0') {
2536             ushort z = _zero.unicode() - '0';
2537             for (int i = 0; i < digits.length(); ++i)
2538                 reinterpret_cast<ushort *>(digits.data())[i] += z;
2539         }
2540
2541         bool always_show_decpt = (flags & Alternate || flags & ForcePoint);
2542         switch (form) {
2543             case DFExponent: {
2544                 num_str = exponentForm(_zero, decimal, exponential, group, plus, minus,
2545                                        digits, decpt, precision, PMDecimalDigits,
2546                                        always_show_decpt);
2547                 break;
2548             }
2549             case DFDecimal: {
2550                 num_str = decimalForm(_zero, decimal, group,
2551                                       digits, decpt, precision, PMDecimalDigits,
2552                                       always_show_decpt, flags & ThousandsGroup);
2553                 break;
2554             }
2555             case DFSignificantDigits: {
2556                 PrecisionMode mode = (flags & Alternate) ?
2557                             PMSignificantDigits : PMChopTrailingZeros;
2558
2559                 if (decpt != digits.length() && (decpt <= -4 || decpt > precision))
2560                     num_str = exponentForm(_zero, decimal, exponential, group, plus, minus,
2561                                            digits, decpt, precision, mode,
2562                                            always_show_decpt);
2563                 else
2564                     num_str = decimalForm(_zero, decimal, group,
2565                                           digits, decpt, precision, mode,
2566                                           always_show_decpt, flags & ThousandsGroup);
2567                 break;
2568             }
2569         }
2570
2571         negative = sign != 0 && !isZero(d);
2572     }
2573
2574     // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
2575     // pad special numbers
2576     if (flags & QLocalePrivate::ZeroPadded
2577             && !(flags & QLocalePrivate::LeftAdjusted)
2578             && !special_number) {
2579         int num_pad_chars = width - num_str.length();
2580         // leave space for the sign
2581         if (negative
2582                 || flags & QLocalePrivate::AlwaysShowSign
2583                 || flags & QLocalePrivate::BlankBeforePositive)
2584             --num_pad_chars;
2585
2586         for (int i = 0; i < num_pad_chars; ++i)
2587             num_str.prepend(_zero);
2588     }
2589
2590     // add sign
2591     if (negative)
2592         num_str.prepend(minus);
2593     else if (flags & QLocalePrivate::AlwaysShowSign)
2594         num_str.prepend(plus);
2595     else if (flags & QLocalePrivate::BlankBeforePositive)
2596         num_str.prepend(QLatin1Char(' '));
2597
2598     if (flags & QLocalePrivate::CapitalEorX)
2599         num_str = num_str.toUpper();
2600
2601     return num_str;
2602 }
2603
2604 QString QLocalePrivate::longLongToString(qlonglong l, int precision,
2605                                             int base, int width,
2606                                             unsigned flags) const
2607 {
2608     return QLocalePrivate::longLongToString(zero(), group(), plus(), minus(),
2609                                             l, precision, base, width, flags);
2610 }
2611
2612 QString QLocalePrivate::longLongToString(const QChar zero, const QChar group,
2613                                          const QChar plus, const QChar minus,
2614                                          qlonglong l, int precision,
2615                                          int base, int width,
2616                                          unsigned flags)
2617 {
2618     bool precision_not_specified = false;
2619     if (precision == -1) {
2620         precision_not_specified = true;
2621         precision = 1;
2622     }
2623
2624     bool negative = l < 0;
2625     if (base != 10) {
2626         // these are not supported by sprintf for octal and hex
2627         flags &= ~AlwaysShowSign;
2628         flags &= ~BlankBeforePositive;
2629         negative = false; // neither are negative numbers
2630     }
2631
2632     QString num_str;
2633     if (base == 10)
2634         num_str = qlltoa(l, base, zero);
2635     else
2636         num_str = qulltoa(l, base, zero);
2637
2638     uint cnt_thousand_sep = 0;
2639     if (flags & ThousandsGroup && base == 10) {
2640         for (int i = num_str.length() - 3; i > 0; i -= 3) {
2641             num_str.insert(i, group);
2642             ++cnt_thousand_sep;
2643         }
2644     }
2645
2646     for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
2647         num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
2648
2649     if ((flags & Alternate || flags & ShowBase)
2650             && base == 8
2651             && (num_str.isEmpty() || num_str[0].unicode() != QLatin1Char('0')))
2652         num_str.prepend(QLatin1Char('0'));
2653
2654     // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
2655     // when precision is not specified in the format string
2656     bool zero_padded = flags & ZeroPadded
2657                         && !(flags & LeftAdjusted)
2658                         && precision_not_specified;
2659
2660     if (zero_padded) {
2661         int num_pad_chars = width - num_str.length();
2662
2663         // leave space for the sign
2664         if (negative
2665                 || flags & AlwaysShowSign
2666                 || flags & BlankBeforePositive)
2667             --num_pad_chars;
2668
2669         // leave space for optional '0x' in hex form
2670         if (base == 16 && (flags & Alternate || flags & ShowBase))
2671             num_pad_chars -= 2;
2672         // leave space for optional '0b' in binary form
2673         else if (base == 2 && (flags & Alternate || flags & ShowBase))
2674             num_pad_chars -= 2;
2675
2676         for (int i = 0; i < num_pad_chars; ++i)
2677             num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
2678     }
2679
2680     if (flags & CapitalEorX)
2681         num_str = num_str.toUpper();
2682
2683     if (base == 16 && (flags & Alternate || flags & ShowBase))
2684         num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
2685     if (base == 2 && (flags & Alternate || flags & ShowBase))
2686         num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));
2687
2688     // add sign
2689     if (negative)
2690         num_str.prepend(minus);
2691     else if (flags & AlwaysShowSign)
2692         num_str.prepend(plus);
2693     else if (flags & BlankBeforePositive)
2694         num_str.prepend(QLatin1Char(' '));
2695
2696     return num_str;
2697 }
2698
2699 QString QLocalePrivate::unsLongLongToString(qulonglong l, int precision,
2700                                             int base, int width,
2701                                             unsigned flags) const
2702 {
2703     return QLocalePrivate::unsLongLongToString(zero(), group(), plus(),
2704                                                l, precision, base, width, flags);
2705 }
2706
2707 QString QLocalePrivate::unsLongLongToString(const QChar zero, const QChar group,
2708                                             const QChar plus,
2709                                             qulonglong l, int precision,
2710                                             int base, int width,
2711                                             unsigned flags)
2712 {
2713     bool precision_not_specified = false;
2714     if (precision == -1) {
2715         precision_not_specified = true;
2716         precision = 1;
2717     }
2718
2719     QString num_str = qulltoa(l, base, zero);
2720
2721     uint cnt_thousand_sep = 0;
2722     if (flags & ThousandsGroup && base == 10) {
2723         for (int i = num_str.length() - 3; i > 0; i -=3) {
2724             num_str.insert(i, group);
2725             ++cnt_thousand_sep;
2726         }
2727     }
2728
2729     for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
2730         num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
2731
2732     if ((flags & Alternate || flags & ShowBase)
2733             && base == 8
2734             && (num_str.isEmpty() || num_str[0].unicode() != QLatin1Char('0')))
2735         num_str.prepend(QLatin1Char('0'));
2736
2737     // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
2738     // when precision is not specified in the format string
2739     bool zero_padded = flags & ZeroPadded
2740                         && !(flags & LeftAdjusted)
2741                         && precision_not_specified;
2742
2743     if (zero_padded) {
2744         int num_pad_chars = width - num_str.length();
2745
2746         // leave space for optional '0x' in hex form
2747         if (base == 16 && flags & Alternate)
2748             num_pad_chars -= 2;
2749         // leave space for optional '0b' in binary form
2750         else if (base == 2 && flags & Alternate)
2751             num_pad_chars -= 2;
2752
2753         for (int i = 0; i < num_pad_chars; ++i)
2754             num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
2755     }
2756
2757     if (flags & CapitalEorX)
2758         num_str = num_str.toUpper();
2759
2760     if (base == 16 && (flags & Alternate || flags & ShowBase))
2761         num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
2762     else if (base == 2 && (flags & Alternate || flags & ShowBase))
2763         num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));
2764
2765     // add sign
2766     if (flags & AlwaysShowSign)
2767         num_str.prepend(plus);
2768     else if (flags & BlankBeforePositive)
2769         num_str.prepend(QLatin1Char(' '));
2770
2771     return num_str;
2772 }
2773
2774 /*
2775     Converts a number in locale to its representation in the C locale.
2776     Only has to guarantee that a string that is a correct representation of
2777     a number will be converted. If junk is passed in, junk will be passed
2778     out and the error will be detected during the actual conversion to a
2779     number. We can't detect junk here, since we don't even know the base
2780     of the number.
2781 */
2782 bool QLocalePrivate::numberToCLocale(const QString &num,
2783                                             GroupSeparatorMode group_sep_mode,
2784                                             CharBuff *result) const
2785 {
2786     const QChar *uc = num.unicode();
2787     int l = num.length();
2788     int idx = 0;
2789
2790     // Skip whitespace
2791     while (idx < l && uc[idx].isSpace())
2792         ++idx;
2793     if (idx == l)
2794         return false;
2795
2796     while (idx < l) {
2797         const QChar in = uc[idx];
2798
2799         char out = digitToCLocale(in);
2800         if (out == 0) {
2801             if (in == list())
2802                 out = ';';
2803             else if (in == percent())
2804                 out = '%';
2805             // for handling base-x numbers
2806             else if (in.unicode() >= 'A' && in.unicode() <= 'Z')
2807                 out = in.toLower().toLatin1();
2808             else if (in.unicode() >= 'a' && in.unicode() <= 'z')
2809                 out = in.toLatin1();
2810             else
2811                 break;
2812         }
2813
2814         result->append(out);
2815
2816         ++idx;
2817     }
2818
2819     // Check trailing whitespace
2820     for (; idx < l; ++idx) {
2821         if (!uc[idx].isSpace())
2822             return false;
2823     }
2824
2825     result->append('\0');
2826
2827     // Check separators
2828     if (group_sep_mode == ParseGroupSeparators
2829             && !removeGroupSeparators(result))
2830         return false;
2831
2832
2833     return true;
2834 }
2835
2836 bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
2837                                     int decDigits) const
2838 {
2839     buff->clear();
2840     buff->reserve(str.length());
2841
2842     const bool scientific = numMode == DoubleScientificMode;
2843     bool lastWasE = false;
2844     bool lastWasDigit = false;
2845     int eCnt = 0;
2846     int decPointCnt = 0;
2847     bool dec = false;
2848     int decDigitCnt = 0;
2849
2850     for (int i = 0; i < str.length(); ++i) {
2851         char c = digitToCLocale(str.at(i));
2852
2853         if (c >= '0' && c <= '9') {
2854             if (numMode != IntegerMode) {
2855                 // If a double has too many digits after decpt, it shall be Invalid.
2856                 if (dec && decDigits != -1 && decDigits < ++decDigitCnt)
2857                     return false;
2858             }
2859             lastWasDigit = true;
2860         } else {
2861             switch (c) {
2862                 case '.':
2863                     if (numMode == IntegerMode) {
2864                         // If an integer has a decimal point, it shall be Invalid.
2865                         return false;
2866                     } else {
2867                         // If a double has more than one decimal point, it shall be Invalid.
2868                         if (++decPointCnt > 1)
2869                             return false;
2870 #if 0
2871                         // If a double with no decimal digits has a decimal point, it shall be
2872                         // Invalid.
2873                         if (decDigits == 0)
2874                             return false;
2875 #endif                  // On second thoughts, it shall be Valid.
2876
2877                         dec = true;
2878                     }
2879                     break;
2880
2881                 case '+':
2882                 case '-':
2883                     if (scientific) {
2884                         // If a scientific has a sign that's not at the beginning or after
2885                         // an 'e', it shall be Invalid.
2886                         if (i != 0 && !lastWasE)
2887                             return false;
2888                     } else {
2889                         // If a non-scientific has a sign that's not at the beginning,
2890                         // it shall be Invalid.
2891                         if (i != 0)
2892                             return false;
2893                     }
2894                     break;
2895
2896                 case ',':
2897                     //it can only be placed after a digit which is before the decimal point
2898                     if (!lastWasDigit || decPointCnt > 0)
2899                         return false;
2900                     break;
2901
2902                 case 'e':
2903                     if (scientific) {
2904                         // If a scientific has more than one 'e', it shall be Invalid.
2905                         if (++eCnt > 1)
2906                             return false;
2907                         dec = false;
2908                     } else {
2909                         // If a non-scientific has an 'e', it shall be Invalid.
2910                         return false;
2911                     }
2912                     break;
2913
2914                 default:
2915                     // If it's not a valid digit, it shall be Invalid.
2916                     return false;
2917             }
2918             lastWasDigit = false;
2919         }
2920
2921         lastWasE = c == 'e';
2922         if (c != ',')
2923             buff->append(c);
2924     }
2925
2926     return true;
2927 }
2928
2929 double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
2930                                         GroupSeparatorMode group_sep_mode) const
2931 {
2932     CharBuff buff;
2933     if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
2934                          group_sep_mode, &buff)) {
2935         if (ok != 0)
2936             *ok = false;
2937         return 0.0;
2938     }
2939     return bytearrayToDouble(buff.constData(), ok);
2940 }
2941
2942 qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
2943                                            bool *ok, GroupSeparatorMode group_sep_mode) const
2944 {
2945     CharBuff buff;
2946     if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
2947                          group_sep_mode, &buff)) {
2948         if (ok != 0)
2949             *ok = false;
2950         return 0;
2951     }
2952
2953     return bytearrayToLongLong(buff.constData(), base, ok);
2954 }
2955
2956 qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
2957                                                bool *ok, GroupSeparatorMode group_sep_mode) const
2958 {
2959     CharBuff buff;
2960     if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
2961                          group_sep_mode, &buff)) {
2962         if (ok != 0)
2963             *ok = false;
2964         return 0;
2965     }
2966
2967     return bytearrayToUnsLongLong(buff.constData(), base, ok);
2968 }
2969
2970
2971 double QLocalePrivate::bytearrayToDouble(const char *num, bool *ok, bool *overflow)
2972 {
2973     if (ok != 0)
2974         *ok = true;
2975     if (overflow != 0)
2976         *overflow = false;
2977
2978     if (*num == '\0') {
2979         if (ok != 0)
2980             *ok = false;
2981         return 0.0;
2982     }
2983
2984     if (qstrcmp(num, "nan") == 0)
2985         return qt_snan();
2986
2987     if (qstrcmp(num, "+inf") == 0 || qstrcmp(num, "inf") == 0)
2988         return qt_inf();
2989
2990     if (qstrcmp(num, "-inf") == 0)
2991         return -qt_inf();
2992
2993     bool _ok;
2994     const char *endptr;
2995     double d = qstrtod(num, &endptr, &_ok);
2996
2997     if (!_ok) {
2998         // the only way strtod can fail with *endptr != '\0' on a non-empty
2999         // input string is overflow
3000         if (ok != 0)
3001             *ok = false;
3002         if (overflow != 0)
3003             *overflow = *endptr != '\0';
3004         return 0.0;
3005     }
3006
3007     if (*endptr != '\0') {
3008         // we stopped at a non-digit character after converting some digits
3009         if (ok != 0)
3010             *ok = false;
3011         if (overflow != 0)
3012             *overflow = false;
3013         return 0.0;
3014     }
3015
3016     if (ok != 0)
3017         *ok = true;
3018     if (overflow != 0)
3019         *overflow = false;
3020     return d;
3021 }
3022
3023 qlonglong QLocalePrivate::bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow)
3024 {
3025     bool _ok;
3026     const char *endptr;
3027
3028     if (*num == '\0') {
3029         if (ok != 0)
3030             *ok = false;
3031         if (overflow != 0)
3032             *overflow = false;
3033         return 0;
3034     }
3035
3036     qlonglong l = qstrtoll(num, &endptr, base, &_ok);
3037
3038     if (!_ok) {
3039         if (ok != 0)
3040             *ok = false;
3041         if (overflow != 0) {
3042             // the only way qstrtoll can fail with *endptr != '\0' on a non-empty
3043             // input string is overflow
3044             *overflow = *endptr != '\0';
3045         }
3046         return 0;
3047     }
3048
3049     if (*endptr != '\0') {
3050         // we stopped at a non-digit character after converting some digits
3051         if (ok != 0)
3052             *ok = false;
3053         if (overflow != 0)
3054             *overflow = false;
3055         return 0;
3056     }
3057
3058     if (ok != 0)
3059         *ok = true;
3060     if (overflow != 0)
3061         *overflow = false;
3062     return l;
3063 }
3064
3065 qulonglong QLocalePrivate::bytearrayToUnsLongLong(const char *num, int base, bool *ok)
3066 {
3067     bool _ok;
3068     const char *endptr;
3069     qulonglong l = qstrtoull(num, &endptr, base, &_ok);
3070
3071     if (!_ok || *endptr != '\0') {
3072         if (ok != 0)
3073             *ok = false;
3074         return 0;
3075     }
3076
3077     if (ok != 0)
3078         *ok = true;
3079     return l;
3080 }
3081
3082 /*!
3083     \since 4.8
3084
3085     \enum QLocale::CurrencySymbolFormat
3086
3087     Specifies the format of the currency symbol.
3088
3089     \value CurrencyIsoCode a ISO-4217 code of the currency.
3090     \value CurrencySymbol a currency symbol.
3091     \value CurrencyDisplayName a user readable name of the currency.
3092 */
3093
3094 /*!
3095     \since 4.8
3096     Returns a currency symbol according to the \a format.
3097 */
3098 QString QLocale::currencySymbol(QLocale::CurrencySymbolFormat format) const
3099 {
3100 #ifndef QT_NO_SYSTEMLOCALE
3101     if (d() == systemPrivate()) {
3102         QVariant res = systemLocale()->query(QSystemLocale::CurrencySymbol, format);
3103         if (!res.isNull())
3104             return res.toString();
3105     }
3106 #endif
3107     quint32 idx, size;
3108     switch (format) {
3109     case CurrencySymbol:
3110         idx = d()->m_currency_symbol_idx;
3111         size = d()->m_currency_symbol_size;
3112         return getLocaleData(currency_symbol_data + idx, size);
3113     case CurrencyDisplayName:
3114         idx = d()->m_currency_display_name_idx;
3115         size = d()->m_currency_display_name_size;
3116         return getLocaleListData(currency_display_name_data + idx, size, 0);
3117     case CurrencyIsoCode: {
3118         int len = 0;
3119         const QLocalePrivate *d = this->d();
3120         for (; len < 3; ++len)
3121             if (!d->m_currency_iso_code[len])
3122                 break;
3123         return len ? QString::fromLatin1(d->m_currency_iso_code, len) : QString();
3124     }
3125     }
3126     return QString();
3127 }
3128
3129 /*!
3130     \since 4.8
3131
3132     Returns a localized string representation of \a value as a currency.
3133     If the \a symbol is provided it is used instead of the default currency symbol.
3134
3135     \sa currencySymbol()
3136 */
3137 QString QLocale::toCurrencyString(qlonglong value, const QString &symbol) const
3138 {
3139 #ifndef QT_NO_SYSTEMLOCALE
3140     if (d() == systemPrivate()) {
3141         QSystemLocale::CurrencyToStringArgument arg(value, symbol);
3142         QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg));
3143         if (!res.isNull())
3144             return res.toString();
3145     }
3146 #endif
3147     const QLocalePrivate *d = this->d();
3148     quint8 idx = d->m_currency_format_idx;
3149     quint8 size = d->m_currency_format_size;
3150     if (d->m_currency_negative_format_size && value < 0) {
3151         idx = d->m_currency_negative_format_idx;
3152         size = d->m_currency_negative_format_size;
3153         value = -value;
3154     }
3155     QString str = d->longLongToString(value);
3156     QString sym = symbol.isNull() ? currencySymbol() : symbol;
3157     if (sym.isEmpty())
3158         sym = currencySymbol(QLocale::CurrencyIsoCode);
3159     QString format = getLocaleData(currency_format_data + idx, size);
3160     return format.arg(str, sym);
3161 }
3162
3163 /*!
3164     \since 4.8
3165     \overload
3166 */
3167 QString QLocale::toCurrencyString(qulonglong value, const QString &symbol) const
3168 {
3169 #ifndef QT_NO_SYSTEMLOCALE
3170     if (d() == systemPrivate()) {
3171         QSystemLocale::CurrencyToStringArgument arg(value, symbol);
3172         QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg));
3173         if (!res.isNull())
3174             return res.toString();
3175     }
3176 #endif
3177     const QLocalePrivate *d = this->d();
3178     quint8 idx = d->m_currency_format_idx;
3179     quint8 size = d->m_currency_format_size;
3180     QString str = d->unsLongLongToString(value);
3181     QString sym = symbol.isNull() ? currencySymbol() : symbol;
3182     if (sym.isEmpty())
3183         sym = currencySymbol(QLocale::CurrencyIsoCode);
3184     QString format = getLocaleData(currency_format_data + idx, size);
3185     return format.arg(str, sym);
3186 }
3187
3188 /*!
3189     \since 4.8
3190     \overload
3191 */
3192 QString QLocale::toCurrencyString(double value, const QString &symbol) const
3193 {
3194 #ifndef QT_NO_SYSTEMLOCALE
3195     if (d() == systemPrivate()) {
3196         QSystemLocale::CurrencyToStringArgument arg(value, symbol);
3197         QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg));
3198         if (!res.isNull())
3199             return res.toString();
3200     }
3201 #endif
3202     const QLocalePrivate *d = this->d();
3203     quint8 idx = d->m_currency_format_idx;
3204     quint8 size = d->m_currency_format_size;
3205     if (d->m_currency_negative_format_size && value < 0) {
3206         idx = d->m_currency_negative_format_idx;
3207         size = d->m_currency_negative_format_size;
3208         value = -value;
3209     }
3210     QString str = d->doubleToString(value, d->m_currency_digits,
3211                                     QLocalePrivate::DFDecimal);
3212     QString sym = symbol.isNull() ? currencySymbol() : symbol;
3213     if (sym.isEmpty())
3214         sym = currencySymbol(QLocale::CurrencyIsoCode);
3215     QString format = getLocaleData(currency_format_data + idx, size);
3216     return format.arg(str, sym);
3217 }
3218
3219 /*!
3220     \since 4.8
3221
3222     Returns an ordered list of locale names for translation purposes in
3223     preference order.
3224
3225     The return value represents locale names that the user expects to see the
3226     UI translation in.
3227
3228     Most like you do not need to use this function directly, but just pass the
3229     QLocale object to the QTranslator::load() function.
3230
3231     The first item in the list is the most preferred one.
3232
3233     \sa QTranslator, bcp47Name()
3234 */
3235 QStringList QLocale::uiLanguages() const
3236 {
3237 #ifndef QT_NO_SYSTEMLOCALE
3238     if (d() == systemPrivate()) {
3239         QVariant res = systemLocale()->query(QSystemLocale::UILanguages, QVariant());
3240         if (!res.isNull()) {
3241             QStringList result = res.toStringList();
3242             if (!result.isEmpty())
3243                 return result;
3244         }
3245     }
3246 #endif
3247     return QStringList(bcp47Name());
3248 }
3249
3250 /*!
3251     \since 4.8
3252
3253     Returns a native name of the language for the locale. For example
3254     "Schwiizertüütsch" for Swiss-German locale.
3255
3256     \sa nativeCountryName(), languageToString()
3257 */
3258 QString QLocale::nativeLanguageName() const
3259 {
3260 #ifndef QT_NO_SYSTEMLOCALE
3261     if (d() == systemPrivate()) {
3262         QVariant res = systemLocale()->query(QSystemLocale::NativeLanguageName, QVariant());
3263         if (!res.isNull())
3264             return res.toString();
3265     }
3266 #endif
3267     return getLocaleData(endonyms_data + d()->m_language_endonym_idx, d()->m_language_endonym_size);
3268 }
3269
3270 /*!
3271     \since 4.8
3272
3273     Returns a native name of the country for the locale. For example
3274     "España" for Spanish/Spain locale.
3275
3276     \sa nativeLanguageName(), countryToString()
3277 */
3278 QString QLocale::nativeCountryName() const
3279 {
3280 #ifndef QT_NO_SYSTEMLOCALE
3281     if (d() == systemPrivate()) {
3282         QVariant res = systemLocale()->query(QSystemLocale::NativeCountryName, QVariant());
3283         if (!res.isNull())
3284             return res.toString();
3285     }
3286 #endif
3287     return getLocaleData(endonyms_data + d()->m_country_endonym_idx, d()->m_country_endonym_size);
3288 }
3289
3290 #ifndef QT_NO_DEBUG_STREAM
3291 QDebug operator<<(QDebug dbg, const QLocale &l)
3292 {
3293     dbg.nospace() << "QLocale(" << qPrintable(QLocale::languageToString(l.language()))
3294                   << ", " << qPrintable(QLocale::scriptToString(l.script()))
3295                   << ", " << qPrintable(QLocale::countryToString(l.country())) << ')';
3296     return dbg.space();
3297 }
3298 #endif
3299 QT_END_NAMESPACE