source: trunk/src/corelib/tools/qlocale.cpp@ 635

Last change on this file since 635 was 635, checked in by Dmitry A. Kuminov, 15 years ago

general: QLocale: Fixed broken tools builds.

File size: 202.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qglobal.h"
43
44#ifndef QT_NO_SYSTEMLOCALE
45QT_BEGIN_NAMESPACE
46class QSystemLocale;
47static QSystemLocale *QSystemLocale_globalSystemLocale();
48QT_END_NAMESPACE
49#endif
50
51#include "qplatformdefs.h"
52
53#include "qdatastream.h"
54#include "qstring.h"
55#include "qlocale.h"
56#include "qlocale_p.h"
57#include "qdatetime_p.h"
58#include "qnamespace.h"
59#include "qdatetime.h"
60#include "qstringlist.h"
61#include "qvariant.h"
62#if defined(Q_WS_WIN)
63# include "qt_windows.h"
64# include <time.h>
65#endif
66#if defined(Q_OS_OS2)
67# include "qt_os2.h"
68# include <unidef.h>
69#endif
70#if !defined(QWS) && defined(Q_OS_MAC)
71# include "private/qcore_mac_p.h"
72# include <CoreFoundation/CoreFoundation.h>
73#endif
74#include "private/qnumeric_p.h"
75
76#include <ctype.h>
77#include <float.h>
78#include <limits.h>
79#include <math.h>
80#include <stdlib.h>
81#include <qdebug.h>
82#include <time.h>
83
84#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
85# include <fenv.h>
86#endif
87
88#if !defined(QT_QLOCALE_NEEDS_VOLATILE)
89# if defined(Q_CC_GNU)
90# if __GNUC__ == 4
91# define QT_QLOCALE_NEEDS_VOLATILE
92# elif defined(Q_OS_WIN)
93# define QT_QLOCALE_NEEDS_VOLATILE
94# endif
95# endif
96#endif
97
98#if defined(QT_QLOCALE_NEEDS_VOLATILE)
99# define NEEDS_VOLATILE volatile
100#else
101# define NEEDS_VOLATILE
102#endif
103
104// Sizes as defined by the ISO C99 standard - fallback
105#ifndef LLONG_MAX
106# define LLONG_MAX Q_INT64_C(0x7fffffffffffffff)
107#endif
108#ifndef LLONG_MIN
109# define LLONG_MIN (-LLONG_MAX - Q_INT64_C(1))
110#endif
111#ifndef ULLONG_MAX
112# define ULLONG_MAX Q_UINT64_C(0xffffffffffffffff)
113#endif
114
115#define CONVERSION_BUFF_SIZE 255
116
117QT_BEGIN_NAMESPACE
118
119#ifndef QT_QLOCALE_USES_FCVT
120static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt,
121 int *sign, char **rve, char **digits_str);
122#endif
123Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt,
124 int *sign, char **rve, char **digits_str);
125Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
126static qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok);
127static qulonglong qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok);
128
129#if defined(Q_CC_MWERKS) && defined(Q_OS_WIN32)
130inline bool isascii(int c)
131{
132 return (c >= 0 && c <=127);
133}
134#endif
135
136/******************************************************************************
137** Helpers for accessing Qt locale database
138*/
139
140QT_BEGIN_INCLUDE_NAMESPACE
141#include "qlocale_data_p.h"
142QT_END_INCLUDE_NAMESPACE
143
144QLocale::MeasurementSystem QLocalePrivate::measurementSystem() const
145{
146 for (int i = 0; i < ImperialMeasurementSystemsCount; ++i) {
147 if (ImperialMeasurementSystems[i].languageId == m_language_id
148 && ImperialMeasurementSystems[i].countryId == m_country_id) {
149 return QLocale::ImperialSystem;
150 }
151 }
152 return QLocale::MetricSystem;
153}
154
155// Assumes that code is a
156// QChar code[3];
157// If the code is two-digit the third digit must be 0
158static QLocale::Language codeToLanguage(const QChar *code)
159{
160 ushort uc1 = code[0].unicode();
161 ushort uc2 = code[1].unicode();
162 ushort uc3 = code[2].unicode();
163
164 if (uc1 == 'n' && uc2 == 'o' && uc3 == 0)
165 uc2 = 'b';
166
167 const unsigned char *c = language_code_list;
168 for (; *c != 0; c += 3) {
169 if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
170 return QLocale::Language((c - language_code_list)/3);
171 }
172
173 return QLocale::C;
174}
175
176// Assumes that code is a
177// QChar code[2];
178static QLocale::Country codeToCountry(const QChar *code)
179{
180 ushort uc1 = code[0].unicode();
181 ushort uc2 = code[1].unicode();
182
183 const unsigned char *c = country_code_list;
184 for (; *c != 0; c += 2) {
185 if (uc1 == c[0] && uc2 == c[1])
186 return QLocale::Country((c - country_code_list)/2);
187 }
188
189 return QLocale::AnyCountry;
190}
191
192static QString languageToCode(QLocale::Language language)
193{
194 if (language == QLocale::C)
195 return QLatin1String("C");
196
197 const unsigned char *c = language_code_list + 3*(uint(language));
198
199 QString code(c[2] == 0 ? 2 : 3, Qt::Uninitialized);
200
201 code[0] = ushort(c[0]);
202 code[1] = ushort(c[1]);
203 if (c[2] != 0)
204 code[2] = ushort(c[2]);
205
206 return code;
207}
208
209static QString countryToCode(QLocale::Country country)
210{
211 if (country == QLocale::AnyCountry)
212 return QString();
213
214 QString code(2, Qt::Uninitialized);
215 const unsigned char *c = country_code_list + 2*(uint(country));
216 code[0] = ushort(c[0]);
217 code[1] = ushort(c[1]);
218 return code;
219}
220
221static const QLocalePrivate *findLocale(QLocale::Language language, QLocale::Country country)
222{
223 unsigned language_id = language;
224 unsigned country_id = country;
225
226 uint idx = locale_index[language_id];
227
228 const QLocalePrivate *d = locale_data + idx;
229
230 if (idx == 0) // default language has no associated country
231 return d;
232
233 if (country == QLocale::AnyCountry)
234 return d;
235
236 Q_ASSERT(d->languageId() == language_id);
237
238 while (d->languageId() == language_id
239 && d->countryId() != country_id)
240 ++d;
241
242 if (d->countryId() == country_id
243 && d->languageId() == language_id)
244 return d;
245
246 return locale_data + idx;
247}
248
249static bool splitLocaleName(const QString &name, QChar *lang_begin, QChar *cntry_begin)
250{
251 for (int i = 0; i < 3; ++i)
252 lang_begin[i] = 0;
253 for (int i = 0; i < 2; ++i)
254 cntry_begin[i] = 0;
255
256 int l = name.length();
257
258 QChar *lang = lang_begin;
259 QChar *cntry = cntry_begin;
260
261 int state = 0;
262 const QChar *uc = name.unicode();
263 for (int i = 0; i < l; ++i) {
264 if (uc->unicode() == '.' || uc->unicode() == '@')
265 break;
266
267 switch (state) {
268 case 0:
269 // parsing language
270 if (uc->unicode() == '_') {
271 state = 1;
272 break;
273 }
274 if (lang - lang_begin == 3)
275 return false;
276 if (uc->unicode() < 'a' || uc->unicode() > 'z')
277 return false;
278
279 *lang = *uc;
280 ++lang;
281 break;
282 case 1:
283 // parsing country
284 if (cntry - cntry_begin == 2) {
285 cntry_begin[0] = 0;
286 break;
287 }
288
289 *cntry = *uc;
290 ++cntry;
291 break;
292 }
293
294 ++uc;
295 }
296
297 int lang_len = lang - lang_begin;
298
299 return lang_len == 2 || lang_len == 3;
300}
301
302void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry)
303{
304 lang = QLocale::C;
305 cntry = QLocale::AnyCountry;
306
307 QChar lang_code[3];
308 QChar cntry_code[2];
309 if (!splitLocaleName(name, lang_code, cntry_code))
310 return;
311
312 lang = codeToLanguage(lang_code);
313 if (lang == QLocale::C)
314 return;
315
316 if (cntry_code[0].unicode() != 0)
317 cntry = codeToCountry(cntry_code);
318}
319
320static const QLocalePrivate *findLocale(const QString &name)
321{
322 QLocale::Language lang;
323 QLocale::Country cntry;
324 getLangAndCountry(name, lang, cntry);
325
326 return findLocale(lang, cntry);
327}
328static QString readEscapedFormatString(const QString &format, int *idx)
329{
330 int &i = *idx;
331
332 Q_ASSERT(format.at(i) == QLatin1Char('\''));
333 ++i;
334 if (i == format.size())
335 return QString();
336 if (format.at(i).unicode() == '\'') { // "''" outside of a quoted stirng
337 ++i;
338 return QLatin1String("'");
339 }
340
341 QString result;
342
343 while (i < format.size()) {
344 if (format.at(i).unicode() == '\'') {
345 if (i + 1 < format.size() && format.at(i + 1).unicode() == '\'') {
346 // "''" inside of a quoted string
347 result.append(QLatin1Char('\''));
348 i += 2;
349 } else {
350 break;
351 }
352 } else {
353 result.append(format.at(i++));
354 }
355 }
356 if (i < format.size())
357 ++i;
358
359 return result;
360}
361
362static int repeatCount(const QString &s, int i)
363{
364 QChar c = s.at(i);
365 int j = i + 1;
366 while (j < s.size() && s.at(j) == c)
367 ++j;
368 return j - i;
369}
370
371static const QLocalePrivate *default_lp = 0;
372static uint default_number_options = 0;
373
374static QByteArray envVarLocale()
375{
376 QByteArray lang;
377#if defined(Q_OS_UNIX) || defined(Q_OS_OS2)
378 lang = qgetenv("LC_ALL");
379#if defined(Q_OS_UNIX)
380 if (lang.isNull())
381 lang = qgetenv("LC_NUMERIC");
382#endif
383 if (lang.isNull())
384#endif
385 lang = qgetenv("LANG");
386 return lang;
387}
388
389#if defined(Q_OS_OS2)
390// Gets the system locale name. Also used by QString::localeAwareCompare() so
391// must be available in QT_NO_SYSTEMLOCALE mode.
392Q_CORE_EXPORT QString qt_system_locale_name()
393{
394 QString locale = QString::fromLatin1(envVarLocale());
395 if (locale.isEmpty()) {
396 // get the locale from the system country code
397 COUNTRYCODE code = { 0, 0 };
398 COUNTRYINFO info;
399 ULONG actual;
400 APIRET arc = DosQueryCtryInfo(sizeof(info), &code, &info, &actual);
401 if (arc == NO_ERROR) {
402 UniChar localeName[8];
403 if (UniMapCtryToLocale(info.country, localeName,
404 sizeof(localeName)) == ULS_SUCCESS)
405 locale = QString::fromUtf16(localeName);
406 }
407 }
408
409 return locale;
410}
411#endif
412
413#ifndef QT_NO_SYSTEMLOCALE
414
415#if defined(Q_OS_WIN)
416/******************************************************************************
417** Wrappers for Windows locale system functions
418*/
419
420static const char *winLangCodeToIsoName(int code);
421static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT);
422static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT);
423
424static QString getWinLocaleInfo(LCTYPE type)
425{
426 LCID id = GetUserDefaultLCID();
427 int cnt = GetLocaleInfo(id, type, 0, 0) * 2;
428
429 if (cnt == 0) {
430 qWarning("QLocale: empty windows locale info (%d)", (int)type);
431 return QString();
432 }
433
434 QByteArray buff(cnt, 0);
435
436 cnt = GetLocaleInfo(id, type, reinterpret_cast<wchar_t*>(buff.data()), buff.size() / 2);
437
438 if (cnt == 0) {
439 qWarning("QLocale: empty windows locale info (%d)", (int)type);
440 return QString();
441 }
442
443 return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(buff.data()));
444}
445
446QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT)
447{
448 QByteArray result;
449 if (id == LOCALE_USER_DEFAULT) {
450 result = envVarLocale();
451 QChar lang[3];
452 QChar cntry[2];
453 if ( result == "C" || (!result.isEmpty()
454 && splitLocaleName(QString::fromLocal8Bit(result), lang, cntry)) ) {
455 long id = 0;
456 bool ok = false;
457 id = qstrtoll(result.data(), 0, 0, &ok);
458 if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX )
459 return result;
460 else
461 return winLangCodeToIsoName( (int)id );
462 }
463 }
464
465#if defined(Q_OS_WINCE)
466 result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID());
467#else
468 if (id == LOCALE_USER_DEFAULT)
469 id = GetUserDefaultLCID();
470 QString resultuage = winIso639LangName(id);
471 QString country = winIso3116CtryName(id);
472 result = resultuage.toLatin1();
473 if (!country.isEmpty()) {
474 result += '_';
475 result += country.toLatin1();
476 }
477#endif
478
479 return result;
480}
481
482Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id)
483{
484 return QLocale(QString::fromLatin1(getWinLocaleName(id)));
485}
486
487static QString winToQtFormat(const QString &sys_fmt)
488{
489 QString result;
490 int i = 0;
491
492 while (i < sys_fmt.size()) {
493 if (sys_fmt.at(i).unicode() == QLatin1Char('\'')) {
494 QString text = readEscapedFormatString(sys_fmt, &i);
495 if (text == QLatin1String("'"))
496 result += QLatin1String("''");
497 else
498 result += QLatin1Char('\'') + text + QLatin1Char('\'');
499 continue;
500 }
501
502 QChar c = sys_fmt.at(i);
503 int repeat = repeatCount(sys_fmt, i);
504
505 switch (c.unicode()) {
506 // Date
507 case 'y':
508 if (repeat > 5)
509 repeat = 5;
510 else if (repeat == 3)
511 repeat = 2;
512 switch (repeat) {
513 case 1:
514 result += QLatin1String("yy"); // "y" unsupported by Qt, use "yy"
515 break;
516 case 5:
517 result += QLatin1String("yyyy"); // "yyyyy" same as "yyyy" on Windows
518 break;
519 default:
520 result += QString(repeat, QLatin1Char('y'));
521 break;
522 }
523 break;
524 case 'g':
525 if (repeat > 2)
526 repeat = 2;
527 switch (repeat) {
528 case 2:
529 break; // no equivalent of "gg" in Qt
530 default:
531 result += QLatin1Char('g');
532 break;
533 }
534 break;
535 case 't':
536 if (repeat > 2)
537 repeat = 2;
538 result += QLatin1String("AP"); // "t" unsupported, use "AP"
539 break;
540 default:
541 result += QString(repeat, c);
542 break;
543 }
544
545 i += repeat;
546 }
547
548 return result;
549}
550
551
552
553static QString winDateToString(const QDate &date, DWORD flags)
554{
555 SYSTEMTIME st;
556 memset(&st, 0, sizeof(SYSTEMTIME));
557 st.wYear = date.year();
558 st.wMonth = date.month();
559 st.wDay = date.day();
560
561 LCID id = GetUserDefaultLCID();
562
563 wchar_t buf[255];
564 if (GetDateFormat(id, flags, &st, 0, buf, 255))
565 return QString::fromWCharArray(buf);
566
567 return QString();
568}
569
570static QString winTimeToString(const QTime &time)
571{
572 SYSTEMTIME st;
573 memset(&st, 0, sizeof(SYSTEMTIME));
574 st.wHour = time.hour();
575 st.wMinute = time.minute();
576 st.wSecond = time.second();
577 st.wMilliseconds = 0;
578
579 DWORD flags = 0;
580 LCID id = GetUserDefaultLCID();
581
582 wchar_t buf[255];
583 if (GetTimeFormat(id, flags, &st, 0, buf, 255))
584 return QString::fromWCharArray(buf);
585
586 return QString();
587}
588
589static QString winDayName(int day, bool short_format)
590{
591 static const LCTYPE short_day_map[]
592 = { LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2,
593 LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5,
594 LOCALE_SABBREVDAYNAME6, LOCALE_SABBREVDAYNAME7 };
595
596 static const LCTYPE long_day_map[]
597 = { LOCALE_SDAYNAME1, LOCALE_SDAYNAME2,
598 LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, LOCALE_SDAYNAME5,
599 LOCALE_SDAYNAME6, LOCALE_SDAYNAME7 };
600
601 day -= 1;
602
603 LCTYPE type = short_format
604 ? short_day_map[day] : long_day_map[day];
605 return getWinLocaleInfo(type);
606}
607
608static QString winMonthName(int month, bool short_format)
609{
610 static const LCTYPE short_month_map[]
611 = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3,
612 LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
613 LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9,
614 LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
615
616 static const LCTYPE long_month_map[]
617 = { LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
618 LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
619 LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9,
620 LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12 };
621
622 month -= 1;
623 if (month < 0 || month > 11)
624 return QString();
625
626 LCTYPE type = short_format ? short_month_map[month] : long_month_map[month];
627 return getWinLocaleInfo(type);
628}
629
630static QLocale::MeasurementSystem winSystemMeasurementSystem()
631{
632 LCID id = GetUserDefaultLCID();
633 wchar_t output[2];
634
635 if (GetLocaleInfo(id, LOCALE_IMEASURE, output, 2)) {
636 QString iMeasure = QString::fromWCharArray(output);
637 if (iMeasure == QLatin1String("1")) {
638 return QLocale::ImperialSystem;
639 }
640 }
641
642 return QLocale::MetricSystem;
643}
644
645static QString winSystemAMText()
646{
647 LCID id = GetUserDefaultLCID();
648 wchar_t output[15]; // maximum length including terminating zero character for Win2003+
649
650 if (GetLocaleInfo(id, LOCALE_S1159, output, 15)) {
651 return QString::fromWCharArray(output);
652 }
653
654 return QString();
655}
656
657static QString winSystemPMText()
658{
659 LCID id = GetUserDefaultLCID();
660 wchar_t output[15]; // maximum length including terminating zero character for Win2003+
661
662 if (GetLocaleInfo(id, LOCALE_S2359, output, 15)) {
663 return QString::fromWCharArray(output);
664 }
665
666 return QString();
667}
668
669/*!
670 \since 4.6
671 Returns the fallback locale obtained from the system.
672 */
673QLocale QSystemLocale::fallbackLocale() const
674{
675 return QLocale(QString::fromLatin1(getWinLocaleName()));
676}
677
678QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
679{
680 LCTYPE locale_info = 0;
681 bool format_string = false;
682
683 switch(type) {
684// case Name:
685// return getWinLocaleName();
686 case DecimalPoint:
687 locale_info = LOCALE_SDECIMAL;
688 break;
689 case GroupSeparator:
690 locale_info = LOCALE_STHOUSAND;
691 break;
692 case NegativeSign:
693 locale_info = LOCALE_SNEGATIVESIGN;
694 break;
695 case PositiveSign:
696 locale_info = LOCALE_SPOSITIVESIGN;
697 break;
698 case DateFormatLong:
699 locale_info = LOCALE_SLONGDATE;
700 format_string = true;
701 break;
702 case DateFormatShort:
703 locale_info = LOCALE_SSHORTDATE;
704 format_string = true;
705 break;
706 case TimeFormatLong:
707 case TimeFormatShort:
708 locale_info = LOCALE_STIMEFORMAT;
709 format_string = true;
710 break;
711
712 case DateTimeFormatLong:
713 case DateTimeFormatShort:
714 return query(type == DateTimeFormatLong ? DateFormatLong : DateFormatShort).toString()
715 + QLatin1Char(' ') + query(type == DateTimeFormatLong ? TimeFormatLong : TimeFormatShort).toString();
716 case DayNameLong:
717 case DayNameShort:
718 return winDayName(in.toInt(), (type == DayNameShort));
719 case MonthNameLong:
720 case MonthNameShort:
721 return winMonthName(in.toInt(), (type == MonthNameShort));
722 case DateToStringShort:
723 case DateToStringLong:
724 return winDateToString(in.toDate(), type == DateToStringShort ? DATE_SHORTDATE : DATE_LONGDATE);
725 case TimeToStringShort:
726 case TimeToStringLong:
727 return winTimeToString(in.toTime());
728 case DateTimeToStringShort:
729 case DateTimeToStringLong: {
730 const QDateTime dt = in.toDateTime();
731 return winDateToString(dt.date(), type == DateTimeToStringShort ? DATE_SHORTDATE : DATE_LONGDATE)
732 + QLatin1Char(' ') + winTimeToString(dt.time()); }
733
734 case ZeroDigit:
735 locale_info = LOCALE_SNATIVEDIGITS;
736 break;
737
738 case LanguageId:
739 case CountryId: {
740 QString locale = QString::fromLatin1(getWinLocaleName());
741 QLocale::Language lang;
742 QLocale::Country cntry;
743 getLangAndCountry(locale, lang, cntry);
744 if (type == LanguageId)
745 return lang;
746 if (cntry == QLocale::AnyCountry)
747 return fallbackLocale().country();
748 return cntry;
749 }
750
751 case MeasurementSystem:
752 return QVariant(static_cast<int>(winSystemMeasurementSystem()));
753
754 case AMText:
755 return QVariant(winSystemAMText());
756 case PMText:
757 return QVariant(winSystemPMText());
758 default:
759 break;
760 }
761 if (locale_info) {
762 QString result = getWinLocaleInfo(locale_info);
763 if (format_string)
764 result = winToQtFormat(result);
765 if (!result.isEmpty())
766 return result;
767 }
768 return QVariant();
769}
770
771struct WindowsToISOListElt {
772 ushort windows_code;
773 char iso_name[6];
774};
775
776static const WindowsToISOListElt windows_to_iso_list[] = {
777 { 0x0401, "ar_SA" },
778 { 0x0402, "bg\0 " },
779 { 0x0403, "ca\0 " },
780 { 0x0404, "zh_TW" },
781 { 0x0405, "cs\0 " },
782 { 0x0406, "da\0 " },
783 { 0x0407, "de\0 " },
784 { 0x0408, "el\0 " },
785 { 0x0409, "en_US" },
786 { 0x040a, "es\0 " },
787 { 0x040b, "fi\0 " },
788 { 0x040c, "fr\0 " },
789 { 0x040d, "he\0 " },
790 { 0x040e, "hu\0 " },
791 { 0x040f, "is\0 " },
792 { 0x0410, "it\0 " },
793 { 0x0411, "ja\0 " },
794 { 0x0412, "ko\0 " },
795 { 0x0413, "nl\0 " },
796 { 0x0414, "no\0 " },
797 { 0x0415, "pl\0 " },
798 { 0x0416, "pt_BR" },
799 { 0x0418, "ro\0 " },
800 { 0x0419, "ru\0 " },
801 { 0x041a, "hr\0 " },
802 { 0x041c, "sq\0 " },
803 { 0x041d, "sv\0 " },
804 { 0x041e, "th\0 " },
805 { 0x041f, "tr\0 " },
806 { 0x0420, "ur\0 " },
807 { 0x0421, "in\0 " },
808 { 0x0422, "uk\0 " },
809 { 0x0423, "be\0 " },
810 { 0x0425, "et\0 " },
811 { 0x0426, "lv\0 " },
812 { 0x0427, "lt\0 " },
813 { 0x0429, "fa\0 " },
814 { 0x042a, "vi\0 " },
815 { 0x042d, "eu\0 " },
816 { 0x042f, "mk\0 " },
817 { 0x0436, "af\0 " },
818 { 0x0438, "fo\0 " },
819 { 0x0439, "hi\0 " },
820 { 0x043e, "ms\0 " },
821 { 0x0458, "mt\0 " },
822 { 0x0801, "ar_IQ" },
823 { 0x0804, "zh_CN" },
824 { 0x0807, "de_CH" },
825 { 0x0809, "en_GB" },
826 { 0x080a, "es_MX" },
827 { 0x080c, "fr_BE" },
828 { 0x0810, "it_CH" },
829 { 0x0812, "ko\0 " },
830 { 0x0813, "nl_BE" },
831 { 0x0814, "no\0 " },
832 { 0x0816, "pt\0 " },
833 { 0x081a, "sr\0 " },
834 { 0x081d, "sv_FI" },
835 { 0x0c01, "ar_EG" },
836 { 0x0c04, "zh_HK" },
837 { 0x0c07, "de_AT" },
838 { 0x0c09, "en_AU" },
839 { 0x0c0a, "es\0 " },
840 { 0x0c0c, "fr_CA" },
841 { 0x0c1a, "sr\0 " },
842 { 0x1001, "ar_LY" },
843 { 0x1004, "zh_SG" },
844 { 0x1007, "de_LU" },
845 { 0x1009, "en_CA" },
846 { 0x100a, "es_GT" },
847 { 0x100c, "fr_CH" },
848 { 0x1401, "ar_DZ" },
849 { 0x1407, "de_LI" },
850 { 0x1409, "en_NZ" },
851 { 0x140a, "es_CR" },
852 { 0x140c, "fr_LU" },
853 { 0x1801, "ar_MA" },
854 { 0x1809, "en_IE" },
855 { 0x180a, "es_PA" },
856 { 0x1c01, "ar_TN" },
857 { 0x1c09, "en_ZA" },
858 { 0x1c0a, "es_DO" },
859 { 0x2001, "ar_OM" },
860 { 0x2009, "en_JM" },
861 { 0x200a, "es_VE" },
862 { 0x2401, "ar_YE" },
863 { 0x2409, "en\0 " },
864 { 0x240a, "es_CO" },
865 { 0x2801, "ar_SY" },
866 { 0x2809, "en_BZ" },
867 { 0x280a, "es_PE" },
868 { 0x2c01, "ar_JO" },
869 { 0x2c09, "en_TT" },
870 { 0x2c0a, "es_AR" },
871 { 0x3001, "ar_LB" },
872 { 0x300a, "es_EC" },
873 { 0x3401, "ar_KW" },
874 { 0x340a, "es_CL" },
875 { 0x3801, "ar_AE" },
876 { 0x380a, "es_UY" },
877 { 0x3c01, "ar_BH" },
878 { 0x3c0a, "es_PY" },
879 { 0x4001, "ar_QA" },
880 { 0x400a, "es_BO" },
881 { 0x440a, "es_SV" },
882 { 0x480a, "es_HN" },
883 { 0x4c0a, "es_NI" },
884 { 0x500a, "es_PR" }
885};
886
887static const int windows_to_iso_count
888 = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt);
889
890static const char *winLangCodeToIsoName(int code)
891{
892 int cmp = code - windows_to_iso_list[0].windows_code;
893 if (cmp < 0)
894 return 0;
895
896 if (cmp == 0)
897 return windows_to_iso_list[0].iso_name;
898
899 int begin = 0;
900 int end = windows_to_iso_count;
901
902 while (end - begin > 1) {
903 uint mid = (begin + end)/2;
904
905 const WindowsToISOListElt *elt = windows_to_iso_list + mid;
906 int cmp = code - elt->windows_code;
907 if (cmp < 0)
908 end = mid;
909 else if (cmp > 0)
910 begin = mid;
911 else
912 return elt->iso_name;
913 }
914
915 return 0;
916
917}
918
919static QString winIso639LangName(LCID id)
920{
921 QString result;
922
923 // Windows returns the wrong ISO639 for some languages, we need to detect them here using
924 // the language code
925 QString lang_code;
926 wchar_t out[256];
927 if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255))
928 lang_code = QString::fromWCharArray(out);
929
930 if (!lang_code.isEmpty()) {
931 const char *endptr;
932 bool ok;
933 QByteArray latin1_lang_code = lang_code.toLatin1();
934 int i = qstrtoull(latin1_lang_code, &endptr, 16, &ok);
935 if (ok && *endptr == '\0') {
936 switch (i) {
937 case 0x814:
938 result = QLatin1String("nn"); // Nynorsk
939 break;
940 default:
941 break;
942 }
943 }
944 }
945
946 if (!result.isEmpty())
947 return result;
948
949 // not one of the problematic languages - do the usual lookup
950 if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME , out, 255))
951 result = QString::fromWCharArray(out);
952
953 return result;
954}
955
956static QString winIso3116CtryName(LCID id)
957{
958 QString result;
959
960 wchar_t out[256];
961 if (GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, out, 255))
962 result = QString::fromWCharArray(out);
963
964 return result;
965}
966
967
968#elif defined(Q_OS_OS2)
969/******************************************************************************
970** Wrappers for OS/2 locale system functions
971*/
972
973/*!
974 \since 4.6
975
976 Returns a fallback locale, that will get used for everything that
977 is not explicitly overridden by the system locale.
978*/
979QLocale QSystemLocale::fallbackLocale() const
980{
981 return QLocale(qt_system_locale_name());
982}
983
984/*!
985 Performs a query of the given \a type in the system locale for
986 customized values or conversion. If the method returns a null
987 QVariant, the conversion of the fallbackLocale() will be used.
988
989 \a in is unused for some of the query types.
990
991 \sa QSystemLocale::QueryType
992*/
993QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
994{
995 static bool ignoreSysLocaleObject =
996 getenv("QT_PM_NO_SYSTEM_LOCALE") || !getenv("QT_PM_SYSTEM_LOCALE");
997
998 if (ignoreSysLocaleObject)
999 return QVariant();
1000
1001 static LocaleItem dayNames[] = {
1002 // 0 ... 6 (Mon - Sun)
1003 LOCI_sDayName1, LOCI_sDayName2, LOCI_sDayName3, LOCI_sDayName4,
1004 LOCI_sDayName5, LOCI_sDayName6, LOCI_sDayName7,
1005 // 7 ... 13 (Mon - Sun)
1006 LOCI_sAbbrevDayName1, LOCI_sAbbrevDayName2, LOCI_sAbbrevDayName3,
1007 LOCI_sAbbrevDayName4, LOCI_sAbbrevDayName5, LOCI_sDayName6,
1008 LOCI_sAbbrevDayName7,
1009 };
1010
1011 static LocaleItem monthNames[] = {
1012 // 0 ... 11 (Jan - Dec)
1013 LOCI_sMonthName1, LOCI_sMonthName2, LOCI_sMonthName3, LOCI_sMonthName4,
1014 LOCI_sMonthName5, LOCI_sMonthName6, LOCI_sMonthName7, LOCI_sMonthName8,
1015 LOCI_sMonthName9, LOCI_sMonthName10, LOCI_sMonthName11, LOCI_sMonthName12,
1016 // 12 ... 23 (Jan - Dec)
1017 LOCI_sAbbrevMonthName1, LOCI_sAbbrevMonthName2, LOCI_sAbbrevMonthName3,
1018 LOCI_sAbbrevMonthName4, LOCI_sAbbrevMonthName5, LOCI_sAbbrevMonthName6,
1019 LOCI_sAbbrevMonthName7, LOCI_sAbbrevMonthName8, LOCI_sAbbrevMonthName9,
1020 LOCI_sAbbrevMonthName10, LOCI_sAbbrevMonthName11, LOCI_sAbbrevMonthName12,
1021 };
1022
1023 QString sysLocaleName = qt_system_locale_name();
1024
1025 LocaleObject lo = 0;
1026 if (UniCreateLocaleObject(UNI_UCS_STRING_POINTER,
1027 sysLocaleName.utf16(), &lo) == ULS_SUCCESS) {
1028 int num;
1029 tm timespec = { 0 };
1030 bool isDateTime = false;
1031
1032 LocaleItem item = 0;
1033
1034 switch(type) {
1035 // case LanguageId:
1036 // case CountryId:
1037 // this is returned by the fallback locale
1038 case DecimalPoint:
1039 item = LOCI_sDecimal;
1040 break;
1041 case GroupSeparator:
1042 item = LOCI_sThousand;
1043 break;
1044 case ZeroDigit:
1045 item = LOCI_sNativeDigits;
1046 break;
1047 case NegativeSign:
1048 item = LOCI_sNegativeSign;
1049 break;
1050 case PositiveSign:
1051 item = LOCI_sPositiveSign;
1052 break;
1053 case DateFormatLong:
1054 item = LOCI_wLongDate;
1055 break;
1056 case DateFormatShort:
1057 item = LOCI_wShortDate;
1058 break;
1059 case TimeFormatLong:
1060 case TimeFormatShort:
1061 item = LOCI_wTimeFormat;
1062 break;
1063 case DayNameLong:
1064 num = in.toInt();
1065 if (num >= 1 && num <= 7)
1066 item = dayNames[num - 1];
1067 break;
1068 case DayNameShort:
1069 num = in.toInt();
1070 if (num >= 1 && num <= 7)
1071 item = dayNames[num - 1 + 7];
1072 break;
1073 case MonthNameLong:
1074 num = in.toInt();
1075 if (num >= 1 && num <= 12)
1076 item = monthNames[num - 1];
1077 break;
1078 case MonthNameShort:
1079 num = in.toInt();
1080 if (num >= 1 && num <= 12)
1081 item = monthNames[num - 1 + 12];
1082 break;
1083 case DateToStringLong:
1084 case DateToStringShort: {
1085 QDate date = in.toDate();
1086 timespec.tm_mday = date.day();
1087 timespec.tm_mon = date.month() - 1;
1088 timespec.tm_year = date.year() - 1900;
1089 timespec.tm_isdst = -1;
1090 item = type == DateToStringShort ? LOCI_sShortDate : LOCI_sLongDate;
1091 isDateTime = true;
1092 break;
1093 }
1094 case TimeToStringLong:
1095 case TimeToStringShort: {
1096 QTime time = in.toTime();
1097 timespec.tm_sec = time.second();
1098 timespec.tm_min = time.minute();
1099 timespec.tm_hour = time.hour();
1100 timespec.tm_isdst = -1;
1101 item = LOCI_sTimeFormat;
1102 isDateTime = true;
1103 break;
1104 }
1105 case DateTimeFormatLong:
1106 case DateTimeFormatShort:
1107 return
1108 query(type == DateTimeFormatLong ?
1109 DateFormatLong : DateFormatShort).toString()
1110 + QLatin1Char(' ')
1111 + query(type == DateTimeFormatLong ?
1112 TimeFormatLong : TimeFormatShort).toString();
1113 case DateTimeToStringShort: {
1114 QDateTime dateTime = in.toDateTime();
1115 return
1116 query(DateToStringShort, dateTime.date()).toString()
1117 + QLatin1Char(' ')
1118 + query(TimeToStringShort, dateTime.time()).toString();
1119 }
1120 case DateTimeToStringLong: {
1121 QDateTime dateTime = in.toDateTime();
1122 timespec.tm_sec = dateTime.time().second();
1123 timespec.tm_min = dateTime.time().minute();
1124 timespec.tm_hour = dateTime.time().hour();
1125 timespec.tm_mday = dateTime.date().day();
1126 timespec.tm_mon = dateTime.date().month() - 1;
1127 timespec.tm_wday = dateTime.date().dayOfWeek() % 7;
1128 timespec.tm_year = dateTime.date().year() - 1900;
1129 timespec.tm_isdst = -1;
1130 item = LOCI_sDateTime;
1131 isDateTime = true;
1132 break;
1133 }
1134 case MeasurementSystem:
1135 if (UniQueryLocaleValue(lo, LOCI_iMeasure, &num) == ULS_SUCCESS &&
1136 num == 1)
1137 return QVariant(static_cast<int>(QLocale::ImperialSystem));
1138 return QVariant(static_cast<int>(QLocale::MetricSystem));
1139 case AMText:
1140 item = LOCI_s1159;
1141 break;
1142 case PMText:
1143 item = LOCI_s2359;
1144 break;
1145 default:
1146 break;
1147 }
1148
1149 QString result;
1150
1151 if (item) {
1152 if (isDateTime) {
1153 UniChar *format = 0;
1154 if (UniQueryLocaleItem(lo, item, &format) == ULS_SUCCESS) {
1155 QByteArray buf;
1156 for (size_t i = 1; i < 10; ++i) {
1157 buf.resize(i * 256 * 2);
1158 if (UniStrftime(lo, (UniChar *)buf.data(), buf.size() / 2,
1159 format, &timespec)) {
1160 result = QString::fromUtf16((const ushort *)buf.data());
1161 break;
1162 }
1163 }
1164 UniFreeMem(format);
1165 }
1166 } else {
1167 UniChar *value = 0;
1168 if (UniQueryLocaleItem(lo, item, &value) == ULS_SUCCESS) {
1169 result = QString::fromUtf16(value);
1170 UniFreeMem(value);
1171 }
1172 }
1173 }
1174
1175 UniFreeLocaleObject(lo);
1176
1177 // Note QLocalePrivate::updateSystemPrivate() doesn't like empty
1178 // strings, make sure we return a null QVariant in such case
1179 if (!result.isEmpty())
1180 return result;
1181 }
1182
1183 return QVariant();
1184}
1185
1186
1187#elif defined(Q_OS_MAC)
1188/******************************************************************************
1189** Wrappers for Mac locale system functions
1190*/
1191
1192static QByteArray getMacLocaleName()
1193{
1194 QByteArray result = envVarLocale();
1195
1196 QChar lang[3];
1197 QChar cntry[2];
1198 if (result.isEmpty() || result != "C"
1199 && !splitLocaleName(QString::fromLocal8Bit(result), lang, cntry)) {
1200 QCFType<CFLocaleRef> l = CFLocaleCopyCurrent();
1201 CFStringRef locale = CFLocaleGetIdentifier(l);
1202 result = QCFString::toQString(locale).toUtf8();
1203 }
1204 return result;
1205}
1206
1207static QString macMonthName(int month, bool short_format)
1208{
1209 month -= 1;
1210 if (month < 0 || month > 11)
1211 return QString();
1212
1213 QCFType<CFDateFormatterRef> formatter
1214 = CFDateFormatterCreate(0, QCFType<CFLocaleRef>(CFLocaleCopyCurrent()),
1215 kCFDateFormatterNoStyle, kCFDateFormatterNoStyle);
1216 QCFType<CFArrayRef> values
1217 = static_cast<CFArrayRef>(CFDateFormatterCopyProperty(formatter,
1218 short_format ? kCFDateFormatterShortMonthSymbols
1219 : kCFDateFormatterMonthSymbols));
1220 if (values != 0) {
1221 CFStringRef cfstring = static_cast<CFStringRef>(CFArrayGetValueAtIndex(values, month));
1222 return QCFString::toQString(cfstring);
1223 }
1224 return QString();
1225}
1226
1227
1228static QString macDayName(int day, bool short_format)
1229{
1230 if (day < 1 || day > 7)
1231 return QString();
1232
1233 QCFType<CFDateFormatterRef> formatter
1234 = CFDateFormatterCreate(0, QCFType<CFLocaleRef>(CFLocaleCopyCurrent()),
1235 kCFDateFormatterNoStyle, kCFDateFormatterNoStyle);
1236 QCFType<CFArrayRef> values = static_cast<CFArrayRef>(CFDateFormatterCopyProperty(formatter,
1237 short_format ? kCFDateFormatterShortWeekdaySymbols
1238 : kCFDateFormatterWeekdaySymbols));
1239 if (values != 0) {
1240 CFStringRef cfstring = static_cast<CFStringRef>(CFArrayGetValueAtIndex(values, day % 7));
1241 return QCFString::toQString(cfstring);
1242 }
1243 return QString();
1244}
1245
1246static QString macDateToString(const QDate &date, bool short_format)
1247{
1248 CFGregorianDate macGDate;
1249 macGDate.year = date.year();
1250 macGDate.month = date.month();
1251 macGDate.day = date.day();
1252 macGDate.hour = 0;
1253 macGDate.minute = 0;
1254 macGDate.second = 0.0;
1255 QCFType<CFDateRef> myDate
1256 = CFDateCreate(0, CFGregorianDateGetAbsoluteTime(macGDate,
1257 QCFType<CFTimeZoneRef>(CFTimeZoneCopyDefault())));
1258 QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
1259 CFDateFormatterStyle style = short_format ? kCFDateFormatterShortStyle : kCFDateFormatterLongStyle;
1260 QCFType<CFDateFormatterRef> myFormatter
1261 = CFDateFormatterCreate(kCFAllocatorDefault,
1262 mylocale, style,
1263 kCFDateFormatterNoStyle);
1264 return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
1265}
1266
1267static QString macTimeToString(const QTime &time, bool short_format)
1268{
1269 CFGregorianDate macGDate;
1270 // Assume this is local time and the current date
1271 QDate dt = QDate::currentDate();
1272 macGDate.year = dt.year();
1273 macGDate.month = dt.month();
1274 macGDate.day = dt.day();
1275 macGDate.hour = time.hour();
1276 macGDate.minute = time.minute();
1277 macGDate.second = time.second();
1278 QCFType<CFDateRef> myDate
1279 = CFDateCreate(0, CFGregorianDateGetAbsoluteTime(macGDate,
1280 QCFType<CFTimeZoneRef>(CFTimeZoneCopyDefault())));
1281
1282 QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
1283 CFDateFormatterStyle style = short_format ? kCFDateFormatterShortStyle : kCFDateFormatterLongStyle;
1284 QCFType<CFDateFormatterRef> myFormatter = CFDateFormatterCreate(kCFAllocatorDefault,
1285 mylocale,
1286 kCFDateFormatterNoStyle,
1287 style);
1288 return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
1289}
1290
1291static QString macToQtFormat(const QString &sys_fmt)
1292{
1293 QString result;
1294 int i = 0;
1295
1296 while (i < sys_fmt.size()) {
1297 if (sys_fmt.at(i).unicode() == '\'') {
1298 QString text = readEscapedFormatString(sys_fmt, &i);
1299 if (text == QLatin1String("'"))
1300 result += QLatin1String("''");
1301 else
1302 result += QLatin1Char('\'') + text + QLatin1Char('\'');
1303 continue;
1304 }
1305
1306 QChar c = sys_fmt.at(i);
1307 int repeat = repeatCount(sys_fmt, i);
1308
1309 switch (c.unicode()) {
1310 case 'G': // Qt doesn't support these :(
1311 case 'Y':
1312 case 'D':
1313 case 'F':
1314 case 'w':
1315 case 'W':
1316 case 'g':
1317 break;
1318
1319 case 'u': // extended year - use 'y'
1320 if (repeat < 4)
1321 result += QLatin1String("yy");
1322 else
1323 result += QLatin1String("yyyy");
1324 break;
1325 case 'S': // fractional second
1326 if (repeat < 3)
1327 result += QLatin1Char('z');
1328 else
1329 result += QLatin1String("zzz");
1330 break;
1331 case 'E':
1332 if (repeat <= 3)
1333 result += QLatin1String("ddd");
1334 else
1335 result += QLatin1String("dddd");
1336 break;
1337 case 'e':
1338 if (repeat >= 2)
1339 result += QLatin1String("dd");
1340 else
1341 result += QLatin1Char('d');
1342 break;
1343 case 'a':
1344 result += QLatin1String("AP");
1345 break;
1346 case 'k':
1347 result += QString(repeat, QLatin1Char('H'));
1348 break;
1349 case 'K':
1350 result += QString(repeat, QLatin1Char('h'));
1351 break;
1352 case 'z':
1353 case 'Z':
1354 case 'v':
1355 result += QLatin1Char('t');
1356 break;
1357 default:
1358 result += QString(repeat, c);
1359 break;
1360 }
1361
1362 i += repeat;
1363 }
1364
1365 return result;
1366}
1367
1368QString getMacDateFormat(CFDateFormatterStyle style)
1369{
1370 QCFType<CFLocaleRef> l = CFLocaleCopyCurrent();
1371 QCFType<CFDateFormatterRef> formatter = CFDateFormatterCreate(kCFAllocatorDefault,
1372 l, style, kCFDateFormatterNoStyle);
1373 return macToQtFormat(QCFString::toQString(CFDateFormatterGetFormat(formatter)));
1374}
1375
1376static QString getMacTimeFormat(CFDateFormatterStyle style)
1377{
1378 QCFType<CFLocaleRef> l = CFLocaleCopyCurrent();
1379 QCFType<CFDateFormatterRef> formatter = CFDateFormatterCreate(kCFAllocatorDefault,
1380 l, kCFDateFormatterNoStyle, style);
1381 return macToQtFormat(QCFString::toQString(CFDateFormatterGetFormat(formatter)));
1382}
1383
1384static QString getCFLocaleValue(CFStringRef key)
1385{
1386 QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
1387 CFTypeRef value = CFLocaleGetValue(locale, key);
1388 return QCFString::toQString(CFStringRef(static_cast<CFTypeRef>(value)));
1389}
1390
1391static QLocale::MeasurementSystem macMeasurementSystem()
1392{
1393 QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
1394 CFStringRef system = static_cast<CFStringRef>(CFLocaleGetValue(locale, kCFLocaleMeasurementSystem));
1395 if (QCFString::toQString(system) == QLatin1String("Metric")) {
1396 return QLocale::MetricSystem;
1397 } else {
1398 return QLocale::ImperialSystem;
1399 }
1400}
1401
1402static void getMacPreferredLanguageAndCountry(QString *language, QString *country)
1403{
1404 QCFType<CFArrayRef> languages = (CFArrayRef)CFPreferencesCopyValue(
1405 CFSTR("AppleLanguages"),
1406 kCFPreferencesAnyApplication,
1407 kCFPreferencesCurrentUser,
1408 kCFPreferencesAnyHost);
1409 if (languages && CFArrayGetCount(languages) > 0) {
1410 QCFType<CFLocaleRef> locale = CFLocaleCreate(kCFAllocatorDefault,
1411 CFStringRef(CFArrayGetValueAtIndex(languages, 0)));
1412 if (language)
1413 *language = QCFString::toQString(CFStringRef(CFLocaleGetValue(locale, kCFLocaleLanguageCode)));
1414 if (country)
1415 *country = QCFString::toQString(CFStringRef(CFLocaleGetValue(locale, kCFLocaleCountryCode)));
1416 }
1417}
1418
1419QLocale QSystemLocale::fallbackLocale() const
1420{
1421 return QLocale(QString::fromUtf8(getMacLocaleName().constData()));
1422}
1423
1424QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
1425{
1426 switch(type) {
1427// case Name:
1428// return getMacLocaleName();
1429 case DecimalPoint: {
1430 QString value = getCFLocaleValue(kCFLocaleDecimalSeparator);
1431 return value.isEmpty() ? QVariant() : value;
1432 }
1433 case GroupSeparator: {
1434 QString value = getCFLocaleValue(kCFLocaleGroupingSeparator);
1435 return value.isEmpty() ? QVariant() : value;
1436 }
1437 case DateFormatLong:
1438 case DateFormatShort:
1439 return getMacDateFormat(type == DateFormatShort
1440 ? kCFDateFormatterShortStyle
1441 : kCFDateFormatterLongStyle);
1442 case TimeFormatLong:
1443 case TimeFormatShort:
1444 return getMacTimeFormat(type == TimeFormatShort
1445 ? kCFDateFormatterShortStyle
1446 : kCFDateFormatterLongStyle);
1447 case DayNameLong:
1448 case DayNameShort:
1449 return macDayName(in.toInt(), (type == DayNameShort));
1450 case MonthNameLong:
1451 case MonthNameShort:
1452 return macMonthName(in.toInt(), (type == MonthNameShort));
1453 case DateToStringShort:
1454 case DateToStringLong:
1455 return macDateToString(in.toDate(), (type == DateToStringShort));
1456 case TimeToStringShort:
1457 case TimeToStringLong:
1458 return macTimeToString(in.toTime(), (type == TimeToStringShort));
1459
1460 case NegativeSign:
1461 case PositiveSign:
1462 case ZeroDigit:
1463 break;
1464 case LanguageId:
1465 case CountryId: {
1466 QString preferredLanguage;
1467 QString preferredCountry;
1468 getMacPreferredLanguageAndCountry(&preferredLanguage, &preferredCountry);
1469 QLocale::Language languageCode = (preferredLanguage.isEmpty() ? QLocale::C : codeToLanguage(preferredLanguage.data()));
1470 QLocale::Country countryCode = (preferredCountry.isEmpty() ? QLocale::AnyCountry : codeToCountry(preferredCountry.data()));
1471 const QLocalePrivate *d = findLocale(languageCode, countryCode);
1472 if (type == LanguageId)
1473 return (QLocale::Language)d->languageId();
1474 return (QLocale::Country)d->countryId();
1475 }
1476
1477 case MeasurementSystem:
1478 return QVariant(static_cast<int>(macMeasurementSystem()));
1479
1480 case AMText:
1481 case PMText:
1482 break;
1483 default:
1484 break;
1485 }
1486 return QVariant();
1487}
1488
1489#elif defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
1490
1491static uint unixGetSystemMeasurementSystem()
1492{
1493 QString meas_locale = QString::fromLocal8Bit(qgetenv("LC_ALL"));
1494 if (meas_locale.isEmpty()) {
1495 meas_locale = QString::fromLocal8Bit(qgetenv("LC_MEASUREMENT"));
1496 }
1497 if (meas_locale.isEmpty()) {
1498 meas_locale = QString::fromLocal8Bit(qgetenv("LANG"));
1499 }
1500 if (meas_locale.isEmpty()) {
1501 meas_locale = QString::fromLocal8Bit("C");
1502 }
1503
1504 if (meas_locale.compare(QString::fromLocal8Bit("Metric"), Qt::CaseInsensitive) == 0)
1505 return 0;
1506 if (meas_locale.compare(QString::fromLocal8Bit("Other"), Qt::CaseInsensitive) == 0)
1507 return 0;
1508
1509 const QLocalePrivate* locale = findLocale(meas_locale);
1510 return locale->measurementSystem();
1511}
1512
1513/*!
1514 \internal
1515*/
1516QLocale QSystemLocale::fallbackLocale() const
1517{
1518 return QLocale(QLatin1String(envVarLocale()));
1519}
1520
1521/*!
1522 \internal
1523*/
1524QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const
1525{
1526 if (type == MeasurementSystem) {
1527 return QVariant(unixGetSystemMeasurementSystem());
1528 } else {
1529 return QVariant();
1530 }
1531}
1532
1533#elif !defined(Q_OS_SYMBIAN)
1534
1535/*!
1536 \since 4.6
1537
1538 Returns a fallback locale, that will get used for everything that
1539 is not explicitly overridden by the system locale.
1540*/
1541QLocale QSystemLocale::fallbackLocale() const
1542{
1543 return QLocale(QLatin1String(envVarLocale()));
1544}
1545
1546/*!
1547 Performs a query of the given \a type in the system locale for
1548 customized values or conversion. If the method returns a null
1549 QVariant, the conversion of the fallbackLocale() will be used.
1550
1551 \a in is unused for some of the query types.
1552
1553 \sa QSystemLocale::QueryType
1554*/
1555QVariant QSystemLocale::query(QueryType /* type */, QVariant /* in */) const
1556{
1557 return QVariant();
1558}
1559
1560#endif
1561
1562#ifndef QT_NO_SYSTEMLOCALE
1563static QSystemLocale *_systemLocale = 0;
1564Q_GLOBAL_STATIC_WITH_ARGS(QSystemLocale, QSystemLocale_globalSystemLocale, (true))
1565static QLocalePrivate *system_lp = 0;
1566Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
1567#endif
1568
1569/******************************************************************************
1570** Default system locale behavior
1571*/
1572
1573/*!
1574 \class QSystemLocale
1575 \brief The QSystemLocale class can be used to finetune the system locale
1576 of the user.
1577 \since 4.2
1578
1579 \ingroup i18n
1580
1581 \warning This class is only useful in very rare cases. Usually QLocale offers
1582 all the functionality required for application development.
1583
1584 QSystemLocale allows to override the values provided by the system
1585 locale (QLocale::system()).
1586
1587 \sa QLocale
1588*/
1589
1590/*!
1591 \enum QSystemLocale::QueryType
1592
1593 Specifies the type of information queried by query(). For each value
1594 the type of information to return from the query() method is listed.
1595
1596 \value LanguageId a uint specifying the language.
1597 \value CountryId a uint specifying the country.
1598 \value DecimalPoint a QString specifying the decimal point.
1599 \value GroupSeparator a QString specifying the group separator.
1600 \value ZeroDigit a QString specifying the zero digit.
1601 \value NegativeSign a QString specifying the minus sign.
1602 \value PositiveSign a QString specifying the plus sign.
1603 \value DateFormatLong a QString specifying the long date format
1604 \value DateFormatShort a QString specifying the short date format
1605 \value TimeFormatLong a QString specifying the long time format
1606 \value TimeFormatShort a QString specifying the short time format
1607 \value DayNameLong a QString specifying the name of a weekday. the in variant contains an integer between 1 and 7 (Monday - Sunday)
1608 \value DayNameShort a QString specifying the short name of a weekday. the in variant contains an integer between 1 and 7 (Monday - Sunday)
1609 \value MonthNameLong a QString specifying the name of a month. the in variant contains an integer between 1 and 12
1610 \value MonthNameShort a QString specifying the short name of a month. the in variant contains an integer between 1 and 12
1611 \value DateToStringLong converts the QDate stored in the in variant to a QString using the long date format
1612 \value DateToStringShort converts the QDate stored in the in variant to a QString using the short date format
1613 \value TimeToStringLong converts the QTime stored in the in variant to a QString using the long time format
1614 \value TimeToStringShort converts the QTime stored in the in variant to a QString using the short time format
1615 \value DateTimeFormatLong a QString specifying the long date time format
1616 \value DateTimeFormatShort a QString specifying the short date time format
1617 \value DateTimeToStringLong converts the QDateTime in the in variant to a QString using the long datetime format
1618 \value DateTimeToStringShort converts the QDateTime in the in variant to a QString using the short datetime format
1619 \value MeasurementSystem a QLocale::MeasurementSystem enum specifying the measurement system
1620 \value AMText a string that represents the system AM designator associated with a 12-hour clock.
1621 \value PMText a string that represents the system PM designator associated with a 12-hour clock.
1622*/
1623
1624/*!
1625 Constructs a QSystemLocale object. The constructor will automatically
1626 install this object as the system locale and remove any earlier installed
1627 system locales.
1628*/
1629QSystemLocale::QSystemLocale()
1630{
1631 delete _systemLocale;
1632 _systemLocale = this;
1633
1634 if (system_lp)
1635 system_lp->m_language_id = 0;
1636}
1637
1638/*! \internal */
1639QSystemLocale::QSystemLocale(bool)
1640{ }
1641
1642/*!
1643 Deletes the object.
1644*/
1645QSystemLocale::~QSystemLocale()
1646{
1647 if (_systemLocale == this) {
1648 _systemLocale = 0;
1649
1650 if (system_lp)
1651 system_lp->m_language_id = 0;
1652 }
1653}
1654
1655static const QSystemLocale *systemLocale()
1656{
1657 if (_systemLocale)
1658 return _systemLocale;
1659 return QSystemLocale_globalSystemLocale();
1660}
1661
1662void QLocalePrivate::updateSystemPrivate()
1663{
1664 const QSystemLocale *sys_locale = systemLocale();
1665 if (!system_lp)
1666 system_lp = globalLocalePrivate();
1667 *system_lp = *sys_locale->fallbackLocale().d();
1668
1669 QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
1670 if (!res.isNull())
1671 system_lp->m_language_id = res.toInt();
1672 res = sys_locale->query(QSystemLocale::CountryId, QVariant());
1673 if (!res.isNull())
1674 system_lp->m_country_id = res.toInt();
1675
1676 res = sys_locale->query(QSystemLocale::DecimalPoint, QVariant());
1677 if (!res.isNull())
1678 system_lp->m_decimal = res.toString().at(0).unicode();
1679
1680 res = sys_locale->query(QSystemLocale::GroupSeparator, QVariant());
1681 if (!res.isNull())
1682 system_lp->m_group = res.toString().at(0).unicode();
1683
1684 res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant());
1685 if (!res.isNull())
1686 system_lp->m_zero = res.toString().at(0).unicode();
1687
1688 res = sys_locale->query(QSystemLocale::NegativeSign, QVariant());
1689 if (!res.isNull())
1690 system_lp->m_minus = res.toString().at(0).unicode();
1691
1692 res = sys_locale->query(QSystemLocale::PositiveSign, QVariant());
1693 if (!res.isNull())
1694 system_lp->m_plus = res.toString().at(0).unicode();
1695}
1696#endif
1697
1698static const QLocalePrivate *systemPrivate()
1699{
1700#ifndef QT_NO_SYSTEMLOCALE
1701 // copy over the information from the fallback locale and modify
1702 if (!system_lp || system_lp->m_language_id == 0)
1703 QLocalePrivate::updateSystemPrivate();
1704
1705 return system_lp;
1706#else
1707 return locale_data;
1708#endif
1709}
1710
1711static const QLocalePrivate *defaultPrivate()
1712{
1713 if (!default_lp)
1714 default_lp = systemPrivate();
1715 return default_lp;
1716}
1717
1718static QString getLocaleListData(const ushort *data, int size, int index)
1719{
1720 static const ushort separator = ';';
1721 while (index && size > 0) {
1722 while (*data != separator)
1723 ++data, --size;
1724 --index;
1725 ++data;
1726 --size;
1727 }
1728 const ushort *end = data;
1729 while (size > 0 && *end != separator)
1730 ++end, --size;
1731 return QString::fromRawData(reinterpret_cast<const QChar*>(data), end-data);
1732}
1733
1734static inline QString getLocaleData(const ushort *data, int size)
1735{
1736 return QString::fromRawData(reinterpret_cast<const QChar*>(data), size);
1737}
1738
1739
1740#ifndef QT_NO_DATASTREAM
1741QDataStream &operator<<(QDataStream &ds, const QLocale &l)
1742{
1743 ds << l.name();
1744 return ds;
1745}
1746
1747QDataStream &operator>>(QDataStream &ds, QLocale &l)
1748{
1749 QString s;
1750 ds >> s;
1751 l = QLocale(s);
1752 return ds;
1753}
1754#endif // QT_NO_DATASTREAM
1755
1756
1757/*!
1758 \class QLocale
1759 \brief The QLocale class converts between numbers and their
1760 string representations in various languages.
1761
1762 \reentrant
1763 \ingroup i18n
1764 \ingroup string-processing
1765 \ingroup shared
1766
1767
1768 QLocale is initialized with a language/country pair in its
1769 constructor and offers number-to-string and string-to-number
1770 conversion functions similar to those in QString.
1771
1772 Example:
1773
1774 \snippet doc/src/snippets/code/src_corelib_tools_qlocale.cpp 0
1775
1776 QLocale supports the concept of a default locale, which is
1777 determined from the system's locale settings at application
1778 startup. The default locale can be changed by calling the
1779 static member setDefault(). Setting the default locale has the
1780 following effects:
1781
1782 \list
1783 \i If a QLocale object is constructed with the default constructor,
1784 it will use the default locale's settings.
1785 \i QString::toInt(), QString::toDouble(), etc., interpret the
1786 string according to the default locale. If this fails, it
1787 falls back on the "C" locale.
1788 \i QString::arg() uses the default locale to format a number when
1789 its position specifier in the format string contains an 'L',
1790 e.g. "%L1".
1791 \endlist
1792
1793 The following example illustrates how to use QLocale directly:
1794
1795 \snippet doc/src/snippets/code/src_corelib_tools_qlocale.cpp 1
1796
1797 When a language/country pair is specified in the constructor, one
1798 of three things can happen:
1799
1800 \list
1801 \i If the language/country pair is found in the database, it is used.
1802 \i If the language is found but the country is not, or if the country
1803 is \c AnyCountry, the language is used with the most
1804 appropriate available country (for example, Germany for German),
1805 \i If neither the language nor the country are found, QLocale
1806 defaults to the default locale (see setDefault()).
1807 \endlist
1808
1809 The "C" locale is identical in behavior to \l{English}/\l{UnitedStates}.
1810
1811 Use language() and country() to determine the actual language and
1812 country values used.
1813
1814 An alternative method for constructing a QLocale object is by
1815 specifying the locale name.
1816
1817 \snippet doc/src/snippets/code/src_corelib_tools_qlocale.cpp 2
1818
1819 This constructor converts the locale name to a language/country
1820 pair; it does not use the system locale database.
1821
1822 QLocale's data is based on Common Locale Data Repository v1.6.1.
1823
1824 The double-to-string and string-to-double conversion functions are
1825 covered by the following licenses:
1826
1827 \legalese
1828 Copyright (c) 1991 by AT&T.
1829
1830 Permission to use, copy, modify, and distribute this software for any
1831 purpose without fee is hereby granted, provided that this entire notice
1832 is included in all copies of any software which is or includes a copy
1833 or modification of this software and in all copies of the supporting
1834 documentation for such software.
1835
1836 THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
1837 WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
1838 REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
1839 OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
1840
1841 This product includes software developed by the University of
1842 California, Berkeley and its contributors.
1843
1844 \sa QString::arg(), QString::toInt(), QString::toDouble()
1845*/
1846
1847/*!
1848 \enum QLocale::Language
1849
1850 This enumerated type is used to specify a language.
1851
1852 \value C The "C" locale is identical in behavior to English/UnitedStates.
1853 \value Abkhazian
1854 \value Afan
1855 \value Afar
1856 \value Afrikaans
1857 \value Albanian
1858 \value Amharic
1859 \value Arabic
1860 \value Armenian
1861 \value Assamese
1862 \value Aymara
1863 \value Azerbaijani
1864 \value Bashkir
1865 \value Basque
1866 \value Bengali
1867 \value Bhutani
1868 \value Bihari
1869 \value Bislama
1870 \value Bosnian
1871 \value Breton
1872 \value Bulgarian
1873 \value Burmese
1874 \value Byelorussian
1875 \value Cambodian
1876 \value Catalan
1877 \value Chinese
1878 \value Cornish
1879 \value Corsican
1880 \value Croatian
1881 \value Czech
1882 \value Danish
1883 \value Divehi
1884 \value Dutch
1885 \value English
1886 \value Esperanto
1887 \value Estonian
1888 \value Faroese
1889 \value FijiLanguage
1890 \value Finnish
1891 \value French
1892 \value Frisian
1893 \value Gaelic
1894 \value Galician
1895 \value Georgian
1896 \value German
1897 \value Greek
1898 \value Greenlandic
1899 \value Guarani
1900 \value Gujarati
1901 \value Hausa
1902 \value Hebrew
1903 \value Hindi
1904 \value Hungarian
1905 \value Icelandic
1906 \value Indonesian
1907 \value Interlingua
1908 \value Interlingue
1909 \value Inuktitut
1910 \value Inupiak
1911 \value Irish
1912 \value Italian
1913 \value Japanese
1914 \value Javanese
1915 \value Kannada
1916 \value Kashmiri
1917 \value Kazakh
1918 \value Kinyarwanda
1919 \value Kirghiz
1920 \value Korean
1921 \value Kurdish
1922 \value Kurundi
1923 \value Laothian
1924 \value Latin
1925 \value Latvian
1926 \value Lingala
1927 \value Lithuanian
1928 \value Macedonian
1929 \value Malagasy
1930 \value Malay
1931 \value Malayalam
1932 \value Maltese
1933 \value Manx
1934 \value Maori
1935 \value Marathi
1936 \value Moldavian
1937 \value Mongolian
1938 \value NauruLanguage
1939 \value Nepali
1940 \value Norwegian
1941 \value NorwegianBokmal
1942 \value Nynorsk Obsolete, please use NorwegianNynorsk
1943 \value NorwegianNynorsk
1944 \value Occitan
1945 \value Oriya
1946 \value Pashto
1947 \value Persian
1948 \value Polish
1949 \value Portuguese
1950 \value Punjabi
1951 \value Quechua
1952 \value RhaetoRomance
1953 \value Romanian
1954 \value Russian
1955 \value Samoan
1956 \value Sangho
1957 \value Sanskrit
1958 \value Serbian
1959 \value SerboCroatian
1960 \value Sesotho
1961 \value Setswana
1962 \value Shona
1963 \value Sindhi
1964 \value Singhalese
1965 \value Siswati
1966 \value Slovak
1967 \value Slovenian
1968 \value Somali
1969 \value Spanish
1970 \value Sundanese
1971 \value Swahili
1972 \value Swedish
1973 \value Tagalog
1974 \value Tajik
1975 \value Tamil
1976 \value Tatar
1977 \value Telugu
1978 \value Thai
1979 \value Tibetan
1980 \value Tigrinya
1981 \value TongaLanguage
1982 \value Tsonga
1983 \value Turkish
1984 \value Turkmen
1985 \value Twi
1986 \value Uigur
1987 \value Ukrainian
1988 \value Urdu
1989 \value Uzbek
1990 \value Vietnamese
1991 \value Volapuk
1992 \value Welsh
1993 \value Wolof
1994 \value Xhosa
1995 \value Yiddish
1996 \value Yoruba
1997 \value Zhuang
1998 \value Zulu
1999 \value Bosnian
2000 \value Divehi
2001 \value Manx
2002 \value Cornish
2003 \value Akan
2004 \value Konkani
2005 \value Ga
2006 \value Igbo
2007 \value Kamba
2008 \value Syriac
2009 \value Blin
2010 \value Geez
2011 \value Koro
2012 \value Sidamo
2013 \value Atsam
2014 \value Tigre
2015 \value Jju
2016 \value Friulian
2017 \value Venda
2018 \value Ewe
2019 \value Walamo
2020 \value Hawaiian
2021 \value Tyap
2022 \value Chewa
2023 \omitvalue LastLanguage
2024
2025 \sa language()
2026*/
2027
2028/*!
2029 \enum QLocale::Country
2030
2031 This enumerated type is used to specify a country.
2032
2033 \value AnyCountry
2034 \value Afghanistan
2035 \value Albania
2036 \value Algeria
2037 \value AmericanSamoa
2038 \value Andorra
2039 \value Angola
2040 \value Anguilla
2041 \value Antarctica
2042 \value AntiguaAndBarbuda
2043 \value Argentina
2044 \value Armenia
2045 \value Aruba
2046 \value Australia
2047 \value Austria
2048 \value Azerbaijan
2049 \value Bahamas
2050 \value Bahrain
2051 \value Bangladesh
2052 \value Barbados
2053 \value Belarus
2054 \value Belgium
2055 \value Belize
2056 \value Benin
2057 \value Bermuda
2058 \value Bhutan
2059 \value Bolivia
2060 \value BosniaAndHerzegowina
2061 \value Botswana
2062 \value BouvetIsland
2063 \value Brazil
2064 \value BritishIndianOceanTerritory
2065 \value BruneiDarussalam
2066 \value Bulgaria
2067 \value BurkinaFaso
2068 \value Burundi
2069 \value Cambodia
2070 \value Cameroon
2071 \value Canada
2072 \value CapeVerde
2073 \value CaymanIslands
2074 \value CentralAfricanRepublic
2075 \value Chad
2076 \value Chile
2077 \value China
2078 \value ChristmasIsland
2079 \value CocosIslands
2080 \value Colombia
2081 \value Comoros
2082 \value DemocraticRepublicOfCongo
2083 \value PeoplesRepublicOfCongo
2084 \value CookIslands
2085 \value CostaRica
2086 \value IvoryCoast
2087 \value Croatia
2088 \value Cuba
2089 \value Cyprus
2090 \value CzechRepublic
2091 \value Denmark
2092 \value Djibouti
2093 \value Dominica
2094 \value DominicanRepublic
2095 \value EastTimor
2096 \value Ecuador
2097 \value Egypt
2098 \value ElSalvador
2099 \value EquatorialGuinea
2100 \value Eritrea
2101 \value Estonia
2102 \value Ethiopia
2103 \value FalklandIslands
2104 \value FaroeIslands
2105 \value FijiCountry
2106 \value Finland
2107 \value France
2108 \value MetropolitanFrance
2109 \value FrenchGuiana
2110 \value FrenchPolynesia
2111 \value FrenchSouthernTerritories
2112 \value Gabon
2113 \value Gambia
2114 \value Georgia
2115 \value Germany
2116 \value Ghana
2117 \value Gibraltar
2118 \value Greece
2119 \value Greenland
2120 \value Grenada
2121 \value Guadeloupe
2122 \value Guam
2123 \value Guatemala
2124 \value Guinea
2125 \value GuineaBissau
2126 \value Guyana
2127 \value Haiti
2128 \value HeardAndMcDonaldIslands
2129 \value Honduras
2130 \value HongKong
2131 \value Hungary
2132 \value Iceland
2133 \value India
2134 \value Indonesia
2135 \value Iran
2136 \value Iraq
2137 \value Ireland
2138 \value Israel
2139 \value Italy
2140 \value Jamaica
2141 \value Japan
2142 \value Jordan
2143 \value Kazakhstan
2144 \value Kenya
2145 \value Kiribati
2146 \value DemocraticRepublicOfKorea
2147 \value RepublicOfKorea
2148 \value Kuwait
2149 \value Kyrgyzstan
2150 \value Lao
2151 \value Latvia
2152 \value Lebanon
2153 \value Lesotho
2154 \value Liberia
2155 \value LibyanArabJamahiriya
2156 \value Liechtenstein
2157 \value Lithuania
2158 \value Luxembourg
2159 \value Macau
2160 \value Macedonia
2161 \value Madagascar
2162 \value Malawi
2163 \value Malaysia
2164 \value Maldives
2165 \value Mali
2166 \value Malta
2167 \value MarshallIslands
2168 \value Martinique
2169 \value Mauritania
2170 \value Mauritius
2171 \value Mayotte
2172 \value Mexico
2173 \value Micronesia
2174 \value Moldova
2175 \value Monaco
2176 \value Mongolia
2177 \value Montserrat
2178 \value Morocco
2179 \value Mozambique
2180 \value Myanmar
2181 \value Namibia
2182 \value NauruCountry
2183 \value Nepal
2184 \value Netherlands
2185 \value NetherlandsAntilles
2186 \value NewCaledonia
2187 \value NewZealand
2188 \value Nicaragua
2189 \value Niger
2190 \value Nigeria
2191 \value Niue
2192 \value NorfolkIsland
2193 \value NorthernMarianaIslands
2194 \value Norway
2195 \value Oman
2196 \value Pakistan
2197 \value Palau
2198 \value PalestinianTerritory
2199 \value Panama
2200 \value PapuaNewGuinea
2201 \value Paraguay
2202 \value Peru
2203 \value Philippines
2204 \value Pitcairn
2205 \value Poland
2206 \value Portugal
2207 \value PuertoRico
2208 \value Qatar
2209 \value Reunion
2210 \value Romania
2211 \value RussianFederation
2212 \value Rwanda
2213 \value SaintKittsAndNevis
2214 \value StLucia
2215 \value StVincentAndTheGrenadines
2216 \value Samoa
2217 \value SanMarino
2218 \value SaoTomeAndPrincipe
2219 \value SaudiArabia
2220 \value Senegal
2221 \value SerbiaAndMontenegro
2222 \value Seychelles
2223 \value SierraLeone
2224 \value Singapore
2225 \value Slovakia
2226 \value Slovenia
2227 \value SolomonIslands
2228 \value Somalia
2229 \value SouthAfrica
2230 \value SouthGeorgiaAndTheSouthSandwichIslands
2231 \value Spain
2232 \value SriLanka
2233 \value StHelena
2234 \value StPierreAndMiquelon
2235 \value Sudan
2236 \value Suriname
2237 \value SvalbardAndJanMayenIslands
2238 \value Swaziland
2239 \value Sweden
2240 \value Switzerland
2241 \value SyrianArabRepublic
2242 \value Taiwan
2243 \value Tajikistan
2244 \value Tanzania
2245 \value Thailand
2246 \value Togo
2247 \value Tokelau
2248 \value TongaCountry
2249 \value TrinidadAndTobago
2250 \value Tunisia
2251 \value Turkey
2252 \value Turkmenistan
2253 \value TurksAndCaicosIslands
2254 \value Tuvalu
2255 \value Uganda
2256 \value Ukraine
2257 \value UnitedArabEmirates
2258 \value UnitedKingdom
2259 \value UnitedStates
2260 \value UnitedStatesMinorOutlyingIslands
2261 \value Uruguay
2262 \value Uzbekistan
2263 \value Vanuatu
2264 \value VaticanCityState
2265 \value Venezuela
2266 \value VietNam
2267 \value BritishVirginIslands
2268 \value USVirginIslands
2269 \value WallisAndFutunaIslands
2270 \value WesternSahara
2271 \value Yemen
2272 \value Yugoslavia
2273 \value Zambia
2274 \value Zimbabwe
2275 \omitvalue LastCountry
2276
2277 \sa country()
2278*/
2279
2280/*!
2281 \enum QLocale::FormatType
2282
2283 This enum describes the types of format that can be used when
2284 converting QDate and QTime objects to strings.
2285
2286 \value LongFormat The long version of day and month names; for
2287 example, returning "January" as a month name.
2288
2289 \value ShortFormat The short version of day and month names; for
2290 example, returning "Jan" as a month name.
2291
2292 \value NarrowFormat A special version of day and month names for
2293 use when space is limited; for example, returning "J" as a month
2294 name. Note that the narrow format might contain the same text for
2295 different months and days or it can even be an empty string if the
2296 locale doesn't support narrow names, so you should avoid using it
2297 for date formatting. Also, for the system locale this format is
2298 the same as ShortFormat.
2299*/
2300
2301/*!
2302 \enum QLocale::NumberOption
2303
2304 This enum defines a set of options for number-to-string and string-to-number
2305 conversions. They can be retrieved with numberOptions() and set with
2306 setNumberOptions().
2307
2308 \value OmitGroupSeparator If this option is set, the number-to-string functions
2309 will not insert group separators in their return values. The default
2310 is to insert group separators.
2311 \value RejectGroupSeparator If this option is set, the string-to-number functions
2312 will fail if they encounter group separators in their input. The default
2313 is to accept numbers containing correctly placed group separators.
2314
2315 \sa setNumberOptions() numberOptions()
2316*/
2317
2318/*!
2319 \enum QLocale::MeasurementSystem
2320
2321 This enum defines which units are used for measurement.
2322
2323 \value MetricSystem This value indicates metric units, such as meters,
2324 centimeters and millimeters.
2325 \value ImperialSystem This value indicates imperial units, such as inches and
2326 miles. There are several distinct imperial systems in the world; this
2327 value stands for the official United States imperial units.
2328
2329 \since 4.4
2330*/
2331
2332
2333/*!
2334 \fn bool QLocale::operator==(const QLocale &other) const
2335
2336 Returns true if the QLocale object is the same as the \a other
2337 locale specified; otherwise returns false.
2338*/
2339
2340/*!
2341 \fn bool QLocale::operator!=(const QLocale &other) const
2342
2343 Returns true if the QLocale object is not the same as the \a other
2344 locale specified; otherwise returns false.
2345*/
2346
2347static const int locale_data_size = sizeof(locale_data)/sizeof(QLocalePrivate) - 1;
2348
2349static const QLocalePrivate *dataPointerHelper(quint16 index)
2350{
2351#ifndef QT_NO_SYSTEMLOCALE
2352 Q_ASSERT(index <= locale_data_size);
2353 if (index == locale_data_size)
2354 return system_lp;
2355#else
2356 Q_ASSERT(index < locale_data_size);
2357#endif
2358
2359 return &locale_data[index];
2360}
2361
2362static quint16 localePrivateIndex(const QLocalePrivate *p)
2363{
2364#ifndef QT_NO_SYSTEMLOCALE
2365 Q_ASSERT((p >= locale_data && p - locale_data < locale_data_size)
2366 || (p != 0 && p == system_lp));
2367 quint16 index = p == system_lp ? locale_data_size : p - locale_data;
2368#else
2369 Q_ASSERT(p >= locale_data && p - locale_data < locale_data_size);
2370 quint16 index = p - locale_data;
2371#endif
2372
2373 return index;
2374}
2375
2376/*!
2377 Constructs a QLocale object with the specified \a name,
2378 which has the format
2379 "language[_country][.codeset][@modifier]" or "C", where:
2380
2381 \list
2382 \i language is a lowercase, two-letter, ISO 639 language code,
2383 \i territory is an uppercase, two-letter, ISO 3166 country code,
2384 \i and codeset and modifier are ignored.
2385 \endlist
2386
2387 If the string violates the locale format, or language is not
2388 a valid ISO 369 code, the "C" locale is used instead. If country
2389 is not present, or is not a valid ISO 3166 code, the most
2390 appropriate country is chosen for the specified language.
2391
2392 The language and country codes are converted to their respective
2393 \c Language and \c Country enums. After this conversion is
2394 performed the constructor behaves exactly like QLocale(Country,
2395 Language).
2396
2397 This constructor is much slower than QLocale(Country, Language).
2398
2399 \sa name()
2400*/
2401
2402QLocale::QLocale(const QString &name)
2403 : v(0)
2404{
2405 p.numberOptions = 0;
2406 p.index = localePrivateIndex(findLocale(name));
2407}
2408
2409/*!
2410 Constructs a QLocale object initialized with the default locale. If
2411 no default locale was set using setDefaultLocale(), this locale will
2412 be the same as the one returned by system().
2413
2414 \sa setDefault()
2415*/
2416
2417QLocale::QLocale()
2418 : v(0)
2419{
2420 p.numberOptions = default_number_options;
2421 p.index = localePrivateIndex(defaultPrivate());
2422}
2423
2424/*!
2425 Constructs a QLocale object with the specified \a language and \a
2426 country.
2427
2428 \list
2429 \i If the language/country pair is found in the database, it is used.
2430 \i If the language is found but the country is not, or if the country
2431 is \c AnyCountry, the language is used with the most
2432 appropriate available country (for example, Germany for German),
2433 \i If neither the language nor the country are found, QLocale
2434 defaults to the default locale (see setDefault()).
2435 \endlist
2436
2437 The language and country that are actually used can be queried
2438 using language() and country().
2439
2440 \sa setDefault() language() country()
2441*/
2442
2443QLocale::QLocale(Language language, Country country)
2444 : v(0)
2445{
2446 const QLocalePrivate *d = findLocale(language, country);
2447
2448 // If not found, should default to system
2449 if (d->languageId() == QLocale::C && language != QLocale::C) {
2450 p.numberOptions = default_number_options;
2451 p.index = localePrivateIndex(defaultPrivate());
2452 } else {
2453 p.numberOptions = 0;
2454 p.index = localePrivateIndex(d);
2455 }
2456}
2457
2458/*!
2459 Constructs a QLocale object as a copy of \a other.
2460*/
2461
2462QLocale::QLocale(const QLocale &other)
2463{
2464 v = other.v;
2465}
2466
2467const QLocalePrivate *QLocale::d() const
2468{
2469 return dataPointerHelper(p.index);
2470}
2471
2472/*!
2473 Assigns \a other to this QLocale object and returns a reference
2474 to this QLocale object.
2475*/
2476
2477QLocale &QLocale::operator=(const QLocale &other)
2478{
2479 v = other.v;
2480 return *this;
2481}
2482
2483/*!
2484 \since 4.2
2485
2486 Sets the \a options related to number conversions for this
2487 QLocale instance.
2488*/
2489void QLocale::setNumberOptions(NumberOptions options)
2490{
2491 p.numberOptions = options;
2492}
2493
2494/*!
2495 \since 4.2
2496
2497 Returns the options related to number conversions for this
2498 QLocale instance.
2499
2500 By default, no options are set for the standard locales.
2501*/
2502QLocale::NumberOptions QLocale::numberOptions() const
2503{
2504 return static_cast<NumberOption>(p.numberOptions);
2505}
2506
2507/*!
2508 \nonreentrant
2509
2510 Sets the global default locale to \a locale. These
2511 values are used when a QLocale object is constructed with
2512 no arguments. If this function is not called, the system's
2513 locale is used.
2514
2515 \warning In a multithreaded application, the default locale
2516 should be set at application startup, before any non-GUI threads
2517 are created.
2518
2519 \sa system() c()
2520*/
2521
2522void QLocale::setDefault(const QLocale &locale)
2523{
2524 default_lp = locale.d();
2525 default_number_options = locale.numberOptions();
2526}
2527
2528/*!
2529 Returns the language of this locale.
2530
2531 \sa country(), languageToString(), name()
2532*/
2533QLocale::Language QLocale::language() const
2534{
2535 return Language(d()->languageId());
2536}
2537
2538/*!
2539 Returns the country of this locale.
2540
2541 \sa language(), countryToString(), name()
2542*/
2543QLocale::Country QLocale::country() const
2544{
2545 return Country(d()->countryId());
2546}
2547
2548/*!
2549 Returns the language and country of this locale as a
2550 string of the form "language_country", where
2551 language is a lowercase, two-letter ISO 639 language code,
2552 and country is an uppercase, two-letter ISO 3166 country code.
2553
2554 \sa language(), country()
2555*/
2556
2557QString QLocale::name() const
2558{
2559 Language l = language();
2560
2561 QString result = languageToCode(l);
2562
2563 if (l == C)
2564 return result;
2565
2566 Country c = country();
2567 if (c == AnyCountry)
2568 return result;
2569
2570 result.append(QLatin1Char('_'));
2571 result.append(countryToCode(c));
2572
2573 return result;
2574}
2575
2576/*!
2577 Returns a QString containing the name of \a language.
2578
2579 \sa countryToString(), name()
2580*/
2581
2582QString QLocale::languageToString(Language language)
2583{
2584 if (uint(language) > uint(QLocale::LastLanguage))
2585 return QLatin1String("Unknown");
2586 return QLatin1String(language_name_list + language_name_index[language]);
2587}
2588
2589/*!
2590 Returns a QString containing the name of \a country.
2591
2592 \sa country(), name()
2593*/
2594
2595QString QLocale::countryToString(Country country)
2596{
2597 if (uint(country) > uint(QLocale::LastCountry))
2598 return QLatin1String("Unknown");
2599 return QLatin1String(country_name_list + country_name_index[country]);
2600}
2601
2602/*!
2603 Returns the short int represented by the localized string \a s,
2604 using base \a base. If \a base is 0 the base is determined
2605 automatically using the following rules: If the string begins with
2606 "0x", it is assumed to be hexadecimal; if it begins with "0", it
2607 is assumed to be octal; otherwise it is assumed to be decimal.
2608
2609 If the conversion fails the function returns 0.
2610
2611 If \a ok is not 0, failure is reported by setting *ok to false, and
2612 success by setting *ok to true.
2613
2614 This function ignores leading and trailing whitespace.
2615
2616 \sa toUShort(), toString()
2617*/
2618
2619short QLocale::toShort(const QString &s, bool *ok, int base) const
2620{
2621 qlonglong i = toLongLong(s, ok, base);
2622 if (i < SHRT_MIN || i > SHRT_MAX) {
2623 if (ok != 0)
2624 *ok = false;
2625 return 0;
2626 }
2627 return short(i);
2628}
2629
2630/*!
2631 Returns the unsigned short int represented by the localized string
2632 \a s, using base \a base. If \a base is 0 the base is determined
2633 automatically using the following rules: If the string begins with
2634 "0x", it is assumed to be hexadecimal; if it begins with "0", it
2635 is assumed to be octal; otherwise it is assumed to be decimal.
2636
2637 If the conversion fails the function returns 0.
2638
2639 If \a ok is not 0, failure is reported by setting *ok to false, and
2640 success by setting *ok to true.
2641
2642 This function ignores leading and trailing whitespace.
2643
2644 \sa toShort(), toString()
2645*/
2646
2647ushort QLocale::toUShort(const QString &s, bool *ok, int base) const
2648{
2649 qulonglong i = toULongLong(s, ok, base);
2650 if (i > USHRT_MAX) {
2651 if (ok != 0)
2652 *ok = false;
2653 return 0;
2654 }
2655 return ushort(i);
2656}
2657
2658/*!
2659 Returns the int represented by the localized string \a s, using
2660 base \a base. If \a base is 0 the base is determined automatically
2661 using the following rules: If the string begins with "0x", it is
2662 assumed to be hexadecimal; if it begins with "0", it is assumed to
2663 be octal; otherwise it is assumed to be decimal.
2664
2665 If the conversion fails the function returns 0.
2666
2667 If \a ok is not 0, failure is reported by setting *ok to false, and
2668 success by setting *ok to true.
2669
2670 This function ignores leading and trailing whitespace.
2671
2672 \sa toUInt(), toString()
2673*/
2674
2675int QLocale::toInt(const QString &s, bool *ok, int base) const
2676{
2677 qlonglong i = toLongLong(s, ok, base);
2678 if (i < INT_MIN || i > INT_MAX) {
2679 if (ok != 0)
2680 *ok = false;
2681 return 0;
2682 }
2683 return int(i);
2684}
2685
2686/*!
2687 Returns the unsigned int represented by the localized string \a s,
2688 using base \a base. If \a base is 0 the base is determined
2689 automatically using the following rules: If the string begins with
2690 "0x", it is assumed to be hexadecimal; if it begins with "0", it
2691 is assumed to be octal; otherwise it is assumed to be decimal.
2692
2693 If the conversion fails the function returns 0.
2694
2695 If \a ok is not 0, failure is reported by setting *ok to false, and
2696 success by setting *ok to true.
2697
2698 This function ignores leading and trailing whitespace.
2699
2700 \sa toInt(), toString()
2701*/
2702
2703uint QLocale::toUInt(const QString &s, bool *ok, int base) const
2704{
2705 qulonglong i = toULongLong(s, ok, base);
2706 if (i > UINT_MAX) {
2707 if (ok != 0)
2708 *ok = false;
2709 return 0;
2710 }
2711 return uint(i);
2712}
2713
2714/*!
2715 Returns the long long int represented by the localized string \a
2716 s, using base \a base. If \a base is 0 the base is determined
2717 automatically using the following rules: If the string begins with
2718 "0x", it is assumed to be hexadecimal; if it begins with "0", it
2719 is assumed to be octal; otherwise it is assumed to be decimal.
2720
2721 If the conversion fails the function returns 0.
2722
2723 If \a ok is not 0, failure is reported by setting *ok to false, and
2724 success by setting *ok to true.
2725
2726 This function ignores leading and trailing whitespace.
2727
2728 \sa toInt(), toULongLong(), toDouble(), toString()
2729*/
2730
2731
2732qlonglong QLocale::toLongLong(const QString &s, bool *ok, int base) const
2733{
2734 QLocalePrivate::GroupSeparatorMode mode
2735 = p.numberOptions & RejectGroupSeparator
2736 ? QLocalePrivate::FailOnGroupSeparators
2737 : QLocalePrivate::ParseGroupSeparators;
2738
2739 return d()->stringToLongLong(s, base, ok, mode);
2740}
2741
2742// ### Qt5: make the return type for toULongLong() qulonglong.
2743
2744/*!
2745 Returns the unsigned long long int represented by the localized
2746 string \a s, using base \a base. If \a base is 0 the base is
2747 determined automatically using the following rules: If the string
2748 begins with "0x", it is assumed to be hexadecimal; if it begins
2749 with "0", it is assumed to be octal; otherwise it is assumed to be
2750 decimal.
2751
2752 If the conversion fails the function returns 0.
2753
2754 If \a ok is not 0, failure is reported by setting *ok to false, and
2755 success by setting *ok to true.
2756
2757 This function ignores leading and trailing whitespace.
2758
2759 \sa toLongLong(), toInt(), toDouble(), toString()
2760*/
2761
2762qlonglong QLocale::toULongLong(const QString &s, bool *ok, int base) const
2763{
2764 QLocalePrivate::GroupSeparatorMode mode
2765 = p.numberOptions & RejectGroupSeparator
2766 ? QLocalePrivate::FailOnGroupSeparators
2767 : QLocalePrivate::ParseGroupSeparators;
2768
2769 return d()->stringToUnsLongLong(s, base, ok, mode);
2770}
2771
2772/*!
2773 Returns the float represented by the localized string \a s, or 0.0
2774 if the conversion failed.
2775
2776 If \a ok is not 0, reports failure by setting
2777 *ok to false and success by setting *ok to true.
2778
2779 This function ignores leading and trailing whitespace.
2780
2781 \sa toDouble(), toInt(), toString()
2782*/
2783
2784#define QT_MAX_FLOAT 3.4028234663852886e+38
2785
2786float QLocale::toFloat(const QString &s, bool *ok) const
2787{
2788 bool myOk;
2789 double d = toDouble(s, &myOk);
2790 if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
2791 if (ok != 0)
2792 *ok = false;
2793 return 0.0;
2794 }
2795 if (ok != 0)
2796 *ok = true;
2797 return float(d);
2798}
2799
2800/*!
2801 Returns the double represented by the localized string \a s, or
2802 0.0 if the conversion failed.
2803
2804 If \a ok is not 0, reports failure by setting
2805 *ok to false and success by setting *ok to true.
2806
2807 Unlike QString::toDouble(), this function does not fall back to
2808 the "C" locale if the string cannot be interpreted in this
2809 locale.
2810
2811 \snippet doc/src/snippets/code/src_corelib_tools_qlocale.cpp 3
2812
2813 Notice that the last conversion returns 1234.0, because '.' is the
2814 thousands group separator in the German locale.
2815
2816 This function ignores leading and trailing whitespace.
2817
2818 \sa toFloat(), toInt(), toString()
2819*/
2820
2821double QLocale::toDouble(const QString &s, bool *ok) const
2822{
2823 QLocalePrivate::GroupSeparatorMode mode
2824 = p.numberOptions & RejectGroupSeparator
2825 ? QLocalePrivate::FailOnGroupSeparators
2826 : QLocalePrivate::ParseGroupSeparators;
2827
2828 return d()->stringToDouble(s, ok, mode);
2829}
2830
2831/*!
2832 Returns a localized string representation of \a i.
2833
2834 \sa toLongLong()
2835*/
2836
2837QString QLocale::toString(qlonglong i) const
2838{
2839 int flags = p.numberOptions & OmitGroupSeparator
2840 ? 0
2841 : QLocalePrivate::ThousandsGroup;
2842
2843 return d()->longLongToString(i, -1, 10, -1, flags);
2844}
2845
2846/*!
2847 \overload
2848
2849 \sa toULongLong()
2850*/
2851
2852QString QLocale::toString(qulonglong i) const
2853{
2854 int flags = p.numberOptions & OmitGroupSeparator
2855 ? 0
2856 : QLocalePrivate::ThousandsGroup;
2857
2858 return d()->unsLongLongToString(i, -1, 10, -1, flags);
2859}
2860
2861/*!
2862 Returns a localized string representation of the given \a date in the
2863 specified \a format.
2864 If \a format is an empty string, an empty string is returned.
2865*/
2866
2867QString QLocale::toString(const QDate &date, const QString &format) const
2868{
2869 return d()->dateTimeToString(format, &date, 0, this);
2870}
2871
2872/*!
2873 Returns a localized string representation of the given \a date according
2874 to the specified \a format.
2875*/
2876
2877QString QLocale::toString(const QDate &date, FormatType format) const
2878{
2879 if (!date.isValid())
2880 return QString();
2881
2882#ifndef QT_NO_SYSTEMLOCALE
2883 if (d() == systemPrivate()) {
2884 QVariant res = systemLocale()->query(format == LongFormat
2885 ? QSystemLocale::DateToStringLong : QSystemLocale::DateToStringShort,
2886 date);
2887 if (!res.isNull())
2888 return res.toString();
2889 }
2890#endif
2891
2892 QString format_str = dateFormat(format);
2893 return toString(date, format_str);
2894}
2895
2896static bool timeFormatContainsAP(const QString &format)
2897{
2898 int i = 0;
2899 while (i < format.size()) {
2900 if (format.at(i).unicode() == '\'') {
2901 readEscapedFormatString(format, &i);
2902 continue;
2903 }
2904
2905 if (format.at(i).toLower().unicode() == 'a')
2906 return true;
2907
2908 ++i;
2909 }
2910 return false;
2911}
2912
2913static QString timeZone()
2914{
2915#if defined(Q_OS_WINCE)
2916 TIME_ZONE_INFORMATION info;
2917 DWORD res = GetTimeZoneInformation(&info);
2918 if (res == TIME_ZONE_ID_UNKNOWN)
2919 return QString();
2920 return QString::fromWCharArray(info.StandardName);
2921#elif defined(Q_OS_WIN)
2922 _tzset();
2923# if defined(_MSC_VER) && _MSC_VER >= 1400
2924 size_t returnSize = 0;
2925 char timeZoneName[512];
2926 if (_get_tzname(&returnSize, timeZoneName, 512, 1))
2927 return QString();
2928 return QString::fromLocal8Bit(timeZoneName);
2929# else
2930 return QString::fromLocal8Bit(_tzname[1]);
2931# endif
2932#elif defined(Q_OS_VXWORKS)
2933 return QString();
2934#else
2935 tzset();
2936 return QString::fromLocal8Bit(tzname[1]);
2937#endif
2938}
2939
2940/*!
2941 Returns a localized string representation of the given \a time according
2942 to the specified \a format.
2943 If \a format is an empty string, an empty string is returned.
2944*/
2945QString QLocale::toString(const QTime &time, const QString &format) const
2946{
2947 return d()->dateTimeToString(format, 0, &time, this);
2948}
2949
2950/*!
2951 \since 4.4
2952
2953 Returns a localized string representation of the given \a dateTime according
2954 to the specified \a format.
2955 If \a format is an empty string, an empty string is returned.
2956*/
2957
2958QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
2959{
2960 const QDate dt = dateTime.date();
2961 const QTime tm = dateTime.time();
2962 return d()->dateTimeToString(format, &dt, &tm, this);
2963}
2964
2965/*!
2966 \since 4.4
2967
2968 Returns a localized string representation of the given \a dateTime according
2969 to the specified \a format.
2970*/
2971
2972QString QLocale::toString(const QDateTime &dateTime, FormatType format) const
2973{
2974 if (!dateTime.isValid())
2975 return QString();
2976
2977#ifndef QT_NO_SYSTEMLOCALE
2978 if (d() == systemPrivate()) {
2979 QVariant res = systemLocale()->query(format == LongFormat
2980 ? QSystemLocale::DateTimeToStringLong
2981 : QSystemLocale::DateTimeToStringShort,
2982 dateTime);
2983 if (!res.isNull())
2984 return res.toString();
2985 }
2986#endif
2987
2988 const QString format_str = dateTimeFormat(format);
2989 return toString(dateTime, format_str);
2990}
2991
2992
2993/*!
2994 Returns a localized string representation of the given \a time in the
2995 specified \a format.
2996*/
2997
2998QString QLocale::toString(const QTime &time, FormatType format) const
2999{
3000 if (!time.isValid())
3001 return QString();
3002
3003#ifndef QT_NO_SYSTEMLOCALE
3004 if (d() == systemPrivate()) {
3005 QVariant res = systemLocale()->query(format == LongFormat
3006 ? QSystemLocale::TimeToStringLong : QSystemLocale::TimeToStringShort,
3007 time);
3008 if (!res.isNull())
3009 return res.toString();
3010 }
3011#endif
3012
3013 QString format_str = timeFormat(format);
3014 return toString(time, format_str);
3015}
3016
3017/*!
3018 \since 4.1
3019
3020 Returns the date format used for the current locale.
3021
3022 If \a format is LongFormat the format will be a long version.
3023 Otherwise it uses a shorter version.
3024
3025 \sa QDate::toString(), QDate::fromString()
3026*/
3027
3028QString QLocale::dateFormat(FormatType format) const
3029{
3030#ifndef QT_NO_SYSTEMLOCALE
3031 if (d() == systemPrivate()) {
3032 QVariant res = systemLocale()->query(format == LongFormat
3033 ? QSystemLocale::DateFormatLong : QSystemLocale::DateFormatShort,
3034 QVariant());
3035 if (!res.isNull())
3036 return res.toString();
3037 }
3038#endif
3039
3040 quint32 idx, size;
3041 switch (format) {
3042 case LongFormat:
3043 idx = d()->m_long_date_format_idx;
3044 size = d()->m_long_date_format_size;
3045 break;
3046 default:
3047 idx = d()->m_short_date_format_idx;
3048 size = d()->m_short_date_format_size;
3049 break;
3050 }
3051 return getLocaleData(date_format_data + idx, size);
3052}
3053
3054/*!
3055 \since 4.1
3056
3057 Returns the time format used for the current locale.
3058
3059 If \a format is LongFormat the format will be a long version.
3060 Otherwise it uses a shorter version.
3061
3062 \sa QTime::toString(), QTime::fromString()
3063*/
3064
3065QString QLocale::timeFormat(FormatType format) const
3066{
3067#ifndef QT_NO_SYSTEMLOCALE
3068 if (d() == systemPrivate()) {
3069 QVariant res = systemLocale()->query(format == LongFormat
3070 ? QSystemLocale::TimeFormatLong : QSystemLocale::TimeFormatShort,
3071 QVariant());
3072 if (!res.isNull())
3073 return res.toString();
3074 }
3075#endif
3076
3077 quint32 idx, size;
3078 switch (format) {
3079 case LongFormat:
3080 idx = d()->m_long_time_format_idx;
3081 size = d()->m_long_time_format_size;
3082 break;
3083 default:
3084 idx = d()->m_short_time_format_idx;
3085 size = d()->m_short_time_format_size;
3086 break;
3087 }
3088 return getLocaleData(time_format_data + idx, size);
3089}
3090
3091/*!
3092 \since 4.4
3093
3094 Returns the date time format used for the current locale.
3095
3096 If \a format is ShortFormat the format will be a short version.
3097 Otherwise it uses a longer version.
3098
3099 \sa QDateTime::toString(), QDateTime::fromString()
3100*/
3101
3102QString QLocale::dateTimeFormat(FormatType format) const
3103{
3104#ifndef QT_NO_SYSTEMLOCALE
3105 if (d() == systemPrivate()) {
3106 QVariant res = systemLocale()->query(format == LongFormat
3107 ? QSystemLocale::DateTimeFormatLong
3108 : QSystemLocale::DateTimeFormatShort,
3109 QVariant());
3110 if (!res.isNull()) {
3111 return res.toString();
3112 }
3113 }
3114#endif
3115 return dateFormat(format) + QLatin1Char(' ') + timeFormat(format);
3116}
3117
3118/*!
3119 \since 4.4
3120
3121 Parses the time string given in \a string and returns the
3122 time. The format of the time string is chosen according to the
3123 \a format parameter (see timeFormat()).
3124
3125 If the time could not be parsed, returns an invalid time.
3126
3127 \sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
3128*/
3129#ifndef QT_NO_DATESTRING
3130QTime QLocale::toTime(const QString &string, FormatType format) const
3131{
3132 return toTime(string, timeFormat(format));
3133}
3134#endif
3135
3136/*!
3137 \since 4.4
3138
3139 Parses the date string given in \a string and returns the
3140 date. The format of the date string is chosen according to the
3141 \a format parameter (see dateFormat()).
3142
3143 If the date could not be parsed, returns an invalid date.
3144
3145 \sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
3146*/
3147#ifndef QT_NO_DATESTRING
3148QDate QLocale::toDate(const QString &string, FormatType format) const
3149{
3150 return toDate(string, dateFormat(format));
3151}
3152#endif
3153
3154/*!
3155 \since 4.4
3156
3157 Parses the date/time string given in \a string and returns the
3158 time. The format of the date/time string is chosen according to the
3159 \a format parameter (see dateTimeFormat()).
3160
3161 If the string could not be parsed, returns an invalid QDateTime.
3162
3163 \sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
3164*/
3165
3166#ifndef QT_NO_DATESTRING
3167QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
3168{
3169 return toDateTime(string, dateFormat(format));
3170}
3171#endif
3172
3173/*!
3174 \since 4.4
3175
3176 Parses the time string given in \a string and returns the
3177 time. See QTime::fromString() for information on what is a valid
3178 format string.
3179
3180 If the time could not be parsed, returns an invalid time.
3181
3182 \sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
3183*/
3184#ifndef QT_NO_DATESTRING
3185QTime QLocale::toTime(const QString &string, const QString &format) const
3186{
3187 QTime time;
3188#ifndef QT_BOOTSTRAPPED
3189 QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
3190 dt.defaultLocale = *this;
3191 if (dt.parseFormat(format))
3192 dt.fromString(string, 0, &time);
3193#else
3194 Q_UNUSED(string);
3195 Q_UNUSED(format);
3196#endif
3197 return time;
3198}
3199#endif
3200
3201/*!
3202 \since 4.4
3203
3204 Parses the date string given in \a string and returns the
3205 date. See QDate::fromString() for information on the expressions
3206 that can be used with this function.
3207
3208 This function searches month names and the names of the days of
3209 the week in the current locale.
3210
3211 If the date could not be parsed, returns an invalid date.
3212
3213 \sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
3214*/
3215#ifndef QT_NO_DATESTRING
3216QDate QLocale::toDate(const QString &string, const QString &format) const
3217{
3218 QDate date;
3219#ifndef QT_BOOTSTRAPPED
3220 QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
3221 dt.defaultLocale = *this;
3222 if (dt.parseFormat(format))
3223 dt.fromString(string, &date, 0);
3224#else
3225 Q_UNUSED(string);
3226 Q_UNUSED(format);
3227#endif
3228 return date;
3229}
3230#endif
3231
3232/*!
3233 \since 4.4
3234
3235 Parses the date/time string given in \a string and returns the
3236 time. See QDateTime::fromString() for information on the expressions
3237 that can be used with this function.
3238
3239 \note The month and day names used must be given in the user's local
3240 language.
3241
3242 If the string could not be parsed, returns an invalid QDateTime.
3243
3244 \sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
3245*/
3246#ifndef QT_NO_DATESTRING
3247QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
3248{
3249#ifndef QT_BOOTSTRAPPED
3250 QTime time;
3251 QDate date;
3252
3253 QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
3254 dt.defaultLocale = *this;
3255 if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
3256 return QDateTime(date, time);
3257#else
3258 Q_UNUSED(string);
3259 Q_UNUSED(format);
3260#endif
3261 return QDateTime(QDate(), QTime(-1, -1, -1));
3262}
3263#endif
3264
3265
3266/*!
3267 \since 4.1
3268
3269 Returns the decimal point character of this locale.
3270*/
3271QChar QLocale::decimalPoint() const
3272{
3273 return d()->decimal();
3274}
3275
3276/*!
3277 \since 4.1
3278
3279 Returns the group separator character of this locale.
3280*/
3281QChar QLocale::groupSeparator() const
3282{
3283 return d()->group();
3284}
3285
3286/*!
3287 \since 4.1
3288
3289 Returns the percent character of this locale.
3290*/
3291QChar QLocale::percent() const
3292{
3293 return d()->percent();
3294}
3295
3296/*!
3297 \since 4.1
3298
3299 Returns the zero digit character of this locale.
3300*/
3301QChar QLocale::zeroDigit() const
3302{
3303 return d()->zero();
3304}
3305
3306/*!
3307 \since 4.1
3308
3309 Returns the negative sign character of this locale.
3310*/
3311QChar QLocale::negativeSign() const
3312{
3313 return d()->minus();
3314}
3315
3316/*!
3317 \since 4.5
3318
3319 Returns the positive sign character of this locale.
3320*/
3321QChar QLocale::positiveSign() const
3322{
3323 return d()->plus();
3324}
3325
3326/*!
3327 \since 4.1
3328
3329 Returns the exponential character of this locale.
3330*/
3331QChar QLocale::exponential() const
3332{
3333 return d()->exponential();
3334}
3335
3336static bool qIsUpper(char c)
3337{
3338 return c >= 'A' && c <= 'Z';
3339}
3340
3341static char qToLower(char c)
3342{
3343 if (c >= 'A' && c <= 'Z')
3344 return c - 'A' + 'a';
3345 else
3346 return c;
3347}
3348
3349/*!
3350 \overload
3351
3352 \a f and \a prec have the same meaning as in QString::number(double, char, int).
3353
3354 \sa toDouble()
3355*/
3356
3357QString QLocale::toString(double i, char f, int prec) const
3358{
3359 QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
3360 uint flags = 0;
3361
3362 if (qIsUpper(f))
3363 flags = QLocalePrivate::CapitalEorX;
3364 f = qToLower(f);
3365
3366 switch (f) {
3367 case 'f':
3368 form = QLocalePrivate::DFDecimal;
3369 break;
3370 case 'e':
3371 form = QLocalePrivate::DFExponent;
3372 break;
3373 case 'g':
3374 form = QLocalePrivate::DFSignificantDigits;
3375 break;
3376 default:
3377 break;
3378 }
3379
3380 if (!(p.numberOptions & OmitGroupSeparator))
3381 flags |= QLocalePrivate::ThousandsGroup;
3382 return d()->doubleToString(i, prec, form, -1, flags);
3383}
3384
3385/*!
3386 \fn QLocale QLocale::c()
3387
3388 Returns a QLocale object initialized to the "C" locale.
3389
3390 \sa system()
3391*/
3392
3393/*!
3394 Returns a QLocale object initialized to the system locale.
3395
3396 On Windows and Mac, this locale will use the decimal/grouping characters and date/time
3397 formats specified in the system configuration panel.
3398
3399 \sa QTextCodec::locale() c()
3400*/
3401
3402QLocale QLocale::system()
3403{
3404 QLocale result(C);
3405 result.p.index = localePrivateIndex(systemPrivate());
3406 return result;
3407}
3408
3409/*!
3410 \since 4.3
3411
3412 Returns the list of countries that have entires for \a language in Qt's locale
3413 database. If the result is an empty list, then \a language is not represented in
3414 Qt's locale database.
3415*/
3416QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
3417{
3418 QList<Country> result;
3419
3420 unsigned language_id = language;
3421 uint idx = locale_index[language_id];
3422
3423 if (language == C) {
3424 result << AnyCountry;
3425 return result;
3426 }
3427
3428 const QLocalePrivate *d = locale_data + idx;
3429
3430 while (d->languageId() == language_id) {
3431 result << static_cast<Country>(d->countryId());
3432 ++d;
3433 }
3434
3435 return result;
3436}
3437
3438/*!
3439 \since 4.2
3440
3441 Returns the localized name of \a month, in the format specified
3442 by \a type.
3443
3444 \sa dayName(), standaloneMonthName()
3445*/
3446QString QLocale::monthName(int month, FormatType type) const
3447{
3448 if (month < 1 || month > 12)
3449 return QString();
3450
3451#ifndef QT_NO_SYSTEMLOCALE
3452 if (d() == systemPrivate()) {
3453 QVariant res = systemLocale()->query(type == LongFormat
3454 ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
3455 month);
3456 if (!res.isNull())
3457 return res.toString();
3458 }
3459#endif
3460
3461 quint32 idx, size;
3462 switch (type) {
3463 case QLocale::LongFormat:
3464 idx = d()->m_long_month_names_idx;
3465 size = d()->m_long_month_names_size;
3466 break;
3467 case QLocale::ShortFormat:
3468 idx = d()->m_short_month_names_idx;
3469 size = d()->m_short_month_names_size;
3470 break;
3471 case QLocale::NarrowFormat:
3472 idx = d()->m_narrow_month_names_idx;
3473 size = d()->m_narrow_month_names_size;
3474 break;
3475 default:
3476 return QString();
3477 }
3478 return getLocaleListData(months_data + idx, size, month - 1);
3479}
3480
3481/*!
3482 \since 4.5
3483
3484 Returns the localized name of \a month that is used as a
3485 standalone text, in the format specified by \a type.
3486
3487 If the locale information doesn't specify the standalone month
3488 name then return value is the same as in monthName().
3489
3490 \sa monthName(), standaloneDayName()
3491*/
3492QString QLocale::standaloneMonthName(int month, FormatType type) const
3493{
3494 if (month < 1 || month > 12)
3495 return QString();
3496
3497#ifndef QT_NO_SYSTEMLOCALE
3498 if (d() == systemPrivate()) {
3499 QVariant res = systemLocale()->query(type == LongFormat
3500 ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
3501 month);
3502 if (!res.isNull())
3503 return res.toString();
3504 }
3505#endif
3506
3507 quint32 idx, size;
3508 switch (type) {
3509 case QLocale::LongFormat:
3510 idx = d()->m_standalone_long_month_names_idx;
3511 size = d()->m_standalone_long_month_names_size;
3512 break;
3513 case QLocale::ShortFormat:
3514 idx = d()->m_standalone_short_month_names_idx;
3515 size = d()->m_standalone_short_month_names_size;
3516 break;
3517 case QLocale::NarrowFormat:
3518 idx = d()->m_standalone_narrow_month_names_idx;
3519 size = d()->m_standalone_narrow_month_names_size;
3520 break;
3521 default:
3522 return QString();
3523 }
3524 QString name = getLocaleListData(standalone_months_data + idx, size, month - 1);
3525 if (name.isEmpty())
3526 return monthName(month, type);
3527 return name;
3528}
3529
3530/*!
3531 \since 4.2
3532
3533 Returns the localized name of the \a day (where 1 represents
3534 Monday, 2 represents Tuesday and so on), in the format specified
3535 by \a type.
3536
3537 \sa monthName(), standaloneDayName()
3538*/
3539QString QLocale::dayName(int day, FormatType type) const
3540{
3541 if (day < 1 || day > 7)
3542 return QString();
3543
3544#ifndef QT_NO_SYSTEMLOCALE
3545 if (d() == systemPrivate()) {
3546 QVariant res = systemLocale()->query(type == LongFormat
3547 ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
3548 day);
3549 if (!res.isNull())
3550 return res.toString();
3551 }
3552#endif
3553 if (day == 7)
3554 day = 0;
3555
3556 quint32 idx, size;
3557 switch (type) {
3558 case QLocale::LongFormat:
3559 idx = d()->m_long_day_names_idx;
3560 size = d()->m_long_day_names_size;
3561 break;
3562 case QLocale::ShortFormat:
3563 idx = d()->m_short_day_names_idx;
3564 size = d()->m_short_day_names_size;
3565 break;
3566 case QLocale::NarrowFormat:
3567 idx = d()->m_narrow_day_names_idx;
3568 size = d()->m_narrow_day_names_size;
3569 break;
3570 default:
3571 return QString();
3572 }
3573 return getLocaleListData(days_data + idx, size, day);
3574}
3575
3576/*!
3577 \since 4.5
3578
3579 Returns the localized name of the \a day (where 1 represents
3580 Monday, 2 represents Tuesday and so on) that is used as a
3581 standalone text, in the format specified by \a type.
3582
3583 If the locale information does not specify the standalone day
3584 name then return value is the same as in dayName().
3585
3586 \sa dayName(), standaloneMonthName()
3587*/
3588QString QLocale::standaloneDayName(int day, FormatType type) const
3589{
3590 if (day < 1 || day > 7)
3591 return QString();
3592
3593#ifndef QT_NO_SYSTEMLOCALE
3594 if (d() == systemPrivate()) {
3595 QVariant res = systemLocale()->query(type == LongFormat
3596 ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
3597 day);
3598 if (!res.isNull())
3599 return res.toString();
3600 }
3601#endif
3602 if (day == 7)
3603 day = 0;
3604
3605 quint32 idx, size;
3606 switch (type) {
3607 case QLocale::LongFormat:
3608 idx = d()->m_standalone_long_day_names_idx;
3609 size = d()->m_standalone_long_day_names_size;
3610 break;
3611 case QLocale::ShortFormat:
3612 idx = d()->m_standalone_short_day_names_idx;
3613 size = d()->m_standalone_short_day_names_size;
3614 break;
3615 case QLocale::NarrowFormat:
3616 idx = d()->m_standalone_narrow_day_names_idx;
3617 size = d()->m_standalone_narrow_day_names_size;
3618 break;
3619 default:
3620 return QString();
3621 }
3622 QString name = getLocaleListData(days_data + idx, size, day);
3623 if (name.isEmpty())
3624 return dayName(day == 0 ? 7 : day, type);
3625 return name;
3626}
3627
3628/*!
3629 \since 4.4
3630
3631 Returns the measurement system for the locale.
3632*/
3633QLocale::MeasurementSystem QLocale::measurementSystem() const
3634{
3635 MeasurementSystem meas = MetricSystem;
3636 bool found = false;
3637
3638#ifndef QT_NO_SYSTEMLOCALE
3639 if (d() == systemPrivate()) {
3640 QVariant res = systemLocale()->query(QSystemLocale::MeasurementSystem, QVariant());
3641 if (!res.isNull()) {
3642 meas = MeasurementSystem(res.toInt());
3643 found = true;
3644 }
3645 }
3646#endif
3647
3648 if (!found) {
3649 meas = d()->measurementSystem();
3650 found = true;
3651 }
3652
3653 return meas;
3654}
3655
3656/*!
3657 \since 4.5
3658
3659 Returns the localized name of the "AM" suffix for times specified using
3660 the conventions of the 12-hour clock.
3661
3662 \sa pmText()
3663*/
3664QString QLocale::amText() const
3665{
3666#ifndef QT_NO_SYSTEMLOCALE
3667 if (d() == systemPrivate()) {
3668 QVariant res = systemLocale()->query(QSystemLocale::AMText, QVariant());
3669 if (!res.isNull())
3670 return res.toString();
3671 }
3672#endif
3673 return getLocaleData(am_data + d()->m_am_idx, d()->m_am_size);
3674}
3675
3676/*!
3677 \since 4.5
3678
3679 Returns the localized name of the "PM" suffix for times specified using
3680 the conventions of the 12-hour clock.
3681
3682 \sa amText()
3683*/
3684QString QLocale::pmText() const
3685{
3686#ifndef QT_NO_SYSTEMLOCALE
3687 if (d() == systemPrivate()) {
3688 QVariant res = systemLocale()->query(QSystemLocale::PMText, QVariant());
3689 if (!res.isNull())
3690 return res.toString();
3691 }
3692#endif
3693 return getLocaleData(pm_data + d()->m_pm_idx, d()->m_pm_size);
3694}
3695
3696
3697/*!
3698\fn QString QLocale::toString(short i) const
3699
3700\overload
3701
3702\sa toShort()
3703*/
3704
3705/*!
3706\fn QString QLocale::toString(ushort i) const
3707
3708\overload
3709
3710\sa toUShort()
3711*/
3712
3713/*!
3714\fn QString QLocale::toString(int i) const
3715
3716\overload
3717
3718\sa toInt()
3719*/
3720
3721/*!
3722\fn QString QLocale::toString(uint i) const
3723
3724\overload
3725
3726\sa toUInt()
3727*/
3728
3729/*
3730\fn QString QLocale::toString(long i) const
3731
3732\overload
3733
3734\sa toLong()
3735*/
3736
3737/*
3738\fn QString QLocale::toString(ulong i) const
3739
3740\overload
3741
3742\sa toULong()
3743*/
3744
3745/*!
3746\fn QString QLocale::toString(float i, char f = 'g', int prec = 6) const
3747
3748\overload
3749
3750\a f and \a prec have the same meaning as in QString::number(double, char, int).
3751
3752\sa toDouble()
3753*/
3754
3755
3756static QString qulltoa(qulonglong l, int base, const QLocalePrivate &locale)
3757{
3758 ushort buff[65]; // length of MAX_ULLONG in base 2
3759 ushort *p = buff + 65;
3760 const QChar _zero = locale.zero();
3761
3762 if (base != 10 || _zero.unicode() == '0') {
3763 while (l != 0) {
3764 int c = l % base;
3765
3766 --p;
3767
3768 if (c < 10)
3769 *p = '0' + c;
3770 else
3771 *p = c - 10 + 'a';
3772
3773 l /= base;
3774 }
3775 }
3776 else {
3777 while (l != 0) {
3778 int c = l % base;
3779
3780 *(--p) = _zero.unicode() + c;
3781
3782 l /= base;
3783 }
3784 }
3785
3786 return QString(reinterpret_cast<QChar *>(p), 65 - (p - buff));
3787}
3788
3789static QString qlltoa(qlonglong l, int base, const QLocalePrivate &locale)
3790{
3791 return qulltoa(l < 0 ? -l : l, base, locale);
3792}
3793
3794enum PrecisionMode {
3795 PMDecimalDigits = 0x01,
3796 PMSignificantDigits = 0x02,
3797 PMChopTrailingZeros = 0x03
3798};
3799
3800static QString &decimalForm(QString &digits, int decpt, uint precision,
3801 PrecisionMode pm,
3802 bool always_show_decpt,
3803 bool thousands_group,
3804 const QLocalePrivate &locale)
3805{
3806 if (decpt < 0) {
3807 for (int i = 0; i < -decpt; ++i)
3808 digits.prepend(locale.zero());
3809 decpt = 0;
3810 }
3811 else if (decpt > digits.length()) {
3812 for (int i = digits.length(); i < decpt; ++i)
3813 digits.append(locale.zero());
3814 }
3815
3816 if (pm == PMDecimalDigits) {
3817 uint decimal_digits = digits.length() - decpt;
3818 for (uint i = decimal_digits; i < precision; ++i)
3819 digits.append(locale.zero());
3820 }
3821 else if (pm == PMSignificantDigits) {
3822 for (uint i = digits.length(); i < precision; ++i)
3823 digits.append(locale.zero());
3824 }
3825 else { // pm == PMChopTrailingZeros
3826 }
3827
3828 if (always_show_decpt || decpt < digits.length())
3829 digits.insert(decpt, locale.decimal());
3830
3831 if (thousands_group) {
3832 for (int i = decpt - 3; i > 0; i -= 3)
3833 digits.insert(i, locale.group());
3834 }
3835
3836 if (decpt == 0)
3837 digits.prepend(locale.zero());
3838
3839 return digits;
3840}
3841
3842static QString &exponentForm(QString &digits, int decpt, uint precision,
3843 PrecisionMode pm,
3844 bool always_show_decpt,
3845 const QLocalePrivate &locale)
3846{
3847 int exp = decpt - 1;
3848
3849 if (pm == PMDecimalDigits) {
3850 for (uint i = digits.length(); i < precision + 1; ++i)
3851 digits.append(locale.zero());
3852 }
3853 else if (pm == PMSignificantDigits) {
3854 for (uint i = digits.length(); i < precision; ++i)
3855 digits.append(locale.zero());
3856 }
3857 else { // pm == PMChopTrailingZeros
3858 }
3859
3860 if (always_show_decpt || digits.length() > 1)
3861 digits.insert(1, locale.decimal());
3862
3863 digits.append(locale.exponential());
3864 digits.append(locale.longLongToString(exp, 2, 10,
3865 -1, QLocalePrivate::AlwaysShowSign));
3866
3867 return digits;
3868}
3869
3870static bool isZero(double d)
3871{
3872 uchar *ch = (uchar *)&d;
3873#ifdef QT_ARMFPA
3874 return !(ch[3] & 0x7F || ch[2] || ch[1] || ch[0] || ch[7] || ch[6] || ch[5] || ch[4]);
3875#else
3876 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
3877 return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]);
3878 } else {
3879 return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]);
3880 }
3881#endif
3882}
3883
3884QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *date, const QTime *time,
3885 const QLocale *q) const
3886{
3887 Q_ASSERT(date || time);
3888 if ((date && !date->isValid()) || (time && !time->isValid()))
3889 return QString();
3890 const bool format_am_pm = time && timeFormatContainsAP(format);
3891
3892 enum { AM, PM } am_pm = AM;
3893 int hour12 = time ? time->hour() : -1;
3894 if (time) {
3895 if (hour12 == 0) {
3896 am_pm = AM;
3897 hour12 = 12;
3898 } else if (hour12 < 12) {
3899 am_pm = AM;
3900 } else if (hour12 == 12) {
3901 am_pm = PM;
3902 } else {
3903 am_pm = PM;
3904 hour12 -= 12;
3905 }
3906 }
3907
3908 QString result;
3909
3910 int i = 0;
3911 while (i < format.size()) {
3912 if (format.at(i).unicode() == '\'') {
3913 result.append(readEscapedFormatString(format, &i));
3914 continue;
3915 }
3916
3917 const QChar c = format.at(i);
3918 int repeat = repeatCount(format, i);
3919 bool used = false;
3920 if (date) {
3921 switch (c.unicode()) {
3922 case 'y':
3923 used = true;
3924 if (repeat >= 4)
3925 repeat = 4;
3926 else if (repeat >= 2)
3927 repeat = 2;
3928
3929 switch (repeat) {
3930 case 4:
3931 result.append(longLongToString(date->year()));
3932 break;
3933 case 2:
3934 result.append(longLongToString(date->year() % 100, -1, 10, 2,
3935 QLocalePrivate::ZeroPadded));
3936 break;
3937 default:
3938 repeat = 1;
3939 result.append(c);
3940 break;
3941 }
3942 break;
3943
3944 case 'M':
3945 used = true;
3946 repeat = qMin(repeat, 4);
3947 switch (repeat) {
3948 case 1:
3949 result.append(longLongToString(date->month()));
3950 break;
3951 case 2:
3952 result.append(longLongToString(date->month(), -1, 10, 2, QLocalePrivate::ZeroPadded));
3953 break;
3954 case 3:
3955 result.append(q->monthName(date->month(), QLocale::ShortFormat));
3956 break;
3957 case 4:
3958 result.append(q->monthName(date->month(), QLocale::LongFormat));
3959 break;
3960 }
3961 break;
3962
3963 case 'd':
3964 used = true;
3965 repeat = qMin(repeat, 4);
3966 switch (repeat) {
3967 case 1:
3968 result.append(longLongToString(date->day()));
3969 break;
3970 case 2:
3971 result.append(longLongToString(date->day(), -1, 10, 2, QLocalePrivate::ZeroPadded));
3972 break;
3973 case 3:
3974 result.append(q->dayName(date->dayOfWeek(), QLocale::ShortFormat));
3975 break;
3976 case 4:
3977 result.append(q->dayName(date->dayOfWeek(), QLocale::LongFormat));
3978 break;
3979 }
3980 break;
3981
3982 default:
3983 break;
3984 }
3985 }
3986 if (!used && time) {
3987 switch (c.unicode()) {
3988 case 'h': {
3989 used = true;
3990 repeat = qMin(repeat, 2);
3991 const int hour = format_am_pm ? hour12 : time->hour();
3992
3993 switch (repeat) {
3994 case 1:
3995 result.append(longLongToString(hour));
3996 break;
3997 case 2:
3998 result.append(longLongToString(hour, -1, 10, 2, QLocalePrivate::ZeroPadded));
3999 break;
4000 }
4001 break;
4002 }
4003 case 'H':
4004 used = true;
4005 repeat = qMin(repeat, 2);
4006 switch (repeat) {
4007 case 1:
4008 result.append(longLongToString(time->hour()));
4009 break;
4010 case 2:
4011 result.append(longLongToString(time->hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
4012 break;
4013 }
4014 break;
4015
4016 case 'm':
4017 used = true;
4018 repeat = qMin(repeat, 2);
4019 switch (repeat) {
4020 case 1:
4021 result.append(longLongToString(time->minute()));
4022 break;
4023 case 2:
4024 result.append(longLongToString(time->minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
4025 break;
4026 }
4027 break;
4028
4029 case 's':
4030 used = true;
4031 repeat = qMin(repeat, 2);
4032 switch (repeat) {
4033 case 1:
4034 result.append(longLongToString(time->second()));
4035 break;
4036 case 2:
4037 result.append(longLongToString(time->second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
4038 break;
4039 }
4040 break;
4041
4042 case 'a':
4043 used = true;
4044 if (i + 1 < format.length() && format.at(i + 1).unicode() == 'p') {
4045 repeat = 2;
4046 } else {
4047 repeat = 1;
4048 }
4049 result.append(am_pm == AM ? QLatin1String("am") : QLatin1String("pm"));
4050 break;
4051
4052 case 'A':
4053 used = true;
4054 if (i + 1 < format.length() && format.at(i + 1).unicode() == 'P') {
4055 repeat = 2;
4056 } else {
4057 repeat = 1;
4058 }
4059 result.append(am_pm == AM ? QLatin1String("AM") : QLatin1String("PM"));
4060 break;
4061
4062 case 'z':
4063 used = true;
4064 if (repeat >= 3) {
4065 repeat = 3;
4066 } else {
4067 repeat = 1;
4068 }
4069 switch (repeat) {
4070 case 1:
4071 result.append(longLongToString(time->msec()));
4072 break;
4073 case 3:
4074 result.append(longLongToString(time->msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
4075 break;
4076 }
4077 break;
4078
4079 case 't':
4080 used = true;
4081 repeat = 1;
4082 result.append(timeZone());
4083 break;
4084 default:
4085 break;
4086 }
4087 }
4088 if (!used) {
4089 result.append(QString(repeat, c));
4090 }
4091 i += repeat;
4092 }
4093
4094 return result;
4095}
4096
4097QString QLocalePrivate::doubleToString(double d,
4098 int precision,
4099 DoubleForm form,
4100 int width,
4101 unsigned flags) const
4102{
4103 if (precision == -1)
4104 precision = 6;
4105 if (width == -1)
4106 width = 0;
4107
4108 bool negative = false;
4109 bool special_number = false; // nan, +/-inf
4110 QString num_str;
4111
4112 // Detect special numbers (nan, +/-inf)
4113 if (qt_is_inf(d)) {
4114 num_str = QString::fromLatin1("inf");
4115 special_number = true;
4116 negative = d < 0;
4117 } else if (qt_is_nan(d)) {
4118 num_str = QString::fromLatin1("nan");
4119 special_number = true;
4120 }
4121
4122 // Handle normal numbers
4123 if (!special_number) {
4124 int decpt, sign;
4125 QString digits;
4126
4127#ifdef QT_QLOCALE_USES_FCVT
4128 // NOT thread safe!
4129 if (form == DFDecimal) {
4130 digits = QLatin1String(fcvt(d, precision, &decpt, &sign));
4131 } else {
4132 int pr = precision;
4133 if (form == DFExponent)
4134 ++pr;
4135 else if (form == DFSignificantDigits && pr == 0)
4136 pr = 1;
4137 digits = QLatin1String(ecvt(d, pr, &decpt, &sign));
4138
4139 // Chop trailing zeros
4140 if (digits.length() > 0) {
4141 int last_nonzero_idx = digits.length() - 1;
4142 while (last_nonzero_idx > 0
4143 && digits.unicode()[last_nonzero_idx] == QLatin1Char('0'))
4144 --last_nonzero_idx;
4145 digits.truncate(last_nonzero_idx + 1);
4146 }
4147
4148 }
4149
4150#else
4151 int mode;
4152 if (form == DFDecimal)
4153 mode = 3;
4154 else
4155 mode = 2;
4156
4157 /* This next bit is a bit quirky. In DFExponent form, the precision
4158 is the number of digits after decpt. So that would suggest using
4159 mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and
4160 precision=0. So we get around this by using mode=2 and reasoning
4161 that we want precision+1 significant digits, since the decimal
4162 point in this mode is always after the first digit. */
4163 int pr = precision;
4164 if (form == DFExponent)
4165 ++pr;
4166
4167 char *rve = 0;
4168 char *buff = 0;
4169 QT_TRY {
4170 digits = QLatin1String(qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff));
4171 } QT_CATCH(...) {
4172 if (buff != 0)
4173 free(buff);
4174 QT_RETHROW;
4175 }
4176 if (buff != 0)
4177 free(buff);
4178#endif // QT_QLOCALE_USES_FCVT
4179
4180 const QChar _zero = zero();
4181
4182 if (_zero.unicode() != '0') {
4183 ushort z = _zero.unicode() - '0';
4184 for (int i = 0; i < digits.length(); ++i)
4185 reinterpret_cast<ushort *>(digits.data())[i] += z;
4186 }
4187
4188 bool always_show_decpt = (flags & Alternate || flags & ForcePoint);
4189 switch (form) {
4190 case DFExponent: {
4191 num_str = exponentForm(digits, decpt, precision, PMDecimalDigits,
4192 always_show_decpt, *this);
4193 break;
4194 }
4195 case DFDecimal: {
4196 num_str = decimalForm(digits, decpt, precision, PMDecimalDigits,
4197 always_show_decpt, flags & ThousandsGroup,
4198 *this);
4199 break;
4200 }
4201 case DFSignificantDigits: {
4202 PrecisionMode mode = (flags & Alternate) ?
4203 PMSignificantDigits : PMChopTrailingZeros;
4204
4205 if (decpt != digits.length() && (decpt <= -4 || decpt > precision))
4206 num_str = exponentForm(digits, decpt, precision, mode,
4207 always_show_decpt, *this);
4208 else
4209 num_str = decimalForm(digits, decpt, precision, mode,
4210 always_show_decpt, flags & ThousandsGroup,
4211 *this);
4212 break;
4213 }
4214 }
4215
4216 negative = sign != 0 && !isZero(d);
4217 }
4218
4219 // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
4220 // pad special numbers
4221 if (flags & QLocalePrivate::ZeroPadded
4222 && !(flags & QLocalePrivate::LeftAdjusted)
4223 && !special_number) {
4224 int num_pad_chars = width - num_str.length();
4225 // leave space for the sign
4226 if (negative
4227 || flags & QLocalePrivate::AlwaysShowSign
4228 || flags & QLocalePrivate::BlankBeforePositive)
4229 --num_pad_chars;
4230
4231 for (int i = 0; i < num_pad_chars; ++i)
4232 num_str.prepend(zero());
4233 }
4234
4235 // add sign
4236 if (negative)
4237 num_str.prepend(minus());
4238 else if (flags & QLocalePrivate::AlwaysShowSign)
4239 num_str.prepend(plus());
4240 else if (flags & QLocalePrivate::BlankBeforePositive)
4241 num_str.prepend(QLatin1Char(' '));
4242
4243 if (flags & QLocalePrivate::CapitalEorX)
4244 num_str = num_str.toUpper();
4245
4246 return num_str;
4247}
4248
4249QString QLocalePrivate::longLongToString(qlonglong l, int precision,
4250 int base, int width,
4251 unsigned flags) const
4252{
4253 bool precision_not_specified = false;
4254 if (precision == -1) {
4255 precision_not_specified = true;
4256 precision = 1;
4257 }
4258
4259 bool negative = l < 0;
4260 if (base != 10) {
4261 // these are not supported by sprintf for octal and hex
4262 flags &= ~AlwaysShowSign;
4263 flags &= ~BlankBeforePositive;
4264 negative = false; // neither are negative numbers
4265 }
4266
4267 QString num_str;
4268 if (base == 10)
4269 num_str = qlltoa(l, base, *this);
4270 else
4271 num_str = qulltoa(l, base, *this);
4272
4273 uint cnt_thousand_sep = 0;
4274 if (flags & ThousandsGroup && base == 10) {
4275 for (int i = num_str.length() - 3; i > 0; i -= 3) {
4276 num_str.insert(i, group());
4277 ++cnt_thousand_sep;
4278 }
4279 }
4280
4281 for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
4282 num_str.prepend(base == 10 ? zero() : QChar::fromLatin1('0'));
4283
4284 if ((flags & Alternate || flags & ShowBase)
4285 && base == 8
4286 && (num_str.isEmpty() || num_str[0].unicode() != QLatin1Char('0')))
4287 num_str.prepend(QLatin1Char('0'));
4288
4289 // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
4290 // when precision is not specified in the format string
4291 bool zero_padded = flags & ZeroPadded
4292 && !(flags & LeftAdjusted)
4293 && precision_not_specified;
4294
4295 if (zero_padded) {
4296 int num_pad_chars = width - num_str.length();
4297
4298 // leave space for the sign
4299 if (negative
4300 || flags & AlwaysShowSign
4301 || flags & BlankBeforePositive)
4302 --num_pad_chars;
4303
4304 // leave space for optional '0x' in hex form
4305 if (base == 16 && (flags & Alternate || flags & ShowBase))
4306 num_pad_chars -= 2;
4307 // leave space for optional '0b' in binary form
4308 else if (base == 2 && (flags & Alternate || flags & ShowBase))
4309 num_pad_chars -= 2;
4310
4311 for (int i = 0; i < num_pad_chars; ++i)
4312 num_str.prepend(base == 10 ? zero() : QChar::fromLatin1('0'));
4313 }
4314
4315 if (flags & CapitalEorX)
4316 num_str = num_str.toUpper();
4317
4318 if (base == 16 && (flags & Alternate || flags & ShowBase))
4319 num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
4320 if (base == 2 && (flags & Alternate || flags & ShowBase))
4321 num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));
4322
4323 // add sign
4324 if (negative)
4325 num_str.prepend(minus());
4326 else if (flags & AlwaysShowSign)
4327 num_str.prepend(plus());
4328 else if (flags & BlankBeforePositive)
4329 num_str.prepend(QLatin1Char(' '));
4330
4331 return num_str;
4332}
4333
4334QString QLocalePrivate::unsLongLongToString(qulonglong l, int precision,
4335 int base, int width,
4336 unsigned flags) const
4337{
4338 bool precision_not_specified = false;
4339 if (precision == -1) {
4340 precision_not_specified = true;
4341 precision = 1;
4342 }
4343
4344 QString num_str = qulltoa(l, base, *this);
4345
4346 uint cnt_thousand_sep = 0;
4347 if (flags & ThousandsGroup && base == 10) {
4348 for (int i = num_str.length() - 3; i > 0; i -=3) {
4349 num_str.insert(i, group());
4350 ++cnt_thousand_sep;
4351 }
4352 }
4353
4354 for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
4355 num_str.prepend(base == 10 ? zero() : QChar::fromLatin1('0'));
4356
4357 if ((flags & Alternate || flags & ShowBase)
4358 && base == 8
4359 && (num_str.isEmpty() || num_str[0].unicode() != QLatin1Char('0')))
4360 num_str.prepend(QLatin1Char('0'));
4361
4362 // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
4363 // when precision is not specified in the format string
4364 bool zero_padded = flags & ZeroPadded
4365 && !(flags & LeftAdjusted)
4366 && precision_not_specified;
4367
4368 if (zero_padded) {
4369 int num_pad_chars = width - num_str.length();
4370
4371 // leave space for optional '0x' in hex form
4372 if (base == 16 && flags & Alternate)
4373 num_pad_chars -= 2;
4374 // leave space for optional '0b' in binary form
4375 else if (base == 2 && flags & Alternate)
4376 num_pad_chars -= 2;
4377
4378 for (int i = 0; i < num_pad_chars; ++i)
4379 num_str.prepend(base == 10 ? zero() : QChar::fromLatin1('0'));
4380 }
4381
4382 if (flags & CapitalEorX)
4383 num_str = num_str.toUpper();
4384
4385 if (base == 16 && (flags & Alternate || flags & ShowBase))
4386 num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
4387 else if (base == 2 && (flags & Alternate || flags & ShowBase))
4388 num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));
4389
4390 // add sign
4391 if (flags & AlwaysShowSign)
4392 num_str.prepend(plus());
4393 else if (flags & BlankBeforePositive)
4394 num_str.prepend(QLatin1Char(' '));
4395
4396 return num_str;
4397}
4398
4399// Removes thousand-group separators in "C" locale.
4400static bool removeGroupSeparators(QLocalePrivate::CharBuff *num)
4401{
4402 int group_cnt = 0; // counts number of group chars
4403 int decpt_idx = -1;
4404
4405 char *data = num->data();
4406 int l = qstrlen(data);
4407
4408 // Find the decimal point and check if there are any group chars
4409 int i = 0;
4410 for (; i < l; ++i) {
4411 char c = data[i];
4412
4413 if (c == ',') {
4414 if (i == 0 || data[i - 1] < '0' || data[i - 1] > '9')
4415 return false;
4416 if (i == l - 1 || data[i + 1] < '0' || data[i + 1] > '9')
4417 return false;
4418 ++group_cnt;
4419 }
4420 else if (c == '.') {
4421 // Fail if more than one decimal points
4422 if (decpt_idx != -1)
4423 return false;
4424 decpt_idx = i;
4425 } else if (c == 'e' || c == 'E') {
4426 // an 'e' or 'E' - if we have not encountered a decimal
4427 // point, this is where it "is".
4428 if (decpt_idx == -1)
4429 decpt_idx = i;
4430 }
4431 }
4432
4433 // If no group chars, we're done
4434 if (group_cnt == 0)
4435 return true;
4436
4437 // No decimal point means that it "is" at the end of the string
4438 if (decpt_idx == -1)
4439 decpt_idx = l;
4440
4441 i = 0;
4442 while (i < l && group_cnt > 0) {
4443 char c = data[i];
4444
4445 if (c == ',') {
4446 // Don't allow group chars after the decimal point
4447 if (i > decpt_idx)
4448 return false;
4449
4450 // Check that it is placed correctly relative to the decpt
4451 if ((decpt_idx - i) % 4 != 0)
4452 return false;
4453
4454 // Remove it
4455 memmove(data + i, data + i + 1, l - i - 1);
4456 data[--l] = '\0';
4457
4458 --group_cnt;
4459 --decpt_idx;
4460 } else {
4461 // Check that we are not missing a separator
4462 if (i < decpt_idx
4463 && (decpt_idx - i) % 4 == 0
4464 && !(i == 0 && c == '-')) // check for negative sign at start of string
4465 return false;
4466 ++i;
4467 }
4468 }
4469
4470 return true;
4471}
4472
4473/*
4474 Converts a number in locale to its representation in the C locale.
4475 Only has to guarantee that a string that is a correct representation of
4476 a number will be converted. If junk is passed in, junk will be passed
4477 out and the error will be detected during the actual conversion to a
4478 number. We can't detect junk here, since we don't even know the base
4479 of the number.
4480*/
4481bool QLocalePrivate::numberToCLocale(const QString &num,
4482 GroupSeparatorMode group_sep_mode,
4483 CharBuff *result) const
4484{
4485 const QChar *uc = num.unicode();
4486 int l = num.length();
4487 int idx = 0;
4488
4489 // Skip whitespace
4490 while (idx < l && uc[idx].isSpace())
4491 ++idx;
4492 if (idx == l)
4493 return false;
4494
4495 const QChar _group = group();
4496
4497 while (idx < l) {
4498 const QChar &in = uc[idx];
4499
4500 char out = digitToCLocale(in);
4501 if (out == 0) {
4502 if (in == list())
4503 out = ';';
4504 else if (in == percent())
4505 out = '%';
4506 // for handling base-x numbers
4507 else if (in.unicode() >= 'A' && in.unicode() <= 'Z')
4508 out = in.toLower().toLatin1();
4509 else if (in.unicode() >= 'a' && in.unicode() <= 'z')
4510 out = in.toLatin1();
4511 else
4512 break;
4513 }
4514
4515 result->append(out);
4516
4517 ++idx;
4518 }
4519
4520 // Check trailing whitespace
4521 for (; idx < l; ++idx) {
4522 if (!uc[idx].isSpace())
4523 return false;
4524 }
4525
4526 result->append('\0');
4527
4528 // Check separators
4529 if (group_sep_mode == ParseGroupSeparators
4530 && !removeGroupSeparators(result))
4531 return false;
4532
4533
4534 return true;
4535}
4536
4537bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
4538 int decDigits) const
4539{
4540 buff->clear();
4541 buff->reserve(str.length());
4542
4543 const bool scientific = numMode == DoubleScientificMode;
4544 bool lastWasE = false;
4545 int eCnt = 0;
4546 int decPointCnt = 0;
4547 bool dec = false;
4548 int decDigitCnt = 0;
4549
4550 for (int i = 0; i < str.length(); ++i) {
4551 char c = digitToCLocale(str.at(i));
4552
4553 if (c >= '0' && c <= '9') {
4554 if (numMode != IntegerMode) {
4555 // If a double has too many digits after decpt, it shall be Invalid.
4556 if (dec && decDigits != -1 && decDigits < ++decDigitCnt)
4557 return false;
4558 }
4559 } else {
4560 switch (c) {
4561 case '.':
4562 if (numMode == IntegerMode) {
4563 // If an integer has a decimal point, it shall be Invalid.
4564 return false;
4565 } else {
4566 // If a double has more than one decimal point, it shall be Invalid.
4567 if (++decPointCnt > 1)
4568 return false;
4569#if 0
4570 // If a double with no decimal digits has a decimal point, it shall be
4571 // Invalid.
4572 if (decDigits == 0)
4573 return false;
4574#endif // On second thoughts, it shall be Valid.
4575
4576 dec = true;
4577 }
4578 break;
4579
4580 case '+':
4581 case '-':
4582 if (scientific) {
4583 // If a scientific has a sign that's not at the beginning or after
4584 // an 'e', it shall be Invalid.
4585 if (i != 0 && !lastWasE)
4586 return false;
4587 } else {
4588 // If a non-scientific has a sign that's not at the beginning,
4589 // it shall be Invalid.
4590 if (i != 0)
4591 return false;
4592 }
4593 break;
4594
4595 case ',':
4596 return false;
4597
4598 case 'e':
4599 if (scientific) {
4600 // If a scientific has more than one 'e', it shall be Invalid.
4601 if (++eCnt > 1)
4602 return false;
4603 dec = false;
4604 } else {
4605 // If a non-scientific has an 'e', it shall be Invalid.
4606 return false;
4607 }
4608 break;
4609
4610 default:
4611 // If it's not a valid digit, it shall be Invalid.
4612 return false;
4613 }
4614 }
4615
4616 lastWasE = c == 'e';
4617 buff->append(c);
4618 }
4619
4620 return true;
4621}
4622
4623double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
4624 GroupSeparatorMode group_sep_mode) const
4625{
4626 CharBuff buff;
4627 if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
4628 group_sep_mode, &buff)) {
4629 if (ok != 0)
4630 *ok = false;
4631 return 0.0;
4632 }
4633 return bytearrayToDouble(buff.constData(), ok);
4634}
4635
4636qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
4637 bool *ok, GroupSeparatorMode group_sep_mode) const
4638{
4639 CharBuff buff;
4640 if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
4641 group_sep_mode, &buff)) {
4642 if (ok != 0)
4643 *ok = false;
4644 return 0;
4645 }
4646
4647 return bytearrayToLongLong(buff.constData(), base, ok);
4648}
4649
4650qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
4651 bool *ok, GroupSeparatorMode group_sep_mode) const
4652{
4653 CharBuff buff;
4654 if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
4655 group_sep_mode, &buff)) {
4656 if (ok != 0)
4657 *ok = false;
4658 return 0;
4659 }
4660
4661 return bytearrayToUnsLongLong(buff.constData(), base, ok);
4662}
4663
4664
4665double QLocalePrivate::bytearrayToDouble(const char *num, bool *ok, bool *overflow)
4666{
4667 if (ok != 0)
4668 *ok = true;
4669 if (overflow != 0)
4670 *overflow = false;
4671
4672 if (*num == '\0') {
4673 if (ok != 0)
4674 *ok = false;
4675 return 0.0;
4676 }
4677
4678 if (qstrcmp(num, "nan") == 0)
4679 return qt_snan();
4680
4681 if (qstrcmp(num, "+inf") == 0 || qstrcmp(num, "inf") == 0)
4682 return qt_inf();
4683
4684 if (qstrcmp(num, "-inf") == 0)
4685 return -qt_inf();
4686
4687 bool _ok;
4688 const char *endptr;
4689 double d = qstrtod(num, &endptr, &_ok);
4690
4691 if (!_ok) {
4692 // the only way strtod can fail with *endptr != '\0' on a non-empty
4693 // input string is overflow
4694 if (ok != 0)
4695 *ok = false;
4696 if (overflow != 0)
4697 *overflow = *endptr != '\0';
4698 return 0.0;
4699 }
4700
4701 if (*endptr != '\0') {
4702 // we stopped at a non-digit character after converting some digits
4703 if (ok != 0)
4704 *ok = false;
4705 if (overflow != 0)
4706 *overflow = false;
4707 return 0.0;
4708 }
4709
4710 if (ok != 0)
4711 *ok = true;
4712 if (overflow != 0)
4713 *overflow = false;
4714 return d;
4715}
4716
4717qlonglong QLocalePrivate::bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow)
4718{
4719 bool _ok;
4720 const char *endptr;
4721
4722 if (*num == '\0') {
4723 if (ok != 0)
4724 *ok = false;
4725 if (overflow != 0)
4726 *overflow = false;
4727 return 0;
4728 }
4729
4730 qlonglong l = qstrtoll(num, &endptr, base, &_ok);
4731
4732 if (!_ok) {
4733 if (ok != 0)
4734 *ok = false;
4735 if (overflow != 0) {
4736 // the only way qstrtoll can fail with *endptr != '\0' on a non-empty
4737 // input string is overflow
4738 *overflow = *endptr != '\0';
4739 }
4740 return 0;
4741 }
4742
4743 if (*endptr != '\0') {
4744 // we stopped at a non-digit character after converting some digits
4745 if (ok != 0)
4746 *ok = false;
4747 if (overflow != 0)
4748 *overflow = false;
4749 return 0;
4750 }
4751
4752 if (ok != 0)
4753 *ok = true;
4754 if (overflow != 0)
4755 *overflow = false;
4756 return l;
4757}
4758
4759qulonglong QLocalePrivate::bytearrayToUnsLongLong(const char *num, int base, bool *ok)
4760{
4761 bool _ok;
4762 const char *endptr;
4763 qulonglong l = qstrtoull(num, &endptr, base, &_ok);
4764
4765 if (!_ok || *endptr != '\0') {
4766 if (ok != 0)
4767 *ok = false;
4768 return 0;
4769 }
4770
4771 if (ok != 0)
4772 *ok = true;
4773 return l;
4774}
4775
4776/*-
4777 * Copyright (c) 1992, 1993
4778 * The Regents of the University of California. All rights reserved.
4779 *
4780 * Redistribution and use in source and binary forms, with or without
4781 * modification, are permitted provided that the following conditions
4782 * are met:
4783 * 1. Redistributions of source code must retain the above copyright
4784 * notice, this list of conditions and the following disclaimer.
4785 * 2. Redistributions in binary form must reproduce the above copyright
4786 * notice, this list of conditions and the following disclaimer in the
4787 * documentation and/or other materials provided with the distribution.
4788 * 3. All advertising materials mentioning features or use of this software
4789 * must display the following acknowledgment:
4790 * This product includes software developed by the University of
4791 * California, Berkeley and its contributors.
4792 * 4. Neither the name of the University nor the names of its contributors
4793 * may be used to endorse or promote products derived from this software
4794 * without specific prior written permission.
4795 *
4796 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
4797 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4798 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4799 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4800 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4801 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4802 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4803 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4804 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4805 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4806 * SUCH DAMAGE.
4807 */
4808
4809// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93";
4810// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
4811
4812/*
4813 * Convert a string to an unsigned long long integer.
4814 *
4815 * Ignores `locale' stuff. Assumes that the upper and lower case
4816 * alphabets and digits are each contiguous.
4817 */
4818static qulonglong qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok)
4819{
4820 register const char *s = nptr;
4821 register qulonglong acc;
4822 register unsigned char c;
4823 register qulonglong qbase, cutoff;
4824 register int any, cutlim;
4825
4826 if (ok != 0)
4827 *ok = true;
4828
4829 /*
4830 * See strtoq for comments as to the logic used.
4831 */
4832 s = nptr;
4833 do {
4834 c = *s++;
4835 } while (isspace(c));
4836 if (c == '-') {
4837 if (ok != 0)
4838 *ok = false;
4839 if (endptr != 0)
4840 *endptr = s - 1;
4841 return 0;
4842 } else {
4843 if (c == '+')
4844 c = *s++;
4845 }
4846 if ((base == 0 || base == 16) &&
4847 c == '0' && (*s == 'x' || *s == 'X')) {
4848 c = s[1];
4849 s += 2;
4850 base = 16;
4851 }
4852 if (base == 0)
4853 base = c == '0' ? 8 : 10;
4854 qbase = unsigned(base);
4855 cutoff = qulonglong(ULLONG_MAX) / qbase;
4856 cutlim = qulonglong(ULLONG_MAX) % qbase;
4857 for (acc = 0, any = 0;; c = *s++) {
4858 if (!isascii(c))
4859 break;
4860 if (isdigit(c))
4861 c -= '0';
4862 else if (isalpha(c))
4863 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4864 else
4865 break;
4866 if (c >= base)
4867 break;
4868 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
4869 any = -1;
4870 else {
4871 any = 1;
4872 acc *= qbase;
4873 acc += c;
4874 }
4875 }
4876 if (any == 0) {
4877 if (ok != 0)
4878 *ok = false;
4879 } else if (any < 0) {
4880 acc = ULLONG_MAX;
4881 if (ok != 0)
4882 *ok = false;
4883 }
4884 if (endptr != 0)
4885 *endptr = (any ? s - 1 : nptr);
4886 return acc;
4887}
4888
4889
4890// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
4891
4892
4893/*
4894 * Convert a string to a long long integer.
4895 *
4896 * Ignores `locale' stuff. Assumes that the upper and lower case
4897 * alphabets and digits are each contiguous.
4898 */
4899static qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok)
4900{
4901 register const char *s;
4902 register qulonglong acc;
4903 register unsigned char c;
4904 register qulonglong qbase, cutoff;
4905 register int neg, any, cutlim;
4906
4907 /*
4908 * Skip white space and pick up leading +/- sign if any.
4909 * If base is 0, allow 0x for hex and 0 for octal, else
4910 * assume decimal; if base is already 16, allow 0x.
4911 */
4912 s = nptr;
4913 do {
4914 c = *s++;
4915 } while (isspace(c));
4916 if (c == '-') {
4917 neg = 1;
4918 c = *s++;
4919 } else {
4920 neg = 0;
4921 if (c == '+')
4922 c = *s++;
4923 }
4924 if ((base == 0 || base == 16) &&
4925 c == '0' && (*s == 'x' || *s == 'X')) {
4926 c = s[1];
4927 s += 2;
4928 base = 16;
4929 }
4930 if (base == 0)
4931 base = c == '0' ? 8 : 10;
4932
4933 /*
4934 * Compute the cutoff value between legal numbers and illegal
4935 * numbers. That is the largest legal value, divided by the
4936 * base. An input number that is greater than this value, if
4937 * followed by a legal input character, is too big. One that
4938 * is equal to this value may be valid or not; the limit
4939 * between valid and invalid numbers is then based on the last
4940 * digit. For instance, if the range for quads is
4941 * [-9223372036854775808..9223372036854775807] and the input base
4942 * is 10, cutoff will be set to 922337203685477580 and cutlim to
4943 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
4944 * accumulated a value > 922337203685477580, or equal but the
4945 * next digit is > 7 (or 8), the number is too big, and we will
4946 * return a range error.
4947 *
4948 * Set any if any `digits' consumed; make it negative to indicate
4949 * overflow.
4950 */
4951 qbase = unsigned(base);
4952 cutoff = neg ? qulonglong(0-(LLONG_MIN + LLONG_MAX)) + LLONG_MAX : LLONG_MAX;
4953 cutlim = cutoff % qbase;
4954 cutoff /= qbase;
4955 for (acc = 0, any = 0;; c = *s++) {
4956 if (!isascii(c))
4957 break;
4958 if (isdigit(c))
4959 c -= '0';
4960 else if (isalpha(c))
4961 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4962 else
4963 break;
4964 if (c >= base)
4965 break;
4966 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
4967 any = -1;
4968 else {
4969 any = 1;
4970 acc *= qbase;
4971 acc += c;
4972 }
4973 }
4974 if (any < 0) {
4975 acc = neg ? LLONG_MIN : LLONG_MAX;
4976 if (ok != 0)
4977 *ok = false;
4978 } else if (neg) {
4979 acc = (~acc) + 1;
4980 }
4981 if (endptr != 0)
4982 *endptr = (any >= 0 ? s - 1 : nptr);
4983
4984 if (ok != 0)
4985 *ok = any > 0;
4986
4987 return acc;
4988}
4989
4990#ifndef QT_QLOCALE_USES_FCVT
4991
4992/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */
4993/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */
4994
4995/* Please send bug reports to
4996 David M. Gay
4997 AT&T Bell Laboratories, Room 2C-463
4998 600 Mountain Avenue
4999 Murray Hill, NJ 07974-2070
5000 U.S.A.
5001 [email protected] or research!dmg
5002 */
5003
5004/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
5005 *
5006 * This strtod returns a nearest machine number to the input decimal
5007 * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
5008 * broken by the IEEE round-even rule. Otherwise ties are broken by
5009 * biased rounding (add half and chop).
5010 *
5011 * Inspired loosely by William D. Clinger's paper "How to Read Floating
5012 * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
5013 *
5014 * Modifications:
5015 *
5016 * 1. We only require IEEE, IBM, or VAX double-precision
5017 * arithmetic (not IEEE double-extended).
5018 * 2. We get by with floating-point arithmetic in a case that
5019 * Clinger missed -- when we're computing d * 10^n
5020 * for a small integer d and the integer n is not too
5021 * much larger than 22 (the maximum integer k for which
5022 * we can represent 10^k exactly), we may be able to
5023 * compute (d*10^k) * 10^(e-k) with just one roundoff.
5024 * 3. Rather than a bit-at-a-time adjustment of the binary
5025 * result in the hard case, we use floating-point
5026 * arithmetic to determine the adjustment to within
5027 * one bit; only in really hard cases do we need to
5028 * compute a second residual.
5029 * 4. Because of 3., we don't need a large table of powers of 10
5030 * for ten-to-e (just some small tables, e.g. of 10^k
5031 * for 0 <= k <= 22).
5032 */
5033
5034/*
5035 * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
5036 * significant byte has the lowest address.
5037 * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
5038 * significant byte has the lowest address.
5039 * #define Long int on machines with 32-bit ints and 64-bit longs.
5040 * #define Sudden_Underflow for IEEE-format machines without gradual
5041 * underflow (i.e., that flush to zero on underflow).
5042 * #define IBM for IBM mainframe-style floating-point arithmetic.
5043 * #define VAX for VAX-style floating-point arithmetic.
5044 * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
5045 * #define No_leftright to omit left-right logic in fast floating-point
5046 * computation of dtoa.
5047 * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
5048 * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
5049 * that use extended-precision instructions to compute rounded
5050 * products and quotients) with IBM.
5051 * #define ROUND_BIASED for IEEE-format with biased rounding.
5052 * #define Inaccurate_Divide for IEEE-format with correctly rounded
5053 * products but inaccurate quotients, e.g., for Intel i860.
5054 * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
5055 * integer arithmetic. Whether this speeds things up or slows things
5056 * down depends on the machine and the number being converted.
5057 * #define KR_headers for old-style C function headers.
5058 * #define Bad_float_h if your system lacks a float.h or if it does not
5059 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
5060 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
5061 * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
5062 * if memory is available and otherwise does something you deem
5063 * appropriate. If MALLOC is undefined, malloc will be invoked
5064 * directly -- and assumed always to succeed.
5065 */
5066
5067#if defined(LIBC_SCCS) && !defined(lint)
5068__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $");
5069#endif /* LIBC_SCCS and not lint */
5070
5071/*
5072#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
5073 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
5074 defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MAC) || \
5075 defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS)
5076# define IEEE_BIG_OR_LITTLE_ENDIAN 1
5077#endif
5078*/
5079
5080// *All* of our architectures have IEEE arithmetic, don't they?
5081#define IEEE_BIG_OR_LITTLE_ENDIAN 1
5082
5083#ifdef __arm32__
5084/*
5085 * Although the CPU is little endian the FP has different
5086 * byte and word endianness. The byte order is still little endian
5087 * but the word order is big endian.
5088 */
5089#define IEEE_BIG_OR_LITTLE_ENDIAN
5090#endif
5091
5092#ifdef vax
5093#define VAX
5094#endif
5095
5096#define Long qint32
5097#define ULong quint32
5098
5099#define MALLOC malloc
5100
5101#ifdef BSD_QDTOA_DEBUG
5102QT_BEGIN_INCLUDE_NAMESPACE
5103#include <stdio.h>
5104QT_END_INCLUDE_NAMESPACE
5105
5106#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
5107#endif
5108
5109#ifdef Unsigned_Shifts
5110#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
5111#else
5112#define Sign_Extend(a,b) /*no-op*/
5113#endif
5114
5115#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1
5116#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined.
5117#endif
5118
5119static inline ULong _getWord0(const NEEDS_VOLATILE double x)
5120{
5121 const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
5122 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
5123 return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
5124 } else {
5125 return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4];
5126 }
5127}
5128
5129static inline void _setWord0(NEEDS_VOLATILE double *x, ULong l)
5130{
5131 NEEDS_VOLATILE uchar *ptr = reinterpret_cast<NEEDS_VOLATILE uchar *>(x);
5132 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
5133 ptr[0] = uchar(l>>24);
5134 ptr[1] = uchar(l>>16);
5135 ptr[2] = uchar(l>>8);
5136 ptr[3] = uchar(l);
5137 } else {
5138 ptr[7] = uchar(l>>24);
5139 ptr[6] = uchar(l>>16);
5140 ptr[5] = uchar(l>>8);
5141 ptr[4] = uchar(l);
5142 }
5143}
5144
5145static inline ULong _getWord1(const NEEDS_VOLATILE double x)
5146{
5147 const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
5148 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
5149 return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7];
5150 } else {
5151 return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0];
5152 }
5153}
5154static inline void _setWord1(NEEDS_VOLATILE double *x, ULong l)
5155{
5156 NEEDS_VOLATILE uchar *ptr = reinterpret_cast<uchar NEEDS_VOLATILE *>(x);
5157 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
5158 ptr[4] = uchar(l>>24);
5159 ptr[5] = uchar(l>>16);
5160 ptr[6] = uchar(l>>8);
5161 ptr[7] = uchar(l);
5162 } else {
5163 ptr[3] = uchar(l>>24);
5164 ptr[2] = uchar(l>>16);
5165 ptr[1] = uchar(l>>8);
5166 ptr[0] = uchar(l);
5167 }
5168}
5169
5170static inline ULong getWord0(const NEEDS_VOLATILE double x)
5171{
5172#ifdef QT_ARMFPA
5173 return _getWord1(x);
5174#else
5175 return _getWord0(x);
5176#endif
5177}
5178
5179static inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
5180{
5181#ifdef QT_ARMFPA
5182 _setWord1(x, l);
5183#else
5184 _setWord0(x, l);
5185#endif
5186}
5187
5188static inline ULong getWord1(const NEEDS_VOLATILE double x)
5189{
5190#ifdef QT_ARMFPA
5191 return _getWord0(x);
5192#else
5193 return _getWord1(x);
5194#endif
5195}
5196
5197static inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
5198{
5199#ifdef QT_ARMFPA
5200 _setWord0(x, l);
5201#else
5202 _setWord1(x, l);
5203#endif
5204}
5205
5206static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c)
5207{
5208
5209 *a = (ushort(b) << 16) | ushort(c);
5210 ++a;
5211}
5212
5213/* #define P DBL_MANT_DIG */
5214/* Ten_pmax = floor(P*log(2)/log(5)) */
5215/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
5216/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
5217/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
5218
5219#if defined(IEEE_BIG_OR_LITTLE_ENDIAN)
5220#define Exp_shift 20
5221#define Exp_shift1 20
5222#define Exp_msk1 0x100000
5223#define Exp_msk11 0x100000
5224#define Exp_mask 0x7ff00000
5225#define P 53
5226#define Bias 1023
5227#define IEEE_Arith
5228#define Emin (-1022)
5229#define Exp_1 0x3ff00000
5230#define Exp_11 0x3ff00000
5231#define Ebits 11
5232#define Frac_mask 0xfffff
5233#define Frac_mask1 0xfffff
5234#define Ten_pmax 22
5235#define Bletch 0x10
5236#define Bndry_mask 0xfffff
5237#define Bndry_mask1 0xfffff
5238#if defined(LSB) && defined(Q_OS_VXWORKS)
5239#undef LSB
5240#endif
5241#define LSB 1
5242#define Sign_bit 0x80000000
5243#define Log2P 1
5244#define Tiny0 0
5245#define Tiny1 1
5246#define Quick_max 14
5247#define Int_max 14
5248#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */
5249#else
5250#undef Sudden_Underflow
5251#define Sudden_Underflow
5252#ifdef IBM
5253#define Exp_shift 24
5254#define Exp_shift1 24
5255#define Exp_msk1 0x1000000
5256#define Exp_msk11 0x1000000
5257#define Exp_mask 0x7f000000
5258#define P 14
5259#define Bias 65
5260#define Exp_1 0x41000000
5261#define Exp_11 0x41000000
5262#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
5263#define Frac_mask 0xffffff
5264#define Frac_mask1 0xffffff
5265#define Bletch 4
5266#define Ten_pmax 22
5267#define Bndry_mask 0xefffff
5268#define Bndry_mask1 0xffffff
5269#define LSB 1
5270#define Sign_bit 0x80000000
5271#define Log2P 4
5272#define Tiny0 0x100000
5273#define Tiny1 0
5274#define Quick_max 14
5275#define Int_max 15
5276#else /* VAX */
5277#define Exp_shift 23
5278#define Exp_shift1 7
5279#define Exp_msk1 0x80
5280#define Exp_msk11 0x800000
5281#define Exp_mask 0x7f80
5282#define P 56
5283#define Bias 129
5284#define Exp_1 0x40800000
5285#define Exp_11 0x4080
5286#define Ebits 8
5287#define Frac_mask 0x7fffff
5288#define Frac_mask1 0xffff007f
5289#define Ten_pmax 24
5290#define Bletch 2
5291#define Bndry_mask 0xffff007f
5292#define Bndry_mask1 0xffff007f
5293#define LSB 0x10000
5294#define Sign_bit 0x8000
5295#define Log2P 1
5296#define Tiny0 0x80
5297#define Tiny1 0
5298#define Quick_max 15
5299#define Int_max 15
5300#endif
5301#endif
5302
5303#ifndef IEEE_Arith
5304#define ROUND_BIASED
5305#endif
5306
5307#ifdef RND_PRODQUOT
5308#define rounded_product(a,b) a = rnd_prod(a, b)
5309#define rounded_quotient(a,b) a = rnd_quot(a, b)
5310extern double rnd_prod(double, double), rnd_quot(double, double);
5311#else
5312#define rounded_product(a,b) a *= b
5313#define rounded_quotient(a,b) a /= b
5314#endif
5315
5316#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
5317#define Big1 0xffffffff
5318
5319#ifndef Just_16
5320/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
5321 * This makes some inner loops simpler and sometimes saves work
5322 * during multiplications, but it often seems to make things slightly
5323 * slower. Hence the default is now to store 32 bits per Long.
5324 */
5325#ifndef Pack_32
5326#define Pack_32
5327#endif
5328#endif
5329
5330#define Kmax 15
5331
5332struct
5333Bigint {
5334 struct Bigint *next;
5335 int k, maxwds, sign, wds;
5336 ULong x[1];
5337};
5338
5339 typedef struct Bigint Bigint;
5340
5341static Bigint *Balloc(int k)
5342{
5343 int x;
5344 Bigint *rv;
5345
5346 x = 1 << k;
5347 rv = static_cast<Bigint *>(MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)));
5348 Q_CHECK_PTR(rv);
5349 rv->k = k;
5350 rv->maxwds = x;
5351 rv->sign = rv->wds = 0;
5352 return rv;
5353}
5354
5355static void Bfree(Bigint *v)
5356{
5357 free(v);
5358}
5359
5360#define Bcopy(x,y) memcpy(reinterpret_cast<char *>(&x->sign), reinterpret_cast<char *>(&y->sign), \
5361y->wds*sizeof(Long) + 2*sizeof(int))
5362
5363/* multiply by m and add a */
5364static Bigint *multadd(Bigint *b, int m, int a)
5365{
5366 int i, wds;
5367 ULong *x, y;
5368#ifdef Pack_32
5369 ULong xi, z;
5370#endif
5371 Bigint *b1;
5372
5373 wds = b->wds;
5374 x = b->x;
5375 i = 0;
5376 do {
5377#ifdef Pack_32
5378 xi = *x;
5379 y = (xi & 0xffff) * m + a;
5380 z = (xi >> 16) * m + (y >> 16);
5381 a = (z >> 16);
5382 *x++ = (z << 16) + (y & 0xffff);
5383#else
5384 y = *x * m + a;
5385 a = (y >> 16);
5386 *x++ = y & 0xffff;
5387#endif
5388 }
5389 while(++i < wds);
5390 if (a) {
5391 if (wds >= b->maxwds) {
5392 b1 = Balloc(b->k+1);
5393 Bcopy(b1, b);
5394 Bfree(b);
5395 b = b1;
5396 }
5397 b->x[wds++] = a;
5398 b->wds = wds;
5399 }
5400 return b;
5401}
5402
5403static Bigint *s2b(const char *s, int nd0, int nd, ULong y9)
5404{
5405 Bigint *b;
5406 int i, k;
5407 Long x, y;
5408
5409 x = (nd + 8) / 9;
5410 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
5411#ifdef Pack_32
5412 b = Balloc(k);
5413 b->x[0] = y9;
5414 b->wds = 1;
5415#else
5416 b = Balloc(k+1);
5417 b->x[0] = y9 & 0xffff;
5418 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
5419#endif
5420
5421 i = 9;
5422 if (9 < nd0) {
5423 s += 9;
5424 do b = multadd(b, 10, *s++ - '0');
5425 while(++i < nd0);
5426 s++;
5427 }
5428 else
5429 s += 10;
5430 for(; i < nd; i++)
5431 b = multadd(b, 10, *s++ - '0');
5432 return b;
5433}
5434
5435static int hi0bits(ULong x)
5436{
5437 int k = 0;
5438
5439 if (!(x & 0xffff0000)) {
5440 k = 16;
5441 x <<= 16;
5442 }
5443 if (!(x & 0xff000000)) {
5444 k += 8;
5445 x <<= 8;
5446 }
5447 if (!(x & 0xf0000000)) {
5448 k += 4;
5449 x <<= 4;
5450 }
5451 if (!(x & 0xc0000000)) {
5452 k += 2;
5453 x <<= 2;
5454 }
5455 if (!(x & 0x80000000)) {
5456 k++;
5457 if (!(x & 0x40000000))
5458 return 32;
5459 }
5460 return k;
5461}
5462
5463static int lo0bits(ULong *y)
5464{
5465 int k;
5466 ULong x = *y;
5467
5468 if (x & 7) {
5469 if (x & 1)
5470 return 0;
5471 if (x & 2) {
5472 *y = x >> 1;
5473 return 1;
5474 }
5475 *y = x >> 2;
5476 return 2;
5477 }
5478 k = 0;
5479 if (!(x & 0xffff)) {
5480 k = 16;
5481 x >>= 16;
5482 }
5483 if (!(x & 0xff)) {
5484 k += 8;
5485 x >>= 8;
5486 }
5487 if (!(x & 0xf)) {
5488 k += 4;
5489 x >>= 4;
5490 }
5491 if (!(x & 0x3)) {
5492 k += 2;
5493 x >>= 2;
5494 }
5495 if (!(x & 1)) {
5496 k++;
5497 x >>= 1;
5498 if (!x & 1)
5499 return 32;
5500 }
5501 *y = x;
5502 return k;
5503}
5504
5505static Bigint *i2b(int i)
5506{
5507 Bigint *b;
5508
5509 b = Balloc(1);
5510 b->x[0] = i;
5511 b->wds = 1;
5512 return b;
5513}
5514
5515static Bigint *mult(Bigint *a, Bigint *b)
5516{
5517 Bigint *c;
5518 int k, wa, wb, wc;
5519 ULong carry, y, z;
5520 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
5521#ifdef Pack_32
5522 ULong z2;
5523#endif
5524
5525 if (a->wds < b->wds) {
5526 c = a;
5527 a = b;
5528 b = c;
5529 }
5530 k = a->k;
5531 wa = a->wds;
5532 wb = b->wds;
5533 wc = wa + wb;
5534 if (wc > a->maxwds)
5535 k++;
5536 c = Balloc(k);
5537 for(x = c->x, xa = x + wc; x < xa; x++)
5538 *x = 0;
5539 xa = a->x;
5540 xae = xa + wa;
5541 xb = b->x;
5542 xbe = xb + wb;
5543 xc0 = c->x;
5544#ifdef Pack_32
5545 for(; xb < xbe; xb++, xc0++) {
5546 if ((y = *xb & 0xffff) != 0) {
5547 x = xa;
5548 xc = xc0;
5549 carry = 0;
5550 do {
5551 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
5552 carry = z >> 16;
5553 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
5554 carry = z2 >> 16;
5555 Storeinc(xc, z2, z);
5556 }
5557 while(x < xae);
5558 *xc = carry;
5559 }
5560 if ((y = *xb >> 16) != 0) {
5561 x = xa;
5562 xc = xc0;
5563 carry = 0;
5564 z2 = *xc;
5565 do {
5566 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
5567 carry = z >> 16;
5568 Storeinc(xc, z, z2);
5569 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
5570 carry = z2 >> 16;
5571 }
5572 while(x < xae);
5573 *xc = z2;
5574 }
5575 }
5576#else
5577 for(; xb < xbe; xc0++) {
5578 if (y = *xb++) {
5579 x = xa;
5580 xc = xc0;
5581 carry = 0;
5582 do {
5583 z = *x++ * y + *xc + carry;
5584 carry = z >> 16;
5585 *xc++ = z & 0xffff;
5586 }
5587 while(x < xae);
5588 *xc = carry;
5589 }
5590 }
5591#endif
5592 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
5593 c->wds = wc;
5594 return c;
5595}
5596
5597static Bigint *p5s;
5598
5599struct p5s_deleter
5600{
5601 ~p5s_deleter()
5602 {
5603 while (p5s) {
5604 Bigint *next = p5s->next;
5605 Bfree(p5s);
5606 p5s = next;
5607 }
5608 }
5609};
5610
5611static Bigint *pow5mult(Bigint *b, int k)
5612{
5613 Bigint *b1, *p5, *p51;
5614 int i;
5615 static const int p05[3] = { 5, 25, 125 };
5616
5617 if ((i = k & 3) != 0)
5618#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
5619 {
5620 // work around a bug on 64 bit IRIX gcc
5621 int *p = (int *) p05;
5622 b = multadd(b, p[i-1], 0);
5623 }
5624#else
5625 b = multadd(b, p05[i-1], 0);
5626#endif
5627
5628 if (!(k >>= 2))
5629 return b;
5630 if (!(p5 = p5s)) {
5631 /* first time */
5632 static p5s_deleter deleter;
5633 p5 = p5s = i2b(625);
5634 p5->next = 0;
5635 }
5636 for(;;) {
5637 if (k & 1) {
5638 b1 = mult(b, p5);
5639 Bfree(b);
5640 b = b1;
5641 }
5642 if (!(k >>= 1))
5643 break;
5644 if (!(p51 = p5->next)) {
5645 p51 = p5->next = mult(p5,p5);
5646 p51->next = 0;
5647 }
5648 p5 = p51;
5649 }
5650 return b;
5651}
5652
5653static Bigint *lshift(Bigint *b, int k)
5654{
5655 int i, k1, n, n1;
5656 Bigint *b1;
5657 ULong *x, *x1, *xe, z;
5658
5659#ifdef Pack_32
5660 n = k >> 5;
5661#else
5662 n = k >> 4;
5663#endif
5664 k1 = b->k;
5665 n1 = n + b->wds + 1;
5666 for(i = b->maxwds; n1 > i; i <<= 1)
5667 k1++;
5668 b1 = Balloc(k1);
5669 x1 = b1->x;
5670 for(i = 0; i < n; i++)
5671 *x1++ = 0;
5672 x = b->x;
5673 xe = x + b->wds;
5674#ifdef Pack_32
5675 if (k &= 0x1f) {
5676 k1 = 32 - k;
5677 z = 0;
5678 do {
5679 *x1++ = *x << k | z;
5680 z = *x++ >> k1;
5681 }
5682 while(x < xe);
5683 if ((*x1 = z) != 0)
5684 ++n1;
5685 }
5686#else
5687 if (k &= 0xf) {
5688 k1 = 16 - k;
5689 z = 0;
5690 do {
5691 *x1++ = *x << k & 0xffff | z;
5692 z = *x++ >> k1;
5693 }
5694 while(x < xe);
5695 if (*x1 = z)
5696 ++n1;
5697 }
5698#endif
5699 else do
5700 *x1++ = *x++;
5701 while(x < xe);
5702 b1->wds = n1 - 1;
5703 Bfree(b);
5704 return b1;
5705}
5706
5707static int cmp(Bigint *a, Bigint *b)
5708{
5709 ULong *xa, *xa0, *xb, *xb0;
5710 int i, j;
5711
5712 i = a->wds;
5713 j = b->wds;
5714#ifdef BSD_QDTOA_DEBUG
5715 if (i > 1 && !a->x[i-1])
5716 Bug("cmp called with a->x[a->wds-1] == 0");
5717 if (j > 1 && !b->x[j-1])
5718 Bug("cmp called with b->x[b->wds-1] == 0");
5719#endif
5720 if (i -= j)
5721 return i;
5722 xa0 = a->x;
5723 xa = xa0 + j;
5724 xb0 = b->x;
5725 xb = xb0 + j;
5726 for(;;) {
5727 if (*--xa != *--xb)
5728 return *xa < *xb ? -1 : 1;
5729 if (xa <= xa0)
5730 break;
5731 }
5732 return 0;
5733}
5734
5735static Bigint *diff(Bigint *a, Bigint *b)
5736{
5737 Bigint *c;
5738 int i, wa, wb;
5739 Long borrow, y; /* We need signed shifts here. */
5740 ULong *xa, *xae, *xb, *xbe, *xc;
5741#ifdef Pack_32
5742 Long z;
5743#endif
5744
5745 i = cmp(a,b);
5746 if (!i) {
5747 c = Balloc(0);
5748 c->wds = 1;
5749 c->x[0] = 0;
5750 return c;
5751 }
5752 if (i < 0) {
5753 c = a;
5754 a = b;
5755 b = c;
5756 i = 1;
5757 }
5758 else
5759 i = 0;
5760 c = Balloc(a->k);
5761 c->sign = i;
5762 wa = a->wds;
5763 xa = a->x;
5764 xae = xa + wa;
5765 wb = b->wds;
5766 xb = b->x;
5767 xbe = xb + wb;
5768 xc = c->x;
5769 borrow = 0;
5770#ifdef Pack_32
5771 do {
5772 y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
5773 borrow = y >> 16;
5774 Sign_Extend(borrow, y);
5775 z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
5776 borrow = z >> 16;
5777 Sign_Extend(borrow, z);
5778 Storeinc(xc, z, y);
5779 }
5780 while(xb < xbe);
5781 while(xa < xae) {
5782 y = (*xa & 0xffff) + borrow;
5783 borrow = y >> 16;
5784 Sign_Extend(borrow, y);
5785 z = (*xa++ >> 16) + borrow;
5786 borrow = z >> 16;
5787 Sign_Extend(borrow, z);
5788 Storeinc(xc, z, y);
5789 }
5790#else
5791 do {
5792 y = *xa++ - *xb++ + borrow;
5793 borrow = y >> 16;
5794 Sign_Extend(borrow, y);
5795 *xc++ = y & 0xffff;
5796 }
5797 while(xb < xbe);
5798 while(xa < xae) {
5799 y = *xa++ + borrow;
5800 borrow = y >> 16;
5801 Sign_Extend(borrow, y);
5802 *xc++ = y & 0xffff;
5803 }
5804#endif
5805 while(!*--xc)
5806 wa--;
5807 c->wds = wa;
5808 return c;
5809}
5810
5811static double ulp(double x)
5812{
5813 Long L;
5814 double a;
5815
5816 L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1;
5817#ifndef Sudden_Underflow
5818 if (L > 0) {
5819#endif
5820#ifdef IBM
5821 L |= Exp_msk1 >> 4;
5822#endif
5823 setWord0(&a, L);
5824 setWord1(&a, 0);
5825#ifndef Sudden_Underflow
5826 }
5827 else {
5828 L = -L >> Exp_shift;
5829 if (L < Exp_shift) {
5830 setWord0(&a, 0x80000 >> L);
5831 setWord1(&a, 0);
5832 }
5833 else {
5834 setWord0(&a, 0);
5835 L -= Exp_shift;
5836 setWord1(&a, L >= 31 ? 1U : 1U << (31 - L));
5837 }
5838 }
5839#endif
5840 return a;
5841}
5842
5843static double b2d(Bigint *a, int *e)
5844{
5845 ULong *xa, *xa0, w, y, z;
5846 int k;
5847 double d;
5848
5849 xa0 = a->x;
5850 xa = xa0 + a->wds;
5851 y = *--xa;
5852#ifdef BSD_QDTOA_DEBUG
5853 if (!y) Bug("zero y in b2d");
5854#endif
5855 k = hi0bits(y);
5856 *e = 32 - k;
5857#ifdef Pack_32
5858 if (k < Ebits) {
5859 setWord0(&d, Exp_1 | y >> (Ebits - k));
5860 w = xa > xa0 ? *--xa : 0;
5861 setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k));
5862 goto ret_d;
5863 }
5864 z = xa > xa0 ? *--xa : 0;
5865 if (k -= Ebits) {
5866 setWord0(&d, Exp_1 | y << k | z >> (32 - k));
5867 y = xa > xa0 ? *--xa : 0;
5868 setWord1(&d, z << k | y >> (32 - k));
5869 }
5870 else {
5871 setWord0(&d, Exp_1 | y);
5872 setWord1(&d, z);
5873 }
5874#else
5875 if (k < Ebits + 16) {
5876 z = xa > xa0 ? *--xa : 0;
5877 setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k);
5878 w = xa > xa0 ? *--xa : 0;
5879 y = xa > xa0 ? *--xa : 0;
5880 setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k);
5881 goto ret_d;
5882 }
5883 z = xa > xa0 ? *--xa : 0;
5884 w = xa > xa0 ? *--xa : 0;
5885 k -= Ebits + 16;
5886 setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k);
5887 y = xa > xa0 ? *--xa : 0;
5888 setWord1(&d, w << k + 16 | y << k);
5889#endif
5890 ret_d:
5891 return d;
5892}
5893
5894static Bigint *d2b(double d, int *e, int *bits)
5895{
5896 Bigint *b;
5897 int de, i, k;
5898 ULong *x, y, z;
5899
5900#ifdef Pack_32
5901 b = Balloc(1);
5902#else
5903 b = Balloc(2);
5904#endif
5905 x = b->x;
5906
5907 z = getWord0(d) & Frac_mask;
5908 setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */
5909#ifdef Sudden_Underflow
5910 de = (int)(getWord0(d) >> Exp_shift);
5911#ifndef IBM
5912 z |= Exp_msk11;
5913#endif
5914#else
5915 if ((de = int(getWord0(d) >> Exp_shift)) != 0)
5916 z |= Exp_msk1;
5917#endif
5918#ifdef Pack_32
5919 if ((y = getWord1(d)) != 0) {
5920 if ((k = lo0bits(&y)) != 0) {
5921 x[0] = y | z << (32 - k);
5922 z >>= k;
5923 }
5924 else
5925 x[0] = y;
5926 i = b->wds = (x[1] = z) ? 2 : 1;
5927 }
5928 else {
5929#ifdef BSD_QDTOA_DEBUG
5930 if (!z)
5931 Bug("Zero passed to d2b");
5932#endif
5933 k = lo0bits(&z);
5934 x[0] = z;
5935 i = b->wds = 1;
5936 k += 32;
5937 }
5938#else
5939 if (y = getWord1(d)) {
5940 if (k = lo0bits(&y))
5941 if (k >= 16) {
5942 x[0] = y | z << 32 - k & 0xffff;
5943 x[1] = z >> k - 16 & 0xffff;
5944 x[2] = z >> k;
5945 i = 2;
5946 }
5947 else {
5948 x[0] = y & 0xffff;
5949 x[1] = y >> 16 | z << 16 - k & 0xffff;
5950 x[2] = z >> k & 0xffff;
5951 x[3] = z >> k+16;
5952 i = 3;
5953 }
5954 else {
5955 x[0] = y & 0xffff;
5956 x[1] = y >> 16;
5957 x[2] = z & 0xffff;
5958 x[3] = z >> 16;
5959 i = 3;
5960 }
5961 }
5962 else {
5963#ifdef BSD_QDTOA_DEBUG
5964 if (!z)
5965 Bug("Zero passed to d2b");
5966#endif
5967 k = lo0bits(&z);
5968 if (k >= 16) {
5969 x[0] = z;
5970 i = 0;
5971 }
5972 else {
5973 x[0] = z & 0xffff;
5974 x[1] = z >> 16;
5975 i = 1;
5976 }
5977 k += 32;
5978 }
5979 while(!x[i])
5980 --i;
5981 b->wds = i + 1;
5982#endif
5983#ifndef Sudden_Underflow
5984 if (de) {
5985#endif
5986#ifdef IBM
5987 *e = (de - Bias - (P-1) << 2) + k;
5988 *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask);
5989#else
5990 *e = de - Bias - (P-1) + k;
5991 *bits = P - k;
5992#endif
5993#ifndef Sudden_Underflow
5994 }
5995 else {
5996 *e = de - Bias - (P-1) + 1 + k;
5997#ifdef Pack_32
5998 *bits = 32*i - hi0bits(x[i-1]);
5999#else
6000 *bits = (i+2)*16 - hi0bits(x[i]);
6001#endif
6002 }
6003#endif
6004 return b;
6005}
6006
6007static double ratio(Bigint *a, Bigint *b)
6008{
6009 double da, db;
6010 int k, ka, kb;
6011
6012 da = b2d(a, &ka);
6013 db = b2d(b, &kb);
6014#ifdef Pack_32
6015 k = ka - kb + 32*(a->wds - b->wds);
6016#else
6017 k = ka - kb + 16*(a->wds - b->wds);
6018#endif
6019#ifdef IBM
6020 if (k > 0) {
6021 setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1);
6022 if (k &= 3)
6023 da *= 1 << k;
6024 }
6025 else {
6026 k = -k;
6027 setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1);
6028 if (k &= 3)
6029 db *= 1 << k;
6030 }
6031#else
6032 if (k > 0)
6033 setWord0(&da, getWord0(da) + k*Exp_msk1);
6034 else {
6035 k = -k;
6036 setWord0(&db, getWord0(db) + k*Exp_msk1);
6037 }
6038#endif
6039 return da / db;
6040}
6041
6042static const double tens[] = {
6043 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
6044 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
6045 1e20, 1e21, 1e22
6046#ifdef VAX
6047 , 1e23, 1e24
6048#endif
6049};
6050
6051#ifdef IEEE_Arith
6052static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
6053static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
6054#define n_bigtens 5
6055#else
6056#ifdef IBM
6057static const double bigtens[] = { 1e16, 1e32, 1e64 };
6058static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
6059#define n_bigtens 3
6060#else
6061static const double bigtens[] = { 1e16, 1e32 };
6062static const double tinytens[] = { 1e-16, 1e-32 };
6063#define n_bigtens 2
6064#endif
6065#endif
6066
6067/*
6068 The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes
6069 the comparison 1e-100 == 0.0 to return true. As a workaround, we
6070 compare it to a global variable containing 0.0, which produces
6071 correct assembler output.
6072
6073 ### consider detecting the broken compilers and using the static
6074 ### double for these, and use a #define for all working compilers
6075*/
6076static double g_double_zero = 0.0;
6077
6078Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok)
6079{
6080 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
6081 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
6082 const char *s, *s0, *s1;
6083 double aadj, aadj1, adj, rv, rv0;
6084 Long L;
6085 ULong y, z;
6086 Bigint *bb1, *bd0;
6087 Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
6088
6089 /*
6090 #ifndef KR_headers
6091 const char decimal_point = localeconv()->decimal_point[0];
6092 #else
6093 const char decimal_point = '.';
6094 #endif */
6095 if (ok != 0)
6096 *ok = true;
6097
6098 const char decimal_point = '.';
6099
6100 sign = nz0 = nz = 0;
6101 rv = 0.;
6102
6103
6104 for(s = s00; isspace(uchar(*s)); s++)
6105 ;
6106
6107 if (*s == '-') {
6108 sign = 1;
6109 s++;
6110 } else if (*s == '+') {
6111 s++;
6112 }
6113
6114 if (*s == '\0') {
6115 s = s00;
6116 goto ret;
6117 }
6118
6119 if (*s == '0') {
6120 nz0 = 1;
6121 while(*++s == '0') ;
6122 if (!*s)
6123 goto ret;
6124 }
6125 s0 = s;
6126 y = z = 0;
6127 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
6128 if (nd < 9)
6129 y = 10*y + c - '0';
6130 else if (nd < 16)
6131 z = 10*z + c - '0';
6132 nd0 = nd;
6133 if (c == decimal_point) {
6134 c = *++s;
6135 if (!nd) {
6136 for(; c == '0'; c = *++s)
6137 nz++;
6138 if (c > '0' && c <= '9') {
6139 s0 = s;
6140 nf += nz;
6141 nz = 0;
6142 goto have_dig;
6143 }
6144 goto dig_done;
6145 }
6146 for(; c >= '0' && c <= '9'; c = *++s) {
6147 have_dig:
6148 nz++;
6149 if (c -= '0') {
6150 nf += nz;
6151 for(i = 1; i < nz; i++)
6152 if (nd++ < 9)
6153 y *= 10;
6154 else if (nd <= DBL_DIG + 1)
6155 z *= 10;
6156 if (nd++ < 9)
6157 y = 10*y + c;
6158 else if (nd <= DBL_DIG + 1)
6159 z = 10*z + c;
6160 nz = 0;
6161 }
6162 }
6163 }
6164 dig_done:
6165 e = 0;
6166 if (c == 'e' || c == 'E') {
6167 if (!nd && !nz && !nz0) {
6168 s = s00;
6169 goto ret;
6170 }
6171 s00 = s;
6172 esign = 0;
6173 switch(c = *++s) {
6174 case '-':
6175 esign = 1;
6176 case '+':
6177 c = *++s;
6178 }
6179 if (c >= '0' && c <= '9') {
6180 while(c == '0')
6181 c = *++s;
6182 if (c > '0' && c <= '9') {
6183 L = c - '0';
6184 s1 = s;
6185 while((c = *++s) >= '0' && c <= '9')
6186 L = 10*L + c - '0';
6187 if (s - s1 > 8 || L > 19999)
6188 /* Avoid confusion from exponents
6189 * so large that e might overflow.
6190 */
6191 e = 19999; /* safe for 16 bit ints */
6192 else
6193 e = int(L);
6194 if (esign)
6195 e = -e;
6196 }
6197 else
6198 e = 0;
6199 }
6200 else
6201 s = s00;
6202 }
6203 if (!nd) {
6204 if (!nz && !nz0)
6205 s = s00;
6206 goto ret;
6207 }
6208 e1 = e -= nf;
6209
6210 /* Now we have nd0 digits, starting at s0, followed by a
6211 * decimal point, followed by nd-nd0 digits. The number we're
6212 * after is the integer represented by those digits times
6213 * 10**e */
6214
6215 if (!nd0)
6216 nd0 = nd;
6217 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
6218 rv = y;
6219 if (k > 9)
6220#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
6221 {
6222 // work around a bug on 64 bit IRIX gcc
6223 double *t = (double *) tens;
6224 rv = t[k - 9] * rv + z;
6225 }
6226#else
6227 rv = tens[k - 9] * rv + z;
6228#endif
6229
6230 bd0 = 0;
6231 if (nd <= DBL_DIG
6232#ifndef RND_PRODQUOT
6233 && FLT_ROUNDS == 1
6234#endif
6235 ) {
6236 if (!e)
6237 goto ret;
6238 if (e > 0) {
6239 if (e <= Ten_pmax) {
6240#ifdef VAX
6241 goto vax_ovfl_check;
6242#else
6243 /* rv = */ rounded_product(rv, tens[e]);
6244 goto ret;
6245#endif
6246 }
6247 i = DBL_DIG - nd;
6248 if (e <= Ten_pmax + i) {
6249 /* A fancier test would sometimes let us do
6250 * this for larger i values.
6251 */
6252 e -= i;
6253 rv *= tens[i];
6254#ifdef VAX
6255 /* VAX exponent range is so narrow we must
6256 * worry about overflow here...
6257 */
6258 vax_ovfl_check:
6259 setWord0(&rv, getWord0(rv) - P*Exp_msk1);
6260 /* rv = */ rounded_product(rv, tens[e]);
6261 if ((getWord0(rv) & Exp_mask)
6262 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
6263 goto ovfl;
6264 setWord0(&rv, getWord0(rv) + P*Exp_msk1);
6265#else
6266 /* rv = */ rounded_product(rv, tens[e]);
6267#endif
6268 goto ret;
6269 }
6270 }
6271#ifndef Inaccurate_Divide
6272 else if (e >= -Ten_pmax) {
6273 /* rv = */ rounded_quotient(rv, tens[-e]);
6274 goto ret;
6275 }
6276#endif
6277 }
6278 e1 += nd - k;
6279
6280 /* Get starting approximation = rv * 10**e1 */
6281
6282 if (e1 > 0) {
6283 if ((i = e1 & 15) != 0)
6284 rv *= tens[i];
6285 if (e1 &= ~15) {
6286 if (e1 > DBL_MAX_10_EXP) {
6287 ovfl:
6288 // errno = ERANGE;
6289 if (ok != 0)
6290 *ok = false;
6291#ifdef __STDC__
6292 rv = HUGE_VAL;
6293#else
6294 /* Can't trust HUGE_VAL */
6295#ifdef IEEE_Arith
6296 setWord0(&rv, Exp_mask);
6297 setWord1(&rv, 0);
6298#else
6299 setWord0(&rv, Big0);
6300 setWord1(&rv, Big1);
6301#endif
6302#endif
6303 if (bd0)
6304 goto retfree;
6305 goto ret;
6306 }
6307 if (e1 >>= 4) {
6308 for(j = 0; e1 > 1; j++, e1 >>= 1)
6309 if (e1 & 1)
6310 rv *= bigtens[j];
6311 /* The last multiplication could overflow. */
6312 setWord0(&rv, getWord0(rv) - P*Exp_msk1);
6313 rv *= bigtens[j];
6314 if ((z = getWord0(rv) & Exp_mask)
6315 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
6316 goto ovfl;
6317 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
6318 /* set to largest number */
6319 /* (Can't trust DBL_MAX) */
6320 setWord0(&rv, Big0);
6321 setWord1(&rv, Big1);
6322 }
6323 else
6324 setWord0(&rv, getWord0(rv) + P*Exp_msk1);
6325 }
6326
6327 }
6328 }
6329 else if (e1 < 0) {
6330 e1 = -e1;
6331 if ((i = e1 & 15) != 0)
6332 rv /= tens[i];
6333 if (e1 &= ~15) {
6334 e1 >>= 4;
6335 if (e1 >= 1 << n_bigtens)
6336 goto undfl;
6337 for(j = 0; e1 > 1; j++, e1 >>= 1)
6338 if (e1 & 1)
6339 rv *= tinytens[j];
6340 /* The last multiplication could underflow. */
6341 rv0 = rv;
6342 rv *= tinytens[j];
6343 if (rv == g_double_zero)
6344 {
6345 rv = 2.*rv0;
6346 rv *= tinytens[j];
6347 if (rv == g_double_zero)
6348 {
6349 undfl:
6350 rv = 0.;
6351 // errno = ERANGE;
6352 if (ok != 0)
6353 *ok = false;
6354 if (bd0)
6355 goto retfree;
6356 goto ret;
6357 }
6358 setWord0(&rv, Tiny0);
6359 setWord1(&rv, Tiny1);
6360 /* The refinement below will clean
6361 * this approximation up.
6362 */
6363 }
6364 }
6365 }
6366
6367 /* Now the hard part -- adjusting rv to the correct value.*/
6368
6369 /* Put digits into bd: true value = bd * 10^e */
6370
6371 bd0 = s2b(s0, nd0, nd, y);
6372
6373 for(;;) {
6374 bd = Balloc(bd0->k);
6375 Bcopy(bd, bd0);
6376 bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
6377 bs = i2b(1);
6378
6379 if (e >= 0) {
6380 bb2 = bb5 = 0;
6381 bd2 = bd5 = e;
6382 }
6383 else {
6384 bb2 = bb5 = -e;
6385 bd2 = bd5 = 0;
6386 }
6387 if (bbe >= 0)
6388 bb2 += bbe;
6389 else
6390 bd2 -= bbe;
6391 bs2 = bb2;
6392#ifdef Sudden_Underflow
6393#ifdef IBM
6394 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
6395#else
6396 j = P + 1 - bbbits;
6397#endif
6398#else
6399 i = bbe + bbbits - 1; /* logb(rv) */
6400 if (i < Emin) /* denormal */
6401 j = bbe + (P-Emin);
6402 else
6403 j = P + 1 - bbbits;
6404#endif
6405 bb2 += j;
6406 bd2 += j;
6407 i = bb2 < bd2 ? bb2 : bd2;
6408 if (i > bs2)
6409 i = bs2;
6410 if (i > 0) {
6411 bb2 -= i;
6412 bd2 -= i;
6413 bs2 -= i;
6414 }
6415 if (bb5 > 0) {
6416 bs = pow5mult(bs, bb5);
6417 bb1 = mult(bs, bb);
6418 Bfree(bb);
6419 bb = bb1;
6420 }
6421 if (bb2 > 0)
6422 bb = lshift(bb, bb2);
6423 if (bd5 > 0)
6424 bd = pow5mult(bd, bd5);
6425 if (bd2 > 0)
6426 bd = lshift(bd, bd2);
6427 if (bs2 > 0)
6428 bs = lshift(bs, bs2);
6429 delta = diff(bb, bd);
6430 dsign = delta->sign;
6431 delta->sign = 0;
6432 i = cmp(delta, bs);
6433 if (i < 0) {
6434 /* Error is less than half an ulp -- check for
6435 * special case of mantissa a power of two.
6436 */
6437 if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask)
6438 break;
6439 delta = lshift(delta,Log2P);
6440 if (cmp(delta, bs) > 0)
6441 goto drop_down;
6442 break;
6443 }
6444 if (i == 0) {
6445 /* exactly half-way between */
6446 if (dsign) {
6447 if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1
6448 && getWord1(rv) == 0xffffffff) {
6449 /*boundary case -- increment exponent*/
6450 setWord0(&rv, (getWord0(rv) & Exp_mask)
6451 + Exp_msk1
6452#ifdef IBM
6453 | Exp_msk1 >> 4
6454#endif
6455 );
6456 setWord1(&rv, 0);
6457 break;
6458 }
6459 }
6460 else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) {
6461 drop_down:
6462 /* boundary case -- decrement exponent */
6463#ifdef Sudden_Underflow
6464 L = getWord0(rv) & Exp_mask;
6465#ifdef IBM
6466 if (L < Exp_msk1)
6467#else
6468 if (L <= Exp_msk1)
6469#endif
6470 goto undfl;
6471 L -= Exp_msk1;
6472#else
6473 L = (getWord0(rv) & Exp_mask) - Exp_msk1;
6474#endif
6475 setWord0(&rv, L | Bndry_mask1);
6476 setWord1(&rv, 0xffffffff);
6477#ifdef IBM
6478 goto cont;
6479#else
6480 break;
6481#endif
6482 }
6483#ifndef ROUND_BIASED
6484 if (!(getWord1(rv) & LSB))
6485 break;
6486#endif
6487 if (dsign)
6488 rv += ulp(rv);
6489#ifndef ROUND_BIASED
6490 else {
6491 rv -= ulp(rv);
6492#ifndef Sudden_Underflow
6493 if (rv == g_double_zero)
6494 goto undfl;
6495#endif
6496 }
6497#endif
6498 break;
6499 }
6500 if ((aadj = ratio(delta, bs)) <= 2.) {
6501 if (dsign)
6502 aadj = aadj1 = 1.;
6503 else if (getWord1(rv) || getWord0(rv) & Bndry_mask) {
6504#ifndef Sudden_Underflow
6505 if (getWord1(rv) == Tiny1 && !getWord0(rv))
6506 goto undfl;
6507#endif
6508 aadj = 1.;
6509 aadj1 = -1.;
6510 }
6511 else {
6512 /* special case -- power of FLT_RADIX to be */
6513 /* rounded down... */
6514
6515 if (aadj < 2./FLT_RADIX)
6516 aadj = 1./FLT_RADIX;
6517 else
6518 aadj *= 0.5;
6519 aadj1 = -aadj;
6520 }
6521 }
6522 else {
6523 aadj *= 0.5;
6524 aadj1 = dsign ? aadj : -aadj;
6525#ifdef Check_FLT_ROUNDS
6526 switch(FLT_ROUNDS) {
6527 case 2: /* towards +infinity */
6528 aadj1 -= 0.5;
6529 break;
6530 case 0: /* towards 0 */
6531 case 3: /* towards -infinity */
6532 aadj1 += 0.5;
6533 }
6534#else
6535 if (FLT_ROUNDS == 0)
6536 aadj1 += 0.5;
6537#endif
6538 }
6539 y = getWord0(rv) & Exp_mask;
6540
6541 /* Check for overflow */
6542
6543 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
6544 rv0 = rv;
6545 setWord0(&rv, getWord0(rv) - P*Exp_msk1);
6546 adj = aadj1 * ulp(rv);
6547 rv += adj;
6548 if ((getWord0(rv) & Exp_mask) >=
6549 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
6550 if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1)
6551 goto ovfl;
6552 setWord0(&rv, Big0);
6553 setWord1(&rv, Big1);
6554 goto cont;
6555 }
6556 else
6557 setWord0(&rv, getWord0(rv) + P*Exp_msk1);
6558 }
6559 else {
6560#ifdef Sudden_Underflow
6561 if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) {
6562 rv0 = rv;
6563 setWord0(&rv, getWord0(rv) + P*Exp_msk1);
6564 adj = aadj1 * ulp(rv);
6565 rv += adj;
6566#ifdef IBM
6567 if ((getWord0(rv) & Exp_mask) < P*Exp_msk1)
6568#else
6569 if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1)
6570#endif
6571 {
6572 if (getWord0(rv0) == Tiny0
6573 && getWord1(rv0) == Tiny1)
6574 goto undfl;
6575 setWord0(&rv, Tiny0);
6576 setWord1(&rv, Tiny1);
6577 goto cont;
6578 }
6579 else
6580 setWord0(&rv, getWord0(rv) - P*Exp_msk1);
6581 }
6582 else {
6583 adj = aadj1 * ulp(rv);
6584 rv += adj;
6585 }
6586#else
6587 /* Compute adj so that the IEEE rounding rules will
6588 * correctly round rv + adj in some half-way cases.
6589 * If rv * ulp(rv) is denormalized (i.e.,
6590 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
6591 * trouble from bits lost to denormalization;
6592 * example: 1.2e-307 .
6593 */
6594 if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
6595 aadj1 = int(aadj + 0.5);
6596 if (!dsign)
6597 aadj1 = -aadj1;
6598 }
6599 adj = aadj1 * ulp(rv);
6600 rv += adj;
6601#endif
6602 }
6603 z = getWord0(rv) & Exp_mask;
6604 if (y == z) {
6605 /* Can we stop now? */
6606 L = Long(aadj);
6607 aadj -= L;
6608 /* The tolerances below are conservative. */
6609 if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) {
6610 if (aadj < .4999999 || aadj > .5000001)
6611 break;
6612 }
6613 else if (aadj < .4999999/FLT_RADIX)
6614 break;
6615 }
6616 cont:
6617 Bfree(bb);
6618 Bfree(bd);
6619 Bfree(bs);
6620 Bfree(delta);
6621 }
6622 retfree:
6623 Bfree(bb);
6624 Bfree(bd);
6625 Bfree(bs);
6626 Bfree(bd0);
6627 Bfree(delta);
6628 ret:
6629 if (se)
6630 *se = s;
6631 return sign ? -rv : rv;
6632}
6633
6634static int quorem(Bigint *b, Bigint *S)
6635{
6636 int n;
6637 Long borrow, y;
6638 ULong carry, q, ys;
6639 ULong *bx, *bxe, *sx, *sxe;
6640#ifdef Pack_32
6641 Long z;
6642 ULong si, zs;
6643#endif
6644
6645 n = S->wds;
6646#ifdef BSD_QDTOA_DEBUG
6647 /*debug*/ if (b->wds > n)
6648 /*debug*/ Bug("oversize b in quorem");
6649#endif
6650 if (b->wds < n)
6651 return 0;
6652 sx = S->x;
6653 sxe = sx + --n;
6654 bx = b->x;
6655 bxe = bx + n;
6656 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
6657#ifdef BSD_QDTOA_DEBUG
6658 /*debug*/ if (q > 9)
6659 /*debug*/ Bug("oversized quotient in quorem");
6660#endif
6661 if (q) {
6662 borrow = 0;
6663 carry = 0;
6664 do {
6665#ifdef Pack_32
6666 si = *sx++;
6667 ys = (si & 0xffff) * q + carry;
6668 zs = (si >> 16) * q + (ys >> 16);
6669 carry = zs >> 16;
6670 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
6671 borrow = y >> 16;
6672 Sign_Extend(borrow, y);
6673 z = (*bx >> 16) - (zs & 0xffff) + borrow;
6674 borrow = z >> 16;
6675 Sign_Extend(borrow, z);
6676 Storeinc(bx, z, y);
6677#else
6678 ys = *sx++ * q + carry;
6679 carry = ys >> 16;
6680 y = *bx - (ys & 0xffff) + borrow;
6681 borrow = y >> 16;
6682 Sign_Extend(borrow, y);
6683 *bx++ = y & 0xffff;
6684#endif
6685 }
6686 while(sx <= sxe);
6687 if (!*bxe) {
6688 bx = b->x;
6689 while(--bxe > bx && !*bxe)
6690 --n;
6691 b->wds = n;
6692 }
6693 }
6694 if (cmp(b, S) >= 0) {
6695 q++;
6696 borrow = 0;
6697 carry = 0;
6698 bx = b->x;
6699 sx = S->x;
6700 do {
6701#ifdef Pack_32
6702 si = *sx++;
6703 ys = (si & 0xffff) + carry;
6704 zs = (si >> 16) + (ys >> 16);
6705 carry = zs >> 16;
6706 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
6707 borrow = y >> 16;
6708 Sign_Extend(borrow, y);
6709 z = (*bx >> 16) - (zs & 0xffff) + borrow;
6710 borrow = z >> 16;
6711 Sign_Extend(borrow, z);
6712 Storeinc(bx, z, y);
6713#else
6714 ys = *sx++ + carry;
6715 carry = ys >> 16;
6716 y = *bx - (ys & 0xffff) + borrow;
6717 borrow = y >> 16;
6718 Sign_Extend(borrow, y);
6719 *bx++ = y & 0xffff;
6720#endif
6721 }
6722 while(sx <= sxe);
6723 bx = b->x;
6724 bxe = bx + n;
6725 if (!*bxe) {
6726 while(--bxe > bx && !*bxe)
6727 --n;
6728 b->wds = n;
6729 }
6730 }
6731 return q;
6732}
6733
6734/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
6735 *
6736 * Inspired by "How to Print Floating-Point Numbers Accurately" by
6737 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
6738 *
6739 * Modifications:
6740 * 1. Rather than iterating, we use a simple numeric overestimate
6741 * to determine k = floor(log10(d)). We scale relevant
6742 * quantities using O(log2(k)) rather than O(k) multiplications.
6743 * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
6744 * try to generate digits strictly left to right. Instead, we
6745 * compute with fewer bits and propagate the carry if necessary
6746 * when rounding the final digit up. This is often faster.
6747 * 3. Under the assumption that input will be rounded nearest,
6748 * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
6749 * That is, we allow equality in stopping tests when the
6750 * round-nearest rule will give the same floating-point value
6751 * as would satisfaction of the stopping test with strict
6752 * inequality.
6753 * 4. We remove common factors of powers of 2 from relevant
6754 * quantities.
6755 * 5. When converting floating-point integers less than 1e16,
6756 * we use floating-point arithmetic rather than resorting
6757 * to multiple-precision integers.
6758 * 6. When asked to produce fewer than 15 digits, we first try
6759 * to get by with floating-point arithmetic; we resort to
6760 * multiple-precision integer arithmetic only if we cannot
6761 * guarantee that the floating-point calculation has given
6762 * the correctly rounded result. For k requested digits and
6763 * "uniformly" distributed input, the probability is
6764 * something like 10^(k-15) that we must resort to the Long
6765 * calculation.
6766 */
6767
6768
6769/* This actually sometimes returns a pointer to a string literal
6770 cast to a char*. Do NOT try to modify the return value. */
6771
6772Q_CORE_EXPORT char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
6773{
6774 // Some values of the floating-point control word can cause _qdtoa to crash with an underflow.
6775 // We set a safe value here.
6776#ifdef Q_OS_WIN
6777 _clear87();
6778 unsigned int oldbits = _control87(0, 0);
6779#ifndef MCW_EM
6780# ifdef _MCW_EM
6781# define MCW_EM _MCW_EM
6782# else
6783# define MCW_EM 0x0008001F
6784# endif
6785#endif
6786 _control87(MCW_EM, MCW_EM);
6787#endif
6788
6789#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
6790 fenv_t envp;
6791 feholdexcept(&envp);
6792#endif
6793
6794 char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp);
6795
6796#ifdef Q_OS_WIN
6797 _clear87();
6798#ifndef _M_X64
6799 _control87(oldbits, 0xFFFFF);
6800#else
6801 _control87(oldbits, _MCW_EM|_MCW_DN|_MCW_RC);
6802#endif //_M_X64
6803#endif //Q_OS_WIN
6804
6805#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
6806 fesetenv(&envp);
6807#endif
6808
6809 return s;
6810}
6811
6812static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
6813{
6814 /*
6815 Arguments ndigits, decpt, sign are similar to those
6816 of ecvt and fcvt; trailing zeros are suppressed from
6817 the returned string. If not null, *rve is set to point
6818 to the end of the return value. If d is +-Infinity or NaN,
6819 then *decpt is set to 9999.
6820
6821 mode:
6822 0 ==> shortest string that yields d when read in
6823 and rounded to nearest.
6824 1 ==> like 0, but with Steele & White stopping rule;
6825 e.g. with IEEE P754 arithmetic , mode 0 gives
6826 1e23 whereas mode 1 gives 9.999999999999999e22.
6827 2 ==> max(1,ndigits) significant digits. This gives a
6828 return value similar to that of ecvt, except
6829 that trailing zeros are suppressed.
6830 3 ==> through ndigits past the decimal point. This
6831 gives a return value similar to that from fcvt,
6832 except that trailing zeros are suppressed, and
6833 ndigits can be negative.
6834 4-9 should give the same return values as 2-3, i.e.,
6835 4 <= mode <= 9 ==> same return as mode
6836 2 + (mode & 1). These modes are mainly for
6837 debugging; often they run slower but sometimes
6838 faster than modes 2-3.
6839 4,5,8,9 ==> left-to-right digit generation.
6840 6-9 ==> don't try fast floating-point estimate
6841 (if applicable).
6842
6843 Values of mode other than 0-9 are treated as mode 0.
6844
6845 Sufficient space is allocated to the return value
6846 to hold the suppressed trailing zeros.
6847 */
6848
6849 int bbits, b2, b5, be, dig, i, ieps, ilim0,
6850 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
6851 try_quick;
6852 int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */
6853 Long L;
6854#ifndef Sudden_Underflow
6855 int denorm;
6856 ULong x;
6857#endif
6858 Bigint *b, *b1, *delta, *mhi, *S;
6859 Bigint *mlo = NULL; /* pacify gcc */
6860 double d2;
6861 double ds, eps;
6862 char *s, *s0;
6863
6864 if (getWord0(d) & Sign_bit) {
6865 /* set sign for everything, including 0's and NaNs */
6866 *sign = 1;
6867 setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */
6868 }
6869 else
6870 *sign = 0;
6871
6872#if defined(IEEE_Arith) + defined(VAX)
6873#ifdef IEEE_Arith
6874 if ((getWord0(d) & Exp_mask) == Exp_mask)
6875#else
6876 if (getWord0(d) == 0x8000)
6877#endif
6878 {
6879 /* Infinity or NaN */
6880 *decpt = 9999;
6881 s =
6882#ifdef IEEE_Arith
6883 !getWord1(d) && !(getWord0(d) & 0xfffff) ? const_cast<char*>("Infinity") :
6884#endif
6885 const_cast<char*>("NaN");
6886 if (rve)
6887 *rve =
6888#ifdef IEEE_Arith
6889 s[3] ? s + 8 :
6890#endif
6891 s + 3;
6892 return s;
6893 }
6894#endif
6895#ifdef IBM
6896 d += 0; /* normalize */
6897#endif
6898 if (d == g_double_zero)
6899 {
6900 *decpt = 1;
6901 s = const_cast<char*>("0");
6902 if (rve)
6903 *rve = s + 1;
6904 return s;
6905 }
6906
6907 b = d2b(d, &be, &bbits);
6908#ifdef Sudden_Underflow
6909 i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
6910#else
6911 if ((i = int(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
6912#endif
6913 d2 = d;
6914 setWord0(&d2, getWord0(d2) & Frac_mask1);
6915 setWord0(&d2, getWord0(d2) | Exp_11);
6916#ifdef IBM
6917 if (j = 11 - hi0bits(getWord0(d2) & Frac_mask))
6918 d2 /= 1 << j;
6919#endif
6920
6921 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
6922 * log10(x) = log(x) / log(10)
6923 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
6924 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
6925 *
6926 * This suggests computing an approximation k to log10(d) by
6927 *
6928 * k = (i - Bias)*0.301029995663981
6929 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
6930 *
6931 * We want k to be too large rather than too small.
6932 * The error in the first-order Taylor series approximation
6933 * is in our favor, so we just round up the constant enough
6934 * to compensate for any error in the multiplication of
6935 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
6936 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
6937 * adding 1e-13 to the constant term more than suffices.
6938 * Hence we adjust the constant term to 0.1760912590558.
6939 * (We could get a more accurate k by invoking log10,
6940 * but this is probably not worthwhile.)
6941 */
6942
6943 i -= Bias;
6944#ifdef IBM
6945 i <<= 2;
6946 i += j;
6947#endif
6948#ifndef Sudden_Underflow
6949 denorm = 0;
6950 }
6951 else {
6952 /* d is denormalized */
6953
6954 i = bbits + be + (Bias + (P-1) - 1);
6955 x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32)
6956 : getWord1(d) << (32 - i);
6957 d2 = x;
6958 setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */
6959 i -= (Bias + (P-1) - 1) + 1;
6960 denorm = 1;
6961 }
6962#endif
6963 ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
6964 k = int(ds);
6965 if (ds < 0. && ds != k)
6966 k--; /* want k = floor(ds) */
6967 k_check = 1;
6968 if (k >= 0 && k <= Ten_pmax) {
6969 if (d < tens[k])
6970 k--;
6971 k_check = 0;
6972 }
6973 j = bbits - i - 1;
6974 if (j >= 0) {
6975 b2 = 0;
6976 s2 = j;
6977 }
6978 else {
6979 b2 = -j;
6980 s2 = 0;
6981 }
6982 if (k >= 0) {
6983 b5 = 0;
6984 s5 = k;
6985 s2 += k;
6986 }
6987 else {
6988 b2 -= k;
6989 b5 = -k;
6990 s5 = 0;
6991 }
6992 if (mode < 0 || mode > 9)
6993 mode = 0;
6994 try_quick = 1;
6995 if (mode > 5) {
6996 mode -= 4;
6997 try_quick = 0;
6998 }
6999 leftright = 1;
7000 switch(mode) {
7001 case 0:
7002 case 1:
7003 ilim = ilim1 = -1;
7004 i = 18;
7005 ndigits = 0;
7006 break;
7007 case 2:
7008 leftright = 0;
7009 /* no break */
7010 case 4:
7011 if (ndigits <= 0)
7012 ndigits = 1;
7013 ilim = ilim1 = i = ndigits;
7014 break;
7015 case 3:
7016 leftright = 0;
7017 /* no break */
7018 case 5:
7019 i = ndigits + k + 1;
7020 ilim = i;
7021 ilim1 = i - 1;
7022 if (i <= 0)
7023 i = 1;
7024 }
7025 QT_TRY {
7026 *resultp = static_cast<char *>(malloc(i + 1));
7027 Q_CHECK_PTR(*resultp);
7028 } QT_CATCH(...) {
7029 Bfree(b);
7030 QT_RETHROW;
7031 }
7032 s = s0 = *resultp;
7033
7034 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
7035
7036 /* Try to get by with floating-point arithmetic. */
7037
7038 i = 0;
7039 d2 = d;
7040 k0 = k;
7041 ilim0 = ilim;
7042 ieps = 2; /* conservative */
7043 if (k > 0) {
7044 ds = tens[k&0xf];
7045 j = k >> 4;
7046 if (j & Bletch) {
7047 /* prevent overflows */
7048 j &= Bletch - 1;
7049 d /= bigtens[n_bigtens-1];
7050 ieps++;
7051 }
7052 for(; j; j >>= 1, i++)
7053 if (j & 1) {
7054 ieps++;
7055 ds *= bigtens[i];
7056 }
7057 d /= ds;
7058 }
7059 else if ((j1 = -k) != 0) {
7060 d *= tens[j1 & 0xf];
7061 for(j = j1 >> 4; j; j >>= 1, i++)
7062 if (j & 1) {
7063 ieps++;
7064 d *= bigtens[i];
7065 }
7066 }
7067 if (k_check && d < 1. && ilim > 0) {
7068 if (ilim1 <= 0)
7069 goto fast_failed;
7070 ilim = ilim1;
7071 k--;
7072 d *= 10.;
7073 ieps++;
7074 }
7075 eps = ieps*d + 7.;
7076 setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1);
7077 if (ilim == 0) {
7078 S = mhi = 0;
7079 d -= 5.;
7080 if (d > eps)
7081 goto one_digit;
7082 if (d < -eps)
7083 goto no_digits;
7084 goto fast_failed;
7085 }
7086#ifndef No_leftright
7087 if (leftright) {
7088 /* Use Steele & White method of only
7089 * generating digits needed.
7090 */
7091 eps = 0.5/tens[ilim-1] - eps;
7092 for(i = 0;;) {
7093 L = Long(d);
7094 d -= L;
7095 *s++ = '0' + int(L);
7096 if (d < eps)
7097 goto ret1;
7098 if (1. - d < eps)
7099 goto bump_up;
7100 if (++i >= ilim)
7101 break;
7102 eps *= 10.;
7103 d *= 10.;
7104 }
7105 }
7106 else {
7107#endif
7108 /* Generate ilim digits, then fix them up. */
7109#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
7110 // work around a bug on 64 bit IRIX gcc
7111 double *t = (double *) tens;
7112 eps *= t[ilim-1];
7113#else
7114 eps *= tens[ilim-1];
7115#endif
7116 for(i = 1;; i++, d *= 10.) {
7117 L = Long(d);
7118 d -= L;
7119 *s++ = '0' + int(L);
7120 if (i == ilim) {
7121 if (d > 0.5 + eps)
7122 goto bump_up;
7123 else if (d < 0.5 - eps) {
7124 while(*--s == '0') {}
7125 s++;
7126 goto ret1;
7127 }
7128 break;
7129 }
7130 }
7131#ifndef No_leftright
7132 }
7133#endif
7134 fast_failed:
7135 s = s0;
7136 d = d2;
7137 k = k0;
7138 ilim = ilim0;
7139 }
7140
7141 /* Do we have a "small" integer? */
7142
7143 if (be >= 0 && k <= Int_max) {
7144 /* Yes. */
7145 ds = tens[k];
7146 if (ndigits < 0 && ilim <= 0) {
7147 S = mhi = 0;
7148 if (ilim < 0 || d <= 5*ds)
7149 goto no_digits;
7150 goto one_digit;
7151 }
7152 for(i = 1;; i++) {
7153 L = Long(d / ds);
7154 d -= L*ds;
7155#ifdef Check_FLT_ROUNDS
7156 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
7157 if (d < 0) {
7158 L--;
7159 d += ds;
7160 }
7161#endif
7162 *s++ = '0' + int(L);
7163 if (i == ilim) {
7164 d += d;
7165 if (d > ds || (d == ds && L & 1)) {
7166 bump_up:
7167 while(*--s == '9')
7168 if (s == s0) {
7169 k++;
7170 *s = '0';
7171 break;
7172 }
7173 ++*s++;
7174 }
7175 break;
7176 }
7177 if ((d *= 10.) == g_double_zero)
7178 break;
7179 }
7180 goto ret1;
7181 }
7182
7183 m2 = b2;
7184 m5 = b5;
7185 mhi = mlo = 0;
7186 if (leftright) {
7187 if (mode < 2) {
7188 i =
7189#ifndef Sudden_Underflow
7190 denorm ? be + (Bias + (P-1) - 1 + 1) :
7191#endif
7192#ifdef IBM
7193 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
7194#else
7195 1 + P - bbits;
7196#endif
7197 }
7198 else {
7199 j = ilim - 1;
7200 if (m5 >= j)
7201 m5 -= j;
7202 else {
7203 s5 += j -= m5;
7204 b5 += j;
7205 m5 = 0;
7206 }
7207 if ((i = ilim) < 0) {
7208 m2 -= i;
7209 i = 0;
7210 }
7211 }
7212 b2 += i;
7213 s2 += i;
7214 mhi = i2b(1);
7215 }
7216 if (m2 > 0 && s2 > 0) {
7217 i = m2 < s2 ? m2 : s2;
7218 b2 -= i;
7219 m2 -= i;
7220 s2 -= i;
7221 }
7222 if (b5 > 0) {
7223 if (leftright) {
7224 if (m5 > 0) {
7225 mhi = pow5mult(mhi, m5);
7226 b1 = mult(mhi, b);
7227 Bfree(b);
7228 b = b1;
7229 }
7230 if ((j = b5 - m5) != 0)
7231 b = pow5mult(b, j);
7232 }
7233 else
7234 b = pow5mult(b, b5);
7235 }
7236 S = i2b(1);
7237 if (s5 > 0)
7238 S = pow5mult(S, s5);
7239
7240 /* Check for special case that d is a normalized power of 2. */
7241
7242 if (mode < 2) {
7243 if (!getWord1(d) && !(getWord0(d) & Bndry_mask)
7244#ifndef Sudden_Underflow
7245 && getWord0(d) & Exp_mask
7246#endif
7247 ) {
7248 /* The special case */
7249 b2 += Log2P;
7250 s2 += Log2P;
7251 spec_case = 1;
7252 }
7253 else
7254 spec_case = 0;
7255 }
7256
7257 /* Arrange for convenient computation of quotients:
7258 * shift left if necessary so divisor has 4 leading 0 bits.
7259 *
7260 * Perhaps we should just compute leading 28 bits of S once
7261 * and for all and pass them and a shift to quorem, so it
7262 * can do shifts and ors to compute the numerator for q.
7263 */
7264#ifdef Pack_32
7265 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
7266 i = 32 - i;
7267#else
7268 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
7269 i = 16 - i;
7270#endif
7271 if (i > 4) {
7272 i -= 4;
7273 b2 += i;
7274 m2 += i;
7275 s2 += i;
7276 }
7277 else if (i < 4) {
7278 i += 28;
7279 b2 += i;
7280 m2 += i;
7281 s2 += i;
7282 }
7283 if (b2 > 0)
7284 b = lshift(b, b2);
7285 if (s2 > 0)
7286 S = lshift(S, s2);
7287 if (k_check) {
7288 if (cmp(b,S) < 0) {
7289 k--;
7290 b = multadd(b, 10, 0); /* we botched the k estimate */
7291 if (leftright)
7292 mhi = multadd(mhi, 10, 0);
7293 ilim = ilim1;
7294 }
7295 }
7296 if (ilim <= 0 && mode > 2) {
7297 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
7298 /* no digits, fcvt style */
7299 no_digits:
7300 k = -1 - ndigits;
7301 goto ret;
7302 }
7303 one_digit:
7304 *s++ = '1';
7305 k++;
7306 goto ret;
7307 }
7308 if (leftright) {
7309 if (m2 > 0)
7310 mhi = lshift(mhi, m2);
7311
7312 /* Compute mlo -- check for special case
7313 * that d is a normalized power of 2.
7314 */
7315
7316 mlo = mhi;
7317 if (spec_case) {
7318 mhi = Balloc(mhi->k);
7319 Bcopy(mhi, mlo);
7320 mhi = lshift(mhi, Log2P);
7321 }
7322
7323 for(i = 1;;i++) {
7324 dig = quorem(b,S) + '0';
7325 /* Do we yet have the shortest decimal string
7326 * that will round to d?
7327 */
7328 j = cmp(b, mlo);
7329 delta = diff(S, mhi);
7330 j1 = delta->sign ? 1 : cmp(b, delta);
7331 Bfree(delta);
7332#ifndef ROUND_BIASED
7333 if (j1 == 0 && !mode && !(getWord1(d) & 1)) {
7334 if (dig == '9')
7335 goto round_9_up;
7336 if (j > 0)
7337 dig++;
7338 *s++ = dig;
7339 goto ret;
7340 }
7341#endif
7342 if (j < 0 || (j == 0 && !mode
7343#ifndef ROUND_BIASED
7344 && !(getWord1(d) & 1)
7345#endif
7346 )) {
7347 if (j1 > 0) {
7348 b = lshift(b, 1);
7349 j1 = cmp(b, S);
7350 if ((j1 > 0 || (j1 == 0 && dig & 1))
7351 && dig++ == '9')
7352 goto round_9_up;
7353 }
7354 *s++ = dig;
7355 goto ret;
7356 }
7357 if (j1 > 0) {
7358 if (dig == '9') { /* possible if i == 1 */
7359 round_9_up:
7360 *s++ = '9';
7361 goto roundoff;
7362 }
7363 *s++ = dig + 1;
7364 goto ret;
7365 }
7366 *s++ = dig;
7367 if (i == ilim)
7368 break;
7369 b = multadd(b, 10, 0);
7370 if (mlo == mhi)
7371 mlo = mhi = multadd(mhi, 10, 0);
7372 else {
7373 mlo = multadd(mlo, 10, 0);
7374 mhi = multadd(mhi, 10, 0);
7375 }
7376 }
7377 }
7378 else
7379 for(i = 1;; i++) {
7380 *s++ = dig = quorem(b,S) + '0';
7381 if (i >= ilim)
7382 break;
7383 b = multadd(b, 10, 0);
7384 }
7385
7386 /* Round off last digit */
7387
7388 b = lshift(b, 1);
7389 j = cmp(b, S);
7390 if (j > 0 || (j == 0 && dig & 1)) {
7391 roundoff:
7392 while(*--s == '9')
7393 if (s == s0) {
7394 k++;
7395 *s++ = '1';
7396 goto ret;
7397 }
7398 ++*s++;
7399 }
7400 else {
7401 while(*--s == '0') {}
7402 s++;
7403 }
7404 ret:
7405 Bfree(S);
7406 if (mhi) {
7407 if (mlo && mlo != mhi)
7408 Bfree(mlo);
7409 Bfree(mhi);
7410 }
7411 ret1:
7412 Bfree(b);
7413 if (s == s0) { /* don't return empty string */
7414 *s++ = '0';
7415 k = 0;
7416 }
7417 *s = 0;
7418 *decpt = k + 1;
7419 if (rve)
7420 *rve = s;
7421 return s0;
7422}
7423#else
7424// NOT thread safe!
7425
7426#include <errno.h>
7427
7428Q_CORE_EXPORT char *qdtoa( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
7429{
7430 if(rve)
7431 *rve = 0;
7432
7433 char *res;
7434 if (mode == 0)
7435 ndigits = 80;
7436
7437 if (mode == 3)
7438 res = fcvt(d, ndigits, decpt, sign);
7439 else
7440 res = ecvt(d, ndigits, decpt, sign);
7441
7442 int n = qstrlen(res);
7443 if (mode == 0) { // remove trailing 0's
7444 const int stop = qMax(1, *decpt);
7445 int i;
7446 for (i = n-1; i >= stop; --i) {
7447 if (res[i] != '0')
7448 break;
7449 }
7450 n = i + 1;
7451 }
7452 *resultp = static_cast<char*>(malloc(n + 1));
7453 Q_CHECK_PTR(resultp);
7454 qstrncpy(*resultp, res, n + 1);
7455 return *resultp;
7456}
7457
7458Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok)
7459{
7460 double ret = strtod((char*)s00, (char**)se);
7461 if (ok) {
7462 if((ret == 0.0l && errno == ERANGE)
7463 || ret == HUGE_VAL || ret == -HUGE_VAL)
7464 *ok = false;
7465 else
7466 *ok = true; // the result will be that we don't report underflow in this case
7467 }
7468 return ret;
7469}
7470#endif // QT_QLOCALE_USES_FCVT
7471
7472QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.