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

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

trunk: Merged in qt 4.6.1 sources.

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