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