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